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?
- Access the terminal in your remote VPS
- Transfer files through
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
- At least 20 characters long
- Contain a mix of
- upper- & lowercase characters
- numbers
- symbols
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
- Setup Nicknames for each server
- Specify the port
- Specify the username
- Specify the keyfile
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
- ← Previous
A Beginners Guide To Selfhosting Part 6