ssh
is the premier in simple remote server access.
Most VPS providers rent out machines that run an sshd
daemon by default.
OpenSSH provides a variety of command-line clients that can be used to access remote machines running sshd.
ssh
- Opens a secure remote shellscp
- copy files to/from machinessftp
- SSH-based FTP client
Examples
Generate SSH Keys
ssh-keygen
Connect to a Remote Machine
ssh joe@example.com
ssh joe@192.168.1.23
Transfer files to/from a Remote Machine
scp abc.txt joe@example.com:~/data
scp joe@example.com:~/data/abc.txt ./
sftp joe@example.com
Authorize a Public Key
cat id_rsa_bob.pub >> /home/bob/.ssh/authorized_keys
Edit Known Hosts
vim ~/.ssh/known_hosts
Server Configuration
vim /etc/ssh/sshd_config
systemctl restart sshd
Installation
pacman -S openssh
- Arch Linuxapt install openssh
- Debian
SSH Key Identities id_rsa
The easiest way to identify yourself to a remote machine is using SSH Keys. These keys are files that act similar to a password.
You can generate SSH Keys using OpenSSH by running
ssh-keygen
By default, this will generate the following key files:
~/.ssh/id_rsa
- the identity key file (or private key file)~/.ssh/id_rsa.pub
- the public key file
You should not share the id_rsa
file with other machines.
However, you can share the id_rsa.pub
file to grant authorization to your
local machine’s identity.
Example id_rsa
identity key file:
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
...
Oumu/bjxfF3A+ZAAAAD21pY2hhZWxAbWVyY3VyeQECAw==
-----END OPENSSH PRIVATE KEY-----
Example id_rsa.pub
public key file:
ssh-rsa AAAAB3NzaC1y...dDpENYwn52XUggnKUfLzB1KjydEKU= michael@mercury
Public Key File Breakdown:
ssh-rsa
indicates that this is an RSA key.AAAA...EKU=
is the encoded public keymichael@mercury
is a tag to make it easier to identify computers in anauthorized_keys
file
By default, the ssh
client will use your ~/.ssh/id_rsa
identity file when
connecting to a remote machine. As long as the remote user has your
~/.ssh/id_rsa.pub
public key in its ~/.ssh/authorized_keys
, you will be
able to log in!
For more information about public/private keys, see Public Key Cryptography, RSA, and ECDSA.
Authorizing Identities authorized_keys
Authorizing an identity is done by adding a public key file’s contents to a
remote user’s ~/.ssh/authorized_keys
.
Example authorized_keys
file:
worker@nas:~$ cat .ssh/authorized_keys
ssh-rsa AAAAB3NzaC1y...cZKlFkZyXdu7yAjSmk= michael@styx
ssh-rsa AAAAB3NzaC1y...w5qm+gckxVXtAZLaqk= michael@mercury
ssh-rsa AAAAB3NzaC1y...6J7HdU/XjhHWE1ZM+c= michael@mars
If the file/directory does not exist yet, you can create them manually with
mkdir
/touch
This authorized_keys
file allows me to connect to the worker user on my nas
using any of the identities on any of my personal computrs. (named styx
,
mercury
, and mars
)
Once your public key file is in the user’s authorized_keys
, you will be able to
connect to the remote machine without a password! (unless you encrypted your identity
file).
If your public key file is not in the user’s authorized_keys
, ssh
will
instead prompt you for the remote user’s password. Password-based authentication
can be useful when you are connecting for the first time.
Connecting to a Remote Machine
Connnect using this command
ssh user@hostname
user
is the linux user that you would like to connect ashostname
is the ip or domain name of the machine to connect to
If your public key file is not in the remote user’s authorized_keys
, ssh will prompt
for the remote user’s password to continue logging in.
Authenticity
The first time you connect to a machine, you will probably get a message similar to this one:
$ ssh joe@example.com
The authenticity of host 'example.com (2004:28fa:6:67a1:94a1:3ac:d2f7:b8e2)' can't be established.
ED25519 key fingerprint is SHA256:V1kuxz/Brxrg1Ga4aIhI1Ekmf6o/Bk+4dGDz2dxT8c0.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])?
Typically, you can get away with answering yes
to this prompt to continue connecting.
The purpose of this authenticity check is to ensure that you are connecting to the machine you expect. This can help prevent man-in-the-middle attacks. If you’re looking to be safe, you can acquire and type/paste in the server’s fingerprint to this prompt. The CLI will verify that it is equal to the fingerprint of the server it is attempting to connect to.
To get the fingerprint on a server:
ssh-keygen -lf /etc/ssh/ssh_host_rsa_key.pub
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
MITM Detection
If ssh
detects that the identity of a host has changed, you get a message similar to the following:
$ ssh joe@example.com
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ED25519 key sent by the remote host is
SHA256:V1kuxy/Gadwf2IH2wFNd29uio23/Yf+23BfawIfjIow.
Please contact your system administrator.
Add correct host key in /home/joe/.ssh/known_hosts to get rid of this message.
Offending ED25519 key in /home/joe/.ssh/known_hosts:5
Host key for example.com has changed and you have requested strict checking.
Host key verification failed.
This message indicates that the identity file of the server changed from the last time you connected to it (which could be a sign of a MITM attack).
This also happens when you deploy a new machine to an existing hostname/ip address.
If you’re sure it’s not a MITM attack, adding the correct key / deleting
the existing key in your ~/.ssh/known_hosts
file will allow you to connect
to the server again. The message notes the line number in known_hosts
after
the :
character. You should notice that the specified line it is marked with
your target hostname in the known_hosts
file too.
Transferring Files
Once you have a working SSH connection, you can use sftp
and scp
to transfer files
to/from a remote machine.
SCP
scp
allows you to copy files to/from a remote machine similarly to how cp
works on
a local machine. To specify a remote file/directory, enter the remote
user
/hostname
/path
in the following format: user@hostname:path
.
Conveniently, you can use ~
inthe server path to specify the remote user’s home
directory.
scp abc.txt joe@example.com:~/data
scp joe@example.com:~/data/abc.txt ./
SFTP
sftp
is an ftp client. It allows you to traverse directories and get
/put
files
on/onto the server.
joe@local ~/src/example $ sftp joe@example.com
> pwd
Remote working directory: /home/joe
> lpwd
Local working directory: /home/joe/src/example
>
> ls
remote_dir remote_file_a.txt
>
> lls
local_file_a.txt local_file_b.txt
>
> put local_file_a.txt
uploaded local_file_a.txt
>
> get remote_file_a.txt
downloaded remote_file_a.txt
>
> cd remote_dir
> put local_file_b.txt
uploaded local_file_b.txt
Hardening
There are tons of internet scanners looking for vulnerable machines 24/7. Doing some hardening can make your server more difficult to scan and attack.
Hardening - Disable Password Authentication
Once your server is set up with SSH Key Identities, you may want to consider disabling password logins entirely. This effectively makes password-based brute force attacks impossible.
However, you will no longer be able to log in without an authorized SSH Key.
To disable password authentication, uncomment and change the following line
in /etc/ssh/sshd_config
on the server
# To disable tunneled clear text passwords, change to no here!
PasswordAuthentication no
Make sure to restart sshd
to apply your configuration
systemctl restart sshd
Hardening - Fail2ban
Fail2ban updates firewall rules to block the IPs of clients with repeated login failures or performing other suspicious activity. It detects these clients using log files.
By default, fail2ban
updates rules in iptables
.
Install
sudo apt install iptables fail2ban
Configure
Create /etc/fail2ban/jail.local
[DEFAULT]
maxretry = 5
findtime = 1d
bantime = 1w
ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24
[sshd]
enabled = true
mode = aggressive
maxretry
- the number of failed attempts required before banning a clientfindtime
- the maximum duration between attempts that count for maxretrybantime
- the duration to ban clientsignoreip
- IP ranges to ignore. This example includes loopback and the local network- You likely also want to include your personal IP address to prevent an attacker who knows your IP from spoofing it, getting your IP banned
Restart fail2ban
to apply your configuration
systemctl restart fail2ban
See Also
man fail2ban
man jail.conf
- https://wiki.archlinux.org/title/Fail2ban
- https://wiki.archlinux.org/title/Iptables
More Reading on SSH
man ssh
man ssl
- https://wiki.archlinux.org/title/OpenSSH