ssh client and server
(Written by Paul Cobbaut, https://github.com/paulcobbaut/, with contributions by: Alex M. Schapelle, https://github.com/zero-pytagoras/, Bert Van Vreckem https://github.com/bertvv)
The secure shell or ssh
is a collection of tools using a secure protocol for communications with remote Linux computers.
This chapter gives an overview of the most common commands related to the use of the sshd
server and the ssh
client.
about ssh
Secure SHell (ssh) is the common way to securely connect to a remote system, e.g. a server in a datacenter, and open a terminal to execute commands. It is considered an essential tool for managing Linux systems, so it is included by default even on minimal installations of most distributions. Server-installations of Linux have the openssh-server
package installed and enabled.
Even some popular services, like Github, also use SSH for communication. Synchronizing code between a local source code repository and a remote repository on github.com is only allowed over SSH.
secure shell in general
The SSH protocol is secure in two ways. Firstly the connection is authenticated both ways, and secondly the connection is encrypted.
An SSH connection always starts with a cryptographic handshake. The authentication takes place (using user id/password or public/private keys) and communication can begin over the encrypted connection. When both sides are accepted as trustworthy parties, it is followed by encryption of the transport layer using a symmetric cypher. The latter is exchanged between the two parties directly after authenticating. In other words, the tunnel is already encrypted before you start typing anything.
The SSH protocol will remember the servers it handshaked with, and warn you in case something suspicious happened, e.g. when the signature or fingerprint of the server changed. This is a 'mitm'-attack prevention.
The openssh
package is maintained by the OpenBSD people and is distributed with a lot of operating systems, including Linux.
Older protocols like telnet
, rlogin
and rsh
can also be used to remotely connect to your servers. However, these protocols do not encrypt the login session, which means confidential information about the server, including your user id and password, can be sniffed by tools like wireshark
or tcpdump
. Consequently, they are no longer installed by default on most Linux distributions and you should never use them in a production environment.
To securely connect to your servers, use ssh
.
public and private keys
The ssh
protocol uses the well known system of public and private keys. The below explanation is succinct, more information about public key cryptography can be found on wikipedia.
Imagine Alice and Bob, two people that like to communicate with each other. Using public and private keys they can communicate with confidentiality and with authentication.
Alice and Bob both need to generate a key pair, each consisting of two cryptographic keys. A key pair has as property that a message that is encrypted with one key can only be decrypted with the other key. This concept is also called asymmetric encryption. One key is kept private and the other is made public.
When Alice wants to send an encrypted message to Bob, she uses the public key of Bob. Since Bob should be the only person to have his private key, Alice is certain that Bob is the only person that can read the encrypted message.
A digital signature is based on the same principle. Alice signs a message with her private key, which usually means that a hash of the message (i.e. a unique number that represents the message) is encrypted with her private key. When Bob wants to verify that the message came from Alice, Bob uses the public key of Alice to decrypt the signature. If the decrypted hash matches the hash of the received message, Bob can be certain the message came from Alice and was not altered during transfer.
public-key cryptosystems
This chapter does not explain the technical implementation of cryptographic algorithms, it only explains how to use the ssh tools some common key exchange types. More information about these algorithms can be found here:
- https://en.wikipedia.org/wiki/RSA_(cryptosystem)
- https://en.wikipedia.org/wiki/Digital_Signature_Algorithm
- https://en.wikipedia.org/wiki/EdDSA
- https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm
ssh remote login: autentication fingerprint
The following screenshot shows how to use ssh
to log on to a remote computer running Linux. The local user is named paul
and he is logging on as user admin42
on the remote system.
paul@linux:~$ ssh admin42@192.168.1.30
The authenticity of host '192.168.1.30 (192.168.1.30)' can't be established.
RSA key fingerprint is b5:fb:3c:53:50:b4:ab:81:f3:cd:2e:bb:ba:44:d3:75.
Are you sure you want to continue connecting (yes/no)?
As you can see, the user paul
is presented with an rsa
authentication fingerprint from the remote system. The user can accepts this by typing yes
. We will see later that an entry will be added to the ~/.ssh/known_hosts
file.
paul@linux:~$ ssh admin42@192.168.1.30
The authenticity of host '192.168.1.30 (192.168.1.30)' can't be established.
RSA key fingerprint is b5:fb:3c:53:50:b4:ab:81:f3:cd:2e:bb:ba:44:d3:75.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.1.30' (RSA) to the list of known hosts.
admin42@192.168.1.30's password:
Welcome to Ubuntu 12.04 LTS (GNU/Linux 3.2.0-26-generic-pae i686)
* Documentation: https://help.ubuntu.com/
1 package can be updated.
0 updates are security updates.
Last login: Wed Jun 6 19:25:57 2024 from 172.28.0.131
admin42@ubuserver:~$
The user can get log out of the remote server by typing exit
or by using Ctrl-d
.
The fingerprint guarantees server-side authentication.
If the user would connect a second time to this server, the authentication question will no longer be asked (as the fingerprint is retained in the known_hosts
file).
If for any reason the fingerprint of the server does not match the one in the known_hosts
file, the user will be warned and the connection will be refused.
paul@linux:~$ ssh admin42@192.168.1.30
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ 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 RSA key sent by the remote host is
6e:45:f9:a8:af:38:3d:a1:a5:c7:76:1d:02:f8:77:00.
Please contact your system administrator.
Add correct host key in /home/paul/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /home/paul/.ssh/known_hosts:14
Host key for 192.168.1.30 has changed and you have requested strict checking.
Host key verification failed.
ssh beyond remote login
Next to 'simply' allowing to log in on a remote node, ssh
also allows for remote exection of commands, and transferring files.
executing a command in remote
This screenshot shows how to execute the pwd
command on the remote server. There is no need to exit
the server manually.
paul@linux:~$ ssh admin42@192.168.1.30 pwd
admin42@192.168.1.30's password:
/home/admin42
paul@linux:~$
scp
The scp
command works just like cp
, but allows the source and
destination of the copy to be behind ssh
. Here is an example where we
copy the /etc/hosts
file from the remote server to the home directory
of user paul.
pau;@linux:~$ scp admin42@192.168.1.30:/etc/hosts /home/paul/serverhosts
admin42@192.168.1.30's password:
hosts 100% 809 0.8KB/s 00:00
Here is an example of the reverse, copying a local file to a remote server.
student@linux:~$ scp ~/serverhosts admin42@192.168.1.30:/etc/hosts.new
admin42@192.168.1.30's password:
serverhosts 100% 809 0.8KB/s 00:00
Remark that the scp
command used to be based on the SCP protocol. However, this protocol is now considered to be insecure. Fortunately, this does not mean that you can't use the scp
command anymore, since it nowadays uses the actually secure SFTP protocol (Secure File Transfer Protocol) to copy files between hosts.
setting up passwordless ssh
Above, the server-side authentication based on a fingerprint was explained. Client-side authentication is by default based on a user/password combination. However: we could use a pub/priv keypair to take care of this authentication - avoiding to type your password every time you want to log in.
To set up passwordless ssh (client-side) authentication through public/private keys, use ssh-keygen
to generate a key pair without a passphrase, and then copy your public key to the destination server.
Let's do this step by step. In the example that follows, we will set up ssh without password between Alice and Bob. Alice is using Ubuntu on her laptoph, and has as an account on an Enterprise Linux server named Bob. Server Bob wants to give Alice access using ssh and the public and private key system. This means that even if the password of Alice is changed on this server Bob, Alice will still have access.
generate with ssh-keygen
The example below shows how Alice uses ssh-keygen
to generate an RSA key pair. Alice does not enter a passphrase1.
[alice@linux ~]$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/alice/.ssh/id_rsa):
Created directory '/home/alice/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/alice/.ssh/id_rsa.
Your public key has been saved in /home/alice/.ssh/id_rsa.pub.
The key fingerprint is:
9b:ac:ac:56:c2:98:e5:d9:18:c4:2a:51:72:bb:45:eb alice@linux
[alice@linux ~]$
With the -t
option, you can specify the type of key to create. The default is rsa-sha2-512
(i.e. RSA-key with SHA-2 as hash algorithm).
Safe key types include:
rsa
(default)ecdsa
(Elliptic Curve Digital Signature Algorithm)ed25519
(Edwards-curve Digital Signature Algorithm)
Key types to avoid include:
dsa
(Digital Signature Algorithm) is considered weak and should not be used. In SSH, this keytype is calledssh-dss
and has been deprecated as of August 2015 - see https://www.openssh.com/txt/release-7.0 .ssh-rsa
uses the SHA-1 hash algorithm, which is considered weak. The latter has been deprecated as af August 2021 - see https://www.openssh.com/txt/release-8.7 .
It an older server is still using these keys, you should consider updating the keypairs. A workaround, e.g. to use the deprecated key one more time be able to log in to work on the updates, could be found on https://www.openssh.com/legacy.html . This is further elaborated in the 'Troubleshooting' section below.
id_rsa and id_rsa.pub
The ssh-keygen
command generate two keys in a hidden folder .ssh
. The public key is named ~/.ssh/id_rsa.pub
. The private key is named ~/.ssh/id_rsa
.
[alice@linux ~]$ ls -l .ssh/id*
total 16
-rw------- 1 alice alice 1671 May 1 07:38 id_rsa
-rw-r--r-- 1 alice alice 393 May 1 07:38 id_rsa.pub
The files will be named id_ecdsa
and id_ecdsa.pub
when using ecdsa
instead of rsa
.
~/.ssh
In general, the .ssh
directory is used to store the user's ssh
related files.
If it doesn't exist, the hidden .ssh
directory will be created automatically when generating the keypair.
If you create the .ssh
directory manually, then you need to chmod 700 it! Otherwise ssh will refuse to use the keys (world readable private keys are not secure!).
As you can see, the .ssh
directory is secure in Alice's home directory on her laptop.
Server Bob decides to manually create the .ssh
directory, so he needs to manually secure it.
bob@linux:~$ mkdir .ssh
bob@linux:~$ ls -ld .ssh
drwxr-xr-x 2 bob bob 4096 2024-05-14 16:53 .ssh
bob@linux:~$ chmod 700 .ssh/
Next to storing the keypair(s) generated by a user, it can also contain other files. Most notably is the file known_hosts
, containing an entry for each fingerprint that has been accepted before when connecting to a new server.
.ssh/authorized_keys
In your ~/.ssh
directory, you can create a file called authorized_keys
. This file can contain one or more public keys from people you trust. Those trusted people can use their private keys to prove their identity and gain access to your account via ssh (without password). The example shows Bob's authorized_keys file containing the public key of Alice.
bob@linux:~$ cat .ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEApCQ9xzyLzJes1sR+hPyqW2vyzt1D4zTLqk\
MDWBR4mMFuUZD/O583I3Lg/Q+JIq0RSksNzaL/BNLDou1jMpBe2Dmf/u22u4KmqlJBfDhe\
yTmGSBzeNYCYRSMq78CT9l9a+y6x/shucwhaILsy8A2XfJ9VCggkVtu7XlWFDL2cum08/0\
mRFwVrfc/uPsAn5XkkTscl4g21mQbnp9wJC40pGSJXXMuFOk8MgCb5ieSnpKFniAKM+tEo\
/vjDGSi3F/bxu691jscrU0VUdIoOSo98HUfEf7jKBRikxGAC7I4HLa+/zX73OIvRFAb2hv\
tUhn6RHrBtUJUjbSGiYeFTLDfcTQ== alice@linux
copy the public key to the other computer
But wait a minute? How did this key get onto server Bob?
To copy the public key from Alice's laptop tot server Bob, Alice decided to use scp
.
[alice@linux .ssh]$ scp id_rsa.pub bob@192.168.48.92:~/.ssh/authorized_keys
bob@192.168.48.92's password:
id_rsa.pub 100% 393 0.4KB/s 00:00
Be careful when copying a second key! Do not overwrite the first key, instead append the key to the same ~/.ssh/authorized_keys
file!
Alice could also have used ssh-copy-id
like in this example.
passwordless ssh
Alice can now use ssh to connect passwordless to server Bob. In combination with ssh
's capability to execute commands on the remote host, this can be useful in pipes across different machines.
[alice@linux ~]$ ssh bob@192.168.48.92 "ls -l .ssh"
total 4
-rw-r--r-- 1 bob bob 393 2024-05-14 17:03 authorized_keys
[alice@linux ~]$
ssh-agent
When generating keys with ssh-keygen
, you have the option to enter a passphrase to protect access to the keys by encrypting them with a symmetric cipher. To avoid having to type this passphrase every time, you can add the key to ssh-agent
using ssh-add
.
Most Linux distributions will start the ssh-agent
automatically when you log on.
If the ssh-agent
is not running, you can start it with eval $(ssh-agent)
.
student@debian:~$ ps -ef | grep ssh-agent
student 1608 1393 0 14:52 pts/0 00:00:00 grep ssh-agent
student@debian:~$ eval $(ssh-agent)
Agent pid 1610
student@debian:~$ ps -ef | grep ssh-agent
student 1610 1 0 14:52 ? 00:00:00 ssh-agent
student 1612 1393 0 14:52 pts/0 00:00:00 grep ssh-agent
This screenshot shows how to use ssh-add
with option -L
to list the keys that are currently added to the ssh-agent
, and to add a key (without arguments):
student@debian:~$ ssh-add -L
The agent has no identities.
student@debian:~$ ssh-add
Identity added: /home/student/.ssh/id_rsa (student@debian)
student@debian:~$ ssh-add -L
ssh-rsa AAAAB3NzaC1yc2EAAAAD......MeoDHPqR5/yUsCO6MzVOCaZpf8Toc= student@debian
All keys can be removed from the ssh-agent
with ssh-add -D
.
X forwarding via ssh
Another popular feature of ssh
is called X11 forwarding. X11 is the foundation of graphical user interfaces on Linux and Unix systems, so X11 forwarding allows you to run graphical applications on a remote computer and have them displayed on your local computer. On the server side, the X11Forwarding
option must be set to yes
in the /etc/ssh/sshd_config
file. On the client side, add option -X
to the ssh
command.
Below an example of X forwarding between a Kali Linux VM (client) and a Linux Mint VM (server), both with a graphical desktop. The default user kali
is logged in and verifies that the app drawing
is not installed. Next, they log in to the Linux Mint VM as user student
and start drawing
. The application will run on the remote computer from mint
, but will be displayed within the Kali VM, as shown in the screenshot.
configuration in /etc/ssh/
Configuration of SSH client and server is done in the /etc/ssh
directory. In the next sections we will discuss most of the files found in /etc/ssh/
.
sshd
The ssh server is provided by the openssh-server
package.
root@linux~# dpkg -l openssh-server | tail -1
ii openssh-server 1:5.9p1-5ubuntu1 secure shell (SSH) server,...
On Debian based distributions, the service is called ssh
. On Enterprise Linux based distributions, the service is called sshd
.
Example on EL:
[student@el ~]$ systemctl status sshd
● sshd.service - OpenSSH server daemon
Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; preset: enabled)
Active: active (running) since Mon 2024-11-11 10:03:58 UTC; 3h 24min ago
Docs: man:sshd(8)
man:sshd_config(5)
Main PID: 668 (sshd)
Tasks: 1 (limit: 11128)
Memory: 6.5M
CPU: 208ms
CGroup: /system.slice/sshd.service
└─668 "sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups"
On Debian:
vagrant@debian:~$ systemctl status ssh
● ssh.service - OpenBSD Secure Shell server
Loaded: loaded (/lib/systemd/system/ssh.service; enabled; preset: enabled)
Active: active (running) since Mon 2024-11-11 10:04:31 UTC; 3h 22min ago
Docs: man:sshd(8)
man:sshd_config(5)
Process: 577 ExecStartPre=/usr/sbin/sshd -t (code=exited, status=0/SUCCESS)
Main PID: 611 (sshd)
Tasks: 1 (limit: 2304)
Memory: 7.6M
CPU: 121ms
CGroup: /system.slice/ssh.service
└─611 "sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups"
The standard port for ssh is 22. You can change this in the /etc/ssh/sshd_config
file.
[vagrant@el ~]$ sudo ss -tlnp
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 0.0.0.0:111 0.0.0.0:* users:(("rpcbind",pid=539,fd=4),("systemd",pid=1,fd=31))
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=668,fd=3))
LISTEN 0 4096 [::]:111 [::]:* users:(("rpcbind",pid=539,fd=6),("systemd",pid=1,fd=34))
LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=668,fd=4))
sshd keys
The public keys used by the sshd server for fingerprints are located in /etc/ssh
and are world readable. The private keys are only readable by root.
root@linux~# ls -l /etc/ssh/ssh_host_*
-rw------- 1 root root 668 Jun 7 2024 /etc/ssh/ssh_host_ecdsa_key
-rw-r--r-- 1 root root 598 Jun 7 2024 /etc/ssh/ssh_host_ecdsa_key.pub
-rw------- 1 root root 1679 Jun 7 2024 /etc/ssh/ssh_host_rsa_key
-rw-r--r-- 1 root root 390 Jun 7 2024 /etc/ssh/ssh_host_rsa_key.pub
troubleshooting ssh
Troubleshooting SSH can be a hard issue: as security standards have evolved through time, and even the SSH protocol has evolved from version 1 to 2, you might encounter compatibility issues between an SSH client and server.
Use ssh -v
to get debug information about the ssh connection attempt.
student@linux:~$ ssh -v paul@192.168.1.192
OpenSSH_4.3p2 Debian-8ubuntu1, OpenSSL 0.9.8c 05 Sep 2006
debug1: Reading configuration data /home/paul/.ssh/config
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: Applying options for *
debug1: Connecting to 192.168.1.192 [192.168.1.192] port 22.
debug1: Connection established.
debug1: identity file /home/paul/.ssh/identity type -1
debug1: identity file /home/paul/.ssh/id_rsa type 1
debug1: identity file /home/paul/.ssh/id_dsa type -1
debug1: Remote protocol version 1.99, remote software version OpenSSH_3
debug1: match: OpenSSH_3.9p1 pat OpenSSH_3.*
debug1: Enabling compatibility mode for protocol 2.0
...
ssh protocol versions
The ssh
protocol has two versions, 1 and 2, that are incompatible. Version 1 is considered insecure since it contains some known vulnerabilities. If you encounter an installation that still uses protocol version version 1, you should endeavour to update it as soon as possible. In current installations, version 1 should no longer be supported. It was removed in 2017 with the release of OpenSSH 7.6.
Check the version of OpenSSH installed with ssh -V
or with your package manager. For example, on Enterprise Linux:
[student@el ssh]$ ssh -V
OpenSSH_8.7p1, OpenSSL 3.0.7 1 Nov 2022
[student@el ssh]$ dnf list installed openssh*
Installed Packages
openssh.x86_64 8.7p1-38.el9_4.4 @baseos
openssh-clients.x86_64 8.7p1-38.el9_4.4 @baseos
openssh-server.x86_64 8.7p1-38.el9_4.4 @baseos
and on Debian:
student@debian:~$ ssh -V
OpenSSH_9.2p1 Debian-2+deb12u2, OpenSSL 3.0.11 19 Sep 2023
student@debian:~$ apt list --installed openssh*
Listing... Done
openssh-client/now 1:9.2p1-2+deb12u2 amd64 [installed,upgradable to: 1:9.2p1-2+deb12u3]
openssh-server/now 1:9.2p1-2+deb12u2 amd64 [installed,upgradable to: 1:9.2p1-2+deb12u3]
openssh-sftp-server/now 1:9.2p1-2+deb12u2 amd64 [installed,upgradable to: 1:9.2p1-2+deb12u3]
You can try to check the protocol version via /etc/ssh/ssh_config
for the client side and /etc/ssh/sshd_config
for the openssh-server daemon. However, on newer installations, the Protocol
directive is not present in the configuration files. An example on an older installation:
student@linux:/etc/ssh$ grep Protocol ssh_config
# Protocol 2,1
student@linux:/etc/ssh$ grep Protocol sshd_config
Protocol 2
dealing with older devices
Unfortunately, some older devices still use insecure key exchange or signing algorithms. For example, the example below is an attempt to connect to a Cisco device (with IOS version 16.09.08, released in 2021) from a Linux system with the OpenSSH client version 9.8:
[student@linux ~]$ ssh cisco@172.16.255.254
Unable to negotiate with 172.16.255.254 port 22: no matching key exchange method found. Their offer: diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1
The Cisco device only uses the SHA-1 hash algorithm for signing messages. This is considered to be insecure, so is no longer supported by the OpenSSH client, at least not by default. Enabling SHA-1 can be done with the following command:
[student@linux ~]$ sudo update-crypto-policies --set DEFAULT:SHA1
Setting system policy to DEFAULT:SHA1
Note: System-wide crypto policies are applied on application start-up.
It is recommended to restart the system for the change of policies
to fully take place.
Trying the connection again yields:
[student@linux ~]$ ssh cisco@172.16.255.254
Unable to negotiate with 172.16.255.254 port 22: no matching host key type found. Their offer: ssh-rsa
The Cisco device only supports the ssh-rsa
host key type, which is also turned off on the client side. Turning it on can be done with the following command:
[student@linux ~]$ ssh -o HostKeyAlgorithms=+ssh-rsa cisco@172.16.255.254
The authenticity of host '172.16.255.254 (172.16.255.254)' can't be established.
RSA key fingerprint is SHA256:oDUj7I3RQi0FSKSaVX7gz8JfM1wpsYVbyF3ADNJTcAw.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '172.16.255.254' (RSA) to the list of known hosts.
(cisco@172.16.255.254) Password:
[... Some output omitted ...]
Router#
Router#exit
Connection to 172.16.255.254 closed.
[student@linux ~]$
Restoring the setting in order to no longer allow SHA-1 can be done with:
practice: ssh
Lab preparation: Make sure that you have access to two Linux computers, e.g. by setting up two VirtualBox VMs either manually or with an automation tool like Vagrant. Ensure that both VMs are attached to the same type of network (preferably Host-only or Internal) and that they have an IP address within the same subnet. One VM will assume the role of the client
, the other the server
.
-
On the
server
, check which version of the OpenSSHserver
is installed, which should be the case (especially for VMs created with Vagrant). If not, install it. -
Verify in the ssh configuration files that the
Protocol
setting is absent, or that only protocol version 2 is allowed. -
Use
ssh
to log on to theserver
, show your current directory and then exit theserver
. -
Use
scp
to copy a file from theclient
to theserver
. -
Use
scp
to copy a file from theserver
to theclient
. -
Use
ssh-keygen
to create a key pair without passphrase on theclient
. Set up passwordless ssh between theclient
andserver
-
Verify that the permissions on the
client
key files are correct; world readable for the public keys and only root access for the private keys. -
On the
server
, check which public keys are authorized for the user you are using to log in. -
Verify that the
ssh-agent
is running. -
(optional) Protect your keypair with a
passphrase
, then add this key to thessh-agent
and test your passwordless ssh to theserver
. -
(optional, only works when you have a graphical install of Linux) Use ssh with X forwarding to run a graphical on the
server
, but display it on yourclient
.
solution: ssh
In this setup, we have two VMs created with Vagrant:
Hostname | Role | Distro | IP address |
---|---|---|---|
debian |
SSH client | Debian 12 | 192.168.56.21/24 |
el |
SSH server | AlmaLinux 9 | 192.168.56.11/24 |
-
On the
server
, check which version of the OpenSSHserver
is installed, which should be the case (especially for VMs created with Vagrant). If not, install it.[vagrant@el ~]$ dnf list installed openssh* Installed Packages openssh.x86_64 8.7p1-38.el9_4.4 @baseos openssh-clients.x86_64 8.7p1-38.el9_4.4 @baseos openssh-server.x86_64 8.7p1-38.el9_4.4 @baseos [vagrant@el ~]$ ssh -V OpenSSH_8.7p1, OpenSSL 3.0.7 1 Nov 2022 [vagrant@el ~]$ systemctl status sshd ● sshd.service - OpenSSH server daemon Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; preset: enabled) Active: active (running) since Mon 2024-11-11 10:03:58 UTC; 4h 22min ago Docs: man:sshd(8) man:sshd_config(5) Main PID: 668 (sshd) Tasks: 1 (limit: 11128) Memory: 6.5M CPU: 208ms CGroup: /system.slice/sshd.service └─668 "sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups"
-
Verify in the ssh configuration files that the
Protocol
setting is absent, or that only protocol version 2 is allowed.No output, so the Protocol setting is absent. Since we have OpenSSH 8.7p1, this is what we can expect, as support for Protocol 1 was dropped in OpenSSH 7.6.
-
Use
ssh
to log on to theserver
, show your current directory and then exit theserver
.vagrant@debian:~$ ssh vagrant@192.168.56.11 pwd The authenticity of host '192.168.56.11 (192.168.56.11)' can't be established. ED25519 key fingerprint is SHA256:yw/ZrRXF4zpgbcjCSvM47MyFfg2DfOoiO1tMLVlthGU. This key is not known by any other names. Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added '192.168.56.11' (ED25519) to the list of known hosts. vagrant@192.168.56.11's password: /home/vagrant
-
Use
scp
to copy a file from theclient
to theserver
.On the server, the home directory of user
vagrant
is now empty:On the client, we create a file and copy it to the server:
vagrant@debian:~$ echo "Hello from Debian" > hello.txt vagrant@debian:~$ scp hello.txt vagrant@192.168.56.11:/home/vagrant vagrant@192.168.56.11's password: hello.txt
On the server, the file is now present:
-
Use
scp
to copy a file from theserver
to theclient
.Let's remove the file locally and copy it back from the server:
vagrant@debian:~$ ls hello.txt vagrant@debian:~$ rm hello.txt vagrant@debian:~$ ls -l total 0 vagrant@debian:~$ scp vagrant@192.168.56.11:/home/vagrant/hello.txt . vagrant@192.168.56.11's password: hello.txt 100% 18 7.3KB/s 00:00 vagrant@debian:~$ ls -l total 4 -rw-r--r-- 1 vagrant vagrant 18 Nov 11 14:36 hello.txt vagrant@debian:~$ cat hello.txt Hello from Debian
-
Use
ssh-keygen
to create a key pair without passphrase on theclient
. Set up passwordless ssh between theclient
andserver
.vagrant@debian:~$ ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/home/vagrant/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/vagrant/.ssh/id_rsa Your public key has been saved in /home/vagrant/.ssh/id_rsa.pub The key fingerprint is: SHA256:U1EQJVRL/BV8IX9XwVBGIBfAJfdtLkds5VNvM70kFxU vagrant@debian The key's randomart image is: +---[RSA 3072]----+ | .B@BOOE@| | =*.==@| | . .o X#| | . =*B| | S ..o| | . o | | | | | | | +----[SHA256]-----+ vagrant@debian:~$ ssh-copy-id -i .ssh/id_rsa.pub vagrant@192.168.56.11 /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: ".ssh/id_rsa.pub" /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 vagrant@192.168.56.11's password: Number of key(s) added: 1 Now try logging into the machine, with: "ssh 'vagrant@192.168.56.11'" and check to make sure that only the key(s) you wanted were added. vagrant@debian:~$ ssh vagrant@192.168.56.11 This system is built by the Bento project by Chef Software More information can be found at https://github.com/chef/bento Use of this system is acceptance of the OS vendor EULA and License Agreements. Last login: Mon Nov 11 10:04:49 2024 from 10.0.2.2 [vagrant@el ~]$
-
Verify that the permissions on the
client
key files are correct; world readable for the public keys and only root access for the private keys.vagrant@debian:~$ ls -ld .ssh/ drwx------ 2 vagrant root 4096 Nov 11 14:41 .ssh/ vagrant@debian:~$ ls -l .ssh/ total 16 -rw------- 1 vagrant vagrant 89 Oct 11 14:35 authorized_keys -rw------- 1 vagrant vagrant 2602 Nov 11 14:40 id_rsa -rw-r--r-- 1 vagrant vagrant 568 Nov 11 14:40 id_rsa.pub -rw------- 1 vagrant vagrant 978 Nov 11 14:30 known_hosts
-
On the
server
, check which public keys are authorized for the user you are using to log in.[vagrant@el ~]$ ls -l .ssh/ total 4 -rw-------. 1 vagrant vagrant 657 Nov 11 14:47 authorized_keys [vagrant@el ~]$ cat .ssh/authorized_keys ssh-ed25519 AAAAC3NzaC1lZDI1N......KVM04 vagrant ssh-rsa AAAAB3NzaC1yc2EAAAADA......8Toc= vagrant@debian
The first key is the one used by Vagrant to log in to the VM, the other one is the key we just added.
-
Verify that the
ssh-agent
is running.In this case, the SSH agent is not running on the client, so we start it manually:
-
(optional) Protect your keypair with a
passphrase
, then add this key to thessh-agent
and test your passwordless ssh to theserver
.We removed the RSA keypair and created a new ED25519 keypair with a passphrase.
vagrant@debian:~$ rm -rf .ssh/id_rsa* vagrant@debian:~$ ssh-keygen -t ed25519 Generating public/private ed25519 key pair. Enter file in which to save the key (/home/vagrant/.ssh/id_ed25519): Enter passphrase (empty for no passphrase): [ENTER PASSPHRASE HERE] Enter same passphrase again: [ENTER PASSPHRASE HERE] Your identification has been saved in /home/vagrant/.ssh/id_ed25519 Your public key has been saved in /home/vagrant/.ssh/id_ed25519.pub The key fingerprint is: SHA256:yo7yb0/iQK6TOGazv7DjibRb0pS5XPkiJ5xdxptoVhw vagrant@debian The key's randomart image is: +--[ED25519 256]--+ | | | | | E | | o + . | | +.o *S | | =o=.*.o | | = @oB++. | |==@.*=oo | |=OB*+o+.. | +----[SHA256]-----+
Next, we copy the public key to the server. Remark that we are not prompted for the passphrase here! This is only necessary when we want to access the private key.
vagrant@debian:~$ ssh-copy-id -i .ssh/id_ed25519.pub vagrant@192.168.56.11 /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: ".ssh/id_ed25519.pub" /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 Number of key(s) added: 1 Now try logging into the machine, with: "ssh 'vagrant@192.168.56.11'" and check to make sure that only the key(s) you wanted were added.
We remove all current keys from the agent and add the new key. At this point, we are prompted for the passphrase.
vagrant@debian:~$ ssh-add -D All identities removed. vagrant@debian:~$ ssh-add -L The agent has no identities. vagrant@debian:~$ ssh-add Enter passphrase for /home/vagrant/.ssh/id_ed25519: [ENTER PASSPHRASE HERE] Identity added: /home/vagrant/.ssh/id_ed25519 (vagrant@debian)
Now we can log in to the server without being prompted for the passphrase:
-
(optional, only works when you have a graphical install of Linux) Use ssh with X forwarding to run a graphical on the
server
, but display it on yourclient
.See example in the theory section.
-
It is possible to specify a passphrase when generating the keypair; that passphrase will be used to encrypt the private key part of this file using 128-bit AES. ↩