Puesto al día el 11 de julio de 2023.
configuración del servidor
el servidor ssh de este ejemplo tendrá una dirección IP fija, 192.168.1.7; un puerto propio, 9776; y el nombre de su dominio (hostname) será RB.
en primer lugar, hay que instalar el servidor y cliente ssh:
sudo apt install ssh
a continuación, se establece el nombre del dominio del servidor como RB y se traduce o vincula el mismo a la dirección IP 192.168.1.7:
sudo nano /etc/hostname
RB
sudo nano /etc/hosts
192.168.1.7 RB
luego, se añaden las direcciones IP permitidas por el servidor en /etc/hosts.allow. por este medio, el servidor sólo dará acceso a las direcciones IP definidas en este archivo (una dirección por línea):
sudo nano /etc/hosts.allow
ALL: 192.168.1.8
en este ejemplo, únicamente se da acceso al servidor a la dirección IP 192.168.1.8. si se definiera ALL:ALL en su lugar, cualquier dirección IP podría acceder al servidor.
a continuación, se edita el contenido de /etc/hosts.deny:
sudo nano /etc/hosts.deny
ALL:ALL
de esta manera, se niegan todas las acciones a todas las direcciones IP. el servidor, sin embargo, antepone las definiciones de hosts.allow a lo declarado en hosts.deny. dicho de otro modo, después de negarle todo a todo el mundo, el servidor permite todo a 192.168.1.8.
configuración de ssh
una vez preparado el servidor, debe prepararse el archivo de configuración de ssh:
sudo nano /etc/ssh/sshd_config
Port 9776
ListenAddress 192.168.1.7
ServerKeyBits 2048
LoginGraceTime 15
PermitRootLogin no
AuthorizedKeysFile %h/.ssh/authorized_keys
PasswordAuthentication no
X11Forwarding no
MaxStartups 3:30:60
mediante ListenAddress y Port, se declaran la dirección IP y el puerto donde escucha el servidor ssh (en este caso, 192.168.1.7:9776). el resto de parámetros, y muchos más, se detallan en «SSH config file for OpenSSH client» de SSH.COM. también pueden consultarse desde consola:
man ssh_config
PasswordAuthentication
Specifies whether to use password authentication. The argument to this keyword must be yes (the default) or no.
claves ssh como método de identificación
en la conexión con el servidor ssh, es preferible no emplear contraseñas al uso para identificarse (PasswordAuthentication no). si la conexión entre el cliente y el servidor va a ser frecuente, resulta mucho más seguro el empleo de claves ssh.
en primer lugar, es necesario crear un directorio local, ~/.ssh, donde almacenar las claves:
mkdir -p ~/.ssh
chmod 700 ~/.ssh
chmod 700 /home/usuario
después, se genera una clave mediante ssh-keygen dentro de ~/.ssh:
cd ~/.ssh
ssh-keygen -b 2048 -t rsa -f RB
donde RB es el nombre de los archivos generados: RB y RB.pub, que contienen las claves privada y pública respectivamente. el valor de -b
, 2048, debe ajustarse al parámetro ServerKeyBits de sshd_config.
a continuación, se otorgan los permisos adecuados a los archivos que contienen la clave (600 a la privada, 644 a la pública) y se reinicia el servicio:
chmod 600 ~/.ssh/RB
chmod 644 ~/.ssh/RB.pub
sudo systemctl restart ssh.service
comprobando la configuración
en este punto, el servidor ssh debería estar activo y escuchando en la dirección IP 192.168.1.8, puerto 9776. mediante netstat, se puede comprobar qué servicios están activos y a la escucha:
sudo netstat -tlpn
tcp 0 0 192.168.1.8:9776 0.0.0.0:* LISTEN 541/sshd
sudo systemctl status ssh.service
mar 19 20:43:21 RB sshd[508]: Server listening on 192.168.1.7 port 9776.
configuración del cliente
habitualmente, al cliente le bastaría con introducir la siguiente orden para conectar vía ssh al servidor:
ssh 192.168.1.7 -p 9776
donde se solicita conectar con el servidor que escucha en 192.168.1.7 y cuyo puerto (-p
) es el 9776.
en el caso de este ejemplo, sucede, sin embargo, que el servidor no solicita ninguna contraseña para identificar al cliente, sino que negocia las claves ssh directamente con la aplicación ssh del cliente y, dado que el cliente carece de la clave ssh adecuada, el servidor le cerrará el paso sin más.
claves ssh para identificarse
llegado a este punto, el cliente debe generar su propia clave ssh y hacérsela llegar al servidor para poder identificarse.
~/.ssh/config
antes de enviar las claves al servidor, resulta muy útil definir los parámetros de acceso al servidor en ~/.ssh/config (en esta ocasión, en el directorio local del cliente):
mkdir -p ~/.ssh
nano ~/.ssh/config
Host RB HostName 192.168.1.7 IdentityFile ~/.ssh/RB IdentitiesOnly yes Port 9776 User root
ssh-keygen + ssh-copy-id
luego, se genera la clave ssh del cliente y se envía al servidor mediante el comando ssh-copy-id:
ssh-keygen -b 2048 -t rsa -f ~/.ssh/cliente
ssh-copy-id -i ~/.ssh/cliente.pub RB
donde RB es el nombre (Host) declarado en ~/.ssh/config y responde, cada vez que se lo llama, a los parámetros de acceso del servidor definidos en este archivo (es decir, HostName, IdentityFile, IdentitiesOnly, Port y User).
si la copia de la identidad cliente al servidor devuelve el siguiente error:
Agent admitted failure to sign using the key
quizá sea necesario ejecutar ssh-add antes de volver a intentarlo con ssh-copy-id:
ssh-add ~/.ssh/cliente
ssh-copy-id -i ~/.ssh/cliente.pub RB
donde ssh-add se ocupa de añadir la identidad de la clave privada al agente de identificación:
man ssh-add
adds private key identities to the authentication agent
copia manual de las claves ssh al servidor
también se puede copiar la clave pública del cliente al servidor de manera manual si se tiene acceso directo (físico) al servidor: sólo hay que añadir el contenido de cliente.pub (la clave pública del cliente) al final de las claves autorizadas del servidor (es decir, en el archivo authorized_keys).
por ejemplo, tras copiar el archivo del cliente ~/.ssh/cliente.pub a una memoria externa, se conecta ésta al servidor, se crea el archivo authorized_keys en la carpeta ~/.ssh del servidor y se vuelca el contenido de cliente.pub a authorized_keys:
touch ~/.ssh/authorized_keys
cat /media/USB/cliente.pub > ~/.ssh/authorized_keys
hay más información sobre el uso de cat en la copia de un archivo a otro en «volcado de cat un archivo».
problemario
la dirección IP no está disponible
si se ha fijado una dirección IP en la opción ListenAddress de /etc/ssh/sshd_config, el servicio ssh espera encontrarla a su disposición durante el arranque, pero, si no se indica lo contrario, el servicio ssh puede lanzarse antes de que la red esté preparada y, en tal caso, devuelve un error y no se ejecuta:
sudo systemctl status ssh.service
sep 22 15:08:27 RB systemd[1]: Starting OpenBSD Secure Shell server…
sep 22 15:08:27 RB sshd[927]: error: Bind to port 9776 on 192.168.1.7 failed: Cannot assign requested address.
sep 22 15:08:27 RB sshd[927]: fatal: Cannot bind any address.
si este es el problema, es necesario modificar el archivo del servicio ssh (/etc/systemd/system/sshd.service) para evitar que éste se lance antes de que la dirección IP esté lista:
sudo nano /etc/systemd/system/sshd.service
After=network-online.target
Wants=network-online.target
hay que añadir el servicio network-online.target a las directivas de dependencia After y Wants del archivo sshd.service para conseguir que el servicio ssh se lance sólo después de que la dirección IP esté disponible.
si se prefiere, en lugar de After y Wants, se puede emplear la directiva Requires:
If this unit gets activated, the units listed will be activated as well. If one of the other units fails to activate, and an ordering dependency After= on the failing unit is set, this unit will not be started. Besides, with or without specifying After=, this unit will be stopped if one of the other units is explicitly stopped.
Often, it is a better choice to use Wants= instead of Requires= in order to achieve a system that is more robust when dealing with failing services.
«Requires=» en systemd.unit de freedesktop.org.
no auth methods could be used
ssh ernesto@192.168.1.7 -p 9776
ssh: Connection to ernesto@192.168.1.7:9776 exited: No auth methods could be used.
si se produce esta situación después de introducir la clave pública del cliente entre las authorized_keys
del servidor, puede que sea necesario señalar la ubicación del archivo de identificación del cliente:
ssh --help
[-i identity_file]
ssh ernesto@192.168.1.7 -p 9776 -i ~/.ssh/RB
Last login: Thu Oct 7 10:53:20 2021 from 192.168.1.7
permission denied (publickey)
tail -f /var/log/auth.log
Jul 11 11:56:19 RB sshd[809]: Authentication refused: bad ownership or modes for directory /home/ernesto
Jul 11 11:56:19 RB sshd[809]: Connection closed by 192.168.1.8 port 48842 [preauth]
en auth.log, se registran las operaciones relativas a las autorizaciones. en este caso, se prohibe el acceso al servidor porque los permisos del directorio /home/ernesto no son los correctos: es decir 700.
fuentes
- «Network Target» en freedesktop.org.
- «sshd_config» en ssh.com.