<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Ssh on </title>
    <link>/tags/ssh/</link>
    <description>Recent content in Ssh on </description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <lastBuildDate>Thu, 16 Jan 2025 04:22:58 +0000</lastBuildDate><atom:link href="/tags/ssh/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>How to do SSH properly</title>
      <link>/posts/ssh/</link>
      <pubDate>Thu, 16 Jan 2025 04:22:58 +0000</pubDate>
      
      <guid>/posts/ssh/</guid>
      <description>&lt;h1 id=&#34;the-things-people-get-wrong&#34;&gt;The things people get wrong&lt;/h1&gt;
&lt;p&gt;When configuring SSH an incredible amount of servers aren&amp;rsquo;t set up correctly and this causes them to be extremely vulnerable to even automated attacks. Common mistakes include failing to disable root login, permitting password-based authentication instead of key-based authentication and more.&lt;/p&gt;
&lt;h1 id=&#34;install-openssh-server&#34;&gt;Install OpenSSH server&lt;/h1&gt;
&lt;p&gt;First install openssh on your machine. You can usually do this on Ubuntu based distro using &lt;code&gt;sudo apt install openssh-server&lt;/code&gt;. Now &lt;strong&gt;before&lt;/strong&gt; enabling the initially vulnerable service it&amp;rsquo;s time to make some changes.&lt;/p&gt;</description>
      <content>&lt;h1 id=&#34;the-things-people-get-wrong&#34;&gt;The things people get wrong&lt;/h1&gt;
&lt;p&gt;When configuring SSH an incredible amount of servers aren&amp;rsquo;t set up correctly and this causes them to be extremely vulnerable to even automated attacks. Common mistakes include failing to disable root login, permitting password-based authentication instead of key-based authentication and more.&lt;/p&gt;
&lt;h1 id=&#34;install-openssh-server&#34;&gt;Install OpenSSH server&lt;/h1&gt;
&lt;p&gt;First install openssh on your machine. You can usually do this on Ubuntu based distro using &lt;code&gt;sudo apt install openssh-server&lt;/code&gt;. Now &lt;strong&gt;before&lt;/strong&gt; enabling the initially vulnerable service it&amp;rsquo;s time to make some changes.&lt;/p&gt;
&lt;h1 id=&#34;lets-get-editing&#34;&gt;Let&amp;rsquo;s get editing!&lt;/h1&gt;
&lt;p&gt;Using your favourite text editor edit (with admin privileges) &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt; on the server. By default it most likely looks similar to this:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Include /etc/ssh/sshd_config.d/*.conf

# This is the sshd server system-wide configuration file.  See
# sshd_config(5) for more information.

# This sshd was compiled with PATH=/usr/local/sbin:/usr/local/bin:/usr/bin

# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented.  Uncommented options override the
# default value.

#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::

#HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_ecdsa_key
#HostKey /etc/ssh/ssh_host_ed25519_key

# Ciphers and keying
#RekeyLimit default none

# Logging
#SyslogFacility AUTH
#LogLevel INFO

# Authentication:

#LoginGraceTime 2m
#PermitRootLogin prohibit-password
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10

#PubkeyAuthentication yes

# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
# but this is overridden so installations will only check .ssh/authorized_keys
AuthorizedKeysFile	.ssh/authorized_keys

#AuthorizedPrincipalsFile none

#AuthorizedKeysCommand none
#AuthorizedKeysCommandUser nobody

# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
#HostbasedAuthentication no
# Change to yes if you don&amp;#39;t trust ~/.ssh/known_hosts for
# HostbasedAuthentication
#IgnoreUserKnownHosts no
# Don&amp;#39;t read the user&amp;#39;s ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes

# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
#PermitEmptyPasswords no

# Change to no to disable s/key passwords
#KbdInteractiveAuthentication yes

# Kerberos options
#KerberosAuthentication no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosGetAFSToken no

# GSSAPI options
#GSSAPIAuthentication no
#GSSAPICleanupCredentials yes

# Set this to &amp;#39;yes&amp;#39; to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the KbdInteractiveAuthentication and
# PasswordAuthentication.  Depending on your PAM configuration,
# PAM authentication via KbdInteractiveAuthentication may bypass
# the setting of &amp;#34;PermitRootLogin prohibit-password&amp;#34;.
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and KbdInteractiveAuthentication to &amp;#39;no&amp;#39;.
#UsePAM no

#AllowAgentForwarding yes
#AllowTcpForwarding yes
#GatewayPorts no
#X11Forwarding no
#X11DisplayOffset 10
#X11UseLocalhost yes
#PermitTTY yes
#PrintMotd yes
#PrintLastLog yes
#TCPKeepAlive yes
#PermitUserEnvironment no
#Compression delayed
#ClientAliveInterval 0
#ClientAliveCountMax 3
#UseDNS no
#PidFile /run/sshd.pid
#MaxStartups 10:30:100
#PermitTunnel no
#ChrootDirectory none
#VersionAddendum none

# no default banner path
#Banner none

# override default of no subsystems
Subsystem	sftp	/usr/lib/ssh/sftp-server

# Example of overriding settings on a per-user basis
#Match User anoncvs
#	X11Forwarding no
#	AllowTcpForwarding no
#	PermitTTY no
#	ForceCommand cvs server
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;change-the-default-port&#34;&gt;Change the default port&lt;/h2&gt;
&lt;p&gt;The first thing I recommend changing is the SSH port you use. This isn&amp;rsquo;t necessarily something that should be relied on to protect you as it&amp;rsquo;s security through obscurity however if there are vulnerabilties in OpenSSH (which there have been in the past) then there&amp;rsquo;s a smaller chance automated bots will find your SSH server. This is because they traditionally look for port 22 and if they do scan for other ports they often wouldn&amp;rsquo;t scan to a really high port such as 9057 for instance; they typically only scan up to 1000.&lt;/p&gt;
&lt;p&gt;Another benefit is that it will keep your logs down as they will get rather big if they&amp;rsquo;re logging automated attacks which try to authenticate with your SSH server. Fortunately they likely won&amp;rsquo;t reach your actual SSH port and so the only logs generated will generally be from your own activity which often is smaller than a hundred or so requests a day from bots. To do this change &lt;code&gt;#Port 22&lt;/code&gt; to &lt;code&gt;Port 7845&lt;/code&gt; or whatever port you choose.&lt;/p&gt;
&lt;h2 id=&#34;disable-root-login&#34;&gt;Disable root login&lt;/h2&gt;
&lt;p&gt;There&amp;rsquo;s a line which says: &lt;code&gt;#PermitRootLogin prohibit-password&lt;/code&gt;. Adjust this to &lt;code&gt;#PermitRootLogin no&lt;/code&gt;. This prevents logging into root (essentially the admin account) via SSH. Much safer! Note that it is possible to only allow specific users to be signed in via SSH but that&amp;rsquo;s out of the scope of this guide and not really necesssary.&lt;/p&gt;
&lt;h2 id=&#34;disable-password-authentication&#34;&gt;Disable password authentication&lt;/h2&gt;
&lt;p&gt;Another crucial line to change if not the most important is: &lt;code&gt;#PasswordAuthentication yes&lt;/code&gt;. This needs to be set to &lt;code&gt;PasswordAuthentication no&lt;/code&gt;. Wonderful!&lt;/p&gt;
&lt;h1 id=&#34;set-up-fail2ban&#34;&gt;Set up Fail2Ban&lt;/h1&gt;
&lt;p&gt;Fail2Ban is a great piece of kit designed to mitigate brute-force attacks (where an attacker will try different combinations until they guess the right password/ key to gain access). Essentially it allows us to ban an IP address of an attacker using various rule-sets. To install it run &lt;code&gt;sudo apt install fail2ban&lt;/code&gt;. Now the configuration file can be found at &lt;code&gt;/etc/fail2ban/jail.conf&lt;/code&gt; however when the package is update this will be overwritten and there it&amp;rsquo;s not recommended to edit this file directly. Instead create a copy in the same directory called &lt;code&gt;jail.local&lt;/code&gt;. To do this run the following command: &lt;code&gt;sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local&lt;/code&gt;. Now you can edit the file using administrator privileges. Under the &amp;ldquo;Jails&amp;rdquo; section you should find sshd. As shown below:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#
# JAILS
#

#
# SSH servers
#

[sshd]

# To use more aggressive sshd modes set filter parameter &amp;#34;mode&amp;#34; in jail.local:
# normal (default), ddos, extra or aggressive (combines all).
# See &amp;#34;tests/files/logs/sshd&amp;#34; or &amp;#34;filter.d/sshd.conf&amp;#34; for usage example and details.
#mode   = normal
port    = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you changed the SSH port in the previous step then adjust that here e.g. &lt;code&gt;port = 7845&lt;/code&gt;. I recommend changing the bantime to at least an hour. To do this edit the following:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# &amp;#34;bantime&amp;#34; is the amount of time that a host is banned, integer in seconds or
# time abbreviation format (m - minutes, h - hours, d - days, w - weeks, mo - months, y - years).
# This is to consider as an initial time if bantime.increment gets enabled.
bantime  = 10m

# A host is banned if it has generated &amp;#34;maxretry&amp;#34; during the last &amp;#34;findtime&amp;#34;
# seconds.
findtime  = 10m

# &amp;#34;maxretry&amp;#34; is the number of failures before a host get banned.
maxretry = 5
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can adjust bantime to your liking e.g. &lt;code&gt;bantime = 1h&lt;/code&gt; will set it to one hour. There&amp;rsquo;s a lot more you can do with fail2ban and formulas you can tinker with which dynamically change the ban time expondentially for repeat offenders but we&amp;rsquo;ll leave it there for now. Save the file and run &lt;code&gt;sudo systemctl enable fail2ban --now&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To test this works you can actually abuse your SSH server (when we&amp;rsquo;ve enabled it later) and see if you get banned (although I recommend setting the bantime to 1m if you&amp;rsquo;re going to do this). To test it, simply try to login to your SSH server with the wrong username and identity key (more on that later) several times.&lt;/p&gt;
&lt;p&gt;You can see the status of bans by running &lt;code&gt;sudo fail2ban-client status sshd&lt;/code&gt;.&lt;/p&gt;
&lt;h1 id=&#34;generate-some-ssh-keys&#34;&gt;Generate some SSH keys&lt;/h1&gt;
&lt;p&gt;At this point it would probably be a good idea to generate some SSH keys. On your client machine (the one you want to use to connect to your SSH server) run &lt;code&gt;ssh-keygen&lt;/code&gt; set the filename to something memorable such as &amp;ldquo;mediaserver&amp;rdquo; and press enter. Then add a password - this encrypts your private key ensuring that even if somebody got hold of it, they&amp;rsquo;d be unable to access your SSH server (providing the password was strong enough). It&amp;rsquo;s an extra step but isn&amp;rsquo;t necessary as long as you feel the files on your computer are secure!!! Are they!?&lt;/p&gt;
&lt;p&gt;Type &lt;code&gt;ls&lt;/code&gt; into the terminal and you should see two files &lt;code&gt;mediasever&lt;/code&gt; and &lt;code&gt;mediaserver.pub&lt;/code&gt; (or whatever you named them). Move these to the .ssh folder in the home directory using the following command &lt;code&gt;mkdir -p ~/.ssh/keys &amp;amp;&amp;amp; mv mediaserver mediaserver.pub ~/.ssh/keys&lt;/code&gt; - this command makes the .ssh directory in the home folder if it doesn&amp;rsquo;t already exist and then moves the ssh keys to a folder called &amp;ldquo;keys&amp;rdquo; inside of the .ssh directory. Your directory structure should look like this:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;.ssh
└── keys
    ├── mediaserver
    └── mediaserver.pub

2 directories, 2 files
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now let&amp;rsquo;s change the permission of the files to ensure they&amp;rsquo;re kept extra safe &lt;code&gt;chmod 600 ~/.ssh/keys/*&lt;/code&gt;. This ensures &lt;strong&gt;only&lt;/strong&gt; the owner of the file has read and write permission.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;mediaserver&lt;/code&gt; file is the private key (this must be kept secret and &lt;strong&gt;NEVER&lt;/strong&gt; shared with anyone else). The &lt;code&gt;mediaserver.pub&lt;/code&gt; key is the public key and this can be shared anywhere without consequences. We need to take the contents of &lt;code&gt;mediaserver.pub&lt;/code&gt; and append them (add as a new line) to a file on our server found at &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt;. Feel free to add this to GitHub or a pastepin service and download it onto the server. I recommend copying the files contents as follows: &lt;code&gt;cat ~/.ssh/keys/mediaserver.pub&lt;/code&gt;. Make sure to copy this exactly and create a paste &lt;a href=&#34;https://pastebin.com&#34;&gt;here&lt;/a&gt;. You should have a link like this &lt;a href=&#34;&#34;&gt;https://pastebin.com/raw/VAuQ6qta&lt;/a&gt;
(note the raw part of the URL is rather important for the next step). Now go to your server and execute the following &lt;code&gt;curl https://pastebin.com/raw/VAuQ6qta &amp;gt;&amp;gt; ~/.ssh/authorized_keys&lt;/code&gt;. Curl will grab the contents and then add it as a new line to the authorized_keys file (and create the file if it didn&amp;rsquo;t already exist). Note that &lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt; means append but &lt;code&gt;&amp;gt;&lt;/code&gt; means overwrite (which is only harmful if you already had keys in there).&lt;/p&gt;
&lt;p&gt;Now it&amp;rsquo;s time to start your SSH server with &lt;code&gt;sudo systemctl enable sshd --now&lt;/code&gt;.&lt;/p&gt;
&lt;h1 id=&#34;a-note-about-firewalls&#34;&gt;A note about firewalls&lt;/h1&gt;
&lt;p&gt;You&amp;rsquo;ll also need to change any firewall settings. If you haven&amp;rsquo;t got a firewall installed already then install one with &lt;code&gt;sudo apt install ufw&lt;/code&gt;. This will install Uncomplicated Firewall. Allow your SSH port with &lt;code&gt;sudo ufw allow 7845/tcp&lt;/code&gt; (or whatever port you chose). Now enable the firewall with &lt;code&gt;sudo ufw enable&lt;/code&gt;. If you want to see the firewall rules run &lt;code&gt;sudo ufw status&lt;/code&gt;. To delete them run &lt;code&gt;sudo ufw status numbered&lt;/code&gt; and then &lt;code&gt;sudo ufw delete NUMBER&lt;/code&gt; where &amp;ldquo;NUMBER&amp;rdquo; is the rule you wish to delete. You can also reset it with &lt;code&gt;sudo ufw reset&lt;/code&gt; but please note this will deactivate it and you&amp;rsquo;ll need to run &lt;code&gt;sudo ufw enable&lt;/code&gt; again to reinstate it. If you want to establish an SSH connection outside of your home network then you&amp;rsquo;ll also need to port forward the appropriate port.&lt;/p&gt;
&lt;p&gt;If all is well you should be able to log in on your client machine with &lt;code&gt;ssh -p 7845 -i ~/.ssh/keys/mediaserver myserverusername@myIPAddress&lt;/code&gt;. The &lt;code&gt;-p 7845&lt;/code&gt; stands for the port you wish to use (if you didn&amp;rsquo;t change it from 22 you can leave this out) and &lt;code&gt;-i&lt;/code&gt; specifies the identity file required to authorize the connection.&lt;/p&gt;
&lt;h1 id=&#34;managing-ssh-keys&#34;&gt;Managing SSH keys&lt;/h1&gt;
&lt;p&gt;Running &lt;code&gt;ssh -p 7845 -i ~/.ssh/keys/mediaserver myserverusername@myIPAddress&lt;/code&gt; can become rather tedious, especially if you need to connect to multiple machines, remember all of their identity files, individual ports etc. To mitiate this create a file in &lt;code&gt;~/.ssh/config&lt;/code&gt;. Inside add the following:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Host mediaserver
    User myserverusername
    Port 7845
    IdentityFile ~/.ssh/keys/mediaserver
    HostName myIPAddress
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This then allows you to run &lt;code&gt;ssh mediaserver&lt;/code&gt; and you&amp;rsquo;ll be able to connect to your server just like that. Note that the name &amp;ldquo;mediaserver&amp;rdquo; is whatever you specify as the &amp;ldquo;Host&amp;rdquo; - you can literally call it anything and it can be different from the key names or username.&lt;/p&gt;
&lt;p&gt;To add more ssh connections edit the file as follows:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Host mediaserver
    User myserverusername
    Port 7845
    IdentityFile ~/.ssh/keys/mediaserver
    HostName myIPAddress
Host linode-vps
    User oden
    Port 5034
    IdentityFile ~/.ssh/keys/linode
    HostName 203.0.113.45
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We can now connect to our Linode VPS (Virtual Private Server - basically a machine running what&amp;rsquo;s usually Ubuntu in the cloud).&lt;/p&gt;
&lt;h1 id=&#34;congratulations-&#34;&gt;Congratulations 🥳&lt;/h1&gt;
&lt;p&gt;Well done! You have successfully (I hope) set up SSH securely and learnt to manage SSH keys. If you&amp;rsquo;d like to create an SSH connection without port forwarding or firewall rules then I suggest looking into &lt;a href=&#34;https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/use-cases/ssh&#34;&gt;Cloudflare tunnels&lt;/a&gt; or &lt;a href=&#34;https://tailscale.com/kb/1193/tailscale-ssh&#34;&gt;TailScale&lt;/a&gt;.&lt;/p&gt;
</content>
    </item>
    
  </channel>
</rss>
