<?xml version="1.0" encoding="utf-8" standalone="yes"?><feed xmlns="http://www.w3.org/2005/Atom">
  <title></title>
  <subtitle></subtitle>
  <id>https://www.endpointdev.com/blog/tags/ssh/</id>
  <link href="https://www.endpointdev.com/blog/tags/ssh/"/>
  <link href="https://www.endpointdev.com/blog/tags/ssh/" rel="self"/>
  <updated>2023-07-21T00:00:00+00:00</updated>
  <author>
    <name>End Point Dev</name>
  </author>
  
    <entry>
      <title>SSH and Old Servers</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2023/07/ssh-and-old-servers/"/>
      <id>https://www.endpointdev.com/blog/2023/07/ssh-and-old-servers/</id>
      <published>2023-07-21T00:00:00+00:00</published>
      <author>
        <name>Josh Ausborne</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;img src=&#34;/blog/2023/07/ssh-and-old-servers/seashell-beach.webp&#34; alt=&#34;A photo of a whole bivalve seashell lying open and flat on the sandy ground.&#34;&gt;&lt;/p&gt;
&lt;!-- Photo by Josh Ausborne --&gt;
&lt;p&gt;We recently updated one of our backup servers from &lt;a href=&#34;https://www.oracle.com/linux/&#34;&gt;Oracle Linux&lt;/a&gt; 8 to Oracle Linux 9, a free rebuild of &lt;a href=&#34;https://www.redhat.com/en/technologies/linux-platforms/enterprise-linux&#34;&gt;Red Hat Enterprise Linux&lt;/a&gt; 9, also known as RHEL 9. As with any newer OS, there are bound to be unexpected little differences which crop up and which need to be handled.&lt;/p&gt;
&lt;p&gt;In the case of our backup server, we found that it could no longer SSH to older servers, which includes a couple running CentOS 5 (yes, there really are a few of those out in the wild), some CentOS 6, and one Debian 8. We saw similar connection problems when we first went from CentOS 7 to Oracle Linux 8, and we addressed the issues by creating a Host entry for the servers in our &lt;code&gt;~/.ssh/config&lt;/code&gt; file.&lt;/p&gt;
&lt;p&gt;Here is an example of of the entry that we used previously:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Host old-server-1 old-server-2 old-server-3
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  User root
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Hostname %h.example.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  KexAlgorithms +diffie-hellman-group-exchange-sha1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This worked fine for a couple of years until we upgraded from Oracle Linux 8 to 9. At this point we started to see a different problem when trying to connect.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Unable to negotiate with &amp;lt;nnn.nnn.nnn.nnn&amp;gt; port 22: no matching host key type found. Their
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;offer: ssh-rsa,ssh-dss&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&#34;troubleshooting&#34;&gt;Troubleshooting&lt;/h3&gt;
&lt;p&gt;One of the good troubleshooting methods for diagnosing SSH connectivity problems is to enable some verbosity when connecting. This can be done via the use of the &lt;code&gt;-v&lt;/code&gt; option, which can be stacked up to three times for increasing levels of detail. In this case, I used &lt;code&gt;ssh -vvv $hostname&lt;/code&gt;, which is the highest level, and I was able to see another error message in the copious output:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ssh_dispatch_run_fatal: Connection to &amp;lt;nnn.nnn.nnn.nnn&amp;gt; port 22: error in libcrypto&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It was at this time that I had to consult with The Fountain of Knowledge (the Internet) to come up with a solution. There were some suggestions to add &lt;code&gt;HostKeyAlgorithms&lt;/code&gt; or &lt;code&gt;PubkeyAcceptedKeyTypes&lt;/code&gt; entries for those hosts in the local SSH config, but that didn’t work in this case.&lt;/p&gt;
&lt;p&gt;What I did find, though, is that RHEL 9-based OSes now forbid via crypto policy the ability to connect using SHA-1, but SHA-1 is the default crypto policy in use by CentOS 5 and CentOS 6! To get around this, I needed to add SHA-1 support to our existing policy. You can compare the crypto policies for &lt;a href=&#34;https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/security_hardening/using-the-system-wide-cryptographic-policies_security-hardening&#34;&gt;RHEL 8 systems&lt;/a&gt; and &lt;a href=&#34;https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/security_hardening/using-the-system-wide-cryptographic-policies_security-hardening&#34;&gt;RHEL 9 systems&lt;/a&gt; to see which is right for your use case.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;update-crypto-policies --set DEFAULT:SHA1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here I also found a bit of info on &lt;a href=&#34;https://access.redhat.com/documentation/fr-fr/red_hat_enterprise_linux/9/html/security_hardening/proc_re-enabling-sha-1_using-the-system-wide-cryptographic-policies&#34;&gt;re-enabling SHA-1&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;a-problem-for-every-solution&#34;&gt;A problem for every solution&lt;/h3&gt;
&lt;p&gt;One more problem that we ran into with one of the CentOS 5 servers is that we were getting a different SSH failure even after having updated the crypto policy. This new problem was about the length of the host key on the old remote server.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Bad server host key: Invalid key length&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;That is because RHEL 9 by default doesn’t like short RSA host keys. Thankfully, there is an option that can be enabled at the SSH client level to help us overcome the limitation. It is solved in the usual manner of adding an option to the &lt;code&gt;~/.ssh/config&lt;/code&gt; file. The option is known as &lt;code&gt;RequiredRSASize&lt;/code&gt;, and it specifies the minimum length of RSA key that is required to be considered valid.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Host old-server-1 old-server-2 old-server-3
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  User root
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Hostname %h.example.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  KexAlgorithms +diffie-hellman-group-exchange-sha1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  RequiredRSASize 1024&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&#34;perfect--enough&#34;&gt;Perfect … enough&lt;/h3&gt;
&lt;p&gt;Obviously we don&amp;rsquo;t want to let old systems just sit out there and keep doing their thing. They increase the attack surface that hackers can target, and it’s important to stay on top of updating and upgrading. In an ideal world, we’d prefer that we simply replace and modernize the old, thus securing everything, and deal with the pain of upgrading all at one time. We like to just get the headache over with.&lt;/p&gt;
&lt;p&gt;In the real world, though, some old systems just have to stay in place for a little longer (or “much longer” in this case) than we’d prefer. It’s helpful to figure out acceptable ways to work around the limitations when these issues arise, while wherever possible making the exceptions only for the specific old hosts we want to tolerate.&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>Mount a remote filesystem over SSH using SSHFS</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2023/05/mount-remote-filesystem-sshfs/"/>
      <id>https://www.endpointdev.com/blog/2023/05/mount-remote-filesystem-sshfs/</id>
      <published>2023-05-25T00:00:00+00:00</published>
      <author>
        <name>Trevor Slocum</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;img src=&#34;/blog/2023/05/mount-remote-filesystem-sshfs/estuary_at_days_end_crop.webp&#34; alt=&#34;A painting of a Dutch port at the end of the day. On the left, sunlight peeks out from clouds low on the horizon, casting rays of light into the light blue sky of the fading day. Trading ships sail the waters, with some disappearing into the horizon. In the foreground, a smaller boat of people and barrels is rowed to an outcropping of land, on which is a boat being tarred by two sailors. A small fire heats a pot next to wooden dock equipment which protrudes into the air.&#34;&gt;&lt;/p&gt;
&lt;!-- Image: Simon de Vlieger, Estuary at Day&#39;s End, c. 1640/1645 (cropped from original). Public domain via CC0 --&gt;
&lt;p&gt;While creating and debugging software, it is important to reduce the amount of
friction between each iteration of making a change to the software and then
testing that change. Over time, even small amounts of friction can lead to
fatigue and decreased performance of a developer. Because of this, we should take every
opportunity to make our workflow as smooth and comfortable as possible.&lt;/p&gt;
&lt;p&gt;A common source of friction when developing software running on remote systems
is the separation between your personal computer and the server. Your personal
computer likely has an IDE configured just the way you like. The server, on the
other hand, is likely configured to be easily available to everyone on your team.&lt;/p&gt;
&lt;p&gt;You could copy files back and forth between systems using SFTP or some other
file transfer protocol. This works for quick one-off changes, but for
development requiring multiple iterations you likely want a more
streamlined workflow.&lt;/p&gt;
&lt;p&gt;If only there was a way to use the software installed on your personal system
to edit files on a remote system, without copying the files back and forth&amp;hellip;&lt;/p&gt;
&lt;p&gt;There is! &lt;a href=&#34;https://en.wikipedia.org/wiki/SSHFS&#34;&gt;SSHFS&lt;/a&gt; is a tool for mounting
and interacting with remote directories over &lt;a href=&#34;https://en.wikipedia.org/wiki/Secure_Shell&#34;&gt;SSH&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;notice&#34;&gt;Notice&lt;/h3&gt;
&lt;p&gt;The &lt;a href=&#34;https://github.com/libfuse/sshfs&#34;&gt;SSHFS repository&lt;/a&gt; has been archived for around a year at the time of writing; the latest release was on May 26, 2022. The repository now has a note about being orphaned and inviting other developers to take over the project. While there are a few forks (most notably &lt;a href=&#34;https://github.com/deadbeefsociety/sshfs&#34;&gt;deadbeefsociety&amp;rsquo;s&lt;/a&gt; and &lt;a href=&#34;https://github.com/stevenxxiu/sshfs&#34;&gt;stephenxxiu&amp;rsquo;s&lt;/a&gt;) with some traction, none is a definitive replacement yet.&lt;/p&gt;
&lt;p&gt;One alternative suggested by the ArchWiki is using &lt;a href=&#34;https://rclone.org/commands/rclone_mount/&#34;&gt;rclone&amp;rsquo;s mount feature&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For macOS users, it&amp;rsquo;s important to note that macFUSE is &lt;a href=&#34;https://colatkinson.site/macos/fuse/2019/09/29/osxfuse/&#34;&gt;no longer open-source&lt;/a&gt; as of 2017.&lt;/p&gt;
&lt;h3 id=&#34;installation&#34;&gt;Installation&lt;/h3&gt;
&lt;p&gt;This guide contains installation instructions for macOS and Linux systems only.&lt;/p&gt;
&lt;p&gt;If you are using Windows, check out &lt;a href=&#34;https://github.com/winfsp/sshfs-win&#34;&gt;sshfs-win&lt;/a&gt;.&lt;/p&gt;
&lt;h4 id=&#34;macos-instructions&#34;&gt;macOS instructions&lt;/h4&gt;
&lt;p&gt;Download the macFUSE and SSHFS packages from &lt;a href=&#34;https://osxfuse.github.io&#34;&gt;the osxfuse website&lt;/a&gt;
and install them as an administrator.&lt;/p&gt;
&lt;h4 id=&#34;linux-instructions&#34;&gt;Linux instructions&lt;/h4&gt;
&lt;p&gt;SSHFS is available from the package repositories of most distributions. This is
usually the preferred way to install software on Linux.&lt;/p&gt;
&lt;p&gt;On Debian and Ubuntu systems, the following command will install the latest
version of SSHFS available:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo apt update &amp;amp;&amp;amp; sudo apt install sshfs&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&#34;usage&#34;&gt;Usage&lt;/h3&gt;
&lt;p&gt;After installation you may interact with SSHFS via the &lt;code&gt;sshfs&lt;/code&gt; command.&lt;/p&gt;
&lt;p&gt;Before we mount a remote directory, let&amp;rsquo;s create a local directory that will
serve as the local mount point:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mkdir /tmp/remote&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Let&amp;rsquo;s say we want to mount the remote directory &lt;code&gt;/var/www/html&lt;/code&gt; of the remote
system at &lt;code&gt;example.com&lt;/code&gt; while connected as the remote user &lt;code&gt;wildfly&lt;/code&gt;. We want to mount this
remote directory at the local directory &lt;code&gt;/tmp/remote&lt;/code&gt;. To accomplish this, we
would execute the following command:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sshfs -o &lt;span style=&#34;color:#369&#34;&gt;compression&lt;/span&gt;=no,cache=yes,cache_timeout=20,auto_cache,idmap=user wildfly@example.com:/var/www/html /tmp/remote&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The following mount options are given using the &lt;code&gt;-o&lt;/code&gt; argument:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;compression=no&lt;/code&gt; - Disable compression. The performance impact of enabling
compression is not worth the minimal bandwidth savings.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cache=yes&lt;/code&gt; - Enable caching. Files that are repeatedly accessed within a
certain period of time will only be retrieved once.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cache_timeout=20&lt;/code&gt; - Set cache timeout, in seconds.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;auto_cache&lt;/code&gt; - Enable caching based on file modification times.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;idmap=user&lt;/code&gt; - Translate between UID of connecting user and remote user. This
causes remote files to appear to be owned by you, even though they are actually
owned by the remote user on the remote system.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To unmount on linux, run &lt;code&gt;fusermount -u /tmp/remote&lt;/code&gt;. On macOS, run &lt;code&gt;umount /tmp/remote&lt;/code&gt;.&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>SSH host key verification: a few useful tips</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2023/04/ssh-host-key/"/>
      <id>https://www.endpointdev.com/blog/2023/04/ssh-host-key/</id>
      <published>2023-04-13T00:00:00+00:00</published>
      <author>
        <name>Selvakumar Arumugam</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;img src=&#34;/blog/2023/04/ssh-host-key/key.webp&#34; alt=&#34;A close shot of a large golden key sitting on top of a wooden fence. There is green grass visible behind the fence, on the left and right upper sides of the image.&#34;&gt;&lt;/p&gt;
&lt;p&gt;The SSH connections between a client and a remote server begin with a host key verification as an initial handshake. If the default key algorithm is not supported between the client and server, the SSH connection attempt is closed with no matching host key type response.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ sftp username@domain
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Unable to negotiate with xx.xx.xx.xx port 22: no matching host key type found. Their offer: ssh-rsa
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Connection closed.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Connection closed&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In this article, we will explore the host key verification process and discuss ways to handle the non-matching host key issue to establish the connection.&lt;/p&gt;
&lt;h3 id=&#34;host-keys&#34;&gt;Host keys&lt;/h3&gt;
&lt;p&gt;By default, OpenSSH automatically generates a public-private key pair on the server and stores it in &lt;code&gt;/etc/ssh&lt;/code&gt;. These keys, known as host keys, are created using several encryption algorithms including RSA, DSA, ECDSA, and ed25519.&lt;/p&gt;
&lt;p&gt;The pair of private and public keys is available on the host server at the path &lt;code&gt;/etc/ssh&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ ls /etc/ssh | grep key
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ssh_host_dsa_key
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ssh_host_dsa_key.pub
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ssh_host_ecdsa_key
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ssh_host_ecdsa_key.pub
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ssh_host_ed25519_key
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ssh_host_ed25519_key.pub
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ssh_host_rsa_key
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ssh_host_rsa_key.pub&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&#34;how-does-openssh-decide-which-host-key-to-use&#34;&gt;How does OpenSSH decide which host key to use?&lt;/h3&gt;
&lt;p&gt;During SSH connection establishment, the OpenSSH server presents a default host key signature algorithm to the SSH client. To check the list of key signature algorithms and their order, you can perform a query with &lt;code&gt;ssh -Q sig&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ ssh -Q sig
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ssh-ed25519
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sk-ssh-ed25519@openssh.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ssh-rsa
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rsa-sha2-256
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rsa-sha2-512
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ssh-dss
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ecdsa-sha2-nistp256
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ecdsa-sha2-nistp384
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ecdsa-sha2-nistp521
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sk-ecdsa-sha2-nistp256@openssh.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;webauthn-sk-ecdsa-sha2-nistp256@openssh.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&#34;hostkeyalgorithms&#34;&gt;HostKeyAlgorithms&lt;/h3&gt;
&lt;p&gt;You can also get a list of key types and signature algorithms with &lt;code&gt;ssh -Q HostKeyAlgorithms&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ ssh -Q HostKeyAlgorithms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ssh-ed25519
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ssh-ed25519-cert-v01@openssh.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sk-ssh-ed25519@openssh.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sk-ssh-ed25519-cert-v01@openssh.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ssh-rsa
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rsa-sha2-256
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rsa-sha2-512
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ssh-dss
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ecdsa-sha2-nistp256
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ecdsa-sha2-nistp384
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ecdsa-sha2-nistp521
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sk-ecdsa-sha2-nistp256@openssh.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;webauthn-sk-ecdsa-sha2-nistp256@openssh.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ssh-rsa-cert-v01@openssh.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rsa-sha2-256-cert-v01@openssh.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rsa-sha2-512-cert-v01@openssh.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ssh-dss-cert-v01@openssh.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ecdsa-sha2-nistp256-cert-v01@openssh.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ecdsa-sha2-nistp384-cert-v01@openssh.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ecdsa-sha2-nistp521-cert-v01@openssh.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sk-ecdsa-sha2-nistp256-cert-v01@openssh.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The default list of host keys can be modified on the OpenSSH server by configuring the &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt; file, as described below.&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Symbol&lt;/th&gt;
          &lt;th&gt;Description&lt;/th&gt;
          &lt;th&gt;Example&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;+&amp;lt;algorithm_name&amp;gt;&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Algorithm will be appended to default set of list&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;+rsa-sha&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;-&amp;lt;algorithm_name&amp;gt;&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Algorithm will be removed&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;-rsa-sha&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;^&amp;lt;algorithm_name&amp;gt;&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Algorithm will be default value on top of list&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;^rsa-sha&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;You can see more in-depth info about SSH configuration with &lt;code&gt;man 5 ssh_config&lt;/code&gt;.&lt;/p&gt;&lt;/blockquote&gt;
&lt;h3 id=&#34;identify-host-key-type&#34;&gt;Identify host key type&lt;/h3&gt;
&lt;p&gt;SSH client and server logs provide valuable information about the host key algorithm types that are offered during SSH connections. In case of a mismatch between the client and server, the logs will record the offered key information from the other end. This information will be useful for troubleshooting and identifying the root cause of the issue.&lt;/p&gt;
&lt;p&gt;SSH client output:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ sftp -o HostKeyAlgorithms=ssh-rsa  username@domain
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Unable to negotiate with &amp;lt;server_id&amp;gt; port 22: no matching host key type found.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Their offer: rsa-sha2-512,rsa-sha2-256&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;SSH Server log (&lt;code&gt;/var/log/auth.log&lt;/code&gt;):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;2022-06-28T22:26:46.692753-07:00 localhost sshd[445086]:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Unable to negotiate with &amp;lt;client_id&amp;gt; port 55872: no matching host key type found.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Their offer: ssh-rsa [preauth]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&#34;third-party-application-logs&#34;&gt;Third-party application logs&lt;/h4&gt;
&lt;p&gt;Some third-party applications return the MD5 hash code in the event of a failed SSH connection attempt. This code can be useful in identifying the exact matching key algorithm that needs to be included in the server.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Limiting the SSH algorithms for the SFTP connection to
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;the following: none, zlib, zlib@openssh.com, aes256-chc, aes192-che,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;aes128-cbe, diffie-hellman-group14-sha256, ecdh-sha2-nistp256,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ecdh-sha2-nistp384, ecdh-sha2-nistp521, ssh-dss, ssh-rsa, hmac-sha2-
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;256, hmac-sha2-512, hmac-shal.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Configuring server validation for the SSH connection using
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;public keys: 3072: 8b 7e de 33 d8 f4 f5 82 d6 86 68 41 17 ba 72 4c.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The MD5 value of a key found in a third-party application log can be used to identify the matching key on the server with the help of the ssh-keygen utility.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ ssh-keygen -lf ssh_host_rsa_key.pub
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;3072 SHA256:kkcdlhNcj8DndHvyLBXGfhI/oZkrTRIAbwuqqd58uY0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ ssh-keygen -E md5 -lf ssh_host_rsa_key.pub
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;3072 MD5:8b:7e:de:33:d8:f4:f5:82:d6:86:68:41:17:ba:72:4c root@ndpbh-test-epitrax-app01 (RSA)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&#34;ssh-rsa-disabled-by-default&#34;&gt;ssh-rsa disabled by default&lt;/h3&gt;
&lt;p&gt;Since the release of OpenSSH version 8.8, the ssh-rsa key algorithm has been disabled. As a result, accessing the latest version of the OpenSSH server from an older client version may lead to non-matching host key failures.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ ssh -V
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;OpenSSH_8.9p1 Ubuntu-3, OpenSSL 3.0.2 15 Mar 2022&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Notice: &lt;a href=&#34;http://www.openssh.com/txt/release-8.7&#34;&gt;http://www.openssh.com/txt/release-8.7&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Imminent deprecation notice
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;===========================
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;OpenSSH will disable the ssh-rsa signature scheme by default in the
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;next release.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Legacy Support: &lt;a href=&#34;https://www.openssh.com/txt/release-8.8&#34;&gt;https://www.openssh.com/txt/release-8.8&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Potentially-incompatible changes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;================================
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;This release disables RSA signatures using the SHA-1 hash algorithm
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;by default. This change has been made as the SHA-1 hash algorithm is
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cryptographically broken, and it is possible to create chosen-prefix
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hash collisions for &amp;lt;USD$50K [1]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;For most users, this change should be invisible and there is
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;no need to replace ssh-rsa keys. OpenSSH has supported RFC8332
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;RSA/SHA-256/512 signatures since release 7.2 and existing ssh-rsa keys
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;will automatically use the stronger algorithm where possible.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Incompatibility is more likely when connecting to older SSH
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;implementations that have not been upgraded or have not closely tracked
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;improvements in the SSH protocol. For these cases, it may be necessary
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;to selectively re-enable RSA/SHA1 to allow connection and/or user
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;authentication via the HostkeyAlgorithms and PubkeyAcceptedAlgorithms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;options. For example, the following stanza in ~/.ssh/config will enable
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;RSA/SHA1 for host and user authentication for a single destination host:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    Host old-host
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        HostkeyAlgorithms +ssh-rsa
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	PubkeyAcceptedAlgorithms +ssh-rsa
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;We recommend enabling RSA/SHA1 only as a stopgap measure until legacy
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;implementations can be upgraded or reconfigured with another key type
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(such as ECDSA or Ed25519).
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[1] &amp;#34;SHA-1 is a Shambles: First Chosen-Prefix Collision on SHA-1 and
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    Application to the PGP Web of Trust&amp;#34; Leurent, G and Peyrin, T
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (2020) https://eprint.iacr.org/2020/014.pdf&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&#34;solution&#34;&gt;Solution&lt;/h3&gt;
&lt;p&gt;The SSH client and server offer options to specify the host key algorithm to use during SSH connections. Therefore, you can modify the client or server configuration to establish a connection based on the restrictions of one of the systems involved.&lt;/p&gt;
&lt;p&gt;Establishing an SSH connection using the most secure host key algorithm is highly recommended for optimal security. However, in situations where there are limitations on upgrading or changing the algorithm, users must make decisions based on the security policies of their application environment.&lt;/p&gt;
&lt;p&gt;In such cases, a suggested solution is to carefully evaluate the security requirements of the application environment and choose the host key algorithm that best aligns with those requirements. This may involve a trade-off between security and compatibility, so it is important to weigh the potential risks and benefits of each option.&lt;/p&gt;
&lt;h4 id=&#34;ssh-client&#34;&gt;SSH Client&lt;/h4&gt;
&lt;p&gt;When the privilege to configure the SSH server is restricted, the SSH client can be configured to use a specific algorithm. To do this, you can use the &lt;code&gt;-o HostKeyAlgorithms=&amp;lt;host_key&amp;gt;&lt;/code&gt; option with the SSH client to specify a particular host key algorithm type.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ sftp username@server
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Unable to negotiate with &amp;lt;server&amp;gt; port 22: no matching host key type found. Their offer: ssh-rsa
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Connection closed.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Connection closed&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In the above case, the SSH server uses ssh-rsa as the host key algorithm to establish connections. To use ssh-rsa as the key algorithm for the SSH client, you can configure it as follows.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ sftp -o HostKeyAlgorithms=ssh-rsa username@server
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;username@server~:$&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&#34;ssh-server&#34;&gt;SSH Server&lt;/h4&gt;
&lt;p&gt;In some cases, it may not be possible to configure the SSH client to use a specific key when a third-party proprietary application is used to establish the connection. In such scenarios, the SSH server can be configured to include the required key.&lt;/p&gt;
&lt;p&gt;In our scenario, the third-party application expects the ssh-rsa key type, but the latest version of OpenSSH server does not provide ssh-rsa as it has been deprecated.&lt;/p&gt;
&lt;p&gt;To support old client attempts with ssh-rsa, the key should be added to the bottom of the list with a &amp;ldquo;+&amp;rdquo; symbol. This will allow the server to present the deprecated ssh-rsa key to old clients, while still offering more secure key algorithms to newer clients. The new lines in &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt; should look like the following:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;HostKeyAlgorithms +ssh-rsa
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PubkeyAcceptedAlgorithms +ssh-rsa&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Before restarting the SSH service, it is advisable to test the configuration for syntax errors to prevent potential issues, like the following which occurs if you add an extra space to &lt;code&gt;Host KeyAlgorithms +ssh-rsa&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# sshd -t
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/etc/ssh/sshd_config: line 32: Bad configuration option: Host
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/etc/ssh/sshd_config: terminating, 1 bad configuration options&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Once you&amp;rsquo;ve verified the configuration and &lt;code&gt;sshd -t&lt;/code&gt; gives no output, go ahead and restart the service to apply the changes.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# sshd -t
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# systemctl reload sshd.service&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;With this configuration, SSH clients can connect to the server using ssh-rsa. To verify the host key type used in an SSH connection, you can use the verbose (&lt;code&gt;-v&lt;/code&gt;) option with the &lt;code&gt;ssh&lt;/code&gt; command. This will display additional information about the SSH connection, including the host key algorithm being used. Here we increase the verbosity by adding the maximum of 3 &lt;code&gt;-v&lt;/code&gt; options.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ ssh -vvv -oHostKeyAlgorithms=ssh-rsa username@domain
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;…
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;debug2: host key algorithms: ssh-rsa
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;debug1: Will attempt key: .ssh/id_rsa RSA
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;SHA256:CmARXi+/8UwrvzwS7RkJNqD/rhroYTnfB285OnovVFs agent
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;…&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h4&gt;
&lt;p&gt;SSH is an incredible tool, but errors like the ones described here can make it a bit harder to work with if you&amp;rsquo;re not aware of what&amp;rsquo;s going on behind the scenes. Let us know in the comments if you&amp;rsquo;ve had any similar experiences!&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>ssh-askpass on macOS for SSH agent confirmation</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2022/11/ssh-askpass-on-mac-os-for-agent-confirmation/"/>
      <id>https://www.endpointdev.com/blog/2022/11/ssh-askpass-on-mac-os-for-agent-confirmation/</id>
      <published>2022-11-23T00:00:00+00:00</published>
      <author>
        <name>Bharathi Ponnusamy</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;img src=&#34;/blog/2022/11/ssh-askpass-on-mac-os-for-agent-confirmation/night-street.webp&#34; alt=&#34;A city street at night. A man sits on a bench, looking at his laptop as cyclists pass by.&#34;&gt;&lt;br&gt;
&lt;a href=&#34;https://flic.kr/p/2nUPsJQ&#34;&gt;Photo&lt;/a&gt; by &lt;a href=&#34;https://www.flickr.com/people/kristoffer-trolle/&#34;&gt;Kristoffer Trolle&lt;/a&gt;, &lt;a href=&#34;https://creativecommons.org/licenses/by/2.0/&#34;&gt;CC BY 2.0&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;At End Point Dev we mostly use SSH keys for authentication when connecting to remote servers and Git services. The majority of the time, the servers we are trying to visit are barred from direct access and require a middle &amp;ldquo;jump server&amp;rdquo; instead.&lt;/p&gt;
&lt;p&gt;Enabling SSH agent forwarding makes it easier to reuse SSH private keys. It keeps the private keys on our local machine and uses them to authenticate with each server in the chain without entering a password.&lt;/p&gt;
&lt;p&gt;However, this approach comes with an inherent risk of the agent being hijacked if one of the servers is compromised. This means a bad guy could use the SSH keys to compromise downstream servers.&lt;/p&gt;
&lt;p&gt;In this post, we’ll cover a simple way to protect against SSH agent hijacking. We will see in detail on macOS how to configure a system-wide agent using ssh-askpass to pop up a graphical window to ask for confirmation before using the agent.&lt;/p&gt;
&lt;h3 id=&#34;how-it-works&#34;&gt;How it works&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2022/11/ssh-askpass-on-mac-os-for-agent-confirmation/ssh-askpass.webp&#34; alt=&#34;Agent confirmation dialog reading &amp;ldquo;Allow us of key /Users/(blank)/.ssh/id_rsa? Key fingerprint (blank) (blank). The cancel button is highlighted.&#34;&gt;&lt;/p&gt;
&lt;p&gt;It is strongly recommended to use the &lt;code&gt;-c&lt;/code&gt; option on the &lt;code&gt;ssh-add&lt;/code&gt; command when adding your SSH keys to the agent in order to protect yourself against SSH agent hijacking.&lt;/p&gt;
&lt;p&gt;With this, every time a request is made to utilize the private key stored in the SSH agent, ssh-askpass will display a prompt on your local computer asking you to approve the usage of the key. By doing this,  it becomes more difficult for a remote attacker to use the private key without authorization.&lt;/p&gt;
&lt;p&gt;If you don&amp;rsquo;t want to use the ssh-askpass agent confirmation, I recommend using the OpenSSH feature ProxyJump rather than agent forwarding to get an equivalent level of security.&lt;/p&gt;
&lt;h3 id=&#34;installing-ssh-askpass-on-macos&#34;&gt;Installing ssh-askpass on macOS&lt;/h3&gt;
&lt;p&gt;So let&amp;rsquo;s set this up. The recommended way is with Homebrew:&lt;/p&gt;
&lt;h4 id=&#34;install-ssh-askpass-with-homebrew&#34;&gt;Install ssh-askpass with Homebrew&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ brew tap theseal/ssh-askpass
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ brew install ssh-askpass&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You might see some warnings. Go ahead and proceed with them.&lt;/p&gt;
&lt;p&gt;Now we need to start the Homebrew services. Note that this is a brew service, not a regular macOS daemon service.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ brew services start theseal/ssh-askpass/ssh-askpass
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;=&amp;gt; Successfully started `ssh-askpass` (label: homebrew.mxcl.ssh-askpass)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Behind the scenes, it just sets the &lt;code&gt;SSH_ASKPASS&lt;/code&gt; and &lt;code&gt;SUDO_ASKPASS&lt;/code&gt; environment variables and stops &lt;code&gt;ssh-agent&lt;/code&gt;, so that the SSH agent can pick up these environment variables when it restarts.&lt;/p&gt;
&lt;p&gt;To list the services and make sure it’s started:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ brew services list | grep ssh-askpass
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ssh-askpass started ~/Library/LaunchAgents/homebrew.mxcl.ssh-askpass.plist&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&#34;install-ssh-askpass-with-macports&#34;&gt;Install ssh-askpass with MacPorts&lt;/h4&gt;
&lt;p&gt;If you prefer MacPorts, do:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ sudo port install ssh-askpass&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&#34;install-ssh-askpass-from-source-code&#34;&gt;Install ssh-askpass from source code&lt;/h4&gt;
&lt;p&gt;And of course you can install from source if you wish:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ cp ssh-askpass /usr/local/bin/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ cp ssh-askpass.plist ~/Library/LaunchAgents/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ launchctl load -w ~/Library/LaunchAgents/ssh-askpass.plist&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&#34;configure-the-ssh-agent-with-the-ssh-add--c-option&#34;&gt;Configure the SSH agent with the &lt;code&gt;ssh-add -c&lt;/code&gt; option&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Let&amp;rsquo;s first verify that the agent is running, then add the private key with the confirmation option:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ ssh-add -l
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;The agent has no identities.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ ssh-add -c .ssh/id_rsa
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Enter passphrase for .ssh/id_rsa (will confirm after each use):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Identity added: .ssh/id_rsa (.ssh/id_rsa)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;The user must confirm each use of the key&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The Identity will get added if you provide the correct passphrase for the key. This can be confirmed by listing the keys again with &lt;code&gt;ssh-add -l&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;ssh-askpass-agent-confirmation&#34;&gt;ssh-askpass agent confirmation&lt;/h3&gt;
&lt;p&gt;Now let&amp;rsquo;s log into a remote server.&lt;/p&gt;
&lt;p&gt;You will be prompted to confirm the private key’s usage with the pop-up window:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2022/11/ssh-askpass-on-mac-os-for-agent-confirmation/ssh-askpass.webp&#34; alt=&#34;Agent confirmation dialog. Identical to the previous dialog.&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;set-up-keyboard-shortcuts&#34;&gt;Set up keyboard shortcuts&lt;/h3&gt;
&lt;p&gt;Since it&amp;rsquo;s too easy to hit the spacebar and accept a connection, ssh-askpass defaults to the cancel option. We can use keyboard shortcuts to press &amp;ldquo;OK&amp;rdquo; by following the below steps.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Go to &amp;ldquo;System Preferences&amp;rdquo; and then &amp;ldquo;Keyboard&amp;rdquo;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;macos-1015-catalina-11-big-sur-12-monterey&#34;&gt;macOS 10.15 Catalina, 11 Big Sur, 12 Monterey&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Go to &amp;ldquo;Shortcuts&amp;rdquo; tab&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;check the option &amp;ldquo;Use keyboard navigation to move focus between controls&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2022/11/ssh-askpass-on-mac-os-for-agent-confirmation/keyboard_shortcuts.webp&#34; alt=&#34;macOS 10.15+ settings open to the Keyboard section. First highlighted is the &amp;ldquo;Shortcuts&amp;rdquo; tab, and second is a checkbox at the bottom of the window reading &amp;ldquo;Use keyboard navigation to move focus between controls.&amp;rdquo;&#34;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;macos-13-ventura&#34;&gt;macOS 13 Ventura&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Turn on the &amp;ldquo;Keyboard navigation&amp;rdquo; option.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2022/11/ssh-askpass-on-mac-os-for-agent-confirmation/keyboard_shortcuts_on_ventura.webp&#34; alt=&#34;macOS 13.0 settings open to the keyboard tab, with a slider button reading &amp;ldquo;Keyboard navigation&amp;rdquo; highlighted.&#34;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now you can press tab ⇥ and then the spacebar to select &amp;ldquo;OK&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>SSH Key Auth using KeeAgent with Git Bash and Windows CLI OpenSSH</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2022/08/keeagent-with-git-bash-and-windows-cli-openssh/"/>
      <id>https://www.endpointdev.com/blog/2022/08/keeagent-with-git-bash-and-windows-cli-openssh/</id>
      <published>2022-08-08T00:00:00+00:00</published>
      <author>
        <name>Ron Phipps</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;img src=&#34;/blog/2022/08/keeagent-with-git-bash-and-windows-cli-openssh/street-couch.webp&#34; alt=&#34;A leather couch in surprisingly good condition sits on a patch of grass between the sidewalk and the road. Harsh sunlight casts shadows of trees and buildings on the street and couch.&#34;&gt;&lt;/p&gt;
&lt;!-- Photo by Seth Jensen --&gt;
&lt;p&gt;In a &lt;a href=&#34;/blog/2022/07/windows-ssh-key-agent-forwarding-confirmation/&#34;&gt;previous blog post&lt;/a&gt; we showed how to configure KeePass and KeeAgent on Windows to provide SSH key agent forwarding with confirmation while using PuTTY and other PuTTY agent compatible programs. In this post we’ll expand on that by showing how to use the same key agent to provide SSH key auth when using Git Bash and the Windows command line OpenSSH.&lt;/p&gt;
&lt;h3 id=&#34;git-bash-support&#34;&gt;Git Bash support&lt;/h3&gt;
&lt;p&gt;Open KeePass, click on Tools → Options, select the KeeAgent tab.&lt;/p&gt;
&lt;p&gt;Create &lt;code&gt;C:\Temp&lt;/code&gt; if it does not exist.&lt;/p&gt;
&lt;p&gt;Check the two boxes in the Cygwin/MSYS Integration section.&lt;/p&gt;
&lt;p&gt;Directly after each box, fill in the path: &lt;code&gt;C:\Temp\cygwin-ssh.socket&lt;/code&gt; for the Cygwin compatible socket file, and &lt;code&gt;C:\Temp\msys-ssh.socket&lt;/code&gt; for the msysGit compatible socket file.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2022/08/keeagent-with-git-bash-and-windows-cli-openssh/1-options-gitbash.webp&#34; alt=&#34;KeePass options, open to the KeeAgent tab. Highlighted is the Cygwin/MSYS section, with two boxes checked. One reads &amp;ldquo;Create Cygwin compatible socket file (works with some versions of MSYS)&amp;rdquo;. The other reads &amp;ldquo;Create msysGit compatible socket file&amp;rdquo;. After each is the path described above.&#34;&gt;&lt;/p&gt;
&lt;p&gt;Click OK.&lt;/p&gt;
&lt;p&gt;Open Git Bash.&lt;/p&gt;
&lt;p&gt;Create the file &lt;code&gt;~/.bash_profile&lt;/code&gt; with the contents:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#038&#34;&gt;test&lt;/span&gt; -f ~/.profile &amp;amp;&amp;amp; . ~/.profile
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#038&#34;&gt;test&lt;/span&gt; -f ~/.bashrc &amp;amp;&amp;amp; . ~/.bashrc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Create the file &lt;code&gt;~/.bashrc&lt;/code&gt; with the contents:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#038&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#369&#34;&gt;SSH_AUTH_SOCK&lt;/span&gt;=&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;C:\Temp\cygwin-ssh.socket&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Close and reopen Git Bash.&lt;/p&gt;
&lt;p&gt;You should now be able to SSH with Git Bash using your loaded SSH key and a dialog box should appear to approve the use of the key.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2022/08/keeagent-with-git-bash-and-windows-cli-openssh/2-gitbash-ssh.webp&#34; alt=&#34;Git Bash running ssh to a redacted server, with a dialog box reading &amp;ldquo;(ssh) has requested to use the SSH key (redacted) with fingerprint (redacted). Do you want to allow this?&amp;rdquo; The dialog&amp;rsquo;s &amp;ldquo;No&amp;rdquo; button is selected by default.&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;windows-command-line-openssh-support&#34;&gt;Windows command line OpenSSH support&lt;/h3&gt;
&lt;p&gt;Open KeePass, click on Tools → Options, select the KeeAgent tab.&lt;/p&gt;
&lt;p&gt;Scroll down and click on the box next to “Enable agent for Windows OpenSSH (experimental).”&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2022/08/keeagent-with-git-bash-and-windows-cli-openssh/3-options-windowsopenssh.webp&#34; alt=&#34;KeePass options open to the KeeAgent tab. Inside a scrollable list is a checked checkbox reading &amp;ldquo;Enable agent for Windows OpenSSH (experimental)&amp;rdquo;&#34;&gt;&lt;/p&gt;
&lt;p&gt;Click OK.&lt;/p&gt;
&lt;p&gt;Open a Windows Command Prompt.&lt;/p&gt;
&lt;p&gt;You should now be able to SSH with Windows CLI using your loaded SSH key and a dialog box should appear to approve the use of the key.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2022/08/keeagent-with-git-bash-and-windows-cli-openssh/4-windows-cli-ssh.webp&#34; alt=&#34;Windows Command Prompt running SSH, with the same KeePass dialog box asking approval for using the loaded SSH key&#34;&gt;&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>Windows SSH key agent forwarding confirmation</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2022/07/windows-ssh-key-agent-forwarding-confirmation/"/>
      <id>https://www.endpointdev.com/blog/2022/07/windows-ssh-key-agent-forwarding-confirmation/</id>
      <published>2022-07-26T00:00:00+00:00</published>
      <author>
        <name>Ron Phipps</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;img src=&#34;/blog/2022/07/windows-ssh-key-agent-forwarding-confirmation/sunset.webp&#34; alt=&#34;A sunset with silhouetted construction equipment&#34;&gt;&lt;/p&gt;
&lt;!-- Photo by Seth Jensen --&gt;
&lt;p&gt;At End Point we use SSH keys extensively, primarily for authentication with servers for remote shell access as well as with Git services including GitHub, GitLab, and Bitbucket. Most of the time the servers we are attempting to reach are blocked from direct access and require that we go through an intermediate “jump server”.&lt;/p&gt;
&lt;p&gt;Because of this need to jump from server to server we utilize SSH key forwarding that allows us to use the private key stored on our local system to authenticate with each of the servers in the chain. When we reach our destination server we can use the same private key to authenticate with the Git hosting service and perform git commands without having to enter a password.&lt;/p&gt;
&lt;p&gt;One of the best practices when using SSH key forwarding is to use an option called key confirmation. When key confirmation is turned on, each time a request is made to use the private key that is loaded in the SSH agent a prompt will appear on your local machine to approve the use of the key. This reduces the ability for an attacker to use your private key without approval.&lt;/p&gt;
&lt;p&gt;For the longest time SSH key confirmation was not available on Windows. One of the most popular SSH clients on Windows is PuTTY and its agent (pageant) does not support the option. Many other SSH key compatible Windows applications use PuTTY’s agent for SSH key caching and as a result these applications also lack the ability for key confirmation.&lt;/p&gt;
&lt;h3 id=&#34;keepass-and-keeagent&#34;&gt;KeePass and KeeAgent&lt;/h3&gt;
&lt;p&gt;To use key confirmation on Windows we need to utilize two programs, KeePass and KeeAgent. KeePass is an open source password manager and KeeAgent is a plugin for KeePass that provides a PuTTY-compatible SSH key agent. It also appears that KeeAgent has support for integration with the Windows shell, Cygwin/MSYS, and Git Bash.&lt;/p&gt;
&lt;p&gt;The instructions below will assume that you already have a SSH key in PuTTY that you’d like to use with key confirmation and that you have previously used PuTTY with key forwarding.&lt;/p&gt;
&lt;p&gt;You should start by &lt;a href=&#34;https://keepass.info/&#34;&gt;installing KeePass&lt;/a&gt;. Then &lt;a href=&#34;https://lechnology.com/software/keeagent/&#34;&gt;install KeeAgent&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Once both are installed create a new KeePass database, or use your existing database if you are already a KeePass user.&lt;/p&gt;
&lt;p&gt;Add a new entry to the database and name it SSH key. Enter your SSH key password into the Password and Repeat fields.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2022/07/windows-ssh-key-agent-forwarding-confirmation/1-add-entry.webp&#34; alt=&#34;KeePass’s Add Entry screen&#34;&gt;&lt;/p&gt;
&lt;p&gt;Then click on the KeeAgent tab and check ‘Allow KeeAgent to use this entry’.&lt;/p&gt;
&lt;p&gt;In the Private Key section select External File and point it at your PuTTY private key. If you have entered the correct password on the first tab you should see your key comment and fingerprint listed. Then press OK.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2022/07/windows-ssh-key-agent-forwarding-confirmation/2-add-entry.webp&#34; alt=&#34;The KeeAgent tab in Add Entry&#34;&gt;&lt;/p&gt;
&lt;p&gt;Verify that confirmation is enabled by clicking on Tools -&amp;gt; Options and selecting the KeeAgent tab.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2022/07/windows-ssh-key-agent-forwarding-confirmation/3-options.webp&#34; alt=&#34;A checked box reading &amp;ldquo;Always require user confirmation when a client program requests to use a key&amp;rdquo;&#34;&gt;&lt;/p&gt;
&lt;p&gt;Press OK.&lt;/p&gt;
&lt;p&gt;Then go to File -&amp;gt; Save. Close KeePass and re-open it. You’ll be asked to enter your KeePass password and then you can verify that the agent is loaded with your key by clicking Tools -&amp;gt; KeeAgent.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2022/07/windows-ssh-key-agent-forwarding-confirmation/4-agent.webp&#34; alt=&#34;KeeAgent in Agent Mode&#34;&gt;&lt;/p&gt;
&lt;p&gt;Now when we use PuTTY or another PuTTY agent-compatible program we’ll be presented with a confirmation dialog. Clicking Yes will allow the key to be used.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2022/07/windows-ssh-key-agent-forwarding-confirmation/5-confirmation.webp&#34; alt=&#34;KeeAgent’s confirmation dialog&#34;&gt;&lt;/p&gt;
&lt;p&gt;Notice that the default selected option is No. This is different than the standard openssh-askpass on Linux, which defaults to Yes. If you’re typing along in a fury and the confirmation window pops up and you hit Enter or space, it will decline the use of your SSH key, rather than accepting it.&lt;/p&gt;
&lt;p&gt;If you have enabled SSH key forwarding in the PuTTY options for the connection you’ll be using you can then SSH to other servers using the same key and each time you do so the confirmation will be presented to you.&lt;/p&gt;
&lt;p&gt;If you close KeePass the key agent will be closed and unavailable for future connections. Re-opening KeePass will allow the key to be used again.&lt;/p&gt;
&lt;p&gt;If you use Windows and SSH agent forwarding but have never tried agent confirmation to protect against malicious use of your secret key, give KeePass and KeeAgent a try!&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>Using SSH tunnels to get around network limitations</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2022/01/using-ssh-tunnels-network-limitations/"/>
      <id>https://www.endpointdev.com/blog/2022/01/using-ssh-tunnels-network-limitations/</id>
      <published>2022-01-26T00:00:00+00:00</published>
      <author>
        <name>Zed Jensen</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;img src=&#34;/blog/2022/01/using-ssh-tunnels-network-limitations/banner.jpg&#34; alt=&#34;Cliff dwelling in Arizona&#34;&gt;&lt;/p&gt;
&lt;!-- Picture by Zed Jensen, 2021 --&gt;
&lt;p&gt;SSH is an extremely useful way to use computers that you aren&amp;rsquo;t in front of physically.&lt;/p&gt;
&lt;p&gt;It can also be used to overcome some unique networking challenges, particularly those where one computer needs to connect to another in an unorthodox way. Let me show you a couple of uses of SSH tunnels that have come in handy for me personally.&lt;/p&gt;
&lt;h3 id=&#34;serving-content-without-a-public-ip-address&#34;&gt;Serving content without a public IP address&lt;/h3&gt;
&lt;p&gt;In the past, I wrote about &lt;a href=&#34;/blog/2020/07/automating-minecraft-server/&#34;&gt;maintaining a Minecraft server&lt;/a&gt; to play on with my friends. In that case I was dealing with being physically separated from the server hardware I intended to use, but once I got that machine back, I realized that I still had a problem: My ISP and their networking gear didn&amp;rsquo;t support port forwarding, meaning that I couldn&amp;rsquo;t connect to my server from outside my home network. But even if I could have, the public IP address I was assigned changed regularly.&lt;/p&gt;
&lt;p&gt;One solution I found was to use a reverse SSH tunnel to forward traffic from a publicly-visible virtual server to my local server.&lt;/p&gt;
&lt;p&gt;To set this up, you just need your local machine and a server with a publicly visible IP address. I used a virtual machine from &lt;a href=&#34;https://upcloud.com/&#34;&gt;UpCloud&lt;/a&gt;, which costs $5 per month, but you could use any other server, as long as it has its own IP address. Setup is fairly simple.&lt;/p&gt;
&lt;p&gt;First, on the local machine, we create a new SSH public &amp;amp; private key pair just for this connection. This serves as a way to authenticate without a password, but without using a personal SSH key that has access to many more places.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ssh-keygen -t ed25519 -f ~/.ssh/ed25519 -q -N &amp;#34;&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Next, we create a new OS user &lt;code&gt;proxy&lt;/code&gt; on the server. Creating a user specifically for this purpose lets us make sure that our password-free SSH key doesn&amp;rsquo;t give access to any sensitive data on the remote server. On Linux:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;useradd -m proxy&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then, we add the public key generated earlier to &lt;code&gt;authorized_keys&lt;/code&gt; in the new proxy user&amp;rsquo;s &lt;code&gt;~/.ssh&lt;/code&gt; folder.&lt;/p&gt;
&lt;p&gt;Finally, on the local machine, we run this command:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ssh -fN -i ~/.ssh/id_ed25519 -R 0.0.0.0:25565:localhost:25565 proxy@myserver&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here&amp;rsquo;s what each part of that does:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-f&lt;/code&gt; tells ssh to run in the background.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-N&lt;/code&gt; doesn&amp;rsquo;t run a command on the remote host, which is perfect since we&amp;rsquo;re just forwarding traffic.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-i&lt;/code&gt; specifies the SSH key we&amp;rsquo;re using.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-R&lt;/code&gt; is a bit more complicated. &lt;code&gt;0.0.0.0:25565&lt;/code&gt; specifies which traffic to intercept on the remote host and &lt;code&gt;localhost:25565&lt;/code&gt; where to forward it to. Note that &lt;code&gt;0.0.0.0&lt;/code&gt; means to listen on all IP addresses, such as 127.0.0.1, your internal network NAT address, and any others. &lt;code&gt;25565&lt;/code&gt; is a TCP port number (UDP isn&amp;rsquo;t supported by SSH out of the box) and will vary based on the application you&amp;rsquo;re using.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;proxy@myserver&lt;/code&gt; is the user and hostname of the remote server.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And that&amp;rsquo;s it! The reverse tunnel will now forward traffic from our publicly visible server to the specified port to our machine.&lt;/p&gt;
&lt;p&gt;Another good use for this setup is when you have an IPv4 address at the edge of a network but only IPv6 internally. This is becoming more common as IPv4 addresses become more scarce.&lt;/p&gt;
&lt;p&gt;Also note that for more permanent situations, a VPN like WireGuard or OpenVPN might be a better choice than an SSH tunnel; however, for lower-volume traffic SSH works just fine, and it is often quicker to set up.&lt;/p&gt;
&lt;h3 id=&#34;splitting-a-multi-container-docker-app-between-multiple-machines&#34;&gt;Splitting a multi-container Docker app between multiple machines&lt;/h3&gt;
&lt;p&gt;There are many other uses for SSH tunnels. One of our clients has an application with a lot of different moving parts that all need to communicate with each other for the entire application to function. For instance, there&amp;rsquo;s a database container, a container for part of the backend that needs CUDA support, and several others, in addition to a React frontend. Applications like this can of course slow your computer down quite a bit. What if you only need to make modifications to the frontend or another light part of the application? I asked around and found that a couple of coworkers had already found a workaround.&lt;/p&gt;
&lt;p&gt;The solution is simple but effective: If you have another computer available — in my case, a desktop computer that I don&amp;rsquo;t usually use for work — you can run the performance-intensive containers on that machine. This allows you to work on the lighter parts of the application without experiencing slowdown (or fan noise, or other things like that) on your laptop.&lt;/p&gt;
&lt;p&gt;Because the different parts of the application were already using Docker, it wasn&amp;rsquo;t hard to run the different pieces on separate machines, but they needed to know to talk to each other across the network. SSH tunnels let us do that without modifying our Docker configuration!&lt;/p&gt;
&lt;p&gt;For the rest of this example I&amp;rsquo;ll refer to the two computers in this scenario as &amp;ldquo;the laptop&amp;rdquo; and &amp;ldquo;the desktop&amp;rdquo;, running the frontend and backend portions respectively, but keep in mind that you could do this with other setups as well.&lt;/p&gt;
&lt;h4 id=&#34;1-collecting-some-info&#34;&gt;1. Collecting some info&lt;/h4&gt;
&lt;p&gt;Before we can set everything up, we need to know which ports our application is communicating on. Examining the Dockerfiles for the backend containers in this application, I found that it was using ports 9933, 9934, and 10004. Normally, our frontend application would be communicating with these containers by talking to &lt;code&gt;http://localhost:9933&lt;/code&gt; and so on, but once we know which ports it&amp;rsquo;s going to use, we can set up SSH to forward the traffic to our desktop machine instead.&lt;/p&gt;
&lt;p&gt;The other important piece of info we&amp;rsquo;ll need is the (private home network) IP address of our desktop machine. In this case, mine is &lt;code&gt;192.168.0.55&lt;/code&gt;, so we&amp;rsquo;ll use that.&lt;/p&gt;
&lt;h4 id=&#34;2-setting-up-the-ssh-config&#34;&gt;2. Setting up the SSH config&lt;/h4&gt;
&lt;p&gt;The most important step to making the different machines talk to each other is going to be in our SSH config, &lt;code&gt;~/.ssh/config&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ll start by coming up with an alias hostname for our desktop, like &lt;code&gt;backend&lt;/code&gt;, and creating a section for it in our config file. We then add a &lt;code&gt;LocalForward&lt;/code&gt; line for each port we want to forward like so:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Host backend
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	HostName 192.168.0.55
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	User zed
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	ForwardAgent yes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	LocalForward 9933 127.0.0.1:9933
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	LocalForward 9934 127.0.0.1:9934
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	LocalForward 10004 127.0.0.1:10004&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&#34;3-connecting-the-computers&#34;&gt;3. Connecting the computers&lt;/h4&gt;
&lt;p&gt;For the different parts of the application to talk to each other, there needs to be an active SSH connection. I usually open an SSH connection like normal (make sure to use the hostname we set in step 2!), start a tmux session, and then run the backend portions of the app in the tmux session:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[zed@laptop ~]$ ssh desktop-machine
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[zed@desktop ~]$ get-stuff-started&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;However, if you&amp;rsquo;d prefer, you can also open a reverse SSH connection that will run in the background until killed:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[zed@laptop ~]$ ssh -fN desktop-machine
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[zed@laptop ~]$&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&#34;4-test-it&#34;&gt;4. Test it!&lt;/h4&gt;
&lt;p&gt;Now that we&amp;rsquo;ve got an SSH session running to forward traffic to the desktop machine, you can try spinning up the React app and see if it connects properly.&lt;/p&gt;
&lt;h3 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;There are many other uses for SSH tunnels. Feel free to let us know in the comments how you&amp;rsquo;ve used them!&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>Setting up SSH in Visual Studio Code</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2022/01/setting-up-ssh-visual-studio-code/"/>
      <id>https://www.endpointdev.com/blog/2022/01/setting-up-ssh-visual-studio-code/</id>
      <published>2022-01-06T00:00:00+00:00</published>
      <author>
        <name>Couragyn Chretien</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;img src=&#34;/blog/2022/01/setting-up-ssh-visual-studio-code/banner.jpg&#34; alt=&#34;View of Grand Canyon&#34;&gt;&lt;/p&gt;
&lt;!-- Photo by Zed Jensen, 2021 --&gt;
&lt;p&gt;Visual Studio Code is a powerful code editor that can create a customized IDE for your development. VS Code&amp;rsquo;s default configuration is great for working locally but lacks the functionality to give the same experience for remote SSH development. Enter the extension &lt;a href=&#34;https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh&#34;&gt;Remote SSH&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;installation&#34;&gt;Installation&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2022/01/setting-up-ssh-visual-studio-code/marketplace.png&#34; alt=&#34;Remote SSH in Visual Studio Code Marketplace&#34;&gt;&lt;/p&gt;
&lt;p&gt;Installing the Remote SSH extension is really easy! First you access the Extension Marketplace with &lt;code&gt;Ctrl+Shift+X&lt;/code&gt; or by clicking &lt;code&gt;View &amp;gt; Extensions&lt;/code&gt; in the menu, then you just search for and select &lt;code&gt;Remote - SSH&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;setting-up-your-ssh-config-file&#34;&gt;Setting up your SSH config file&lt;/h3&gt;
&lt;p&gt;To configure your connection, you&amp;rsquo;ll need to add a few lines to your SSH config. Click the green &lt;code&gt;Open a Remote Window&lt;/code&gt; icon on the bottom left corner:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/blog/2022/01/setting-up-ssh-visual-studio-code/open_remote_window.png&#34; alt=&#34;Open Remote Window&#34;&gt;&lt;/p&gt;
&lt;p&gt;Select &lt;code&gt;Open SSH Configuration File...&lt;/code&gt; and select the config file you want to use. I use the Linux default, &lt;code&gt;/home/$USER/.ssh/config&lt;/code&gt;. Add the Host, HostName, and User as required and save:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Host MySite
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  HostName site.endpointdev.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  User couragyn&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&#34;connecting&#34;&gt;Connecting&lt;/h3&gt;
&lt;p&gt;Click the green &lt;code&gt;Open a Remote Window&lt;/code&gt; icon on the bottom left corner, select &lt;code&gt;Connect to Host...&lt;/code&gt;, and pick your desired host, in this case &lt;code&gt;MySite&lt;/code&gt;. If your public SSH key isn&amp;rsquo;t on the remote server, you will be prompted to enter a password. If your key is on the server, it will state it has your fingerprint and prompt you to continue.&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;re now connected and can use VS Code&amp;rsquo;s features like Terminal and Debug Console just like you would locally.&lt;/p&gt;
&lt;h3 id=&#34;opening-the-working-directory&#34;&gt;Opening the working directory&lt;/h3&gt;
&lt;p&gt;Wouldn&amp;rsquo;t it be nice to have VS Code automatically open to the correct folder once your SSH connection is established? Unfortunately there isn&amp;rsquo;t a way to set a folder location in the settings yet; you&amp;rsquo;d need to click Open Folder and navigate to the project root every time you connect.&lt;/p&gt;
&lt;p&gt;There is, however, a workaround to make this a bit less tedious:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Click &lt;code&gt;Open Folder&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Navigate to the project root&lt;/li&gt;
&lt;li&gt;Click &lt;code&gt;File &amp;gt; Save Workplace As...&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Save your &lt;code&gt;.code-workspace&lt;/code&gt; file somewhere it won&amp;rsquo;t be picked up by Git&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now open your workspace again with a new connection. If the workspace was recently used, you can use &lt;code&gt;File &amp;gt; Open Recent &amp;gt; $Workspace.code-workspace&lt;/code&gt;; otherwise go to &lt;code&gt;File &amp;gt; Open Workspace...&lt;/code&gt; and select your &lt;code&gt;.code-workspace&lt;/code&gt; file. This should get you set up right in the correct directory after you&amp;rsquo;ve connected.&lt;/p&gt;
&lt;h3 id=&#34;ssh-with-multiple-hops&#34;&gt;SSH with multiple hops&lt;/h3&gt;
&lt;p&gt;Sometimes you will need to SSH into one location before tunneling into another. To connect to a remote host through an intermediate jump host, you will need to add &lt;code&gt;ForwardAgent&lt;/code&gt; and &lt;code&gt;ProxyJump&lt;/code&gt; to the config file, like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Host MySite
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  HostName site.endpointdev.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  User couragyn
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ForwardAgent yes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Host SiteThatNeedsToGoThroughMySite
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  HostName completely.different.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  User couragyn
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ProxyJump MySite&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Happy remote development!&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>Lock down your security with GPG on a YubiKey</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2021/09/gpg-keys-on-a-yubikey/"/>
      <id>https://www.endpointdev.com/blog/2021/09/gpg-keys-on-a-yubikey/</id>
      <published>2021-09-10T00:00:00+00:00</published>
      <author>
        <name>Ardyn Majere</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;img src=&#34;/blog/2021/09/gpg-keys-on-a-yubikey/banner.jpg&#34; alt=&#34;&#34;&gt;
&lt;a href=&#34;https://unsplash.com/photos/4hfpVsi-gSg&#34;&gt;Photo&lt;/a&gt; by &lt;a href=&#34;https://unsplash.com/@maurosbicego&#34;&gt;Mauro Sbicego&lt;/a&gt; on Unsplash&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://gnupg.org/&#34;&gt;Gnu Privacy Guard&lt;/a&gt; (GnuPG or GPG) is a tool we use a lot at End Point. Its ubiquity and quite decent security is a perfect fit for us — and there&amp;rsquo;s a way to make it even safer.&lt;/p&gt;
&lt;p&gt;GPG uses the OpenPGP standard to encrypt files. Normally, one creates a PGP key on their computer and just keeps the keyfile safe. A password is generally used, but as with any private key, it&amp;rsquo;s only as safe as the computer it&amp;rsquo;s on.&lt;/p&gt;
&lt;h3 id=&#34;got-a-yubikey-and-not-sure-what-to-do-with-it-want-to-get-a-little-more-secure-with-your-encryption&#34;&gt;Got a YubiKey and not sure what to do with it? Want to get a little more secure with your encryption?&lt;/h3&gt;
&lt;p&gt;In case you haven&amp;rsquo;t heard of them, &lt;a href=&#34;https://www.yubico.com/why-yubico/&#34;&gt;YubiKeys&lt;/a&gt; are hardware USB keys that can be used as a multi-factor authentication (MFA) token, or to fill in one-time password (OTP) fields (like those generated by Google Authenticator) on sites that don&amp;rsquo;t support the YubiKey directly as an MFA token.&lt;/p&gt;
&lt;p&gt;Using a smart card like a YubiKey can increase GPG&amp;rsquo;s security, especially if the key is generated on an &lt;a href=&#34;https://en.wikipedia.org/wiki/Air_gap_(networking)&#34;&gt;air-gapped&lt;/a&gt; machine. This way the keyfile is stored in the hardware security token, and is never exposed to the internet.&lt;/p&gt;
&lt;p&gt;In addition, you can even store an SSH key on the card, which will enable you to log in to remote Linux machines while keeping your private key secured.&lt;/p&gt;
&lt;p&gt;While there isn&amp;rsquo;t full password locking on hardware tokens, YubiKey and almost all OpenPGP keys have two PINs — a user PIN and an administrative PIN to reset the user PIN. If you enter either or both three times incorrectly, the card will lock and you&amp;rsquo;ll need to reload from backup (or, in some cases, throw the card away) which is why it&amp;rsquo;s critical to have a backup.&lt;/p&gt;
&lt;p&gt;There are several options for smart cards beyond the YubiKey. You can use any OpenPGP compatible card and reader, or an all-in-one solution that&amp;rsquo;s compatible with OpenPGP.&lt;/p&gt;
&lt;p&gt;The following instructions do require a basic understanding of the command line and of how to create a live CD/​USB stick, but if you need to use GPG, you&amp;rsquo;re probably already at least somewhat familiar with these requirements.&lt;/p&gt;
&lt;p&gt;An air-gapped machine isn&amp;rsquo;t required for these instructions. You could do this on any machine you trust, but using a machine with a fresh OS that hasn&amp;rsquo;t been connected to the internet affords the highest level of security. Simply booting from a live CD/​USB is fairly easy. Choosing an operating sytem that comes with the smart card daemon (&lt;a href=&#34;https://linux.die.net/man/1/scdaemon&#34;&gt;scdaemon&lt;/a&gt;) will help. If you don&amp;rsquo;t, make sure you download the scdaemon package for your operating system to use with the live CD/​USB.&lt;/p&gt;
&lt;h3 id=&#34;prepare&#34;&gt;Prepare&lt;/h3&gt;
&lt;p&gt;Before you begin, you&amp;rsquo;ll need:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A smart card solution as described above.&lt;/li&gt;
&lt;li&gt;A backup smart card, or external media on which to store an encrypted copy of the key.&lt;/li&gt;
&lt;li&gt;A machine on which to generate the key.&lt;/li&gt;
&lt;li&gt;A live OS. For this demonstration I used &lt;a href=&#34;https://tails.boum.org/&#34;&gt;Tails&lt;/a&gt;, The Amnesic Incognito Live System. It&amp;rsquo;s specifically designed to not store logs or keep data from one reboot to another.&lt;/li&gt;
&lt;li&gt;A way to access these instructions, like a second computer, phone, printout, or a very good memory.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Boot up the live machine. Note that if you&amp;rsquo;re using Tails, there are two settings you&amp;rsquo;ll need to choose on the welcome screen. Click the plus button and do the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Set an administrative password. Tails doesn&amp;rsquo;t set a root password by default, and thus disallows root access for better security. You can set one yourself.&lt;/li&gt;
&lt;li&gt;Disable networking in the &amp;lsquo;Network Connection&amp;rsquo; section.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;access-and-configure-the-card&#34;&gt;Access and configure the card&lt;/h3&gt;
&lt;p&gt;Once booted, run an admin terminal, or load a terminal and run &lt;code&gt;sudo -i&lt;/code&gt;. It&amp;rsquo;ll prompt you for the password you just set.&lt;/p&gt;
&lt;p&gt;Ensure you can access the card and that the smart card daemon is installed by running &lt;code&gt;gpg --edit-card&lt;/code&gt;. It should display information about your smart card.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you&amp;rsquo;re using an air-gapped machine and your live OS is missing requisite packages, don&amp;rsquo;t access the internet with the machine in order to install it, since that would break the air gap. Instead, copy the installation files across using sneakernet: Add the files to a USB drive, perhaps the one you&amp;rsquo;ll be using to back up your PGP key). The packages for a Debian-based machine are: &lt;code&gt;scdaemon&lt;/code&gt;, &lt;code&gt;libccid&lt;/code&gt;, &lt;code&gt;pcscd&lt;/code&gt;, &lt;code&gt;rng-tools&lt;/code&gt;, and &lt;code&gt;gnupg2&lt;/code&gt;. Debian has &lt;a href=&#34;https://www.debian.org/doc/manuals/apt-offline/index.en.html&#34;&gt;instructions&lt;/a&gt; on how to get packages to an air-gapped machine.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Set a PIN for your card, if you haven&amp;rsquo;t already. Start with:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ gpg --edit-card&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The default PIN for a YubiKey should be 123456, and the default admin PIN should be 12345678. Check the documentation that came with your key, though!&lt;/p&gt;
&lt;p&gt;Enable admin features first:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;gpg/card&amp;gt; admin&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This should return &lt;code&gt;Admin commands are allowed&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Set the passwords, both for the regular PIN and the admin PIN:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;gpg/card&amp;gt; passwd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;1 - change PIN &amp;lt;- Default 123456
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;2 - unblock PIN &amp;lt;- To reset the pin with the AdminPin / Reset Code
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;3 - change Admin PIN &amp;lt;- Default 12345678
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;4 - set the Reset Code &amp;lt;- See below
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Q - quit&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Do not mix up your PIN and admin PIN! You can lock up your card, which will require a factory reset.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The reset code is set if you are setting up the card for someone else to use, and wish to give them a way to reset the PIN without having full access to the rest of the admin functions.&lt;/p&gt;
&lt;h3 id=&#34;generate-the-keys&#34;&gt;Generate the keys&lt;/h3&gt;
&lt;p&gt;Run the following to generate the key:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ gpg --expert --full-gen-key&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Key type:&lt;/strong&gt; 1 (RSA &amp;amp; RSA). (You can also use &amp;ldquo;ECC &amp;amp; ECC&amp;rdquo; if you&amp;rsquo;re brave. These types of keys may not work with older systems and implementations of GPG, however, so your mileage may vary. If you do want to use ECC &amp;amp; ECC, use Curve 25519 in the next step.)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Key size:&lt;/strong&gt; this should be the maximum supported by your key. YubiKey 4 or 5 can support up to 4096. Use this for both main and subkey.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Expiry:&lt;/strong&gt; This is your choice. I&amp;rsquo;d set it to a year or two.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Real name, email, and comment:&lt;/strong&gt; I recommend leaving the comment blank, since most of the time the email address will be enough information.&lt;/li&gt;
&lt;li&gt;Next, GPG will ask you to move your mouse around — don&amp;rsquo;t sprain anything while generating entropy!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now your key is generated. If you only have one spare storage device which you want to use for backups, copy the revocation certificate and the SSH public key to storage, sneak this on to your main computer, and only then copy the keys over to the backup drive. Don&amp;rsquo;t attach the backup drive to anything but an air-gapped machine once it holds your key!&lt;/p&gt;
&lt;p&gt;You might as well generate an SSH key now. Even if you don&amp;rsquo;t use it, there&amp;rsquo;s no harm in having it.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ gpg --expert --edit-key &amp;lt;your email/key id&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Run &lt;code&gt;gpg/card&amp;gt; addkey&lt;/code&gt; to add a key.&lt;/li&gt;
&lt;li&gt;Type 8, RSA (set your own capabilities). If this option doesn&amp;rsquo;t show up, ensure you used &lt;code&gt;--expert&lt;/code&gt; above.&lt;/li&gt;
&lt;li&gt;Enable authentication and disable signing and encrypting — type &lt;code&gt;s&lt;/code&gt;, &lt;code&gt;e&lt;/code&gt;, &lt;code&gt;a&lt;/code&gt;, then &lt;code&gt;q&lt;/code&gt; to save.&lt;/li&gt;
&lt;li&gt;4096 bits is the best number to use, at least for RSA on modern YubiKeys. If you have an older key you may be limited to 3072 or 2048.&lt;/li&gt;
&lt;li&gt;You can choose to have the key expire, but ensure you have a backup method of logging in.&lt;/li&gt;
&lt;li&gt;Confirm your choices, then quit, confirming you want to save.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;For more in-depth instructions, visit &lt;a href=&#34;https://opensource.com/article/19/4/gpg-subkeys-ssh&#34;&gt;https://opensource.com/article/19/4/gpg-subkeys-ssh&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Export the public keys:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ gpg --export --armor &amp;lt;key ID&amp;gt; &amp;gt; /path/to/thumbdrive/&amp;lt;email&amp;gt;_pub.asc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ gpg --export-ssh &amp;lt;key ID&amp;gt; &amp;gt; /path/to/thumbdrive/YubiKey_id_rsa.pub&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&#34;move-the-keys-to-your-card&#34;&gt;Move the keys to your card&lt;/h3&gt;
&lt;p&gt;Once you have the key added to your keyring, you&amp;rsquo;ll need to transfer that key to your card:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ gpg --edit-key &amp;lt;key id&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To export the public SSH key you&amp;rsquo;ll need to put on remote servers, you can run the command: &lt;code&gt;gpg --export-ssh-key 0x123456789ABCDE&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;gpg&amp;gt; keytocard&lt;/code&gt; — confirm you want to move the primary key and store this in position 1 of the card.
&lt;ul&gt;
&lt;li&gt;To select the encryption key, type &lt;code&gt;key 1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;keytocard&lt;/code&gt; to store the encryption key in the encryption slot.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;If you have an encryption key:
&lt;ul&gt;
&lt;li&gt;To select the authentication key, run &lt;code&gt;key 2&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;To deselect the key first key, run &lt;code&gt;key 1&lt;/code&gt;. You should only have one key with &lt;code&gt;*&lt;/code&gt; marking it.&lt;/li&gt;
&lt;li&gt;Store in the authentication slot: &lt;code&gt;keytocard&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Repeat this for as many subkeys as you have.&lt;/li&gt;
&lt;li&gt;Once you&amp;rsquo;re done, quit and confirm the saved changes.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Time to test your new key!&lt;/p&gt;
&lt;p&gt;And that&amp;rsquo;s it. Publish your new public GPG key, use your new SSH key, secure in the knowledge that your private key is protected from malicious attacks by an additional hardware layer.&lt;/p&gt;
&lt;h3 id=&#34;what-do-i-do-if-it-all-went-wrong-or-i-locked-up-the-card&#34;&gt;What do I do if it all went wrong or I locked up the card?&lt;/h3&gt;
&lt;p&gt;You can start again. The following command will restore the GPG-compatible portion of your YubiKey to factory settings. You will lose any keys stored on the card. I don&amp;rsquo;t believe it&amp;rsquo;ll cause any OTP/2FA set up with the card to be lost, but I make no guarantees.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ONLY RUN THE FOLLOWING IF YOUR PIN IS LOCKED AND THE SMART CARD IS UNUSABLE:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ gpg --edit-card
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;gpg/card&amp;gt; factory-reset&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Follow the confirmation steps on screen.&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>Consolidating Multiple SFTP Accounts Into One Master Account</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2020/03/consolidating-multiple-sftp-accounts/"/>
      <id>https://www.endpointdev.com/blog/2020/03/consolidating-multiple-sftp-accounts/</id>
      <published>2020-03-16T00:00:00+00:00</published>
      <author>
        <name>Selvakumar Arumugam</name>
      </author>
      <content type="html">
        &lt;img src=&#34;/blog/2020/03/consolidating-multiple-sftp-accounts/image-0.jpg&#34; alt=&#34;merging roads&#34; /&gt;
&lt;p&gt;&lt;a href=&#34;https://unsplash.com/photos/kzSNNqqS3Qs&#34;&gt;Photo&lt;/a&gt; by &lt;a href=&#34;https://unsplash.com/@dmey503&#34;&gt;Dan Meyers&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Recently, a client implemented a data-intensive workflow to generate various reports and insights from a list of facilities as part of an EpiTrax installation. Because a significant portion of these files contain sensitive healthcare data, they needed to strictly comply with HIPAA. Optimally, facilities should be able to transfer files securely and exclusively to our server. One of the best methods of achieving this is to create individual SSH File Transfer Protocol (SFTP) accounts for each source.&lt;/p&gt;
&lt;h3 id=&#34;sftp-account&#34;&gt;SFTP account&lt;/h3&gt;
&lt;p&gt;Private SFTP accounts were established for each facility and the data was received at a designated path. At these individual points of contact, a third-party application picks up the data and processes further into the pipeline. The following demonstrates how SFTP accounts are developed and configured:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Create a user group for SFTP accounts:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ addgroup sftpusers&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Configure the following settings in sshd_config (this enables an SFTP account and sets the default location as the home path):&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ vi /etc/ssh/sshd_config
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;# override default of no subsystems&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Subsystem       sftp    internal-sftp...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Match Group sftpusers
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ChrootDirectory /home/%u
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    AllowTCPForwarding no
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    X11Forwarding no
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ForceCommand internal-sftp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Restart SSH server to apply changes:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ systemctl restart ssh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Create an SFTP user account for a facility and place in a folder on the home path to receive data:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;# set new user name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#369&#34;&gt;sftpuser&lt;/span&gt;=the-new-username
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;useradd &lt;span style=&#34;color:#369&#34;&gt;$sftpuser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;usermod -g sftpusers -s /usr/sbin/nologin &lt;span style=&#34;color:#369&#34;&gt;$sftpuser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mkdir -p /home/&lt;span style=&#34;color:#369&#34;&gt;$sftpuser&lt;/span&gt;/INPUT_PATH/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;chown -R root:root /home/&lt;span style=&#34;color:#369&#34;&gt;$sftpuser&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&#34;mount-multiple-accounts-to-one-account&#34;&gt;Mount multiple accounts to one account&lt;/h3&gt;
&lt;p&gt;The goal here is to point the data from many facilities to one location, but using a single account and path for multiple sites’ data could result in a breach of security and/​or privacy. Mounting the receiving path of a facility’s data onto a single master account and then to a “mount point” with a unique facility name takes care of this issue. The process next consolidates files from individual paths on a master account in one place where the application picks up messages for further processing.&lt;/p&gt;
&lt;p&gt;The SFTP accounts and the master account should be attached to the same group. This will permit individual accounts to write on the master account-mounted path. In turn, the master account can read files from the same location. This location now has administrative rights for both the SFTP user the group. Group permission of the mounted folder is set to sftpgroup and user permission is set to the facility account.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;# create master user account&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ adduser master
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ passwd master
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;# Add master user to sftpgroup group&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;usermod -a -G sftpgroup master
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;getent group sftpgroup
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;# MOUNT_PATH and sub folders&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mkdir -p /home/master/MOUNT_PATH/{Input,Pickup,Backup,Archive}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;chown -R master:master /home/master/MOUNT_PATH&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We wrote a script to automate the process of creating an SFTP account, mounting it at the master account path, and adding fstab entries to save the mount in the case of a reboot. The script not only saves time, but also avoids human error when creating accounts for all facilities.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#c00;font-weight:bold&#34;&gt;#!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#c00;font-weight:bold&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;# ./create_sftp_account.sh sftpfacilityone FACILITY_ONE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#369&#34;&gt;sftpuser&lt;/span&gt;=&lt;span style=&#34;color:#369&#34;&gt;$1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#369&#34;&gt;facility_name&lt;/span&gt;=&lt;span style=&#34;color:#369&#34;&gt;$2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;# Create SFTP account and add to sftpgroup&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;useradd &lt;span style=&#34;color:#369&#34;&gt;$sftpuser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;usermod -g sftpusers -s /usr/sbin/nologin &lt;span style=&#34;color:#369&#34;&gt;$sftpuser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;usermod -a -G sftpgroup &lt;span style=&#34;color:#369&#34;&gt;$sftpuser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mkdir -p /home/&lt;span style=&#34;color:#369&#34;&gt;$sftpuser&lt;/span&gt;/INPUT_PATH
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;chown root:root /home/&lt;span style=&#34;color:#369&#34;&gt;$sftpuser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;# Create path specific to facility in master account Input folder&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mkdir -p /home/master/MOUNT_PATH/Input/&lt;span style=&#34;color:#369&#34;&gt;$facility_name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;chown -R &lt;span style=&#34;color:#369&#34;&gt;$sftpuser&lt;/span&gt;:sftpgroup /home/master/MOUNT_PATH/Input/&lt;span style=&#34;color:#369&#34;&gt;$facility_name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;# Mount sftp account into master account and set permissions&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mount --bind /home/master/MOUNT_PATH/Input/&lt;span style=&#34;color:#369&#34;&gt;$facility_name&lt;/span&gt; /home/&lt;span style=&#34;color:#369&#34;&gt;$sftpuser&lt;/span&gt;/INPUT_PATH
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;chown -R &lt;span style=&#34;color:#369&#34;&gt;$sftpuser&lt;/span&gt;:sftpgroup /home/&lt;span style=&#34;color:#369&#34;&gt;$sftpuser&lt;/span&gt;/INPUT_PATH
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;chmod &lt;span style=&#34;color:#369&#34;&gt;g&lt;/span&gt;=rwxs /home/&lt;span style=&#34;color:#369&#34;&gt;$sftpuser&lt;/span&gt;/INPUT_PATH
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;# Add fstab entry to persist and mount on reboot&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#038&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;/home/master/MOUNT_PATH/Input/&lt;/span&gt;&lt;span style=&#34;color:#369&#34;&gt;$facility_name&lt;/span&gt;&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt; /home/&lt;/span&gt;&lt;span style=&#34;color:#369&#34;&gt;$sftpuser&lt;/span&gt;&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;/INPUT_PATH none bind 0 0&amp;#34;&lt;/span&gt; &amp;gt;&amp;gt; /etc/fstab
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#038&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;Created user &lt;/span&gt;&lt;span style=&#34;color:#369&#34;&gt;$sftpuser&lt;/span&gt;&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt; at &lt;/span&gt;&lt;span style=&#34;color:#369&#34;&gt;$facility_name&lt;/span&gt;&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt; mount point successfully&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&#34;files-at-one-location&#34;&gt;Files at one location&lt;/h3&gt;
&lt;p&gt;Now, data files from facilities are available at individual folders under MOUNT_PATH/Input on the master account. This enables third-party applications to pick up files in a straightforward way to proceed with further processing. It also helps our client access the files for review from the master account easily without navigating into each separate account.&lt;/p&gt;
&lt;h3 id=&#34;summary&#34;&gt;Summary&lt;/h3&gt;
&lt;p&gt;Mounting multiple SFTP accounts onto one master account turns out to be an efficient and beneficial method of consolidating data. Both safe and secure, running separate SFTP accounts establishes an exclusive private link between facilities and servers. The master account has the unique ability to access files belonging to each facility in order to process the data further.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: In order to avoid broken mounts, check the status by using the command &lt;code&gt;mount -fav&lt;/code&gt;. Problems with mount configurations can cause broken mounts after rebooting the server.&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>The mystery of the disappearing SSH key</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2017/04/the-mystery-of-disappearing-ssh-key/"/>
      <id>https://www.endpointdev.com/blog/2017/04/the-mystery-of-disappearing-ssh-key/</id>
      <published>2017-04-13T00:00:00+00:00</published>
      <author>
        <name>Greg Sabino Mullane</name>
      </author>
      <content type="html">
        &lt;div class=&#34;separator&#34; style=&#34;clear: both; float: right; text-align: center; padding: 0 0 2em 1em&#34;&gt;&lt;a href=&#34;/blog/2017/04/the-mystery-of-disappearing-ssh-key/image-0.jpeg&#34; imageanchor=&#34;1&#34; style=&#34;clear: right; margin-bottom: 1em; margin-left: 1em;&#34;&gt;&lt;img border=&#34;0&#34; src=&#34;/blog/2017/04/the-mystery-of-disappearing-ssh-key/image-0.jpeg&#34;/&gt;&lt;/a&gt;&lt;br/&gt;&lt;small&gt;&lt;a href=&#34;https://flic.kr/p/SnZgVF&#34;&gt;Photo&lt;/a&gt; by &lt;a href=&#34;https://www.flickr.com/photos/50663863@N02/&#34;&gt;Jay Huang&lt;/a&gt;&lt;/small&gt;&lt;/div&gt;
&lt;p&gt;SSH (&lt;a href=&#34;https://en.wikipedia.org/wiki/Secure_Shell&#34;&gt;Secure Shell&lt;/a&gt;) is one of the programs I use every single day at &lt;a href=&#34;/&#34;&gt;work&lt;/a&gt;, primarily to connect
to our client’s servers. Usually it is a rock-solid program that simply
works as expected, but recently I discovered it behaving quite strangely -
a server I had visited many times before was now refusing my attempts
to login. The underlying problem turned out to be a misguided decision by the developers
of &lt;a href=&#34;https://www.openssh.com/&#34;&gt;OpenSSH&lt;/a&gt; to deprecate &lt;a href=&#34;https://en.wikipedia.org/wiki/Digital_Signature_Algorithm&#34;&gt;DSA&lt;/a&gt; keys. How I discovered this problem is described below
(as well as two solutions).&lt;/p&gt;
&lt;p&gt;The use of the ssh program is not simply limited to logging in and connecting
to remote servers. It also supports many powerful features, one of the most
important being the ability to chain multiple connections with the
ProxyCommand option. By using this, you can “login” to servers
that you cannot reach directly, by linking together two or more servers behind the scenes.&lt;/p&gt;
&lt;p&gt;As as example, let’s consider a client named “Acme Anvils” that strictly
controls access to its production servers. They make all SSH traffic
come in through a single server, named dmz.acme-anvils.com, and only on port 2222.
They also only allow certain public IPs to connect to this server, via whitelisting.
On our side, End Point has a server, named portal.endpoint.com, that I can use as a jumping off point,
which has a fixed IP that we can give to our clients to whitelist.
Rather than logging in to “portal”, getting a prompt, and then logging in to “dmz”, I can
simply add an entry in my ~/.ssh/config file to automatically create a tunnel between
the servers -
at which point I can reach the client’s server by typing “ssh acmedmz”:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;##
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;## Client: ACME ANVILS
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;##
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;## Acme Anvil&amp;#39;s DMZ server (dmz.acme-anvils.com)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Host acmedmz
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;User endpoint
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;HostName 555.123.45.67
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Port 2222
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ProxyCommand ssh -q greg@portal.endpoint.com nc -w 180s %h %p&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Notice that the “Host” name may be set to anything you want. The connection
to the client’s server uses a non-standard port, and the username
changes from “greg” to “endpoint”, but all of that is hidden away from
me as now the login is simply:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[greg@localhost]$ ssh acmedmz
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[endpoint@dmz]$&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It’s unusual that I’ll actually need to do any work on the dmz server, of course,
so the tunnel gets extended another hop to the db1.acme-anvils.com server:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;##
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;## Client: ACME ANVILS
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;##
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;## Acme Anvil&amp;#39;s DMZ server (dmz.acme-anvils.com)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Host acmedmz
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;User endpoint
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;HostName 555.123.45.67
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Port 2222
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ProxyCommand ssh -q greg@portal.endpoint.com nc -w 180s %h %p
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;## Acme Anvil&amp;#39;s main database (db1.acme-anvils.com)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Host acmedb1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;User postgres
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;HostName db1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ProxyCommand ssh -q acmedmz nc -w 180s %h %p&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Notice how the second ProxyCommand references the “Host” of the section
above it. Neat stuff. When I type “ssh acemdb1”, I’m actually connecting to
the portal.endpoint.com server, then immediately running the netcat (nc) command
in the background, then going through netcat to dmz.acme-anvils.com and
running a second netcat command on &lt;em&gt;that&lt;/em&gt; server, and finally going through
both netcats to login to the db1.acme-anvils.com server. It sounds a little complicated,
but quickly becomes part of your standard tool set once you wrap your head around it.
After you update your .ssh/config file, you soon forget about
all the tunneling and feel as though you are connecting directly to all your servers. That is, until
something breaks, as it did recently for me.&lt;/p&gt;
&lt;p&gt;The actual client this happened with was not “Acme Anvils”, of course, and it
was a connection that went through four servers and three ProxyCommands,
but for demonstration purposes let’s pretend it happened on a simple
connection to the dmz.acme-anvils.com server. I had not connected to
the server in question for a long time, but I needed to make some adjustments
to a &lt;a href=&#34;https://bucardo.org/wiki/Tail_n_mail&#34;&gt;tail_n_mail&lt;/a&gt; configuration file. The first login attempt failed
completely:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[greg@localhost]$ ssh acmedmz
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;endpoint@dmz.acme-anvils.com&amp;#39;s password:&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Although the connection to portal.endpoint.com worked fine, the connection
to the client server failed. This is not an unusual problem: it usually signifies that either ssh-agent is not running,
or that I forgot to feed it the correct key via the ssh-add program. However, I quickly discovered
that ssh-agent was working and contained all my usual keys. Moreover, I was able to
connect to other sites with no problem! On a hunch, I tried breaking down the connections
into manual steps. First, I tried logging in to the “portal” server. It logged me in
with no problem. Then I tried to login from there to dmz.acme-anvils.com—​which also logged
me in with no problem! But trying to get there via ProxyCommand still failed.
What was going on?&lt;/p&gt;
&lt;p&gt;When in doubt, crank up the debugging. For the ssh program, using the
-v option turns on some minimal debugging. Running the
original command from my computer with this option enabled quickly revealed the problem:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[greg@localhost]$ ssh -v acmedmz
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;OpenSSH_7.4p1, OpenSSL 1.0.2k-fips  26 Jan 2017
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;debug1: Reading configuration data /home/greg/.ssh/config
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;debug1: /home/greg/.ssh/config line 1227: Applying options for acmedmz
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;debug1: Reading configuration data /etc/ssh/ssh_config
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;debug1: Executing proxy command: exec ssh -q greg@portal.endpoint.com nc -w 180s 555.123.45.67 2222
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;debug1: Authenticating to dmz.acme-anvils.com:2222 as &amp;#39;endpoint&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;debug1: Host &amp;#39;dmz.acme-anvils.com&amp;#39; is known and matches the ECDSA host key.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;debug1: Skipping ssh-dss key /home/greg/.ssh/greg2048dsa.key - not in PubkeyAcceptedKeyTypes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;debug1: SSH2_MSG_SERVICE_ACCEPT received
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;debug1: Authentications that can continue: publickey,password
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;debug1: Next authentication method: publickey
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;debug1: Offering RSA public key: /home/greg/.ssh/greg4096rsa.key
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;debug1: Next authentication method: password
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;endpoint@dmz.acme-anvils.com&amp;#39;s password:&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The problem is that my DSA key (the “ssh-dss key”) was rejected by
my ssh program. As we will see below, DSA keys are rejected by default in recent versions
of the OpenSSH program. But why was I still able to login when not hopping through
the middle server? The solution lays in the fact that when I use the ProxyCommand,
&lt;em&gt;my&lt;/em&gt; ssh program is negotiating with the final server, and is refusing to use my DSA
key. However, when I ssh to the portal.endpoint.com server, and then on to the next one,
the second server has no problem using my (forwarded) DSA key! Using the -v option on the connection
from portal.endpoint.com to dmz.acme-anvils.com reveals another clue:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[greg@portal]$ ssh -v endpoint@dmz.acme-anvils.com:2222
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;debug1: Connecting to dmz [1234:5678:90ab:cd::e] port 2222.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;debug1: Next authentication method: publickey
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;debug1: Offering RSA public key: /home/greg/.ssh/endpoint2.ssh
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;debug1: Authentications that can continue: publickey,password
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;debug1: Offering DSA public key: /home/greg/.ssh/endpoint.ssh
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;debug1: Server accepts key: pkalg ssh-dss blen 819
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;debug1: Authentication succeeded (publickey).
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Authenticated to dmz ([1234:5678:90ab:cd::e]:2222).
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;debug1: Entering interactive session.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[endpoint@dmz]$&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you look closely at the above, you will see that we first offered an RSA key, which
was rejected, and then we successfully offered a DSA key. This means that the
endpoint@dm account has a DSA, but not a RSA, public key inside of its
~/.ssh/authorized_keys file. Since I was able to connect
to portal.endpoint.com, its ~/.ssh/authorized_keys file
must have my RSA key.&lt;/p&gt;
&lt;p&gt;For the failing connection, ssh was able to use my RSA key to connect
to portal.endpoint.com, run the netcat command, and then continue on to
the dmz.acme-anvils.com server. However, this connection failed as the only key my local ssh
program would provide was the RSA one, which the dmz server did not have.&lt;/p&gt;
&lt;p&gt;For the working connection, ssh was able to connect to portal.endpoint.com
as before, and then into an interactive prompt. However, when I then connected
via ssh to dmz.acme-anvils.com, it was the ssh program on portal, not my local computer,
which negotiated with the dmz server. It had no problem using a DSA key, so I
was able to login. Note that both keys were happily forwarded to portal.endpoint.com,
even though my ssh program refused to use them!&lt;/p&gt;
&lt;p&gt;The quick solution to the problem, of course, was to upload my RSA key to the dmz.acme-anvils.com
server. Once this was done, my local ssh program was more than happy to login
by sending the RSA key along the tunnel.&lt;/p&gt;
&lt;p&gt;Another solution to this problem is to instruct your SSH programs to recognize DSA
keys again. To do this, add this line to your local SSH config file
($HOME/.ssh/config), or to the global SSH config file
(/etc/ssh/config):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PubkeyAcceptedKeyTypes +ssh-dss&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As mentioned earlier, this whole mess was caused by the OpenSSH program deciding
to deprecate DSA keys. Their rationale for targeting all DSA keys seems a little weak at best: certainly
I don’t feel that my 2048-bit DSA key is in any way a weak link. But
the writing is on the wall now for DSA, so you may as well replace your DSA
keys with RSA ones (and an &lt;a href=&#34;https://en.wikipedia.org/wiki/EdDSA&#34;&gt;ed25519 key&lt;/a&gt; as well, in anticipation of when ssh-agent
is able to support them!). More information about the decision to force out
DSA keys can be found in &lt;a href=&#34;https://security.stackexchange.com/questions/5096/rsa-vs-dsa-for-ssh-authentication-keys&#34;&gt;this great analysis of the OpenSSH source code&lt;/a&gt;.&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>SSH Key Access Recovery on EC2 Instances</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2016/10/ssh-key-access-recovery-on-ec2-instances/"/>
      <id>https://www.endpointdev.com/blog/2016/10/ssh-key-access-recovery-on-ec2-instances/</id>
      <published>2016-10-02T00:00:00+00:00</published>
      <author>
        <name>Josh Williams</name>
      </author>
      <content type="html">
        &lt;p&gt;Can’t access your EC2 instance? Throw it away and spin up a new one! Everyone subscribes to the cattle server pattern, yes?&lt;/p&gt;
&lt;p&gt;Not quite, of course. Until you reach a certain scale, that’s not as easy to maintain as a smaller grouping of pet servers. While you can certainly run with that pattern on Amazon, EC2 instances aren’t quite as friendly about overcoming access issues as other providers are. That’s to say, even if you have access to the AWS account there’s no interface for forcing a root password change or the like.&lt;/p&gt;
&lt;p&gt;But sometimes you need that, as an End Point client did recently. It was a legacy platform, and the party that set up the environment wasn’t available. However an issue popped up that needed solved, so we needed a way to get in. The process involves some EBS surgery and does involve a little bit of downtime, but is fairly straightforward. The client’s system was effectively down already, so taking it all the way offline had little impact.&lt;/p&gt;
&lt;p&gt;Also do make sure this is the actual problem, and not that the connection is blocked by security group configuration or some such.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;div class=&#34;separator&#34; style=&#34;float: left; margin-bottom: 1em; margin-right: 1em;&#34;&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img border=&#34;0&#34; height=&#34;150&#34; src=&#34;/blog/2016/10/ssh-key-access-recovery-on-ec2-instances/image-0.png&#34;/&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;For safe keeping, it’s recommended to create a snapshot of the original root volume. If something goes wrong, you can then roll back to that point.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;div class=&#34;separator&#34; style=&#34;float: right; margin-bottom: 1em; margin-left: 1em;&#34;&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img border=&#34;0&#34; src=&#34;/blog/2016/10/ssh-key-access-recovery-on-ec2-instances/image-1.png&#34;/&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;Create temporary working instance in the same availability zone as the instance to fix. A micro instance is fine. Don’t forget to set a key that you do have access to.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;div class=&#34;separator&#34; style=&#34;float: left; margin-bottom: 1em; margin-right: 1em;&#34;&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img border=&#34;0&#34; height=&#34;181&#34; src=&#34;/blog/2016/10/ssh-key-access-recovery-on-ec2-instances/image-2.png&#34;/&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;Find the instance you need to fix and note the root volume ID. Double check that it has an elastic IP assignment: when stopped the instance IP address will change if not associated with a static elastic IP. Similarly, ephemeral storage will be cleared (but hopefully you’re not relying on having anything permanently there anyway.)&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;div class=&#34;separator&#34; style=&#34;float: right; margin-bottom: 1em; margin-left: 1em;&#34;&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img border=&#34;0&#34; height=&#34;95&#34; src=&#34;/blog/2016/10/ssh-key-access-recovery-on-ec2-instances/image-3.png&#34;/&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;Stop, do not terminate, the instance to be fixed.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;div class=&#34;separator&#34; style=&#34;float: left; margin-bottom: 1em; margin-right: 1em;&#34;&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img border=&#34;0&#34; src=&#34;/blog/2016/10/ssh-key-access-recovery-on-ec2-instances/image-4.png&#34;/&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;Find the root volume for the instance to be fixed using the ID found earlier (or just click it within the instance details pane) and detach it from the instance. Attach it to your working instance.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;div class=&#34;separator&#34; style=&#34;float: right; margin-bottom: 1em; margin-left: 1em;&#34;&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img border=&#34;0&#34; height=&#34;33&#34; src=&#34;/blog/2016/10/ssh-key-access-recovery-on-ec2-instances/image-5.png&#34;/&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;Connect in to your working instance, and mount that volume as /mnt (or anywhere, really. Just using /mnt as an example here.)&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;div class=&#34;separator&#34; style=&#34;float: left; margin-bottom: 1em; margin-right: 1em;&#34;&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img border=&#34;0&#34; src=&#34;/blog/2016/10/ssh-key-access-recovery-on-ec2-instances/image-6.png&#34;/&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;Copy any needed ssh keys into the .ssh/authorized_keys under /mnt/home/ubuntu/ or /mnt/home/ec2-user/ depending on the base distro used for the image, or even just to /mnt/root/. And/or make any other fixes needed.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;div class=&#34;separator&#34; style=&#34;float: right; margin-bottom: 1em; margin-left: 1em;&#34;&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img border=&#34;0&#34; height=&#34;125&#34; src=&#34;/blog/2016/10/ssh-key-access-recovery-on-ec2-instances/image-7.png&#34;/&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;When all is good, umount the volume and detach it from the working instance. Attach it back to the original instance as /dev/sda1 (even though it doesn’t say that’s an option.)&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;div class=&#34;separator&#34; style=&#34;float: left; margin-bottom: 1em; margin-right: 1em;&#34;&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img border=&#34;0&#34; height=&#34;117&#34; src=&#34;/blog/2016/10/ssh-key-access-recovery-on-ec2-instances/image-8.png&#34;/&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;Boot original instance. If all goes well you should now be able to connect in using the ssh key you added. Ensure that everything comes up on boot. Terminate the temporary working instance (and do make sure you don’t terminate the wrong one.)&lt;/p&gt;
&lt;p&gt;That’s not the only approach, of course. If you have a partially functional system, for example, you may be better off immediately creating a volume from the snapshot created in step 0, mounting that in another instance for the modifications, and then performing the stop, root volume swap, and start in quick succession. That’ll minimize any actual downtime, at the potential expense of losing any data changes happening in between the snapshot and the reboot.&lt;/p&gt;
&lt;p&gt;Either way just remember there are options, and all is not lost!&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>One-time password SSH solutions</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2015/02/one-time-password-ssh-solutions/"/>
      <id>https://www.endpointdev.com/blog/2015/02/one-time-password-ssh-solutions/</id>
      <published>2015-02-02T00:00:00+00:00</published>
      <author>
        <name>Greg Sabino Mullane</name>
      </author>
      <content type="html">
        &lt;div class=&#34;separator&#34; style=&#34;clear: both; float:right; text-align: center; margin-bottom: 1.5em; margin-left: 3em; margin-right: 2em; &#34;&gt;&lt;a href=&#34;/blog/2015/02/one-time-password-ssh-solutions/image-0-big.jpeg&#34; imageanchor=&#34;1&#34; style=&#34;clear: right; float: right; margin-left: 1em;&#34;&gt;&lt;img border=&#34;0&#34; src=&#34;/blog/2015/02/one-time-password-ssh-solutions/image-0.jpeg&#34;/&gt;&lt;/a&gt;&lt;br/&gt;&lt;small&gt;[how encryption was done in the 18th century]&lt;/small&gt;&lt;/div&gt;
&lt;p&gt;In a &lt;a href=&#34;/blog/2015/01/ssh-one-time-passwords-otpw-on/&#34;&gt;previous article&lt;/a&gt; I explained how I used a one‑time password system to enable SSH on my Chromebook. While this is still working great for me, there are a few problems that can pop
up.&lt;/p&gt;
&lt;h3 id=&#34;problem-1-tripping-the-alarm&#34;&gt;Problem 1: Tripping the alarm&lt;/h3&gt;
&lt;p&gt;Normally a single password is asked for when logging in using one-time passwords via the &lt;a href=&#34;https://www.cl.cam.ac.uk/~mgk25/otpw.html&#34;&gt;otpw program&lt;/a&gt;. However, otpw will issue a three‑password prompt when it thinks someone may be trying to perform a race attack (in other words, it think two people are trying to log in at once). The prompt will change from the normal one to this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Password 206/002/011:&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This alarm can be tripped from SSH timing out, or from getting pulled away from your computer mid‑login. In theory, it could be someone trying to break in to my laptop, but that is very unlikely. Needless to say, trying to squint at a paper and keyboard in the dark is hard enough with one password, much less three! It’s usually much easier (in most cases) for me to walk to my laptop and remove the &lt;strong&gt;~/.otpw.lock&lt;/strong&gt; file, which will clear the “intruder alarm” and cause otpw to prompt for a single password again. Another solution is to set a timeout on clearing the lock, for example via a cronjob that removes the lock file if it was created more than 10 minutes ago. Finally, it may be helpful to have a way to remotely clear the lock. I’ve not written it yet, but one good approach would be to use &lt;a href=&#34;http://portknocking.org/&#34;&gt;port knocking&lt;/a&gt; to remove the lock file.&lt;/p&gt;
&lt;h3 id=&#34;problem-2-lost-or-compromised-passwords&#34;&gt;Problem 2: Lost or compromised passwords&lt;/h3&gt;
&lt;p&gt;The physical sheet of paper containing your one‑time passwords is definitely a single point of failure—​but an easy one to remedy. Maybe you lost the paper, maybe your arch‑nemesis stole it, or maybe it got destroyed in a freak hunting accident. No worries at all, just generate a new one! Run the otpw‑bin command again:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ otpw-gen -e 30 | lpr&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;When you do so, the old &lt;strong&gt;~/.otpw&lt;/strong&gt; file is completely overwritten, and the old sheet of paper is now completely worthless. Solutions don’t get any easier than that. If your sheet is stolen and you need to quickly disable one‑time passwords, you can also just manually remove the .otpw file, which effectively turns off one‑time passwords for that account.&lt;/p&gt;
&lt;h3 id=&#34;problem-3-unusable-passwords&#34;&gt;Problem 3: Unusable passwords&lt;/h3&gt;
&lt;p&gt;The password to use for login is randomly determined, so one time you may be asked to look up password 312 and the next 031. Sometimes, however, you cannot use one of the passwords on your printout. Perhaps you spilled something on it. Perhaps (as has happened to me!) the paper was folded in such a way that the crease made it difficult to read the characters. Perhaps your keyboard has a really hard time typing a certain letter. :) Whatever the reason, there are two solutions. First, generate a new sheet by rerunning otpw‑bin as described in Problem 2 above. Second, you can mark the current password as “complete” and have otpw move on to the next number.&lt;/p&gt;
&lt;p&gt;Forcing otpw to advance to the next number is slightly tricky. Basically, you need to modify the .otpw file and change the current password hash to a line of hyphens. Here is what the top of a .otpw file looks like after 3 successful logins:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;OTPW1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;392 3 12 5
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;---------------
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;---------------
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;---------------
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;077jA:EAgMCJ2uM
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;097yG3IDv%gyUB7
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;1077T7EQq%K7E/F
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;101xeS3I+zMw8GZ
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;109xCEBXYFb3%3v
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;121AzwjOJYyBqD%
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;068WewLA3EIsLmx
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;065Jdq=2WDwHZ9D
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;089npYNavK9MIVA&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The first line states the format of the file, while the second line indicates the number of passwords generated, the digits per password number, the digits in the hash, and the digits in the actual passwords. All the other lines are passwords—​either an unused one consisting of the number and the hash, or a line of hyphens. The goal is to replace the current password with hyphens. Here’s a quick recipe to do so:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;perl -ni -e &amp;#39;print unless /^\d\d\d\S/ and ! $x++&amp;#39; ~/.otpw&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We do an in‑place edit (&lt;strong&gt;-i&lt;/strong&gt;) of the .otpw file, looping through a line at a time (&lt;strong&gt;-n&lt;/strong&gt;), and run a command against each line (&lt;strong&gt;-e &amp;hellip;&lt;/strong&gt;). The first time we find a line that starts with three numbers and then contains non‑whitespace, we skip it. Everything else is printed and thus goes back into the file.&lt;/p&gt;
&lt;p&gt;Those are some ways to handle three of the common problems that can occur when using one‑time passwords. Have other problems, or better solutions to the above? Let me know in the comments.&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>SSH one-time passwords (otpw) on chromebook</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2015/01/ssh-one-time-passwords-otpw-on/"/>
      <id>https://www.endpointdev.com/blog/2015/01/ssh-one-time-passwords-otpw-on/</id>
      <published>2015-01-21T00:00:00+00:00</published>
      <author>
        <name>Greg Sabino Mullane</name>
      </author>
      <content type="html">
        &lt;div class=&#34;separator&#34; style=&#34;clear: both; float: right; margin-bottom: 1em; text-align: center;&#34;&gt;&lt;a href=&#34;/blog/2015/01/ssh-one-time-passwords-otpw-on/image-0-big.jpeg&#34; imageanchor=&#34;1&#34; style=&#34;clear: right; float: right; margin-bottom: 1em; margin-left: 1em;&#34;&gt;&lt;img border=&#34;0&#34; src=&#34;/blog/2015/01/ssh-one-time-passwords-otpw-on/image-0.jpeg&#34;/&gt;&lt;/a&gt;
&lt;br/&gt;&lt;small&gt;&lt;a href=&#34;https://flic.kr/p/e55Nqb&#34;&gt;Henri Coandă Bucureşt Airport&lt;/a&gt;&lt;br/&gt;by &lt;a href=&#34;https://www.flickr.com/photos/bortescristian/&#34;&gt;Cristian Bortes&lt;/a&gt;&lt;/small&gt;&lt;/div&gt;
&lt;p&gt;A little while ago, I bought a &lt;a href=&#34;https://www.samsung.com/us/computer/chromebook&#34;&gt;Chromebook&lt;/a&gt; as an alternative to my sturdy-but-heavy laptop. So far, it has been great—​quick boot up, no fan, long battery life, and light as a feather. Perfect for bringing from room to room, and for getting some work done in a darkened bedroom at night. The one large drawback was a lack of &lt;a href=&#34;https://en.wikipedia.org/wiki/Secure_Shell&#34;&gt;SSH&lt;/a&gt;, a tool I use very often. I’ll describe how I used one-time passwords to overcome this problem, and made my Chromebook a much more productive tool.&lt;/p&gt;
&lt;p&gt;The options for using SSH on &lt;a href=&#34;https://en.wikipedia.org/wiki/Chrome_OS&#34;&gt;Chrome OS&lt;/a&gt; are not that good. I downloaded and tried a handful of apps, but each had some significant problems. One flaw shared across all of them was a lack of something like &lt;a href=&#34;https://en.wikipedia.org/wiki/Ssh-agent&#34;&gt;ssh-agent&lt;/a&gt;, which will cache your SSH passphrase so that you don’t have to type it every time you open a new SSH session. An option was to use a password-less key, or a very short passphrase, but I did not want to make everything less secure. The storage of the SSH private key was an issue as well—​the Chromebook has very limited storage options, and relies on putting most things “in the cloud”.&lt;/p&gt;
&lt;p&gt;What was needed was a way to use SSH in a very insecure environment, while providing as much security as possible. Eureka! A &lt;a href=&#34;https://en.wikipedia.org/wiki/One-time_password&#34;&gt;one-time password&lt;/a&gt; system is exactly what I needed. Specifically, the wonderful &lt;a href=&#34;http://www.cl.cam.ac.uk/~mgk25/otpw.html&#34;&gt;otpw program&lt;/a&gt;. Chromebooks have a simple shell (accessed via ctrl-alt-t) that has SSH support. So the solution was to use one-time passwords and not store anything at all on the Chromebook.&lt;/p&gt;
&lt;p&gt;Rather than trying to get otpw setup on all the servers I might need to reach, I simply set it up on my main laptop, carefully allowed incoming SSH connections, and now I can ssh from my Chromebook to my laptop. From there, to the world. Best of all, when I ssh in, I can use the already running ssh-agent on the laptop! All it takes is memorizing a single passphrase and securing a sheet of paper (which is far easier to secure than an entire Chromebook :)&lt;/p&gt;
&lt;p&gt;Here are some details on how I set things up. On the Chromebook, nothing is needed except to open up a crosh tab with ctrl-alt-t, and run ssh. On the laptop side, the first step is to install the otpw program, and then configure PAM so that it uses it:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ sudo aptitude install otpw-bin
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ sudo cat &amp;gt;&amp;gt; /etc/pam.d/ssh
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  auth     required  pam_otpw.so
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  session  optional  pam_otpw.so&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;That is the bare minimum, but I also wanted to make sure that only ‘local’ machines could SSH in. While there are a number of ways to do this, such as iptables or /etc/hosts.allow, I decided the best approach was to configure sshd itself. The “Match” directive instructs that the lines after it only take effect on a positive match. Thus:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ sudo cat &amp;gt;&amp;gt; /etc/ssh/sshd_config
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;AllowUsers nobodyatall
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Match Address 192.168.1.0/24,127.0.0.0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;AllowUsers greg
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ service ssh restart&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The next step is to create the one-time password list. This is done with the otwp-gen program; here is the command I use:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ otpw-gen -e 30 | lpr
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Generating random seed ...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;If your paper password list is stolen, the thief should not gain access to your account with this information alone. Therefore, you need to memorize and enter below a prefix password. You will have to enter that each time directly before entering the one-time password (on the same line).
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;When you log in, a 3-digit password number will be displayed. It identifies the one-time password on your list that you have to append to the prefix password. If another login to your account is in progress at the same time, several password numbers may be shown and all corresponding passwords have to be appended after the prefix password. Best generate a new password list when you have used up half of the old one.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Enter new prefix password: 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Reenter prefix password: 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Creating &amp;#39;~/.otpw&amp;#39;.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Generating new one-time passwords ...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The otpw-gen command creates a file named &lt;strong&gt;.otpw&lt;/strong&gt; in your home directory, which contains the hash of all the one-time passwords to use. In the example above, the &lt;strong&gt;-e&lt;/strong&gt; controls the entropy of the generated passwords—​in other words, how long they are. otpw-gen will not accept an entropy lower than 30, which will generate passwords that are five characters long. The default entropy, 48, generates passwords that are eight characters long, which I found a little too long to remember when trying to read from the printout in a dark room. :). Rather than show the list of passwords on the screen, or save them to a local file, the output goes directly to the printer. otpw-gen does a great job of formatting the page, and it ends up looking like this:&lt;/p&gt;
&lt;div class=&#34;separator&#34; style=&#34;clear: both; text-align: center;&#34;&gt;&lt;a href=&#34;/blog/2015/01/ssh-one-time-passwords-otpw-on/image-1-big.png&#34; imageanchor=&#34;1&#34; style=&#34;margin-left: 1em; margin-right: 1em;&#34;&gt;&lt;img border=&#34;0&#34; src=&#34;/blog/2015/01/ssh-one-time-passwords-otpw-on/image-1.png&#34;/&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;Here are some close-ups of what the passwords look like at various entropies:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Sample output with a low entropy of 30:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;OTPW list generated 2015-07-12 13:23 on gregsbox
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;000 GGS%F  056 bTqut  112 f8iJs  168 lQVjk  224 gNG2x  280 -x8ke  336 egm5n
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;001 urHLf  057 a/Wwh  113 -PEpV  169 9ABpK  225 -K2db  281 babfX  337 feeED
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;002 vqrX:  058 rZszx  114 r3m8a  170 -UzX3  226 g74RI  282 gusBJ  338 ;Tr4m
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;003 fa%6G  059 -i4FZ  115 nPEaJ  171 o64FR  227 uBu:h  283 uBo/U  339 ;pYY8
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;004 -LYZY  060 vWDnw  116 f5Sb+  172 hopr+  228 rWXvb  284 rksPQ  340 ;v6GN&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Sample output with the default entropy of 48:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;OTPW list generated 2015-15-05 15:53 on gregsbox
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;000 tcsx qqlb  056 ougp yuzo  112 lxwt oitl  168 giap vqsj  224 vtvk rjc/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;001 mfui ukph  057 wbpw aktt  113 kert wozj  169 ihed psyx  225 ducx pze=
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;002 wwsj hdcr  058 jmwa mguo  114 idtk zrzw  170 ecow fepm  226 ikru hty+
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;003 aoeb klnz  059 pvie fbfc  115 fmlb sptb  171 ftrd jotb  227 mqns ivq:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;004 yclw hyml  060 slvj ezfi  116 djsy ycse  172 butg guzm  228 pfyv ytq%
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;005 eilj cufp  061 zlma yxxl  117 skyf ieht  173 vbtd rmsy  229 pzyn zlc/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Sample output with a high entropy of 79:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;OTPW list generated 2015-07-05 18:74 on gregsbox
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;000 jeo SqM bQ9Y ato  056 AyT jsc YbU0 rXB  112 Og/ I3O 39nY W/Z
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;001 AFk W+5 J+2m e1J  057 MXy O9j FjA8 8q;  113 a6A 8R9 /Ofr E4s
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;002 02+ XPB 8B2S +qT  058 Cl4 6g2 /9Bk KO=  114 HEK vd3 T2TT Rr.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;003 Exb jqE iK49 rfX  059 Qhz eU+ J2VG kwQ  115 aJ7 tg1 dJsr vf.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;004 Bg1 b;5 p0qI f/m  060 VKz dpa G7;e 7jR  116 kaL OSw dC8e kx.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The final step is to SSH from the Chromebook to the laptop! Hit ctrl-alt-t, and you will get a new tab with a crosh prompt. From there, attempt to ssh to the laptop, and you will see the usual otpw prompt:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ ssh greg@192.168.1.10
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Password 140: &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;So you type in the passphrase you entered above when running the otpw-gen command, then pull out your sheet of paper and look up the matching password next to number 140. Voila! I am now connected securely to my more powerful computer, and can SSH from there to anywhere I am used to going to from my laptop. I can even run mutt as if I were at the laptop! A nice workaround for the limitations of the Chromebook.&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>Scripting ssh master connections</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2014/03/scripting-ssh-master-connections/"/>
      <id>https://www.endpointdev.com/blog/2014/03/scripting-ssh-master-connections/</id>
      <published>2014-03-17T00:00:00+00:00</published>
      <author>
        <name>Josh Williams</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;a href=&#34;http://www.flickr.com/photos/pennstatelive/4947288981/&#34; title=&#34;Elephant Parade 005 by pennstatenews, on Flickr&#34;&gt;&lt;img alt=&#34;Elephant Parade 005&#34; height=&#34;138&#34; src=&#34;/blog/2014/03/scripting-ssh-master-connections/image-0.jpeg&#34; width=&#34;240&#34;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;At End Point, security is a top priority. We just phased out the last of the 1024-bit keys for all of our employees—​those of us in ops roles that have keys lots of places had done so a long while back. Similarly, since we’ll tend to have several sessions open for a long while, a number of us will use ssh-agent’s -c (confirm) option. That forces a prompt for confirmation of each request the agent gets. It can get a little annoying (especially since it takes the focus over to one monitor, even if I’m working on the other) but it combats SSH socket hijacking when we have the agent forwarded to remote servers.&lt;/p&gt;
&lt;p&gt;Working on server migrations is where it gets really annoying. I like to write little repeatable scripts that I can tweak and re-run as needed. They’re usually simple little things, starting with a bunch of rsync’s or pipe-over-ssh’s for pg_dump or any other data we need to move across. With any more than a couple of those ssh connections in there, repeatedly hitting the confirm button gets irritating fast. And if a large transfer takes a while, I’ll go off to do something else, later getting an unexpected confirmation box when I’m not thinking about the running script. Unexpected SSH auth confirmations, of course, get denied. So the script has to be re-run, and the vicious cycle repeats anew.&lt;/p&gt;
&lt;p&gt;ssh has a neat ability to multiplex over a single connection. I have it set to do that locally in auto mode, and that made me wonder if it could be used in these scripts so I only have to authorize the connection once. Well, of course it can, and it turns out to be nothing special. But here’s what I got to work:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ssh
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -o ControlPath=~/.ssh/user@server.domain.foo  &amp;lt;em&amp;gt;# Set the socket location&amp;lt;/em&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -M  &amp;lt;em&amp;gt;# Defines master mode for the client&amp;lt;/em&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -N  &amp;lt;em&amp;gt;# Don&amp;#39;t bother to do anything remotely yet&amp;lt;/em&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -f  &amp;lt;em&amp;gt;# Drop into the background so we can continue on&amp;lt;/em&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    user@server.domain.foo  &amp;lt;em&amp;gt;# And the typical connection username/host&amp;lt;/em&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;At the end of the script, remember to shut down the control socket by passing it an exit command, otherwise it’ll leave a connection hanging around out there:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ssh -o ControlPath=~/.ssh/user@server.domain.foo -O exit user@server.domain.foo&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In between, it’s just a matter of using the ControlPath option. It can get a little repetitive, so a variable can be helpful. The latest iteration I have wraps the ssh command together with its -o ControlPath option, which can be executed directly or passed to rsync, as below.&lt;/p&gt;
&lt;p&gt;As an example, here’s a somewhat stripped-down version of the script we used to move &lt;a href=&#34;https://bucardo.org&#34;&gt;bucardo.org&lt;/a&gt; to a new host, minus some error handling and such:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;#!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;MSSH=&amp;#34;ssh -o ControlPath=~/.ssh/root@bucardo.org&amp;#34; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$MSSH -MNf bucardo.org
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# Tell rsync to use ssh pointed at the master socket
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rsync -e &amp;#34;$MSSH&amp;#34; -aHAX --del bucardo.org:/var/lib/git/ /var/lib/git/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# Pipe pg_dump (or whatever you need) over ssh
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$MSSH bucardo.org &amp;#39;su - postgres -c &amp;#34;pg_dump -c wikidb&amp;#34;&amp;#39; | su - postgres -c &amp;#34;psql wikidb&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# sed -i commands or anything else that&amp;#39;s needed to fix up the local configuration
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$MSSH -O exit bucardo.org&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


      </content>
    </entry>
  
    <entry>
      <title>Ansiblizing SSH Keys</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2014/03/ansiblizing-ssh-keys-it-is-occasionally/"/>
      <id>https://www.endpointdev.com/blog/2014/03/ansiblizing-ssh-keys-it-is-occasionally/</id>
      <published>2014-03-03T00:00:00+00:00</published>
      <author>
        <name>Cas Rusnov</name>
      </author>
      <content type="html">
        &lt;p&gt;It is occasionally the case that several users share a particular account on a few boxes, such as in a scenario where a test server and a production server share a deployment account, and several developers work on them. In these situations the preference is to authenticate the users with their ssh keys through authorized_keys on the account they are sharing, which leads to the problem of keeping the keys synchronized when they are updated and changed. We add the additional parameter that perhaps any given box will have a few users of the account that aren’t shared by the others, but otherwise allow a core of developers to access them. Now extend this scenario across hundreds of machines, and the maintenance becomes difficult or impossible when updating any of the core accounts. Obviously this is a job for a remote management framework like Ansible.&lt;/p&gt;
&lt;h3 id=&#34;our-example-scenario&#34;&gt;Our Example Scenario&lt;/h3&gt;
&lt;p&gt;We have developers Alice, Bob and Carla which need access to every box. We have additional developers Dwayne and Edward that only need access to one box each. We have a collection of servers: dev1, dev2, staging and prod. All of the servers have an account called web_deployment.&lt;/p&gt;
&lt;p&gt;The authorized_keys for web_deployment on each box contains:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;dev1&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;alice&lt;/li&gt;
&lt;li&gt;bob&lt;/li&gt;
&lt;li&gt;carla&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;dev2&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;alice&lt;/li&gt;
&lt;li&gt;bob&lt;/li&gt;
&lt;li&gt;carla&lt;/li&gt;
&lt;li&gt;dwayne&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;staging&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;alice&lt;/li&gt;
&lt;li&gt;bob&lt;/li&gt;
&lt;li&gt;carla&lt;/li&gt;
&lt;li&gt;edward&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;prod&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;alice&lt;/li&gt;
&lt;li&gt;bob&lt;/li&gt;
&lt;li&gt;carla&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;enter-ansible&#34;&gt;Enter Ansible&lt;/h3&gt;
&lt;p&gt;Ansible is setup for every box already. The basic strategy for managing the keys is to copy a default authorized_keys file from the ansible host containing Alice, Bob and Carla (since they are present on all of the destination machines) and assemble the keys with a collection of keys local to the host (Dwayne’s key on dev2, and Edward’s key on staging). To perform the assembly action we also want to provide a script so that the keys can be manually manipulated (local keys changed) without touching the ansible box. The script is thus:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#c00;font-weight:bold&#34;&gt;#!/usr/bin/env bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#c00;font-weight:bold&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#038&#34;&gt;set&lt;/span&gt; -u -o errexit -o pipefail
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#369&#34;&gt;target_ssh_dir&lt;/span&gt;=&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;/home/web_deployment/.ssh&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#369&#34;&gt;base_authorized_key_file&lt;/span&gt;=&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;authorized_keys&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#369&#34;&gt;local_authorized_keys&lt;/span&gt;=&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#33b;background-color:#fff0f0&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#369&#34;&gt;target_ssh_dir&lt;/span&gt;&lt;span style=&#34;color:#33b;background-color:#fff0f0&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#33b;background-color:#fff0f0&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#369&#34;&gt;base_authorized_key_file&lt;/span&gt;&lt;span style=&#34;color:#33b;background-color:#fff0f0&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;.local&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#369&#34;&gt;hosting_authorized_keys&lt;/span&gt;=&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#33b;background-color:#fff0f0&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#369&#34;&gt;target_ssh_dir&lt;/span&gt;&lt;span style=&#34;color:#33b;background-color:#fff0f0&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#33b;background-color:#fff0f0&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#369&#34;&gt;base_authorized_key_file&lt;/span&gt;&lt;span style=&#34;color:#33b;background-color:#fff0f0&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;.hosting&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#369&#34;&gt;target_authorized_keys&lt;/span&gt;=&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#33b;background-color:#fff0f0&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#369&#34;&gt;target_ssh_dir&lt;/span&gt;&lt;span style=&#34;color:#33b;background-color:#fff0f0&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#33b;background-color:#fff0f0&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#369&#34;&gt;base_authorized_key_file&lt;/span&gt;&lt;span style=&#34;color:#33b;background-color:#fff0f0&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#369&#34;&gt;tmp_authorized_keys&lt;/span&gt;=&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#33b;background-color:#fff0f0&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#369&#34;&gt;target_ssh_dir&lt;/span&gt;&lt;span style=&#34;color:#33b;background-color:#fff0f0&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#33b;background-color:#fff0f0&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#369&#34;&gt;base_authorized_key_file&lt;/span&gt;&lt;span style=&#34;color:#33b;background-color:#fff0f0&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;.tmp&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#369&#34;&gt;authorized_keys_backup_dir&lt;/span&gt;=&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#33b;background-color:#fff0f0&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#369&#34;&gt;target_ssh_dir&lt;/span&gt;&lt;span style=&#34;color:#33b;background-color:#fff0f0&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;/history&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;# BEGIN multiline configuration_management_disclaimer string variable&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#369&#34;&gt;configuration_management_disclaimer&lt;/span&gt;=&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;\n\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;# ******************************************************************************\n\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;# This file is automatically managed by End Point Configuration management
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;# system. In order to change it please apply your changes
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;# to &lt;/span&gt;&lt;span style=&#34;color:#369&#34;&gt;$local_authorized_keys&lt;/span&gt;&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt; and run &lt;/span&gt;&lt;span style=&#34;color:#369&#34;&gt;$0&lt;/span&gt;&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;\n\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;# so to assemble a new &lt;/span&gt;&lt;span style=&#34;color:#369&#34;&gt;$target_authorized_keys&lt;/span&gt;&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;\n\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;# ******************************************************************************\n\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;# END multiline configuration_management_disclaimer string variable&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;# BEGIN assembling tmp file&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#038&#34;&gt;echo&lt;/span&gt; -e &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#369&#34;&gt;$configuration_management_disclaimer&lt;/span&gt;&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;&lt;/span&gt; &amp;gt; &lt;span style=&#34;color:#369&#34;&gt;$tmp_authorized_keys&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#038&#34;&gt;echo&lt;/span&gt; -e &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;# BEGIN STANDARD HOSTING KEYS\n&amp;#34;&lt;/span&gt; &amp;gt;&amp;gt; &lt;span style=&#34;color:#369&#34;&gt;$tmp_authorized_keys&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cat &lt;span style=&#34;color:#369&#34;&gt;$hosting_authorized_keys&lt;/span&gt; &amp;gt;&amp;gt; &lt;span style=&#34;color:#369&#34;&gt;$tmp_authorized_keys&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#038&#34;&gt;echo&lt;/span&gt; -e &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;# END STANDARD HOSTING KEYS\n&amp;#34;&lt;/span&gt; &amp;gt;&amp;gt; &lt;span style=&#34;color:#369&#34;&gt;$tmp_authorized_keys&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;if&lt;/span&gt; [[ -r &lt;span style=&#34;color:#369&#34;&gt;$local_authorized_keys&lt;/span&gt; ]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#038&#34;&gt;echo&lt;/span&gt; -e &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;# BEGIN LOCAL KEYS\n&amp;#34;&lt;/span&gt; &amp;gt;&amp;gt; &lt;span style=&#34;color:#369&#34;&gt;$tmp_authorized_keys&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  cat &lt;span style=&#34;color:#369&#34;&gt;$local_authorized_keys&lt;/span&gt; &amp;gt;&amp;gt; &lt;span style=&#34;color:#369&#34;&gt;$tmp_authorized_keys&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#038&#34;&gt;echo&lt;/span&gt; -e &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;# END LOCAL KEYS\n&amp;#34;&lt;/span&gt; &amp;gt;&amp;gt; &lt;span style=&#34;color:#369&#34;&gt;$tmp_authorized_keys&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#038&#34;&gt;echo&lt;/span&gt; -e &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#369&#34;&gt;$configuration_management_disclaimer&lt;/span&gt;&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;&lt;/span&gt; &amp;gt;&amp;gt; &lt;span style=&#34;color:#369&#34;&gt;$tmp_authorized_keys&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;# END assembling tmp file&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;# BEGIN check (and do) backup of old file&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;if&lt;/span&gt; ! cmp &lt;span style=&#34;color:#369&#34;&gt;$tmp_authorized_keys&lt;/span&gt; &lt;span style=&#34;color:#369&#34;&gt;$target_authorized_keys&lt;/span&gt; &amp;amp;&amp;gt; /dev/null
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  mkdir -p &lt;span style=&#34;color:#369&#34;&gt;$authorized_keys_backup_dir&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#369&#34;&gt;backup_old_auth_keys&lt;/span&gt;=&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#33b;background-color:#fff0f0&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#369&#34;&gt;authorized_keys_backup_dir&lt;/span&gt;&lt;span style=&#34;color:#33b;background-color:#fff0f0&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#33b;background-color:#fff0f0&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#369&#34;&gt;base_authorized_key_file&lt;/span&gt;&lt;span style=&#34;color:#33b;background-color:#fff0f0&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;_&lt;/span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;$(&lt;/span&gt;date &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#39;+%Y%m%dT%H%M%z&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  cat &lt;span style=&#34;color:#369&#34;&gt;$target_authorized_keys&lt;/span&gt; &amp;gt; &lt;span style=&#34;color:#369&#34;&gt;$backup_old_auth_keys&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;# END check (and do) backup of old file&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cat &lt;span style=&#34;color:#369&#34;&gt;$tmp_authorized_keys&lt;/span&gt; &amp;gt; &lt;span style=&#34;color:#369&#34;&gt;$target_authorized_keys&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rm &lt;span style=&#34;color:#369&#34;&gt;$tmp_authorized_keys&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;if&lt;/span&gt; [ -d &lt;span style=&#34;color:#369&#34;&gt;$authorized_keys_backup_dir&lt;/span&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;if&lt;/span&gt; [ -n &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;$(&lt;/span&gt;find &lt;span style=&#34;color:#369&#34;&gt;$authorized_keys_backup_dir&lt;/span&gt; -maxdepth &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;0&lt;/span&gt; -type d&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;&lt;/span&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    chmod -R &lt;span style=&#34;color:#369&#34;&gt;u&lt;/span&gt;=rwX,go= &lt;span style=&#34;color:#369&#34;&gt;$authorized_keys_backup_dir&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;if&lt;/span&gt; [ -f &lt;span style=&#34;color:#369&#34;&gt;$local_authorized_keys&lt;/span&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;if&lt;/span&gt; [ -n &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;$(&lt;/span&gt;find &lt;span style=&#34;color:#369&#34;&gt;$local_authorized_keys&lt;/span&gt; -maxdepth &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;0&lt;/span&gt; -type f&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;&lt;/span&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    chmod &lt;span style=&#34;color:#369&#34;&gt;u&lt;/span&gt;=rw &lt;span style=&#34;color:#369&#34;&gt;$local_authorized_keys&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;if&lt;/span&gt; [ -f &lt;span style=&#34;color:#369&#34;&gt;$hosting_authorized_keys&lt;/span&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;if&lt;/span&gt; [ -n &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;$(&lt;/span&gt;find &lt;span style=&#34;color:#369&#34;&gt;$hosting_authorized_keys&lt;/span&gt; -maxdepth &lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;0&lt;/span&gt; -type f&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;&lt;/span&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    chmod &lt;span style=&#34;color:#369&#34;&gt;u&lt;/span&gt;=rw &lt;span style=&#34;color:#369&#34;&gt;$hosting_authorized_keys&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-weight:bold&#34;&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We then use an Ansible task to distribute the files to the destination hosts:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;#&lt;/span&gt; tasks/authorized_keys_deploy.yml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  - name: Create /home/web_deployment subdirectories
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    file: path=&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;/home/web_deployment/{{ item }}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          state=directory
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          owner=web_deployment
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          group=web_deployment
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          mode=&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;0700&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    with_items:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - .ssh
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - bin
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  - name: Copy /home/web_deployment/.ssh/authorized_keys.universal
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    template: src=all/home/web_deployment/.ssh/authorized_keys.universal.j2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          dest=&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;/home/web_deployment/.ssh/authorized_keys.hosting&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          owner=web_deployment
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          group=web_deployment
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          mode=&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;0600&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    notify:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - Use shellscript to locally assemble authorized_keys
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  - name: Copy /home/web_deployment/bin/assemble_authorized_keys.sh
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    copy: src=files/all/home/web_deployment/bin/assemble_authorized_keys.sh
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          dest=&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;/home/web_deployment/bin/assemble_authorized_keys.sh&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          owner=web_deployment
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          group=web_deployment
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          mode=&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;0700&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    notify:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - Use shellscript to locally assemble authorized_keys&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This task is invoked by an Ansible playbook:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;#&lt;/span&gt; authorized_keys_deploy.yml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;- name: authorized_keys file deployment/management
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  hosts: authorized_keys_servers
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  user: root
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  handlers:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  - include: handlers/authorized_keys_deploy.yml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  tasks:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  - include: tasks/authorized_keys_deploy.yml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And finally the handler which invokes the assembly script:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a61717;background-color:#e3d2d2&#34;&gt;#&lt;/span&gt; handlers/authorized_keys_deploy.yml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  - name: Use shellscript to locally assemble authorized_keys
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    command: &lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;/home/web_deployment/bin/assemble_authorized_keys.sh&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;A note about this setup: The authorized_keys.universal has the extension .j2, and is invoked as a Jinja2 template. This allows server-specific conditionals amongst other things. It is useful for example when per-key shell features are used (for example restricting one particular key to invoking rsync for backups), and if the OS selection is mixed thus requiring the paths to differ between hosts.&lt;/p&gt;
&lt;h3 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;We hope that this example is helpful. There are some clear directions for improvement and ways to make this suit other scenarios, such as having the universal keys list also merged with an additional keys list select by host or other information such as OS or abstract values associated with the host. One could also envision a system in which some arbitrary collection of key files are merged at the destination server selected through the aforementioned means or others.&lt;/p&gt;
&lt;p&gt;Shout out to Lele Calo for his putting together the Ansible setup for this procedure.&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>Use Ansible/Jinja2 templates to change file content based on target OS</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2013/12/use-ansiblejinja2-templates-to-change/"/>
      <id>https://www.endpointdev.com/blog/2013/12/use-ansiblejinja2-templates-to-change/</id>
      <published>2013-12-19T00:00:00+00:00</published>
      <author>
        <name>Emanuele “Lele” Calò</name>
      </author>
      <content type="html">
        &lt;p&gt;In the End Point hosting team we really love automating repetitive tasks, especially when it involves remembering many little details which can over time be forgotten, like differences of &lt;em&gt;coreutils&lt;/em&gt; location between some versions of Ubuntu (Debian), CentOS (Red Hat) and OpenBSD variants.&lt;/p&gt;
&lt;p&gt;In our environment we bind the backup SSH user authorized_keys entry to a custom command in order to have it secured by being, among other aspects, tied to a specific rsync call.&lt;/p&gt;
&lt;p&gt;So in our case the content of our &lt;strong&gt;CentOS&lt;/strong&gt; authorized_keys would be something like:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#369&#34;&gt;command&lt;/span&gt;=&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;/bin/nice -15 /usr/bin/rsync --server --daemon .&amp;#34;&lt;/span&gt;,no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa AAAB3[...]&lt;span style=&#34;color:#369&#34;&gt;Q&lt;/span&gt;== endpoint-backup&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Sadly that’s only true for CentOS systems so that if you want to &lt;strong&gt;automate the distribution of authorized_keys&lt;/strong&gt; (as we’ll show in another post) to different Linux distributions (like &lt;strong&gt;Ubuntu&lt;/strong&gt;) you may need to tweak it to comply to the new standard “/usr/bin” location, which will be eventually adopted by all new Linux versions overtime.. RHEL 7.x onward included.&lt;/p&gt;
&lt;p&gt;To do the OS version detection we decided to use an &lt;strong&gt;Ansible&lt;/strong&gt;/&lt;strong&gt;Jinja2&lt;/strong&gt; template by placing the following line in the Ansible task:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;- name: Deploy /root/.ssh/authorized_keys
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  template: &lt;span style=&#34;color:#369&#34;&gt;src&lt;/span&gt;=all/root/.ssh/authorized_keys.j2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#369&#34;&gt;dest&lt;/span&gt;=/root/.ssh/authorized_keys
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#369&#34;&gt;owner&lt;/span&gt;=root
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#369&#34;&gt;group&lt;/span&gt;=root
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#369&#34;&gt;mode&lt;/span&gt;=&lt;span style=&#34;color:#00d;font-weight:bold&#34;&gt;0600&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And inside the actual file place a slightly modified version of the line above:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#369&#34;&gt;command&lt;/span&gt;=&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;{% if ansible_os_family != &amp;#34;&lt;/span&gt;RedHat&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34; %}/usr{% endif %}/bin/nice -15 /usr/bin/rsync --server --daemon .&amp;#34;&lt;/span&gt;,no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa AAAB3[...]&lt;span style=&#34;color:#369&#34;&gt;Q&lt;/span&gt;== endpoint-backup&lt;span style=&#34;color:#d20;background-color:#fff0f0&#34;&gt;&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;So that if the target OS is not part of the “RedHat” family it will add the “/usr” in front of the “/bin/nice” absolute path.&lt;/p&gt;
&lt;p&gt;Easy peasy, ain’t it?&lt;/p&gt;
&lt;p&gt;Now go out there and exploit this feature to all your needs.&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>Managing Multiple Hosts and SSH Identities with OpenSSH</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2013/12/managing-multiple-hosts-and-ssh/"/>
      <id>https://www.endpointdev.com/blog/2013/12/managing-multiple-hosts-and-ssh/</id>
      <published>2013-12-12T00:00:00+00:00</published>
      <author>
        <name>Patrick Lewis</name>
      </author>
      <content type="html">
        &lt;p&gt;When I started working at End Point I was faced with the prospect of having multiple SSH identities for the first time. I had historically used an RSA SSH key with the default length of 2048 bits, but for my work at End Point I needed to generate a new key that was 4096 bits long.&lt;/p&gt;
&lt;p&gt;Although I could have used &lt;a href=&#34;https://linux.die.net/man/1/ssh-copy-id&#34;&gt;ssh-copy-id&lt;/a&gt; to copy my new SSH public key to all of my old servers, I liked the idea of maintaining separate “personal” and “work” identities and decided to look for a way to automatically use the right key based on the server I was trying to connect to.&lt;/p&gt;
&lt;p&gt;For the first few days I was specifying my new identity on the command line using:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ssh -i .ssh/endpoint_rsa patrick@server.example.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;That worked, but I often forgot to specify my new SSH identity when connecting to a server, only realizing my mistake when I was prompted for a password instead of being authenticated automatically.&lt;/p&gt;
&lt;h3 id=&#34;host-definitions&#34;&gt;Host Definitions&lt;/h3&gt;
&lt;p&gt;I had previously learned the value of creating an &lt;a href=&#34;https://linux.die.net/man/5/ssh_config&#34;&gt;ssh_config&lt;/a&gt; file when I replaced a series of command-line aliases with equivalent entries in the SSH config file.&lt;/p&gt;
&lt;p&gt;Instead of creating aliases in my shell:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;alias server1=&amp;#39;ssh -p 2222 -L 3389:192.168.1.99:3389 patrick@server1.example.com&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I learned that I could add an equivalent entry to my ~/.ssh/config file:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Host server1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  HostName server1.example.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Port 2222
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  User patrick
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  LocalForward 3389 192.168.1.99:3389&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then, to connect to that server, all I needed to do was run &lt;strong&gt;ssh server1&lt;/strong&gt; and all of the configuration details would be pulled in from the SSH config file. Replacing my series of shell aliases with Host definitions had the added benefit of automatically carrying over to other tools like &lt;a href=&#34;https://git-scm.com/&#34;&gt;git&lt;/a&gt; and &lt;a href=&#34;https://mosh.mit.edu/&#34;&gt;mosh&lt;/a&gt; which read the same configuration.&lt;/p&gt;
&lt;h3 id=&#34;switching-identities-automatically&#34;&gt;Switching Identities Automatically&lt;/h3&gt;
&lt;p&gt;There’s an easy solution to managing multiple SSH identities if you only use one identity per server; use &lt;a href=&#34;https://linux.die.net/man/1/ssh-add&#34;&gt;ssh-add&lt;/a&gt; to store all of your keys in the SSH authentication agent. For example, I used &lt;strong&gt;ssh-add ~/.ssh/endpoint_rsa&lt;/strong&gt; to add my new key, and &lt;strong&gt;ssh-add -l&lt;/strong&gt; to verify that it was showing up in the list of known keys. After adding all of your keys to the agent, it will automatically try them in order for SSH connections until it finds one that authenticates successfully.&lt;/p&gt;
&lt;h3 id=&#34;manually-defining-identities&#34;&gt;Manually Defining Identities&lt;/h3&gt;
&lt;p&gt;If you need more control over which identity an SSH session is using, the &lt;strong&gt;IdentityFile&lt;/strong&gt; option in &lt;a href=&#34;https://linux.die.net/man/5/ssh_config&#34;&gt;ssh_config&lt;/a&gt; lets you specify which key will be used to authenticate. Here’s an example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Host server2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  HostName server2.example.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  User patrick
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  IdentityFile ~/.ssh/endpoint_rsa&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This usage is particularly helpful when you have a server that accepts more than one of your identities and you need to control which one should be used.&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>SSH ProxyCommand with netcat and socat</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2013/04/socat-and-netcat-proxycommand-ssh/"/>
      <id>https://www.endpointdev.com/blog/2013/04/socat-and-netcat-proxycommand-ssh/</id>
      <published>2013-04-24T00:00:00+00:00</published>
      <author>
        <name>Greg Sabino Mullane</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;a href=&#34;/blog/2013/04/socat-and-netcat-proxycommand-ssh/image-0-big.jpeg&#34; imageanchor=&#34;1&#34;&gt;&lt;img border=&#34;0&#34; src=&#34;/blog/2013/04/socat-and-netcat-proxycommand-ssh/image-0.jpeg&#34;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.flickr.com/photos/tambako/5880777651/&#34;&gt;Picture&lt;/a&gt; by &lt;a href=&#34;https://www.flickr.com/photos/tambako/&#34;&gt;Tambako the Jaguar&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Most of my day to day is work is conducted via a terminal, using
&lt;a href=&#34;https://en.wikipedia.org/wiki/Secure_Shell&#34;&gt;Secure Shell&lt;/a&gt;
(SSH) to connect to various servers. I make extensive use of the local SSH
configuration file, &lt;strong&gt;~/.ssh/config&lt;/strong&gt; file, both to reduce typing by aliasing connections,
and to allow me to seamlessly connect to servers, even when a direct connection
is not possible, by use of the &lt;strong&gt;ProxyCommand&lt;/strong&gt; option.&lt;/p&gt;
&lt;p&gt;There are many servers I work on that cannot be directly reached, and this is
where the ProxyCommand option really comes to the rescue. It allows you to
chain two or more servers, such that your SSH connections bounce through the
servers to get to the one that you need. For example, some of our clients only allow
SSH connections from specific IPs. Rather than worry about which engineers need to connect, and
what IPs they may have at the moment, engineers can access servers through certain
trusted shell servers. Then our engineers can SSH to one of those servers, and from
there on to the client’s servers. As one does not want to actually SSH twice every time a
connection is needed, the ProxyCommand option allows a quick tunnel to be created. Here’s
an example entry for a &lt;code&gt;.ssh/config&lt;/code&gt; file:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Host proxy
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;User greg
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;HostName proxy.example.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Host acme
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;User gmullane
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;HostName pgdev.acme.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ProxyCommand ssh -q proxy nc -w 180 %h %p&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;So now when we run the command &lt;strong&gt;ssh acme&lt;/strong&gt;, ssh actually first logs into proxy.example.com
as the user “greg”, runs the nc (netcat) command (after plugging in the host and port parameters for us),
and then logs in to &lt;a href=&#34;mailto:gmullane@pgdev.acme.com&#34;&gt;gmullane@pgdev.acme.com&lt;/a&gt; from proxy.example.com. We don’t see any of this
happening: one simply types “ssh acme” and gets a prompt on the pgdev.acme.com server.&lt;/p&gt;
&lt;p&gt;Often times more than one “jump” is needed, but it is easy to chain servers together,
such that you can log into a third server by running two ProxyCommands. Recently,
this situation arose but with a further wrinkle. There was a server, we’ll call
it &lt;strong&gt;calamity.acme.com&lt;/strong&gt;, which was not directly reachable via SSH from the outside world, as
it was a tightly locked down production box. However, it was reachable by other boxes
within the company’s intranet, including pgdev.acme.com. Thus to login as gmullane
on the calamity server, the .ssh/config file would normally look like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Host proxy
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;User greg
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;HostName proxy.example.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Host acme
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;User gmullane
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;HostName pgdev.acme.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ProxyCommand ssh -q proxy nc -w 180 %h %p
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Host acme_calamity
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;User gmullane
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;## This is calamity.acme.com, but pgdev.acme.com cannot resolve that, so we use the IP
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;HostName 192.168.7.113
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ProxyCommand ssh -q acme nc -w 180 %h %p&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Thus, we’d expect to run &lt;strong&gt;ssh acme_calamity&lt;/strong&gt; and get a prompt on the calamity box.
However, this was not the case. Although I was able to ssh from proxy to acme,
and then from acme to calamity, things were failing because acme did not have the nc (netcat)
program installed. Further investigation showed that it was not even available
via packaging, which surprised me a bit as netcat is a pretty old, standard,
and stable program. However, a quick check showed that the
&lt;a href=&#34;http://www.dest-unreach.org/socat/doc/socat.html&#34;&gt;socat program&lt;/a&gt; was available, so I installed that instead.
The socat program is similar to netcat, but much more advanced. I did not need
any advanced functionality, however, just a simple bidirectional pipe which
the SSH connections could flow over. The new entry in the config file thus
became:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Host acme_calamity
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;User gmullane
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;HostName 192.168.13.123
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ProxyCommand ssh -q acme socat STDIN TCP:%h:%p&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;After that, everything worked as expected. It’s perfectly fine to mix socat and
netcat as we’ve done here; at the end of the day, they are simple dumb pipes
(although socat allows them to be not so simple or dumb if desired!). The arguments
to socat are simply the two sides of the pipe. One is stdin (sometimes written as
stdio or a single dash), and the other is a TCP connection to a specific host
and port (which SSH will plug in). You may also see it written as TCP4, which
simply forces IPv4 only, where TCP encompasses IPv6 as well.&lt;/p&gt;
&lt;p&gt;The options to netcat are very similar, but shorter as it already defaults to
using stdin for the one side, and because it defaults to a TCP connection,
so we can leave that out as well. The “-w 180” simply establishes a three minute
timeout so the connection will close itself on a problem rather than hanging out
until manually killed.&lt;/p&gt;
&lt;p&gt;Even if both netcat and socat were not available, there are other solutions.
In addition to other programs, it is easy enough to write a quick Perl script
to create your own bidirectional pipe!&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>OpenSSH Tips and Tricks with Matt Vollrath</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2012/06/openssh-tips-and-tricks-with-matt/"/>
      <id>https://www.endpointdev.com/blog/2012/06/openssh-tips-and-tricks-with-matt/</id>
      <published>2012-06-14T00:00:00+00:00</published>
      <author>
        <name>Brian Buchalter</name>
      </author>
      <content type="html">
        &lt;p&gt;Matt Vollrath’s presentation focused on unique solutions Liquid Galaxy administration requires.&lt;/p&gt;
&lt;p&gt;Specifically, Liquid Galaxy requires secure access to many public sites, which we don’t have physical access to. OpenSSH helps handle these remote challenges securely and quickly.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.flickr.com/photos/80083124@N08/7372338082/&#34; title=&#34;IMG_0803.JPG by endpoint920, on Flickr&#34;&gt;&lt;img alt=&#34;IMG_0803.JPG&#34; height=&#34;375&#34; src=&#34;/blog/2012/06/openssh-tips-and-tricks-with-matt/image-0.jpeg&#34; width=&#34;500&#34;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;multiplexing-for-speed&#34;&gt;Multiplexing for Speed&lt;/h3&gt;
&lt;p&gt;The LG master node can send commands to all the slave nodes at the same time. This can be helpful to examine all display nodes’ current states without manual work. The multiplexed connection uses options -f (background), -M (control socket), -N (no command), and -T (prevents pseudo-terminal from being allocated), and any further connections to the host do not need to authenticate, for speed.:&lt;/p&gt;
&lt;p&gt;ssh -fMNT hostname &amp;amp;&lt;/p&gt;
&lt;p&gt;Include the ampersand to be able to track the PID of the background ssh connection. This connection will be maintained until it fails or is killed.&lt;/p&gt;
&lt;p&gt;Additionally -O allows us to examine the state of the control connection as well as exit. As of OpenSSH 5.9, you can also use -O with the “stop” command to not accept any more multiplexers.&lt;/p&gt;
&lt;p&gt;When combined with a simple bash script to inspect the host connection first, the script can create that multiplexed connection first. This allows for &lt;strong&gt;very&lt;/strong&gt; fast work. Without control connection it takes 700ms to run a command; with sockets, 85ms.&lt;/p&gt;
&lt;p&gt;For Liquid Galaxy, everything is done over SSH so this speed is critical for a responsive experience while maintaining security. This responsive experience is multiplied for each node in the setup, which in LG’s case, may be up to 8 nodes.&lt;/p&gt;
&lt;h3 id=&#34;reverse-ssh-for-security&#34;&gt;Reverse SSH for Security&lt;/h3&gt;
&lt;p&gt;In order to allow access behind deployments’ firewalls, the LG head node connects to a proxy server and then forwards its own SSH port to that proxy server, allowing secure remote connectivity from any network which will allow output SSH.&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>SSH config wildcards and multiple Postgres servers per client</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2011/01/ssh-config-wildcards-and-multiple/"/>
      <id>https://www.endpointdev.com/blog/2011/01/ssh-config-wildcards-and-multiple/</id>
      <published>2011-01-07T00:00:00+00:00</published>
      <author>
        <name>Greg Sabino Mullane</name>
      </author>
      <content type="html">
        &lt;p&gt;The SSH config file has some nice features that help me to keep my sanity among a wide variety of servers spread across many different clients. Nearly all of my Postgres work is done by using SSH to connect to remote client sites, so the ability to connect to the various servers easily and intuitively is important. I’ll go over an example of how a ssh config file might progress as you deal with an ever‑expanding client.&lt;/p&gt;
&lt;p&gt;Some quick background: the ssh config file is a per‑user configuration file for &lt;a href=&#34;https://www.openssh.com/&#34;&gt;the SSH program&lt;/a&gt;. It typically exists as &lt;strong&gt;~/.ssh/config&lt;/strong&gt;. It has two main purposes: setting global configuration items (such as ForwardX11 no), and setting things on a host‑by‑host basis. We’ll be focusing on the latter.&lt;/p&gt;
&lt;p&gt;Inside the ssh config file, you can create &lt;strong&gt;Host&lt;/strong&gt; sections which specify options that apply only to one or more matching hosts. The sections are applied if the host name you type in as the argument to the ssh command matches what is after the word “Host”. As we’ll see, this also allows for wildcards, which can be very useful.&lt;/p&gt;
&lt;p&gt;I’m going to walk through a hypothetical client, Acme Corporation, and show how the ssh config can grow as the client does, until the final example mirrors an actual section of my ssh config section file.&lt;/p&gt;
&lt;p&gt;So, you’ve just got a new Postgres client called Acme Corporation, and they are using Amazon Web Services (AWS) to host their server. We’re coming in as the postgres user, and have our public ssh keys already in place inside &lt;strong&gt;~postgres/.ssh/authorized_keys&lt;/strong&gt; on their server. The hostname is &lt;strong&gt;ec2‑456‑55‑123‑45.compute‑1.amazonaws.com&lt;/strong&gt;. So, generally, we would connect by running:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ ssh postgres@ec2‑456‑55‑123‑45.compute‑1.amazonaws.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;That’s a lot to type each time! We could create a bash alias to handle this, but it’s better to use the ssh config file instead. We’ll add this to the end of our ssh config:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;##
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;## Client: Acme Corporation
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;##
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Host  acmecorp
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;User postgres
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Hostname  ec2-456-55-123-45.compute-1.amazonaws.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now we can simply use ‘acmecorp’ in place of that ugly string:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ ssh acmecorp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Notice that we don’t need to specify the user anymore: ssh config plugs that in for us. We can still override it if we need to connect as someone else:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ ssh greg@acmecorp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The next week, Acme Corporation decides that rather than allow anyone to SSH to their servers, they will use iptables or something similar to restrict access to select known hosts. Because different people with different IPs at End Point may need to access Acme, and because we don’t want to have Acme have to open a new hole each time we connect from a different place, we will connect from a shared company box. In this case, the box is &lt;strong&gt;vp.endpoint.com&lt;/strong&gt;. Acme arranges to allow SSH from that box to their servers, and each End Point employee has a login on the vp.endpoint.com box. What we need to do now is create a SSH tunnel. Inside of the ssh config file, we add a new line to the entry for ‘acmecorp’:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Host  acmecorp
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;User  postgres
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Hostname  ec2-456-55-123-45.compute-1.amazonaws.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ProxyCommand  ssh -q greg@vp.endpoint.com nc -w 180 %h %p&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, when we run this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ ssh acmecorp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&amp;hellip;everything looks the same to us, but what we are really doing is connecting to vp.endpoint.com, running the nc (netcat) command, and then connecting to the amazonaws.com box over the new netcat connection. (The arguments to netcat specify that the connection should be closed if there is the connection goes away for 180 seconds, and the host and port should be echoed along). As far as amazonaws.com is concerned, we are connecting from vp.endpoint.com. As far as &lt;em&gt;we&lt;/em&gt; are concerned, we are going directly to amazonaws.com. A nice side effect, and a big reason why we don’t simply use bash aliases, is that the &lt;strong&gt;scp&lt;/strong&gt; program will use these aliases as well. So we can now do something like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ scp check_postgres.pl acmecorp:&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This will copy the &lt;a href=&#34;https://bucardo.org/check_postgres/&#34;&gt;check_postgres.pl program&lt;/a&gt; from our computer to the Acme one, going through the tunnel at vp.endpoint.com.&lt;/p&gt;
&lt;p&gt;Business has been good for Acme lately and they finally have conceded to your strong suggestion to set up a warm standby server (using &lt;a href=&#34;https://www.postgresql.org/docs/current/static/continuous-archiving.html&#34;&gt;Postgres’ Point In Time Recovery system&lt;/a&gt;). This new server is located at &lt;strong&gt;ec2‑456‑55‑123‑99.compute‑1.amazonaws.com&lt;/strong&gt;, and the internal host name they give it is &lt;strong&gt;maindb‑replica&lt;/strong&gt; (the original box is known as &lt;strong&gt;maindb‑db&lt;/strong&gt;). This new server requires another host entry to ssh config. Rather than copy over the same ProxyCommand, we’ll refactor the information out into a separate host entry. What we end up with is this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Host  acmetunnel
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;User  greg
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Hostname  vp.endpoint.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Host  acmedb
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;User  postgres
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Hostname  ec2-456-55-123-45.compute-1.amazonaws.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ProxyCommand  ssh -q acmetunnel nc -w 180 %h %p
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Host  acmereplica
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;User  postgres
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Hostname  ec2-456-55-123-99.compute-1.amazonaws.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ProxyCommand  ssh -q acmetunnel nc -w 180 %h %p&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We also changed the name from acmecorp to just “acme” as that’s enough to uniquely identify among our clients, and who wants to type more than they have to?&lt;/p&gt;
&lt;p&gt;Next, the company adds a QA box they want End Point to help setup. This box, however, is &lt;em&gt;not&lt;/em&gt; reachable from outside their network; it can be reached only from other hosts in their network. Luckily, we already have access to some of those. What we’ll do is extend our tunnel by one more host, so that the path we travel from us to the Acme QA box is:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Local box → vp.endpoint.com → acreplica → acqa&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Here’s the section of the ssh config after we’ve added in the QA box:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Host  acmetunnel
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;User  greg
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Hostname  vp.endpoint.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Host  acmedb
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;User  postgres
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Hostname  ec2-456-55-123-45.compute-1.amazonaws.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ProxyCommand  ssh -q acmetunnel nc -w 180 %h %p
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Host  acmereplica
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;User  postgres
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Hostname  ec2-456-55-123-99.compute-1.amazonaws.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ProxyCommand  ssh -q acmetunnel nc -w 180 %h %p
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Host  acmeqa
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;User  postgres
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Hostname  qa
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ProxyCommand  ssh -q acreplica nc -w 180 %h %p&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note that we don’t need the full hostname at this point for the “acmeqa” Hostname, as we can simply say ‘qa’ and the acreplica box knows how to get there.&lt;/p&gt;
&lt;p&gt;There is still some unwanted repetition in the file, so let’s take advantage of the fact that the “Host” item inside the ssh config file will take wildcards as well. It’s not really apparent until you use wildcards, but a ssh host can match more than one “Host” section in the ssh config file, and thus you can achieve a form of inheritance. (However, once something has been set, it cannot be changed, so you always want to set the more specific items first). Here’s what the file looks like after adding a wildcard section:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Host  acme*
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;User  postgres
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ProxyCommand  ssh -q greg@vp.endpoint.com nc -w 180 %h %p
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Host  acmedb
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Hostname  ec2-456-55-123-45.compute-1.amazonaws.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Host  acmereplica
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Hostname  ec2-456-55-123-99.compute-1.amazonaws.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Host  acmeqa
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;User  root
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Hostname  qa
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ProxyCommand  ssh -q acreplica nc -w 180 %h %p&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Notice that the file is now simplified quite a bit. If we run this command:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ ssh acmereplica&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&amp;hellip;then the &lt;strong&gt;Host acme&lt;/strong&gt;* section sets up both the &lt;strong&gt;User&lt;/strong&gt; and the &lt;strong&gt;ProxyCommand&lt;/strong&gt;. It then also matches on the &lt;strong&gt;Host acmereplica&lt;/strong&gt; section and applies the &lt;strong&gt;Hostname&lt;/strong&gt; there.&lt;/p&gt;
&lt;p&gt;Note that we have removed the “acmetunnel” section. Now that all the ProxyCommands are in a single place, we can simply go back to the original ProxyCommand and specify the exact user and host.&lt;/p&gt;
&lt;p&gt;All of the above presumes we want to login as the postgres user, but there are also times when we need to login as a different user (e.g. ‘root’). We can again use wildcards, this time to match the &lt;em&gt;end&lt;/em&gt; of the host, to specify which user we want. Anything ending in the letter &lt;strong&gt;“r”&lt;/strong&gt; means we log in as user root, and anything ending in the letter &lt;strong&gt;“p”&lt;/strong&gt; means we log in as user postgres. Our final ssh config section for Acme is now:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;##
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;## Client: Acme Corporation
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;##
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Host  acme*
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ProxyCommand  ssh -q greg@vp.endpoint.com nc -w 180 %h %p
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Host  acme*r
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;User  root
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Host  acme*p
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;User  postgres
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Host  acmedb*
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Hostname  ec2-456-55-123-45.compute-1.amazonaws.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Host  acmereplica*
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Hostname  ec2-456-55-123-99.compute-1.amazonaws.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Host  acmeqa*
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Hostname  qa
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ProxyCommand  ssh -q acreplica nc -w 180 %h %p&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;From this point on, if Acme decides to add a new server, adding it into our ssh config is as simple as adding two lines:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Host  acmedev*
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Hostname  ec2-456-55-999-45.compute-1.amazonaws.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This automatically sets up two hosts for us, &lt;strong&gt;“acmedevr”&lt;/strong&gt; and &lt;strong&gt;“acmedevp”&lt;/strong&gt;. What if we leave out the ending “r” or “p” and just ssh to &lt;strong&gt;“acmedev”&lt;/strong&gt;? Then we’ll connect as the default user, or &lt;strong&gt;$ENV{USER}&lt;/strong&gt; (in my case, “greg”).&lt;/p&gt;
&lt;p&gt;Have fun configuring your ssh config file, don’t be afraid to leave lots of comments inside of it, and of course keep it in version control!&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>Long Lasting SSH Multiplexing Made Simplish</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2010/09/long-lasting-ssh-multiplexing-made/"/>
      <id>https://www.endpointdev.com/blog/2010/09/long-lasting-ssh-multiplexing-made/</id>
      <published>2010-09-01T00:00:00+00:00</published>
      <author>
        <name>Brian J. Miller</name>
      </author>
      <content type="html">
        &lt;h3 id=&#34;my-digression&#34;&gt;My Digression&lt;/h3&gt;
&lt;p&gt;To start off digressing just a little, I am primarily a developer, lately on longer projects of relatively significant size which means that I stay logged in to the same system for weeks (so long as my X session, local connection, and remote server allow it). I’m also a big believer in lots of screen real estate and using it all when you have it, so I have two monitors running high resolutions (1920x1200), and I use anywhere from 4-6 virtual pages/desktops/screens/(insert term of preference here). On 2-3 of those spaces I generally keep 8 &amp;ldquo;little black screens&amp;rdquo; (as my wife likes to call them) or terminals open in 2 rows of 4 windows. In each of those terminals I stay logged in to the same system as long as those aforementioned outside sources will allow me. A little absurd I know&amp;hellip;&lt;/p&gt;
&lt;p&gt;If you are still with me you may be thinking &amp;ldquo;why don’t you just use &lt;code&gt;screen&lt;/code&gt;?&amp;rdquo;, I do, in each of those terminals for the inevitable times when network hiccups occur, etc. Next you’ll ask, &amp;ldquo;why don’t you just use separate tabs/windows/partitions/(whatever they are called) within screen?&amp;rdquo;, I do, generally I have 2-3 (or more) in each screen instance set to multiple locations on the remote file system. In general I’ve just found being able to look across a row of terminals at various different libs, a database client, tailed logs, etc. is much faster than toggling between windows (heaven forbid they’d be minimized), screen pages, virtual desktops, or even shell job control (though I use a good bit of that too). Inevitably I also seem to pop up an additional window (or two) every now and again and ssh into the same remote destination for the occasional one off command (particularly since I’ve never quite gotten the SSH key thing figured out with long running screens, potential future blog post?). So the bottom line, for any given sizable project I probably ssh to the same location a minimum of 8 times each time I set up my desktop and over the course of a particular X session maybe 20 (or more) times? (End digression)&lt;/p&gt;
&lt;h3 id=&#34;the-point&#34;&gt;The Point&lt;/h3&gt;
&lt;p&gt;As fast as SSHing is, waiting for a prompt when doing it that many times (particularly over the course of a year, or career) really starts to make the clock tick by (or at least it seems that way). Enter &amp;ldquo;multiplexing&amp;rdquo; which is essentially a wonderful feature in newer SSH that allows you to start one instance with a control channel that handles many of the slow parts (such as authentication) and so long as it is still running when you connect to the same remote location the new connection uses the existing control channel and is lightning fast getting you to the prompt. Simple enough, to turn on multiplexing you can add the following to your ~/.ssh/config:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888&#34;&gt;# for multiplexing&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ControlMaster auto
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ControlPath ~/.ssh/multi/master-%r@%h:%p&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The above indicates that a master should be used for each connection, and the location of where to store the master’s control socket file. The %r, %h, and %p are expanded to the login, host, and port respectively which is usually enough to make it unique. This should be enough to start using multiplexing, but&amp;hellip;and you knew there had to be one&amp;hellip;when the master’s control connection is lost all of the slaves to that connection lose their’s as well. With the occasional hung terminal window, or accidental closing of it (if you can remember which is master to begin with), etc. you quickly find that when you normally would not lose connection in a separate terminal window you all of a sudden have lost all of your connections (8+ in my case) which is really painful. Here is where the fun comes in, I use the &amp;ldquo;-n&amp;rdquo; and &amp;ldquo;-N&amp;rdquo; flags to SSH in a terminal window when I first load up an X session and background the process:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;gt; ssh -Nn user@remote &amp;amp;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The above redirects stdin from /dev/null (a necessary evil when backgrounding SSH procs), prevents the execution of a remote command (meaning we don’t want a shell), and puts the new process in the local shell’s background. Unfortunately, and the part that took me the longest to figure out, is that SSH really likes to have a TTY around (we aren’t using the daemon after all) so simply killing the original terminal window will cause the SSH process to die and zap there went your control connection and all the little children. To get around this little snafu I follow the backgrounding of my SSH process with a bash specific built in disassociating it from the TTY:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;gt; disown&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now I am free to close the original terminal window, the SSH process lives on in the background (as if it were a daemon) and keeps the control connection open so that whenever I use SSH to that remote location (or ‘scp’, etc.) I get an instant response.&lt;/p&gt;
&lt;h3 id=&#34;other-notes&#34;&gt;Other notes&lt;/h3&gt;
&lt;p&gt;I could probably set this up to occur when I start X initially automatically, but with a flaky connection I end up needing to do it a few times per X session anyways and you would have to watch out for the sequence of events making sure it occurred after any ssh-agent set up was required.&lt;/p&gt;
&lt;p&gt;I tried using ‘nohup’ and can’t remember if I ran into an actual show stopper problem, or if I could just never quite get it to do what I wanted before I stumbled on bash’s disown.&lt;/p&gt;

      </content>
    </entry>
  
</feed>
