diff --git a/archetypes/posts.md b/archetypes/posts.md index 11b1a82..7bf0ce4 100644 --- a/archetypes/posts.md +++ b/archetypes/posts.md @@ -14,7 +14,6 @@ cover: alt: "" # alt text caption: "" # display caption under cover relative: false # when using page bundles set this to true - searchHidden: false showtoc: true -searchHidden: true +searchHidden: false --- diff --git a/content/posts/securing-ssh.md b/content/posts/securing-ssh.md new file mode 100644 index 0000000..9e91bf4 --- /dev/null +++ b/content/posts/securing-ssh.md @@ -0,0 +1,425 @@ +--- +title: Securing SSH +date: 2021-12-07T22:41:02Z +author: "ahmza" +draft: false +weight: + +tags: ["HomeLab", "SSH", "RemoteAccess"] +description: "Ever wanted to make your SSH connections more secure. Read this" +canonicalURL: "https://blog.ahmza.com/Page%28/posts/securing-ssh.md%29" + +cover: + image: "" + alt: "ssh-alt image" # alt text + caption: "" # display caption under cover + relative: false # when using page bundles set this to true +showtoc: true +searchHidden: false +--- +# **Introduction** +SSH is a widely used protocol to access remote devices. The problem +with SSH is at the authentication stage, Brute force attacks are one of +the ways an SSH connection can be compromised. A malicious actor will +constantly hammer the remote host with different passwords until it can +gain access. With further configuration of SSH we can make the service +a lot more secure. + +# **Configure SSH** +![this is fine](/img/gifs/this-is-fine.gif) +> **Famous last words:** Configuring SSH like many things in Linux is +as simple as editing a few config files + +Always be sure to **create a backup file** it's very easy to end up +locking yourself out of a device. + +I would recommend practising on a machine that is not critical. + +## **Create SSH Keys** +SSH keys use public and private key encryption for authentication. + +To create a set of keys, **on the client do:** +``` bash +ssh-keygen +``` +You will be asked where you want to save the keys, **I recommend the \ +default location** for less hair pulling later. +``` bash +Enter file in which to save the key (/home/user/.ssh/id_rsa): +``` +You will be asked to enter a password for the ssh keys, be sure to use +a strong password. +``` bash +Enter passphrase (empty for no passphrase): +``` +Once that is done you will see a confirmation screen like the one below +``` +Output +Your identification has been saved in /home/user/.ssh/id_rsa +Your public key has been saved in /home/user/.ssh/id_rsa.pub +The key fingerprint is: +SHA256:tIurljnWJRBc1RnHUJQ5GtND7p9HWKnjV6zjE9AFR1Y user@host +The key's randomart image is: ++---[RSA 3072]----+ +| . .....oX=o.oE| +| o =oB oo| +| . . +.+ o.| +| . . .... o+ | +| . S .+. +| +| .... ..o+.| +| +.o. .=o.| +| * .. .oo | +| o.o. .. | ++----[SHA256]-----+ +``` + +## **Copy SSH Keys** +> **Quick note:** user@host is the **username** on the **remeote host** +you would like to copy your public key to. + +``` bash +ssh-copy-id user@host +``` + +**If asked to confirm the connection to the remote host answer yes**, this +happens when a new machine with an unknown identity wants to connect to +the client. + +``` +Output +The authenticity of host 'host(host)' can't be established. +ECDSA key fingerprint is xx:xx:xx:xx:xx:xx:xx:xx. +Are you sure you want to continue connecting (yes/no)? yes +``` + +You will then be asked to **enter a password** for the user on the remote +host + +``` +Output +/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed +/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys +user@host's password: +``` + +If successful you should be able to access the device using the SSH key + +To verify this, SSH to the device and **it should ask for the Keys's +password not the users** + +``` bash +Enter passphrase for key '/home/user/.ssh/id_rsa': +``` + +## **Modify SSH Config** +create a backup +``` bash +sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak +``` +open the original file in a text editor +``` bash +sudo vim /etc/ssh/sshd_config +``` +For a new user this might be daunting. Take your time and you will be +fine 😊 + +![that's a big one](/img/gifs/thats-a-big-one.gif) + +**Lines we want to modify** + +> **Quick note:** you may need to uncomment some lines as well as add a +few + +* Protocol 2 - add to line 15 +* Port 2222 - modify line 17 +* PermitRootLogin no - modify line 36 +* Max Auth Tries 5 - modify line 38 +* PasswordAuthentication no - modify line 60 +* PermitEmptyPasswords no -modify line 61 +* AllowUsers ahmza - add line 67 +* ClientAliveInterval 180 - modify line 104 + +``` +# $OpenBSD: sshd_config,v 1.103 2018/04/09 20:41:22 tj Exp $ + +# This is the sshd server system-wide configuration file. See +# sshd_config(5) for more information. + +# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin + +# 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. + +Include /etc/ssh/sshd_config.d/*.conf + +Protocol 2 + +Port 2222 +#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 no +#StrictModes yes +MaxAuthTries 5 +#MaxSessions 10 + +#PubkeyAuthentication yes + +# Expect .ssh/authorized_keys2 to be disregarded by default in future. +#AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2 + +#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't trust ~/.ssh/known_hosts for +# HostbasedAuthentication +#IgnoreUserKnownHosts no +# Don't read the user's ~/.rhosts and ~/.shosts files +#IgnoreRhosts yes + +# To disable tunneled clear text passwords, change to no here! +PasswordAuthentication no +PermitEmptyPasswords no + +AllowUsers ahmza + +# Change to yes to enable challenge-response passwords (beware issues with +# some PAM modules and threads) +ChallengeResponseAuthentication no + +# Kerberos options +#KerberosAuthentication no +#KerberosOrLocalPasswd yes +#KerberosTicketCleanup yes +#KerberosGetAFSToken no + +# GSSAPI options +#GSSAPIAuthentication no +#GSSAPICleanupCredentials yes +#GSSAPIStrictAcceptorCheck yes +#GSSAPIKeyExchange no + +# Set this to 'yes' to enable PAM authentication, account processing, +# and session processing. If this is enabled, PAM authentication will +# be allowed through the ChallengeResponseAuthentication and +# PasswordAuthentication. Depending on your PAM configuration, +# PAM authentication via ChallengeResponseAuthentication may bypass +# the setting of "PermitRootLogin without-password". +# If you just want the PAM account and session checks to run without +# PAM authentication, then enable this but set PasswordAuthentication +# and ChallengeResponseAuthentication to 'no'. +UsePAM yes + +#AllowAgentForwarding yes +#AllowTcpForwarding yes +#GatewayPorts no +X11Forwarding yes +#X11DisplayOffset 10 +#X11UseLocalhost yes +#PermitTTY yes +PrintMotd no +#PrintLastLog yes +#TCPKeepAlive yes +#PermitUserEnvironment no +#Compression delayed +ClientAliveInterval 180 +#ClientAliveCountMax 3 +#UseDNS no +#PidFile /var/run/sshd.pid +#MaxStartups 10:30:100 +#PermitTunnel no +#ChrootDirectory none +#VersionAddendum none + +# no default banner path +#Banner none + +# Allow client to pass locale environment variables +AcceptEnv LANG LC_* + +# override default of no subsystems +Subsystem sftp /usr/lib/openssh/sftp-server + +# Example of overriding settings on a per-user basis +#Match User anoncvs +# X11Forwarding no +# AllowTcpForwarding no +# PermitTTY no +# ForceCommand cvs server +``` +![not so bad](/img/gifs/star-trek-not-so-bad.gif) + +**Now lets explain what we just did** +* **Protocol 2** - released in 2006, SSH2 introduced improved +encryption algorithms. +* **Port 2222** - The port number can be whatever number you want. +Choose something other than 22 this will help hide your device from malicious actors +* **PermitRootLogin no** - If the root account were to be compromised +then the attacker has full control of the system so we stop it from being able to log in. +* **MaxAuthTries 5** - After 5 failed attempts the remote host blocks +requests from that IP for a period of time. +* **PasswordAuthentication no** - We have the SSH key installed so we +no longer need to have password authentication. +* **PermitEmptyPasswords no** - We don't want to allow empty passwords +to be used as authentication for obvious reasons. +* **AllowUsers username** - Add the usernames of users you want to be +able to connect to the remote host and other users trying to connect +will be dropped. +* **Client Alive Interval 180** - Drop the connection after a certain +period of inactivity + +## **Check were able to connect** +restart sshd service +``` bash +sudo systemctl restart sshd +``` +**Keep the current SSH connection open** and create a new session. + +If you are able to connect to the remote hosts then you are all set. If +not then you still have the initial connection to the remote host to +roll back the changes and troubleshoot. + +# **Success** + +![clap](/img/gifs/clap.gif) + +# **Setting up** ***Fail2Ban*** +_Fail2Ban_ is an intrusion prevention tool. Although we are slowing +bots down with MaxAuthTries the attacker is still able to carry on +brute forcing. Which is what Fail2Ban is for, it actually blocks the +connections from that IP. + +## **Install** ***Fail2Ban*** +**We will install Fail2Ban on the remote host** +First upgrade any packages, then **install** ***Fail2Ban*** +``` bash +sudo apt update && sudo apt upgrade +sudo apt install fail2ban +``` +Now we need to enable the service so it starts when the remote host +starts +``` bash +sudo systemctl enable --now fail2ban +``` +## **Configure** ***Fail2Ban*** +The Fail2Ban config file we want to edit is called **jail.local** located in **/etc/fail2ban/** +open jail.local in your editor of choice +``` bash +sudo vim /etc/fail2ban/jail.local +``` +The config for _Fail2Ban_ is a lot shorter than sshd so this should be +quick +``` +[DEFAULT] + bantime = 8h + ignoreip = 127.0.0.1 + ignoreself = true + +[sshd] + enabled = true + port = 2222 + filter = sshd + logpath = /var/log/auth.log + maxretry = 3 + findtime = 10m +``` + +**[Default]** - Settings in here apply to all jails + +* **bantime** - how long the ban will last +* **ignoreip** - IP addresses to ignore +* **ignoreself** - stops from locking itself out + +**[sshd]** - this is the jail for sshd + +* **enabled** - decides weather the jail is active or not +* **port** - the port number the service +* **filter** - tells the jail which filter to use from /etc/fail2ban/filter.d +* **logpath** - where the log you want fail2ban to read is +* **maxretry** - Times the client can attempt a login before being banned +* **findtime** - An amount of time which maxretry must occur to trigger a +ban for example in 10 minutes if 3 failed login attempts are made the +ban the IP + +**Restart** ***Fail2Ban*** to load the configuration +``` bash +sudo systemctl restart fail2ban +``` + +## **Testing** ***Fail2Ban*** +To test Fail2Ban lets create a test user and set a password for the +user +``` bash +sudo useradd test +sudo passwd test +``` +**open the sshd config** +``` bash +sudo vim /etc/ssh/sshd_config +``` +modify the line **PasswordAuthentication** to say **yes** and add the test user to **AllowUsers** +``` bash +PasswordAuthentication yes +AllowUsers user test +``` +**restart the sshd service** +``` bash +sudo systemctl restart sshd +``` +Attempt to login to the remote host using the test account using an +incorrect password. After 3 failed attempts it should say connection +refused. +``` bash +ssh test@host -p 2222 +``` +_Fail2Ban_ should do something along the lines of ... +![you shall not pass](/img/gifs/you-shall-not-pass.gif) +log back in as your normal user, remove the test user and restore the +sshd config. + +**To remove the user** +``` bash +sudo userdel test +``` +**restore the /etc/ssh/sshd_config file** +``` bash +sudo vim /etc/ssh/sshd_config +``` +Set **PasswordAuthentication** back to **no** and remove test from **AllowUsers** +``` bash +PasswordAuthentication no +AllowUsers user +``` +# **Conclusion** +well done, you managed to make it through all that !! At least now you +can be reassured that if them pesky brute-force attackers decide to +target your machine they wont have a fun time being in Jail 🤣 sorry +bad joke. + +By now you have managed to setup an ssh key for a client and copy it to +a remote host, re-configure the sshd config to lockdown authentication +and last but not least install and configure Fail2Ban to block pesky +attackers. + +![proud](/img/gifs/proud.gif) diff --git a/static/img/gifs/clap.gif b/static/img/gifs/clap.gif new file mode 100644 index 0000000..446cea6 Binary files /dev/null and b/static/img/gifs/clap.gif differ diff --git a/static/img/gifs/proud.gif b/static/img/gifs/proud.gif new file mode 100644 index 0000000..6a2c47c Binary files /dev/null and b/static/img/gifs/proud.gif differ diff --git a/static/img/gifs/star-trek-not-so-bad.gif b/static/img/gifs/star-trek-not-so-bad.gif new file mode 100644 index 0000000..465801d Binary files /dev/null and b/static/img/gifs/star-trek-not-so-bad.gif differ diff --git a/static/img/gifs/thats-a-big-one.gif b/static/img/gifs/thats-a-big-one.gif new file mode 100644 index 0000000..1addd16 Binary files /dev/null and b/static/img/gifs/thats-a-big-one.gif differ diff --git a/static/img/gifs/this-is-fine.gif b/static/img/gifs/this-is-fine.gif new file mode 100644 index 0000000..09af4fa Binary files /dev/null and b/static/img/gifs/this-is-fine.gif differ diff --git a/static/img/gifs/you-shall-not-pass.gif b/static/img/gifs/you-shall-not-pass.gif new file mode 100644 index 0000000..37b7930 Binary files /dev/null and b/static/img/gifs/you-shall-not-pass.gif differ