/dev/random

Rsync via SSH

Come sincronizzare dati tra due computer senza installare servizi sul server.

SSH continua a stupirmi ogni giorno. Sapevo che permetteva di trasferire file, tramite protocollo SFTP, come se si trattasse si un FTP (e con Nautilus si possono vedere i server remoti come fossero cartelle locali). Sapevo che ci si potesse forwardare X attraverso, anche se non ho ancora mai provato. Sapevo che ci si potevano fare tunnel generici. Ieri ho scoperto che lo si può usare come proxy SOCKS verso un proprio server, in modo da navigare “protetti” anche da reti pubbliche.

Oggi ho scoperto che lo si può usare direttamente da rsync senza bisogno di configurare nulla sul server. A patto di avere rsync installato sul server, naturalmente, ma non è necessario configurarlo in modalità daemon, né definire le “share” da esportare o le protezioni da attuare. Una porta aperta in meno! Vediamo come fare...

Uso di base

Per un uso normale, con autenticazione tramite password, si può usare direttamente rsync, aggiungendo un solo parametro, oltre ai soliti utente, nome server, cartella remota e cartella locale:

rsync -ravz -e ssh utenteremoto@serverremoto:/path/alla/dir/remota/ /path/alla/dir/locale/

Fatto. Non serve altro. Le opzioni che ho usato sono quelle classiche: a per mantenere i permessi, r per fare una copia ricorsiva, v per aumentare la “verbosità” dell'operazione, z per comprimere i file in transito (utile se si fanno backup di log non compressi o di file di testo). L'opzione -e è quella che ci interessa qui: specifica la shell remota da utilizzare per la copia. rsync richiamerà automaticamente il suo omologo sul server remoto e gestirà automaticamente le differenze tra i file. In questo caso specifichiamo ssh come shell remota.

Seguono il nome utente (sul server), il nome del server stesso (o il suo IP) e il path alla directory che vogliamo copiare, raggruppati. Quindi il path locale dove vogliamo copiare i file. Sarà sufficiente invertire questi due componenti (prima il locale e poi il remoto) per caricare i file sul server, invece di scaricarli. Rimangono validi tutti gli altri switch di rsync (cancellazione dei file, tipi di controllo per determinare l'aggiornamento, ecc.)

Naturalmente questo sistema ci chiederà la password dell'utente sul server remoto ogni volta che faremo la sincronizzazione, quindi è poco adatto ad essere usato, per esempio, con cron.

Autenticazione tramite chiavi pubblica e privata

Per questo ci viene in aiuto ssh. Possiamo generare una coppia di chiavi, una pubblica e una privata, da utilizzare per autenticarci sul server senza bisogno della password. Ecco il comando per generarla:

ssh-keygen -t dsa -b 1024 -f chiave-ssh

Questo comando crea una chiave DSA a 1024 bit e la memorizza in due file: la parte privata nel file “chiave-ssh”, e quella pubblica in “chiave-ssh.pub”.

La chiave privata va tenuta al sicuro, non deve essere vista da nessuno. Assicuratevi che abbia permessi 600 (rw——-) e come proprietario l'utente stesso. Copiatela in ~/.ssh (la cartella .ssh nella home dell'utente), e assicuratevi che la stessa cartella .ssh abbia permessi 700 (rwx——).

La chiave pubblica, invece, mandatela sul server in qualche modo. Io ho attivato SFTP, quindi mi basta un

scp chiave-ssh.pub utenteremoto@serverremoto:~/

Ora collegatevi al serverremoto, e aggiungete questa chiave al portachiavi, che si chiama authorized_keys e si trova, sorpresa sorpresa, nella directory .ssh

cat chiave-ssh.pub >>.ssh/authorized_keys

Poi potete cancellare il file con la chiave pubblica, tanto lo avete appena accodato al portachiavi (attenzione a non fare il redirect con un solo >, altrimenti cancellerete eventuali altre chiavi pubbliche conservate lì dentro).

Assicuratevi che anche questo file (authorized_keys) abbia permessi 600.

Abbiamo concluso la fase preparatoria, ora potrete usare la chiave pubblica sia per loggarvi su quel server via ssh, sia per fare SFTP, sia con rsync. Per esempio, per collegarvi:

ssh -i .ssh/chiave-ssh utenteremoto@serverremoto

Mentre per usare rsync dovrete ricordare di racchiudere la linea di comando di ssh tra virgolette:

rsync -e "ssh -i .ssh/chiave-ssh" utenteremoto@serverremoto:/dir/da/copiare /dir/locale/

Una piccola dritta

Il sistema descritto sopra è ottimo per tenere le chiavi separate tra diversi server. In pratica potete avere una coppia di chiavi (pubblica e privata) per ogni server al quale dovete collegarvi.

Ma potete anche semplificare il processo e usare la stessa coppia di chiavi per tutti i server. In questo caso generate le chiavi e memorizzate la parte pubblica su tutti i server come ho scritto sopra. In locale, invece, copiate la chiave privata nella directory .ssh ma chiamatela “id_dsa” (per le chiavi DSA) o “id_rsa” (per le chiavi RSA):

cp chiave-ssh .ssh/id_dsa

Assicuratevi sempre che abbia permessi 600.

Così facendo non sarà più necessario specificare la parte “-i nomechiaveprivata”, perché ssh se la andrà a cercare direttamente.

Possibili problemi

Ricordate che se perdete la chiave privata dovrete entrare col solito sistema a password, ma se qualcuno ve la ruba potrà entrare su tutti i server che la utilizzano senza bisogno di altre autorizzazioni! In questo caso conviene fare immediatamente il giro di tutti i server e rimuovere la chiave pubblica dal file authorized_keys, e quindi rigenerare una nuova coppia di chiavi (sono sempre diverse).

Se il login automatico non funziona, verificate sul server che non siano disabilitati i login con chiave pubblica (di solito nel file /etc/ssh/sshd_config):

RSAAuthentication     yes
PubkeyAuthentication  yes
AuthorizedKeysFile    .ssh/authorized_keys

Consiglio di usare l'autenticazione DSA, e possibilmente di disabilitare il protocollo SSH1 e lasciare attivo solo SSH2, molto più sicuro.

Se ancora non funziona niente, aumentate il logging di ssh sul server tramite il parametro LogLevel (potete impostarlo a DEBUG per avere molto output, o a DEBUG3 per averne anche troppo).