SSH in CHROOT: la soluzione nativa

Nei precedenti articoli pubblicati nella serie “SSH in CHROOT: Una gabbia per la shell sicura” parte 1 e parte 2, veniva affrontato il tema della messa in sicurezza di SSH attraverso una Patch che obbligava determinati utenti a rimanere chiusi all’interno di una gabbia virtuale. Dalla versione 5 di SSH però è possibile sfruttare un…

openssh

Nei precedenti articoli pubblicati nella serie “SSH in CHROOT: Una gabbia per la shell sicura” parte 1 e parte 2, veniva affrontato il tema della messa in sicurezza di SSH attraverso una Patch che obbligava determinati utenti a rimanere chiusi all’interno di una gabbia virtuale.
Dalla versione 5 di SSH però è possibile sfruttare un meccanismo nativo che implementa il CHROOT. Ecco spiegato come.

Capire la versione di SSH installata nel sistema

Prima di procedere con la configurazione del pacchetto è bene accertarsi che la versione di SSH installata nel sistema sia uguale o superiore alla 4.8p1, su sistemi Debian e derivati, l’interrogazione è possibile attraverso il seguente comando:

# dpkg -l openssh-*
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Cfg-files/Unpacked/Failed-cfg/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Hold/Reinst-required/X=both-problems (Status,Err: uppercase=bad)
||/ Nome                                    Versione                                Descrizione
+++-=======================================-=======================================-==============================================================================================
ii  openssh-blacklist                       0.4.1                                   list of default blacklisted OpenSSH RSA and DSA keys
ii  openssh-blacklist-extra                 0.4.1                                   list of non-default blacklisted OpenSSH RSA and DSA keys
ii  openssh-client                          1:5.1p1-5                               secure shell client, an rlogin/rsh/rcp replacement
ii  openssh-server                          1:5.1p1-5                               secure shell server, an rshd replacement

Mentre in sistemi RedHat e derivati è sufficiente interrogare l’elenco pacchetti installati con rpm:

$ rpm -qa openssh*
openssh-4.3p2-16.el5
openssh-askpass-4.3p2-16.el5
openssh-clients-4.3p2-16.el5
openssh-server-4.3p2-16.el5

Nei casi riportati, sul sistema Debian (versione Lenny) la versione di SSH supporta nativamente il Chroot mentre il sistema RedHat (versione 5) no. In questo caso è necessario eseguire l’aggiornamento del pacchetto se ne si vorrà sfruttare la nuova funzionalità, ricompilando localmente la versione 5 partendo dai sorgenti disponibili presso il sito ufficiale del progetto OpenSSH oppure scaricando un rpm precompilato da repository pubblici come http://www.rpmfind.net.

Come funziona il CHROOT nativo

Il metodo con cui il demone SSH, previa configurazione, costruisce la gabbia per l’utente che effettua la login può essere diviso in due tipologie: l’accesso diretto via ssh e quello via sftp.
Nel primo caso la directory nella quale l’utente effettuerà il login dovrà contenere la struttura essenziale di file e directory necessaria alla navigazione all’interno del sistema, mentre attraverso il funzionamento sftp il demone non necessiterà di un ambiente nativo, ma sfruttando il comando interno sftp, fornirà l’interfaccia di accesso al sistema.

Predisposizione del sistema

I test che verranno effettuati nel corso dell’articolo partiranno dal presupposto che esista un gruppo denominato test e che tutte le utenze facenti parte di questo gruppo vengano ingabbiate.
Verrà quindi creato un utente denominato test con cui verranno effettuate le prove:

$ adduser test

Il comando crea automaticamente il gruppo omonimo.
Terminata la creazione dell’utente di test è necessario creare la struttura relativa alla gabbia. Per far questo è possibile utilizzare lo script create_chroot_env.sh contenuto nel file ssh-in-chroot-scripts.tar presentato nella precedente serie di articoli.
Lanciando il comando come segue:

$ ./create_chroot_env.sh /chroot

nella cartella /chroot verrà creato un ambiente con tutti i requisiti imposti da ssh per l’implementazione della gabbia.
Requisito essenziale per il corretto funzionamento del sistema è che la cartella nella quale verrà impostata la gabbia sia accessibile in scrittura alla sola utenza di root. Avendo lanciato lo script come utente root (non sarebbe possibile altrimenti utilizzare il path definito) tale requisito è pienamente rispettato.

Configurazione del demone per l’utilizzo via ssh

A questo punto la configurazione del server ssh andrà variata per supportare il chroot esclusivamente per le utenze facenti parte del gruppo test attraverso l’aggiunta delle seguenti righe nel file /etc/ssh/sshd_config:

Match Group test
        ChrootDirectory /chroot/

terminata la modifica le configurazioni andranno ricaricate attraverso il seguente comando:

$ /etc/init.d/ssh reload

Verifica del funzionamento

Per verificare il funzionamento della gabbia è sufficiente effettuare il login nel sistema e controllare come e se sia possibile muoversi all’interno di questo:

$ ssh test@172.16.1.130
test@172.16.1.130's password: 
Linux anomalia 2.6.26-1-686 #1 SMP Fri Mar 13 18:08:45 UTC 2009 i686

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Tue Jun  9 23:09:39 2009 from 172.16.1.1
-bash-3.2$ pwd
/
-bash-3.2$ ls
bin  dev  etc  home  lib
-bash-3.2$ cd ..
-bash-3.2$ pwd
/
-bash-3.2$ ls
bin  dev  etc  home  lib

l’output illustrato conferma le aspettative: a login effettuato non è possibile scorrere il path precedente alla cartella /. La gabbia funziona.

Configurazione del demone per l’utilizzo via sftp

La configurazione impostata non prevede l’utilizzo di sftp, infatti un tentativo di connessione non andrebbe a buon fine:

$ sftp test@172.16.1.130
Connecting to 172.16.1.130...
test@172.16.1.130's password: 
subsystem request failed on channel 0
Couldn't read packet: Connection reset by peer

per fare in modo che questo tipo di connessione sia utilizzabile, è necessario modificare nuovamente /etc/ssh/sshd_config sostituendo la riga

Subsystem sftp /usr/lib/openssh/sftp-server

con

Subsystem sftp internal-sftp

In questo modo si indica ad ssh di utilizzare per il comando sftp non lo script locale /usr/lib/openssh/sftp-server ma la versione interna al demone.

Verifica del funzionamento

A questo punto dopo aver ricaricato il demone, è possibile provare nuovamente la login via sftp:

$ sftp test@172.16.1.130
Connecting to 172.16.1.130...
test@172.16.1.130's password: 
subsystem request failed on channel 0
Couldn't read packet: Connection reset by peer
rasca@anomalia:~$ sftp test@172.16.1.130
Connecting to 172.16.1.130...
test@172.16.1.130's password: 
sftp> ls
bin   dev   etc   home  lib   
sftp> cd ..
sftp> ls 
bin   dev   etc   home  lib   

Come da pronostico, il login ha avuto successo.
E’ da notare che in questo caso la directory di arrivo dell’utenza è sempre la / del chroot ma si può fare in modo che questa corrisponda ad una qualsiasi cartella o alla home dell’utente modificando il parametro ChrootDirectory nel file di configurazione di ssh. E’ consentito l’utilizzo delle diciture speciali %h, corrispondente alla homedir dell’utente, e %u, corrispondente al nome dell’utente.

        ChrootDirectory %h

E’ chiaro che ogni directory scelta dovrà possedere il requisito essenziale di essere di proprietà di root e non scrivibile da alcun gruppo.

Conclusioni

Rispetto alla soluzione presentata nei precedenti articoli, che comportava l’applicazione di una patch ai sorgenti di ssh, quanto illustrato ha l’indubbio vantaggio di sfruttare un’implementazione nativa che non necessita di operazioni sul pacchetto. Certo i requisiti richiesti, in particolare relativamente alla proprietà della cartella madre del chroot, sono piuttosto rigidi ed obbligano a riflettere su come distribuire le utenze.
La soluzione migliore, come sempre, è quella più funzionale allo scopo che ci si prefigge.

Da sempre appassionato del mondo open-source e di Linux nel 2009 ho fondato il portale Mia Mamma Usa Linux! per condividere articoli, notizie ed in generale tutto quello che riguarda il mondo del pinguino, con particolare attenzione alle tematiche di interoperabilità, HA e cloud.
E, sì, mia mamma usa Linux dal 2009.

Iscriviti
Notificami
guest
35 Comments
alessio

I miei complimenti!!! ho risolto l\’errore che ricevevo in sftp-chroot:

\"Request for subsystem \’sftp\’ failed on channel 0 chroot\"

siete dei grandi!!

in barba agli americani che mi dicevano, /./ non è lo standard nel passwd…ma vavava

Paolo Ponte

Ho utilizato lo script create_chroot_env.sh per una macchina acceduta dall’esterno ed utilizzata come gateway per raggiungere una rete interna. Tutto ok per il jail ma non sono riuscito ad esportare la grafica, neppure con il classico ssh -X. Quindi si accede ‘da fuori’, si e’ in una jail, ma non si usa la grafica (provato con xclock).

benjo

Ciao!
grazie 1000 per la guida! l’ho trovata fantastica!
ho solo un problema… ossia,
come abilitare eventuali altri comandi ??

-bash-3.2$ ps ux
-bash: ps: command not found
-bash-3.2$ top
-bash: top: command not found
-bash-3.2$ wget
-bash: wget: command not found
-bash-3.2$ rar
-bash: rar: command not found
-bash-3.2$ unrar
-bash: unrar: command not found
-bash-3.2$ chmod
-bash: chmod: command not found
-bash-3.2$ man
-bash: man: command not found

Grazie!

benjo

ok perfetto, ora ho un ultimo problema,
comandi tipo “top” o ancora più importante “ps”
non mi funzionano in nessun modo 🙁

-bash-3.2$ ps
Error, do this: mount -t proc none /proc

ricevo errori sul mount del proc 🙁
come posso risolvere??? :°

benjo

Ciao Raoul:)
beh, la mia idea era di permettere solo i comandi che volevo io (ls, chmod, mv, rm, ecc ecc) oltre alla gabbia per gli utenti, per non farli uscire dalla cartella che gli assegnavo.

io in pratica creo un ambiente chroot per ogni utente, ossia:

./create_chroot_env.sh /home/pippo

ma si può montare il proc per ogni utente?
o come potrei fare esattamente? scusa il disturbo ma è l’unica cosa che mi manca :s

benjo

Grazie 1000!! sei un grande!!
ha funzionato benissimo il secondo
mount -t proc proc /chroot/path/proc/
:):)

Tony

Ciao Raoul, prima di tutto grazie per il tuo sito, per la sua chiarezza. Io ti scrivo in quando non sono ancora riuscito a risolvere il mio problema che è il seguente: dovrei applicare chroot in ssh per gli utenti di un dominio windows 2000.

Ho seguito tutti i tuoi step, ma qualcosa non funziona a dovere.

Grazie mille

Tony

Ciao Raoul,
il mio linux è già integrato in un dominio windows, si tratta di un file server su cui ho scoperto qualche giorno fà che un paio di utenti, un pò svegli, hanno fatto accesso con putty su questa macchina con il loro account di rete.
Da qui è nata l’esigenza di settare il parametro chroot in openssh.

Grazie mille

Tony

Tony

Si per i log uso ubuntu 10.04 lts, ma in questo momento devo abilitare il “choordirectory” in ssh e sftp.

rossana

aiutatemi per favore:
eseguendo questo comando da una macchina linux ad una macchina remota
ssh -v pubblica@192.168.nn.nnn ‘( cd /export/home/flexsogeiV65/flex/ ; pwd )’ 2> /tmp/2.out, ssh restituisce una serie di righe di cui l’ultima è – debug1: Exit status 0.
Lo stesso comando eseguito da crontab con lo stesso resistuisce come output una serie di righe di cui l’ultima è – debug1: Exit status -1.
Facendo un diff dei file di output delle due esecuzioni ho queste differenze:
> debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
38,39d38
< debug1: fd 0 clearing O_NONBLOCK
< debug1: fd 1 clearing O_NONBLOCK
41c40
debug1: Transferred: stdin 0, stdout 0, stderr 0 bytes in 0.1 seconds
43c42
debug1: Exit status 0
Potete aiutarmi a capire perchè succede questo

Giuseppe

Grazie per la guida, ma ho un paio di problemi.
Uso una Red Hat Enterprise Linux Server release 5.2 (Tikanga)
quando ho lanciato il comando “./create_chroot_env.sh /chroot” mi ha dato il seguente errore
“cp: cannot stat `/bin/rbash’: No such file or directory
cp: cannot stat `/lib/libncurse*’: No such file or directory”

comunque sono andato avanti e quando tento di fare login con un utente inserito nel gruppo chroot putty mi si chiude immediatamente

giuseppe

ho corretto un’errore di digitazione sul file sshd_config
ora l’utente entra ma non va nella directory chroot, ma in quella normale
nei log ‘message’ e ‘secure’ non vedo nulla di anomalo
i permessi per la cartella chroot e le sotto cartelle sono 755 con proprietario root

giuseppe

ho fatto il copia e incolla di quello che è scritto nel tuo articolo e ho riavviato la macchina

giuseppe

il gruppo è test e nel /var/log/secure non ho nulla.
ho provato a installare un VM con centos 5.5 ma ho i medesimi problemi

giuseppe

si scusa vedo il login dell’utente, ma in messagge e non in secure
la versione di ssh usata è 5.1 qualcosa

questo è il log del message dopo il livello debug

Feb 17 18:13:00 localhost sshd[5079]: Set /proc/self/oom_adj to 0
Feb 17 18:13:00 localhost sshd[5079]: Connection from 172.20.1.8 port 54239
Feb 17 18:13:03 localhost sshd[5079]: Accepted password for test from 172.20.1.8 port 54239 ssh2
Feb 17 18:13:03 localhost sshd[5079]: User child is on pid 5081
Feb 17 18:13:05 localhost sshd[5081]: Received disconnect from 172.20.1.8: 11: disconnected by user
giuseppe

un po lungo ma è tutto sshd_config

#	$OpenBSD: sshd_config,v 1.73 2005/12/06 22:38:28 reyk Exp $

# This is the sshd server system-wide configuration file.  See
# sshd_config(5) for more information.

# This sshd was compiled with PATH=/usr/local/bin:/bin:/usr/bin

# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented.  Uncommented options change a
# default value.

#Port 22
#Protocol 2,1
Protocol 2
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::

# HostKey for protocol version 1
#HostKey /etc/ssh/ssh_host_key
# HostKeys for protocol version 2
#HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_dsa_key

# Lifetime and size of ephemeral version 1 server key
#KeyRegenerationInterval 1h
#ServerKeyBits 768

# Logging
# obsoletes QuietMode and FascistLogging
#SyslogFacility AUTH
SyslogFacility AUTHPRIV
LogLevel DEBUG

# Authentication:

#LoginGraceTime 2m
#PermitRootLogin yes
#StrictModes yes
#MaxAuthTries 6

#RSAAuthentication yes
#PubkeyAuthentication yes
#AuthorizedKeysFile	.ssh/authorized_keys

# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
#RhostsRSAAuthentication no
# similar for protocol version 2
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# RhostsRSAAuthentication and HostbasedAuthentication
#IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes

# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
#PermitEmptyPasswords no
PasswordAuthentication yes

# Change to no to disable s/key passwords
#ChallengeResponseAuthentication yes
ChallengeResponseAuthentication no

# Kerberos options
#KerberosAuthentication no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosGetAFSToken no

# GSSAPI options
#GSSAPIAuthentication no
GSSAPIAuthentication yes
#GSSAPICleanupCredentials yes
GSSAPICleanupCredentials yes

# Set this to 'yes' to enable PAM authentication, account processing, 
# and session processing. If this is enabled, PAM authentication will 
# be allowed through the ChallengeResponseAuthentication mechanism. 
# Depending on your PAM configuration, this may bypass the setting of 
# PasswordAuthentication, PermitEmptyPasswords, and 
# "PermitRootLogin without-password". If you just want the PAM account and 
# session checks to run without PAM authentication, then enable this but set 
# ChallengeResponseAuthentication=no
#UsePAM no
UsePAM yes

# Accept locale-related environment variables
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES 
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT 
AcceptEnv LC_IDENTIFICATION LC_ALL
#AllowTcpForwarding yes
#GatewayPorts no
#X11Forwarding no
X11Forwarding yes
#X11DisplayOffset 10
#X11UseLocalhost yes
#PrintMotd yes
#PrintLastLog yes
#TCPKeepAlive yes
#UseLogin no
#UsePrivilegeSeparation yes
#PermitUserEnvironment no
#Compression delayed
#ClientAliveInterval 0
#ClientAliveCountMax 3
#ShowPatchLevel no
#UseDNS yes
#PidFile /var/run/sshd.pid
#MaxStartups 10
#PermitTunnel no
#ChrootDirectory none

# no default banner path
#Banner /some/path

# override default of no subsystems
#Subsystem	sftp	/usr/libexec/openssh/sftp-server
Subsystem sftp internal-sftp

Match Group test
        ChrootDirectory /chroot/
antonio

Ciao, complimenti per l’articolo che mi ha aiutato tantissimo a creare la gabbia e a limitare il navigazione degli utenti in giro per il filesystem.
Ora però non riesco a far funzioanre i servizi scp ed sftp. O meglio: ogni volta che provo a copiare un file con scp o con sftp mi viene restituito il messaggio di errore “Permission denied”… hai dei suggerimenti?
Ho fatto tantissime prove ma non riesco a capire dove sta il problema.
Grazie
Ciao

Chalda

Grazie dell’articolo,
Una precisazione: in Debian occorre copiare anche la cartella /lib64, altrimenti da quest’errore nella fase di login:

/bin/sh: No such file or directory
Connection to x.x.x.x closed.