Mastering SSH on Linux: Connect, Keys, and Tunneling
The OpenSSH package offers remote access service to computers running Linux securely with end-to-end encrypted connection through the ssh command in Linux.
It uses the ssh protocol (secure shell) to allow file transfer and secure shell.
It was created to replace connection servers that traffic unencrypted data like telnet, rsh and rlogin. The free open source version can be obtained at the website http://www.openssh.org or installed directly as a package in most distributions.
OpenSSH has portability for various systems like Linux, Solaris, FreeBSD, NetBSD, AIX, IRIX, HP-UX and OpenBSD.
Installing OpenSSH is simple and can be done through packages with apt-get on Debian or yum on Red Hat.
OpenSSH encryption uses the concept of public and private key pairs.
Encryption Algorithms
OpenSSH supports various signature algorithms for authentication keys that can be divided into two groups, depending on the mathematical properties they exploit:
- DSA and RSA, which depend on the practical difficulty of factoring the product of two large prime numbers;
- ECDSA and Ed25519, which depend on the elliptic curve discrete logarithm problem.
Elliptic curve cryptography (ECC) algorithms are a more recent addition to public key cryptography systems. One of their main advantages is the ability to provide the same level of security with smaller keys, which makes operations less computationally intensive (that is, faster key creation, encryption and decryption as well.
OpenSSH Client Configuration 2
For each user, ssh also creates their key pairs, which reside in the ".ssh" subdirectory of the user's HOME directory. At any time, the user can create their key pairs with the ssh-keygen command:
$ ssh-keygen Generating public/private rsa key pair.Enter file in which to save the key (/home/uiraribeiro/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Your identification has been saved in /home/uiraribeiro/.ssh/id_rsa.Your public key has been saved in /home/uiraribeiro/.ssh/id_rsa.pub.The key fingerprint is:SHA256:7p177xnRUY0HDcrdUbDCQg uiraribeiro@Notebook-do-UiraThe key's randomart image is:+---[RSA 2048]----+| E==o=+=o .. || =+ =o.=.oo|| = +o oo |+----[SHA256]-----+
ssh-keygen can create the following key pairs with different encryption algorithms:
- DSA private key: ~/.ssh/id_dsa (DSA);
- DSA public key: ~/.ssh/id_dsa.pub (DSA);
- ECDSA private key: ~/.ssh/id_ecdsa (ECDSA);
- ECDSA public key: ~/.ssh/id_ecdsa.pub (ECDSA);
- Ed25519 private key: ~/.ssh/id_ed25519 (Ed25519);
- Ed25519 public key: ~/.ssh/id_ed25519.pub (Ed25519);
- RSA private key: ~/.ssh/id_rsa (RSA);
- RSA public key: ~/.ssh/id_rsa.pub (RSA)
Passwordless Authentication
If the user wishes, they can copy their public key to the HOME directory of the user they use to connect to on the remote machine in the file ~/.ssh/authorized_keys. That way, they will no longer need to provide the password for a remote connection to that specific host and user.
/etc/ssh_config File
The ssh client maintains a file /etc/ssh/ssh_config for SSH client settings. Among them, the following stand out:
Protocol 2 # permite que somente o SSH2 seja usadoPort 22 # altera a porta padrão do SSH de 22 para outraForwardX11Trusted no # não permite login remote via X11
Remote Connection using SSH
When a connection to an SSH server is made, there is an exchange of public keys between the ssh client and the sshd server.
Then when the server wants to send something to the client, it uses the client's public key to encrypt the data for them. Only the client's private key is capable of decrypting what was encrypted with its public key.
The same happens when the client wants to send something to the server. It uses the server's public key to encrypt something for it. This way only the server's private key is capable of reading its contents.
To connect to a host using ssh, the command follows the pattern:
$ ssh nomedousuario@enderecodohost
And to make a connection with X11 protocol, use the "-X" or "-Y" option:
$ ssh -X [email protected]
ssh automatically exchanges the local user's public keys with the remote user's keys, transparently.
It is also possible to remotely execute a command on the destination host using ssh:
$ ssh [email protected] svn /var/www/html
In this example, ssh will authenticate, and execute the command "svn /var/www/html" on the remote server.
ssh allows specifying a connection port, when port 22 is not the remote server's default port:
$ ssh -p 2222 [email protected]
The "-p" option allows specifying the port.
ssh_known_hosts
The file /etc/ssh/ssh_known_hosts or ~/.ssh/known_hosts is consulted when the access method used is based on RSA authentication. This file contains the public keys of a machine so that the connection is successful.
As soon as a connection is established for the first time, ssh writes a hash of the server in the file ~/.ssh/know_hosts. In subsequent connections this hash is compared with the one received from the server and from the know_hosts file.
If for some reason the server is changed, the comparison will fail, SSH will not connect and will issue an alert, saying that the server is possibly another machine and not the known one.
When there is a need to replace the server, the ssh client must remove the corresponding line to the server in the file ~/.ssh/know_hosts.
OpenSSH Server
The service that provides remote connection using SSH from the OpenSSH package is sshd. This service is usually run through the Systemd service manager.
At the time of installing OpenSSH Server, a public key and a private key of your host will be created. In SSH version 2, the following files are created:
/etc/ssh/ssh_host_rsa_key (RSA private key)
/etc/ssh/ssh_host_rsa_key.pub (RSA public key)
/etc/ssh/ssh_host_dsa_key (DSA private key)
/etc/ssh/ssh_host_dsa_key.pub (DSA public key)
/etc/ssh/ssh_host_ecdsa_key (ECDSA private key)
/etc/ssh/ssh_host_ecdsa_key.pub (ECDSA public key)
/etc/ssh/ssh_host_ed25519_key (Ed25519 private key)
/etc/ssh/ssh_host_ed25519_key.pub (Ed25519 public key)
These keys should not be changed, as they are your host's encryption keys. If any of these keys are changed, the machines you connected to will no longer accept your connection, as they will understand that someone is impersonating you.
sshd_config
The main configuration file for sshd is /etc/ssh/sshd_config. It is important that this file has read and write permission only for the super user, as it contains sensitive information, such as allowing root login or just a list of users.
The sshd_config file is very rich in configuration possibilities.
The following information is relevant when configuring sshd:
Protocol 2 # permite que somente o SSH2 seja usadoPort 4999 # altera a porta padrão do SSH de 22 para outraForwardX11 no # não permite login remote via X11PermitRootLogin no # não permite que o root entre remotamenteMaxAuthTries 2 # define o número máximo de tentativas de erroAllowUsers tom jerry # define quais logins são permitidos via ssh
Generally, for security reasons, it is not common to allow direct root access to ssh, so the administrator should log in with another account with normal privileges and use sudo for commands that require superuser access.
Enabling sshd
To start the ssh server service:
$ systemctl start sshd
To enable the service at system boot:
$ systemctl enable sshd
ssh-agent and ssh-add
The ssh-agent and ssh-add applications can be used to control the ssh connection, so that the user does not need to type their authentication password on the destination machine for each connection.
The destination machine needs to have a copy of the user's public key in the ~/.ssh home folder of the destination user on the destination machine:
# scp /root/.ssh2/hostkeys/key.pub root@server:/root/.ssh
The "scp" command makes a secure copy of the public key created with ssh-keygen to the "/root/.ssh" directory on the destination machine.
After this, the "ssh-agent" command shows which environment variables need to be created and what the PID of the SSH agent process is that will control the connection:
# ssh-agentSSH_AUTH_SOCK=/tmp/ssh-lqMuRR398/agent.398; export SSH_AUTH_SOCK;SSH_AGENT_PID=399; export SSH_AGENT_PID;
Copy and paste into the shell the text that ssh-agent showed:
# SSH_AUTH_SOCK=/tmp/ssh-lqMuRR398/agent.398; export SSH_AUTH_SOCK;# SSH_AGENT_PID=399; export SSH_AGENT_PID;
After that, it is necessary to run "ssh-add" and enter the "passphrase" that was entered when the keys were created:
# ssh-addEnter passphrase:
This way, when you make a secure connection to the "destinationmachine", ssh will not ask for your password.
# ssh root@maquinadestino
Another way to do this is to copy the contents of the id_rsa.pub public key from the client machine to the ~/.ssh/authorized_keys file on the server machine. This way when the client needs to log into the server machine, no password will be required.
ssh-copy-id
The ssh-copy-id program can be used to securely and quickly copy the public key to the remote machine. It copies the user's public key to the remote server in ~/.ssh/authorized_keys.
$ ssh-copy-id [email protected]/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed:
/home/uiraribeiro/.ssh/[email protected]'s password: Number of key(s) added: 1Now try logging into the machine, with: "ssh '[email protected]'"and check to make sure that only the key(s) you wanted were added.
Personally, I don't like using this passwordless access method. Once your machine is vulnerable, all the machines where you regularly use ssh key access will also be compromised.
Making SSHD More Secure
Changing the SSH Port
One trick to make ssh more secure is to change the default connection port of the ssh service.
This can be done by editing the /etc/ssh/sshd_config, changing the "Port" directive. Usually this line will be commented out with "#". You need to uncomment it and change the port from 22 to something else above 1024:
Port 2323
Disallowing Root Login
It is also interesting to disable superuser root access in ssh, thus allowing only regular users to log in remotely.
This can be done by editing the /etc/ssh/sshd_config, in the "PermitRootLogin" directive, which should be uncommented and set to "no":
PermitRootLogin no
After any changes to the sshd_config file, it is necessary to restart the ssh service:
# systemctl restart sshd
Using Tcpwrapper
An old technique in Linux to limit access to a certain service is the use of tcpwrapper.
The tcpwrapper works like a doorman that intercepts a connection and checks whether a certain service can be accessed by a client. This way it is possible to limit which client IP addresses could access a certain service.
Linux programs that use tcpwrapper link to the libwrap.so library.
To determine if a program uses tcpwrapper, you can check which libraries it uses with the ldd program:
$ ldd /usr/sbin/sshd | grep wrap libwrap.so.0 => /lib/x86_64-linux-gnu/libwrap.so.0
In this case, it is possible to see that the sshd program uses the libwrap library, and therefore, is capable of limiting which hosts can access the secure shell.
To limit which client hosts can access which service, tcpwrapper checks the /etc/hosts.allow and /etc/hosts.deny files to know which IP addresses can access which service.
hosts.allow and hosts.deny
The /etc/hosts.allow and /etc/hosts.deny files are used to define access rules for services offered by the computer.
The contents of the hosts.allow and hosts.deny files follow this format:
nome_do_serviço: endereço_ip
There is a logic and an established order:
When a connection is established, tcpwrapper first reads the contents of the /etc/hosts.allow file. If there is a rule for this connection it does not check the hosts.deny file.
$ cat /etc/hosts.allow sshd: 10.10.100.1
If no rule is found in hosts.allow, it reads /etc/hosts.deny looking for a rule. If something matching is found in hosts.deny, it terminates the connection. If nothing matching is found, it allows access.
If you want only explicitly allowed connections in the hosts.allow file to be permitted, denying any other undeclared client, the "ALL:ALL" rule can be placed in the /etc/hosts.deny file so that only connections explicitly defined by rules in hosts.allow are accepted.
Another possible combination in hosts.deny is to deny everything per service with the rule "sshd:all". Some distributions replace the word "all" with "paranoid".
IP addresses declared in the hosts.allow and hosts.deny files can be in either IPv4 or IPv6 version. More than one address should be separated by commas:
sshd: 192.168.0.10, 192.168.0.15
You can also declare a machine address:
sshd: uira.certificacaolinux.com.br
It's also possible to allow by subnet:
sshd: 192.168.0.0/255.255.255.0
The tcpwrapper also accepts a partial combination if the line ends with a ".":
sshd: 192.168.0.
In this case, all addresses that start with "192.168.0" will be included.
Restricting which clients can connect to a specific service is a task today delegated to using a good Firewall. However, tcpwrappers offers an extra layer of security, since if the firewall fails, there's still tcpwrapper to ensure some extra protection.
Learn much more about Linux in our online course. You can enroll here. If you already have an account, or want to create one, just log in or create your user here.
Did you like it? Share
That was just one piece. The course teaches the whole path — from your first command to exam day.