Gibdos Talks FOSS

All Things SSH

In this blog post, I will go over all the useful features of SSH, how to set it up, secure it and use it to access your server and transfer files and folder to and from your server.

What is SSH?

SSH stands for Secure Shell. It's a protocoll that allows access to a remote machine through an encrypted tunnel.

What can I do with SSH?

How can I use it?

OpenSSH comes preinstalled in any modern operating system. Just open a Terminal window and type ssh USERNAME@SERVER, where USERNAME is the user on your server.

SERVER can be the IP address (XXX.XXX.XXX.XXX) or the webaddress (example.com). By default, SSH will use port 22 and the ~/.ssh/id_rsa keyfile. If it doesn't find a keyfile, it will ask you for your USERNAME password.

Once you've entered your USERNAME password, you will be presented with your servers Terminal.

The SSH Keyfiles

The SSH keyfile is an additional security measure. It acts as a key, to unlock your server. The keyfile comes in a pair of private and public keyfiles.

To create a keyfile pair, open a terminal on your local computer and type ssh-keygen -f ~/.ssh/KEYFILE (if you don't specify a file with -f, it will default to ~/.ssh/id_rsa). It will ask if you want to use a password to secure the key. It's important, that any keyfile you create has a long and complicated password. Use a password generator to generate a password it. It should be

It's important, that you keep your private keyfile private. If it's not password protected, anyone with your keyfile has access to your server and can easily compromise it.

To add the new keyfile to your server, open the ~/.ssh/KEYFILE.pub and copy the content of the file. Then SSH into it and use the following commands

# Create the .ssh folder (if it doesn't exist)
mkdir ~/.ssh

# Open / Edit the authorized_keys file
nano ~/.ssh/authorized_keys

# Copy your public key into it with CTRL + SHIFT + V (Example)
ssh-ed25519 ASkdlJSAJDSAJDIOWIOFANFOSAIFIOAWOPAIFJOWA user@hostname

# Save the file with CTRL + O

# Close the editor with CTRL + X -> ENTER

Now you can connect to the server with ssh -i ~/.ssh/KEYFILE.pub USERNAME@SERVER.

SSH Agent

An SSH Agent can be used to store your keyfile passwords. To add a keyfile to your SSH agent, run the ssd-add ~/.ssh/KEYFILE command.

If you use BitWarden as your password manager, you can also store your SSH keys in it and use it as your SSH agent. Check the offical BitWarden documentation, if you are interested.

The SSH Config File

SSH can also use the ~/.ssh/config file, to set up different settings for different servers.

In this file, you can

An example config can look like this

Host *
 IdentitiesOnly=yes

 Host NICKNAME
  Hostname XXX.XXX.XXX.XXX
  User USERNAME
  Port 22
  IdentityFile ~/.ssh/KEYFILE

 Host ANOTHER_NICK
  Hostname YYY.YYY.YYY.YYY
  User ANOTHERUSER
  Port 2222
  IdentityFile ~/.ssh/ANOTHER_KEYFILE

Let's go through each entry in detail.

Host *
Applies IdentitiesOnly to all Host entries

IdentitiesOnly
Only tries the specified keyfiles in each host

Host NICKNAME
Enables the use of ssh NICKNAME to connect to the server

Hostname
The IP or webaddress of your server

User
The username on your server

Port
The port used to connect to SSH (default 22)

IdentityFile
The keyfile used to authenticate. Can also use KEYFILE.pub

When SSH finds a ~/.ssh/config file, it will check the entries and apply the correct settings accordingly.

SCP, rsync and many other programs, which rely on SSH, will also use the ~/.ssh/config file. This makes it possible to shorten commands and making sure the correct user, ports and keyfiles are used.

Securing SSH

Because SSH is used by almost every server on the internet, it is always under attack by bots and bad actors. And while it is by nature a secure system, there are different ways to make it even more secure.

sshd_config

The /etc/ssh/sshd_config file on your server contains the settings for the SSH service that is running on the server.

Once you can connect with your keyfile, it's best to disable the password login on your server and make the keyfile mandatory to connect.

To do that, connect to your server and use the following commands

# Open the config file with nano
sudo nano /etc/ssh/sshd_config

# Scroll down to #PasswordAuthentication yes and change it to
PasswordAuthentication no

# Save the file with CTRL + O

# Close the editor with CTRL + X -> ENTER

To make sure, that you don't lock yourself out, open a second Terminal window and SSH into your server. Then you can restart the SSH service with sudo systemctl restart ssh.

Disconnect one of your SSH sessions with CTRL + D and try to SSH into the server again. If something went wrong, just use the still connected Terminal to undo the changes and restart the SSH service again.

Fail2Ban

Fail2Ban is a service that checks your /var/log/auth.log log file and (temporarily) bans bots & bad actors that unsuccessfully try to SSH into your server.

To install it, SSH into your server and use the following commands

# Install fail2ban
sudo apt install fail2ban

# Enable the fail2ban service
sudo systemctl enable fail2ban

# Start the fail2ban service
sudo systemctl start fail2ban

By default, it will ban anyone for 10 minutes that failed to login 5 times in the last 10 minutes. To change these defaults, use the following commands

# Copy the default config file
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

# Open the new copy in nano
sudo nano /etc/fail2ban/jail.local

# Change the defaults inside [DEFAULT]
bantime  = 10m # Banned for x minutes
findtime  = 10m # Failed login in x minutes
maxretry = 5 # Allowed fails before ban

# Save your changes with CTRL + O

# Close the editor with CTRL + X -> ENTER

# Restart the fail2ban service
sudo systemctl restart fail2ban

# Check all currently banned IPs
sudo fail2ban-client status sshd

Keep in mind, that it will also ban you, if you fail too many times. So it's best to keep the bantime sensible.

Transfering Files

There are many programs that use SSH to transfer files to and from a server. The most commonly used are SCP and rsync.

SCP - Secure Copy

SCP copies files and folders to and from your server. It's basically the same as cp on your local machine. Here are a few examples on how to use it

# Copy a single file from local to server
scp ~/Downloads/file SERVER:~/Downloads/

# Copy a folder with content to your server
scp -r ~/Downloads/FOLDER SERVER:~/Downloads/

# Copy a single file from server to local
scp SERVER:~/Downloads/file ~/Downloads/

# Copy a folder with content from your server
scp -r SERVER:~/Downloads/FOLDER ~/Downloads/

# In case of problems, use the -v argument
scp -v ...

rsync - Diff-Based File Transfer

While SCP will always copy everything, even if an exact copy already exists at the destination, rsync will check for existing files and compare them before copying. This speeds up file transfers significantly and makes it extremely useful for t.ex. regular backups.

The rsync command can be very confusing, and dangerous. So it is important, to always do a --dry-run beforehand. With a dry-run, rsync will simulate the transfer and you can easily spot if it actually does what you want.

The most basic command for rsync is

# Copy the content of SRC (local) to DEST (server)
rsync -r /PATH/TO/SRC/ SERVER:/PATH/TO/DEST/

# Copy the content of SRC (server) to DEST (local)
rsync -r SERVER:/PATH/TO/SRC/ /PATH/TO/DEST/

But rsync also offers a ton of additional options. The most common ones are

--archive (-a)
Uses -r (recursive) and preserves permissions (-p), owner (-o), group (-g) and times (-t)

--update (-u)
Skips files in DEST that are newer then SRC

--dry-run (-n)
Simulates the transfer

--delete-before / --delete-during / --delete-after
Deletes files in DEST that don't exist in SRC before, during or after the transfer.

--delete-excluded
Deletes all files from DEST that are defined by --excluded=""

--compress (-z)
Uses compression algorithms to speed up file transfer at the cost of CPU usage

--partial
Keeps partially transfered files if transfer gets interrupted. Can be used to resume a transfer.

--exclude=PATTERN
Excludes files from transfer that fit PATTERN (t.ex. .git, .DS_Store, etc.)

--stats
Shows helpfull statistics after the transfer

--itemize-changes (-i)
Gives useful information for each file

--human-readable (-h)
Makes numbers more readable (KB, MB, GB, etc.).

Backup Commands

An example with these options can be used to backup files and folders from your server to your local harddisk (or, when SSHed into your server, from your server to another server to which you have SSH access).

rsync -azhni --exclude={'file1.txt','dir1/*','dir2'} --partial --stats --delete-before --delete-excluded /PATH/TO/SRC/ SERVER:/PATH/TO/DEST/

or to backup a local folder to an external harddrive

rsync -azhni --exclude={'file1.txt','dir1/*','dir2'} --partial --stats --delete-before --delete-excluded /PATH/TO/SRC/ /PATH/TO/EXTERNAL/HDD/

Rsync can be an incredibly powerful tool, but, as mentioned before, always use the -n (--dry-run) option first, to prevent a disaster.

SSHFS Mount

SSHFS is a fuse-based filesystem driver. It enables you to mount a server folder to a local folder on your computer.

While it's convenient for quick and easy file access, I do not recommend using it for larger file transfers, since it is not as reliable and stable as SCP or rsync.

To use it, open a local Terminal and follow these commands

# Install SSHFS and fuse3 on Linux (Debian based)
sudo apt install sshfs fuse3

# Install SSHFS and fuse3 on Linux (RHEL based)
sudo dnf install sshfs fuse-sshfs

# Install SSHFS on Linux (Arch)
sudo pacman -S sshfs

# Install SSHFS on MacOS
brew install --cask macfuse
brew install gromgull/fuse/sshfs-mac

# Install SSHFS on Windows (not recommended)
## Download and install WinFsp (https://github.com/winfsp/winfsp/releases)
## Download and install SSHFS-Win (https://github.com/winfsp/sshfs-win/releases)

# Verify installation
sshfs --version

# Add your user to fuse group (Linux)
sudo groupadd fuse
sudo usermod -a -G fuse $USER

# Logout & Login to update your group membership

# Create a folder for mounting
mkdir /PATH/TO/LOCAL/FOLDER

# Mount your server folder to the created folder
sshfs -o compression=yes,cache=yes,auto_cache,reconnect,ServerAliveInterval=15,ServerAliveCountMax=3,default_permissions,idmap=user,uid=1000,gid=1000,umask=0022,IdentityFile=~/.ssh/KEYFILE SERVER:/PATH/TO/FOLDER/ /PATH/TO/LOCAL/FOLDER

# Unmount SSHFS folder with
umount /PATH/TO/LOCAL/FOLDER