added a new post and modified post archetype
This commit is contained in:
+1
-2
@@ -14,7 +14,6 @@ cover:
|
||||
alt: "<alt text>" # alt text
|
||||
caption: "<text>" # display caption under cover
|
||||
relative: false # when using page bundles set this to true
|
||||
searchHidden: false
|
||||
showtoc: true
|
||||
searchHidden: true
|
||||
searchHidden: false
|
||||
---
|
||||
|
||||
@@ -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: "<image path/url>"
|
||||
alt: "ssh-alt image" # alt text
|
||||
caption: "<text>" # 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**
|
||||

|
||||
> **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 😊
|
||||
|
||||

|
||||
|
||||
**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
|
||||
```
|
||||

|
||||
|
||||
**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**
|
||||
|
||||

|
||||
|
||||
# **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 <ip addresses to be ignored>
|
||||
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 ...
|
||||

|
||||
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.
|
||||
|
||||

|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.1 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.6 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 13 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.9 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.9 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.1 MiB |
Reference in New Issue
Block a user