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 adeces.
  • LoginGraceTime: Temps màxim per autenticar, A 0 és sense límit.
  • MaxAuthTries: Màxims d'intents d'autenticació.
  • MaxStartups: Connexions màximens simultanies.
  • 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.

Ú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

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

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

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ó.


Enllaços