Jak nastavit "chrooted" SFTP s OpenSSH a SELinuxem ve Fedoře 16.
Základní požadavky
Pro dále popisované řešení je potřeba aktualizovaná Fedora 16 nebo novější, nainstalovaný balík openssh-server ve verzi alespoň openssh-5.8p2-24.fc16 a zapnutý SELinux.
Nastavení openssh serveru
Abychom neomezili všechny uživatele, ale jen vybranou skupinu, vytvoříme skupinu sftponly s tím, že každý uživatel patřící do této skupiny bude omezen jen na sftp:
server# groupadd sftponly
V konfiguračním souboru /etc/ssh/sshd_config přidáme následující řádky:
Match Group sftponly ForceCommand internal-sftp ChrootDirectory %h
Nebo-li pokud je uživatel ve skupine sftponly, pak vynuť internal-sftp a změň pro něj kořenový adresář do jeho domovského adresáře. Na závěr proveďte restart serveru:
server# systemctl restart sshd.service
Nastavení uživatele
server# useradd -M -g sftponly sftponlyuser
Tímto příkazem vytvořím nového uživatele "sftponlyuser" s nastavenou hlavní skupinou "sftponly" a domovským adresářem /home/sftponlyuser, který ale nebude vytvořen. Tento adresář bude použit jako kořenový, musí ho vlastnit uživatel root a nesmí být zapisovatelný pro nikoho jiného. Proto v něm vytvoříme podadresář upload, který bude určen pro data uživatele.
server# mkdir -p /home/sftponlyuser/upload server# chown sftponlyuser: /home/sftponlyuser/upload server# restorecon -R -v /home/sftponlyuser restorecon reset /home/sftponlyuser context unconfined_u:object_r:home_root_t:s0->unconfined_u:object_r:user_home_dir_t:s0 restorecon reset /home/sftponlyuser/upload context unconfined_u:object_r:home_root_t:s0->unconfined_u:object_r:user_home_t:s0
Teď už se uživatel může zkusit připojit:
client$ sftp sftponlyuser@f16-openssh Connecting to f16-openssh... sftponlyuser@f16-openssh's password: password sftp> ls upload sftp> cd upload sftp>
Vypadá to dobře, ale...
SELinux
sftp> put myfile.txt Uploading myfile.txt to /upload/myfile.txt Couldn't get handle: Permission denied
To je způsobeno tím, že všechny ssh/sftp procesy se změněným kořenovým adresářem běží v SELinuxovém kontextu chroot_user_t:
system_u:system_r:chroot_user_t:s0-s0:c0.c1023 \_ sshd: sftponlyuser@notty system_u:system_r:chroot_user_t:s0-s0:c0.c1023 \_ sshd: sftponlyuser@internal-sftp
A tento typ nemá v základní konfiguraci právo na zápis do souborů s typem user_home_t:
type=AVC msg=audit(1328793486.912:654): avc: denied { write } for pid=12722 comm="sshd" name="upload" dev=vda3 ino=971 scontext=system_u:system_r:chroot_user_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:user_home_t:s0 tclass=dir
Tato operace se povolí nastavením SELinuxové proměnné ssh_chroot_rw_homedirs:
server# setsebool -P ssh_chroot_rw_homedirs on sftp> put myfile.txt Uploading myfile.txt to /upload/myfile.txt myfile.txt 100% 29 0.0KB/s 00:00
Výhoda chroot_user_t je hlavně v tom, že tento typ nemůže číst jiné typy než ty, které jsou určeny pro domovské adresáře. Takže pokud by se stalo, že v rámci chyby v openssh se uživatel dostane mimo svůj domovský adresář, nebude schopný si prečíst žádný soubor:
server# echo 'secret data' > ~sftponlyuser/upload/secret_file.txt server# chcon -t admin_home_t ~sftponlyuser/upload/secret_file.txt server# cp /etc/passwd /home/sftponlyuser/upload server# chcon -t etc_t /home/sftponlyuser/upload/passwd sftp> ls myfile.txt sftp> get secret_file.txt Couldn't stat remote file: Permission denied File "/upload/secret_file.txt" not found. sftp> get passwd Couldn't stat remote file: Permission denied File "/upload/passwd" not found.
Vidíme, že nové soubory nevidíme. Ale stačí přepnout do permissive modu a soubory začnou být viditelné:
server# setenforce 0 sftp> ls myfile.txt passwd secret_file.txt sftp> get secret_file.txt Fetching /upload/secret_file.txt to secret_file.txt /upload/secret_file.txt 100% 12 0.0KB/s 00:00