SSH

De Jose Castillo Aliaga
Ir a la navegación Ir a la búsqueda

SSH (Secure SHell) És un protocol per a la transferència d'arxius i gestió de maquines remotes amb connexió segura.

En base a aquest protocol hi han diferents programes per a la realitzar aquest tipus de tasques.

El que anem a estudiar és OpenSSH

Instal·lació i configuració d' OpenSSH

 $ sudo apt install ssh
 o
 $ sudo apt install openssh-server
  • Instal·la un paquet buit que fa referència a openssh-server i openssh-client
  • Es creen unes claus SSH2 RSA i DSA per identificar el servidor.
  • Les claus es guarden a la carpeta /etc/ssh
 $ cd /etc/ssh
 $ ls *key*
 ssh_host_dsa_key  ssh_host_dsa_key.pub  ssh_host_rsa_key  ssh_host_rsa_key.pub

Per defecte, té reservat el port 22 TCP i UPD, encara que el habitual és el TCP.

El fitxer de configuració del servidor és /etc/ssh/sshd_config

Opcions de configuració

  • AllowGroups: Una llista de grups separats per espais dels usuaris que poden accedir.
  • AllowUsers: Llista d'usuaris, es poden utilitzar patrons ? *
  • Banner <fitxer>: Quan entra un usuari, es pot especificar el missatge de benvinguda abans de fer login.
  • Compression <yes|delayed|no>: Per defecte és delayed. Especifica si es va fer servir compressió. Delayed significa que sols quant l'usuari ja s'ha autenticat.
  • DenyGroups: Llist de grups que no poden accedir.
  • DenyUsers: Llista d'usuaris que no poden accedir.
  • Port: El port on escolta, per defecte el 22
  • ListenAddress: Adreça en la que escolta. Es poden especificar ports distints per a distintes adreces amb <adreça>:<port>
  • LoginGraceTime: Temps màxim per autenticar, A 0 és sense límit.
  • MaxAuthTries: Màxims d'intents d'autenticació.
  • MaxStartups: Connexions màximes simultanies. Per defecte és 10:30:100 (10 connexions: 30% de probabilitat de eliminar una nova connexió quan hi ha més de 10, amb 100 les elimina totes.)
  • PasswordAuthentication <yes|no>: Si autentica per contrasenya o no.
  • PermitEmptyPasswords <no|yes>: Permet contrasenyes buides o no.
  • PermitRootLogin: <yes|without-password|forced-commands-only|no> Permet o no connectar a root. Es pot forçar a que siga sols sense password o sols uns comandaments determinats.
  • Protocol: Pot ser 1 o 2 o els dos, es reconama no utilitzar 1 perquè no és tant segur.
  • PubkeyAuthentication <yes|no>: S'accepta l'autenticació per clau pública.
  • X11Forwarding <no|yes>: Accepta reenviar X11 al client.
  • AllowTcpForwarding: Perment fer tcp forwarding amb aquest servidor.
  • MaxSessions: Limita les sessions obertes. En realitat es refereix a la multiplexió d'una connexió, no a les diferents connexions simultànies.
Si volem que un usuari no puga connectar-se en més d'una sessió a un servidor, aixó no és cosa de SSH, és cosa dels límits del sistema operatiu. En Ubuntu podem modificar el fitxer /etc/security/limits.conf per indicar el màxim de logins d'un usuari amb, per exemple: ubuntu hard maxlogins 1

Si vols vorer totes les opcions: man sshd_config

Motorització del servici

Com molts dels servicis de Linux, es pot veure cóm está en:

 # service sshd status

El servidor openssh-server no té un fitxer específic de log, però es pot veure en aquest comandament:

tail -500 /var/log/auth.log | grep 'sshd'

Si volem veure un debug del propi servidor, es pot parar e iniciar així:

/usr/sbin/sshd -ddd

Però no el pares mai si está connectat remotament. En eixe cas, es pot provar amb:

/usr/sbin/sshd -ddd -p 2222

Obrint un altre port i entrant per ell.

Ús bàsic

La sintaxi de SSH segueix un esquema similar al del correu electrònic:

usuari@nom_maquina_remota

Els següents són exemples de connexió amb SSH a una màquina remota:

 $ ssh lliurex@upv.edu
 $ ssh lliurex@192.168.1.1
 $ ssh 192.168.1.1

De vegades necessitem que quan fem una connexió remota tenim que carregar aplicacions amb entorn gràfic i ho faríem:

 $ ssh -X [usuari de la maquina de destí]@[IP o Hostmane de la maquina de destí]

El -X sols funciona si el servidor té interficie gràfica i el servidor SSH ho permet.

Si volem connectar a un altre port:

 $ ssh [usuari de la maquina de destí]@[IP o Hostmane de la maquina de destí] -p 2222

Connexió sense contrasenya

En ocasion podem necessitar accedir a un servidor sense contrasenya. En aquest cas, tenim que indicar al servidor que es "fie" de la nostra clau pública. Però no de la del host, sino de la del nostre usuari en un altre usuari del servidor.

La comanda ssh-keygen s'encarrega de la creació dels parells de claus pública/privada per al nostre usuari. Per defecte, els fitxers depenent del protocol escollit:

   $HOME/.ssh/identity (clau privada) i $HOME/.ssh/identity.pub (clau pública)
   $HOME/.ssh/id_dsa (clau privada) i $HOME/.ssh/id_dsa.pub (clau pública) si el protocol escollit es DSA.
   $HOME/.ssh/id_rsa (clau privada) i $HOME/.ssh/id_rsa.pub (clau pública) si el protocol escollit es RSA. 

Les comandes exactes a utilitzar per generar les claus en cadascun dels casos anteriors són:

 $ ssh-keygen
 $ ssh-keygen -t <rsa|dsa> 

El nom dels fitxers per defecte es pot canviar utilitzant el paràmetre -f.

Durant la creació de la clau se'ns preguntarà per la possibilitat de protegir l'ús de la clau amb contrasenya. Si la nostra intenció és automatitzar tasques podem anular aquest pas si no introduïm cap contrasenya (Enter).

El id_dsa.pub cal afegir-lo al .ssh/authorized_keys del servidor. Es pot fer amb scp, copiant i pegant o, preferiblement amb ssh-copy-id.

 $ ssh-copy-id usuari@servidor

Com que al generar les claus no hem ficat contrasenya, es connectarà directament. Si no, ens demana la de desencriptar la clau privada.

Per a eliminar un client:

 ssh-keygen -R IP_client

Però crear la clau privada sense contrasenya no és molt recomanable. Per tant, es pot fer en contrasenya de manera que no ens la demane després.

Cal fer que el sistema la recorde una vegada per sessió amb el ssh-agent.

 $ ssh-add -l                    # Llista de les claus que administra
 $ ssh-add ~/.ssh/id_dsa         # Afegir la nostra

Pot ser que, avans de res, tingam que iniciar el ssh-agent:

 $ eval "$(ssh-agent)"

Amb la autentificació a nivell de usuari pot ser insegura. En qualsevol cas, es fa una autentificació a nivell de màquina. Quant connectem per primera vegada ens diu si volem guardar el fingerprint del servidor.

Es guarda en .ssh/know_hosts

Si volem que l'autentificació siga sols per el client, es pot forçar en la connexió ssh:

 $ ssh -o "ConnectTimeout=10" -o "StrictHostKeyChecking no" root@server

D'aquesta manera mai ens demana escriure yes i es pot automatitzar en scripts.

Connexions no interactives

Quasi sempre necessitem connectar per SSH per obrir una sessió de terminal en l'equip remot. Per defecte, SSH executa un bash o el shell de l'usuari en la màquina remota. Però no sempre necessitem una terminal.

Imaginem que necessitem sols obtindre el resultat de ifconfig d'un servidor remot:

 $ ssh root@10.20.250.1 who

Molt més fàcil que entrar, executar who i eixir. Amés es poden fer scripts si es fa autentificació per client.

Inclús es pot fer un script que envíe un script a la màquina remota:

for i in server1 server2 server3
do
 ssh root@$i 'bash -s' </tmp/script.sh &>> /tmp/errors
done


La seguretat en SSH

Els protocols i cifrats que utilitza SSH són molt segurs, però no podem confiar en una configuració deficient i, sobretot, en un ús negligent. A continuació anem a veure alguns principis bàsics de seguretat:

  • La connexió en contrasenya basa la seua seguretat en la contrasenya de l'usuari. Per tant, ha de ser robusta. Tampoc es deu permetre entrar per SSH a root o a qualsevol usuari.
  • Els servidors ssh tenen una clau pública en la que deguem confiar. Si ens connectem a un servidor i en avisa de que no té eixa clau en known-hosts tenim que sospitar. Això sols ha de dir-ho en la primera connexió. Aquesta es farà en xarxa local per evitar atacs man in the middle o, si cal fer-ho de forma remota, tenim que comparar el finguerprint amb el del servidor. Per veure el finguerprint del servidor s'ha d'executar:
 ssh-keygen -lf /etc/ssh/ssh_host_ecdsa_key.pub
  • L'autentificació sense contrasenya és molt segura entre màquines segures, però no és recomanable quan el client pot ser manipulat per altres persones (PCs públics, Portàtils que ens poden furtar, PCs domèstics...).
  • Si necessitem que moltes persones puguen accedir per gestionar els seus serveis, deguem plantejar coses com màquines virtuals o contenidors (LXD) que aïllen a eixos usuaris del sistema operatiu.

Configurar el client SSH

L'arxiu de configuració està a ~/ssh/config El seu contingut pot ser, per exemple:

Host server1   # Servidor1 sistemes.com
    Hostname 192.168.1.201
    User root
Host server2   # Servidor2 sistemes2.com
    Hostname 192.168.1.202
Host *
    IdentityFile ~/.ssh/id_rsa
    IdentitiesOnly yes
    User ubuntu
    Port 22

D'aquesta manera es simplifica molt la connexió. En l'arxiu de configuració es poden incloure túnels:

 Host work
 HostName 66.35.250.203
        User lliurex # L'usuari és lliurex i el nom de la connexió es diu work. Per tant es pot fer '''$ ssh work'''
        LocalForward 20000 192.168.0.66:80
        LocalForward 22000 192.168.0.66:22

scp

Funciona de forma anàloga a la comanda cp, però utilitza prefixos de conexió a màquina remota:

usuari@host:/PATH_AL_FITXER 

Per exemple:

 $ scp $HOME/file1 jose@sga2.upv.es:$HOME

Copia el fitxer file1 de la carpeta home local a la carpeta home del servidor sga2.upv.es.

SSH va en scp, però pot ser que necessitem sols que l'usuari puga pujar arxius però no entrar en una terminal. Per a permetre sols scp mireu rssh
En -3 es pot fer una copia entre dos hosts remots sense passar per el nostre.

Tunnels SSH

SSH es pot utilitzar per tunnelitzar connexions de protocols insegurs per xarxes no confiables. D'aquesta manera evitem que ens puguen espiar o limitar les nostres connexions.

Anem a veure els diferents casos que es poden donar:

Dynamic port forwarding

Permet accedir via SSH a una màquina darrere d'un firewall. Sshproxy.png

La situació és alguna de les següents:
  • Tens accés a Internet, però algunes pàgines web estan tallades per el tallafocs o el ISP.
  • Tens accés a Internet i vols connectar-te a una pàgina personal però no vols que ningú de la teua xarxa escolte la comunicació ni sàpiga a quines web estàs entrant.
Amés, tens accés a una màquina en ta casa o la teua empresa que està connectada a Internet i dona accés per SSH.

Si la màquina de ta casa té accés cap a l'exterior aleshores es possible saltar-se el tallafocs si tenim accés a la màquina.

Si existeix un tallafocs o necessites una certa privacitat en les connexions a Internet.

 $ ssh -D 7070 jo@macasa.com

Redirecciona la connexió al port 7070.

Cal que el servidor tinga en /etc/ssh/sshd_config:

AllowTcpForwarding yes
GatewayPorts yes
TCPKeepAlive yes

En el Firefox es fica com a proxy sols en SOCKS v5 localhost:7070 i a funcionar!

Aquesta configuració crea un port dinàmic (-D). El que ha fet, realment, és convertir el servidor SSH en un servidor SOCKS. Un servidor SOCKS funciona com un proxy que no es llimita a tràfic http o https sino que és capaç de redireccionar qualsevol port.

Es pot millorar amb:

 $ ssh -fN -D 0.0.0.0:7070 jo@macasa.com

Amb -f i -N creem un dimoni sense terminal remota que queda en un segon pla i amb 0.0.0.0 podem donar servici a altres hosts de la mateixa xarxa.

Amés del firefox, el programa curl també pot utilitzar un proxy SOCKS v5:

 $ curl --socks5-hostname 127.0.0.1:1080 http://www.upv.es

Siguent: 1080 el port configurat per SSH.

Accedir a servicis darrere d'un tallafocs

Proxyssh2.png

En aquest cas, el problema és que vols accedir a una intranet a través d'un servidor SSH, que eś l'unic que dona servei a l'exterior de la xarxa.

En este cas, el tallafocs sols deixa passar el port 22.

Necessitem utilitzar el Samba, la web i el correu de la intranet.

El servidor SSH té com a IP pública 66.35.250.203

Cal configurar el portàtil per a tunelitzar el tràfic a través del servidor.

~/.ssh/config (amb permissos 600)

 ## Linux Laptop .ssh/config ##
 Host work
 HostName 66.35.250.203
        User lliurex # L'usuari és lliurex i el nom de la connexió es diu work. Per tant es pot fer '''$ ssh work'''
        LocalForward 20000 192.168.0.66:80
        LocalForward 22000 192.168.0.66:22
        LocalForward 22139 192.168.0.8:139
        LocalForward 22110 192.168.0.5:110
 
 Host http
 HostName localhost # després de la connexió és possible accedir directament al servidor http per ssh
        User donkey
        Port 22000
        HostKeyAlias localhosthttp

Aquesta sería la manera permanent de fer-ho, peró es poden fer coses en una sola comanda:

 $ ssh -L 4000:destinacio:80 user@intermediari

(font)


Fer un servidor per accedir a servicis darrere d'un tallafocs

Sshdia3.png

En aquests cas, passa com en l'anterior. Però volem que el client1 siga el servidor del tunel al client2.

En el client1:

$ ssh -L 0.0.0.0:8080:localhost:80 usuario@servidorWeb
o:
$ ssh -L 192.168.24.80:8080:localhost:80 usuario@servidorWeb

En el primer cas, permet que qualsevol IP es connecte al port 8080 per entrar al port 80 del servidor Web al que està connectat. En el segon cas, sols permet utilitzar el tunel per una IP.

També es pot fer en l'opció -g:

 ssh -g -L 8080:localhost:80 usuario@servidorWeb

En el client2, cal entrar al navegador en la direcció: client1:8080

Accedir des del servidor a servicis del client

Sshdia4.png

En aquest cas, la connexió SSH s'ha fer des del client, com en el cas anterior. Anem a suposar que el client no té servici SSH, però si servidor Web i volem utilitzar aquesta connexió per tunelitzar el por 80, però del client1.

$ ssh -R 8080:localhost:80 usuario@servidorWeb

En aquesta ocasió, el port que s'obri és el 8080 del servidorWeb per a accedir via SSH al 80 del client1.

De la mateixa manera que l'anterior, es pot obrir aquest port 8080 a altres servidors:

$ ssh -R 0.0.0.0:8080:localhost:80 usuario@servidorWeb

No obstant, no funcionarà a la primera, cal permetre fer de Gateway de ports amb:

GatewayPorts clientspecified

Una altra opció és accedir al port 80 del client2 desde el servidor Web o altres utilitzant la connexió SSH establida pel client1

$ ssh -R 0.0.0.0:8080:client2:80 usuario@servidorWeb

Local tun : remote tun

Del manual del ssh:

     -w local_tun[:remote_tun]
             Requests tunnel device forwarding with the specified tun(4) devices between the client
             (local_tun) and the server (remote_tun).

             The devices may be specified by numerical ID or the keyword “any”, which uses the next avail‐
             able tunnel device.  If remote_tun is not specified, it defaults to “any”.  See also the
             Tunnel and TunnelDevice directives in ssh_config(5).  If the Tunnel directive is unset, it is
             set to the default tunnel mode, which is “point-to-point”.

En sshd_config:

PermitTunnel yes

En el client:

 $ ssh -f [-C] -w 0:0 IPservidor -N    # (-C, compresió)
 $ ifconfig tun0 10.10.10.2 pointopoint 10.10.10.1 netmask 255.255.255.252

En el server

 $ ifconfig tun0 10.10.10.1 pointopoint 10.10.10.2 netmask 255.255.255.252

sshuttle

https://github.com/sshuttle/sshuttle http://sshuttle.readthedocs.io/en/stable/manpage.html

Sshuttle permet crear un tunnel a una xarxa sencera en una única connexió ssh. Exemples:

Tot el tràfic:

sshuttle -r username@sshserver 0.0.0.0/0

Una xarxa concreta:

sshuttle -r username@sshserver 192.168.2.0/24

AutoSSH

En ocasion, el tunel SSH cau per motius diversos. Aleshores cal reiniciar el servici. El programa autoSSH permet mantindre i reiniciar les connexions SSH en entorns inestables.

Observem un cas complet del comandament:

autossh -M 0 -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -L 8888:localhost:80 192.168.0.1

El significat dels paràmetres és:

  • -M [:echo_port]: Amb aquesta opció, va enviant dades per la connexió per a mantindre-la oberta. Si no passa informació, la reinicia. Cal indicar quin és el port i no ha d'estar utilitzat per ningú. En el manual recomanen utilitzar les opcions de serverAliveInterval i serverAliveCountMax. Per això, en l'exemple està a -M 0 que el deshabilita.
  • -o "ServerAliveInterval 30" : Quantitat de segons que el client espera fins a enviar un paquet nul que manté la connexió viva.
  • -o "ServerAliveCountMax 3": El nombre de missatges de vida que es poden enviar al server sense que retorne res. Si s'arriba als 3 missatges s'acaba la sessió.

Tutorial de AutoSSH

Usos interessants

Backup d'un disc dur sobre SSH

# dd if=/dev/sda | ssh <usuari>@<servidor> "dd of=/<directori de backups>/backupfile.iso"

Inclús es pot comprimir:

# dd if=/dev/sda | gzip -c | ssh  <usuari>@<servidor> "dd of=/<directori de backups>/backupfile.gz"

D'aquesta manera podem mostrar una barra de progrés:

# dd if=/dev/sda | gzip -c | pv -s `sudo mount /dev/sda /media/sda && du -sb /media/sda/ | awk '{print $1}' && sudo umount /media/sda`| \
ssh  <usuari>@<servidor> "dd =/<directori de backups>/backupfile.gz"

El que hi ha entre `` és per a traurer la mida en bytes de la partició. D'aquesta manera, la barra de progrés és més realista.


Arrancar una aplicació gráfica amb SSH

Si al connectar utilitzem l'opció -X podem executar aplicacions amb interficie gràfica en la nostra màquina.

Si el que volem és que s'executen en l'altra, podem fer ús d'aquest comandament:

$ export DISPLAY=:0

I després executar l'aplicació.

Caracters d'escapament

En una sessió oberta de SSH, de vegades volem configurar coses relatives a la propia connexió. Es poden utilitzar alguns escapaments per poder manipular la sessió. Per exemple:

  • ~C : Obre una terminal on podem, per exemple, llançar un nou tunnel:
~C
ssh> -L 8080:192.168.2.2:80          
Forwarding port.

També es poden tancar tunnels amb -KL -KD o -KR:

ssh> -KL 8080
Canceled forwarding.
  • ~#: Lista les connexions redirigides que estan actives actualment. (les fetes en -L, -R o -D)
  • ~?: Llista tots els caracters d'escapament disponibles.

Enllaços