VSFTPD
Virtuální uživatelé
Podpora virtuálních uživatelů je v serveru VSFTPD realizována za pomoci
PAM (Pluggable Authentication Modules) modulů. Jména virtuálních uživatelů a
jejich hesla lze ukládat buď do textových souborů podobných
.htaccess
souborům serveru Apache (PAM modul pam_pwdfile) nebo do některé
z relačních databází (Berkeley DB, MySQL, PostgreSQL, ...). Virtuální
uživatelé jsou vždy mapováni na jednoho systémového uživatele.
pam_pwdfile
Modul pam_pwdfile využívá pro ukládání virtuálních uživatelů a jejich hesel stejný formát souboru
jako server Apache (.htaccess
, .htpasswd
).
Výhodou tohoto řešení je snadná správa souboru s virtuálními uživateli a hesly (při malém počtu těchto uživatelů) a možnost sdílet tyto uživatele s uživateli Apache. Formát tohoto souboru je následující:
username:password_crypt
Pro někoho může být jednou z nevýhod tohoto řešení to, že modul pam_pwdfile není standardní součástí distribuce CentOS a nenalezl jsem jej ani v žádném z neoficiálních repozitářů pro CentOS.
Zdrojový balíček pro modul pam_pwdfile však lze stáhnout například z těchto stránek: http://www.invoca.ch/pub/packages/pam_pwdfile/.
Při základní znalosti vytváření binárních balíčků z balíčků zdrojových nebo po přečtení článku o Buildování RPM balíčků asi nebude pro nikoho problém si případně upravit SPEC soubor a daný binární RPM balíček si vytvořit.
Jak jsem již předeslal výše, virtuální uživatelé musí být mapováni přes
nějakého konkrétního systémového uživatele, který nemusí mít validní shell.
Tohoto uživatele si založím následujícím způsobem (více informací
o jednotlivých volbách příkazu useradd
se dozvíte
v článku, který se týká
příkazů pro správu uživatelských účtů):
useradd virtualftp -m -c "Virtual FTP user" -d /data/virtualftp -s /sbin/nologin
Defaultně je v konfiguračním souboru /etc/vsftpd/vsftpd.conf
nastavena volba pam_service_name=vsftpd
, tzn. při autentizaci
se budou využívat direktivy definované v PAM souboru, který leží
v /etc/pam.d/vsftpd
. Tento
soubor musíme upravit pro naše potřeby virtuálních uživatelů. Buď budeme
upravovat stávající soubor /etc/pam.d/vsftpd
nebo si jej
pomocí direktivy pam_service_name
předefinujeme na jiný
a ten si vytvoříme. Já zvolím třeba druhou variantu a vytvořím si nový soubor
/etc/pam.d/ftp
a v souboru
/etc/vsftpd/vsftpd.conf
si nastavím direktivu
pam_service_name=ftp
.
Obsah souboru /etc/pam.d/ftp
bude vypadat následovně:
auth required pam_pwdfile.so pwdfile /etc/vsftpd/passwd account required pam_permit.so
Pro autentizaci uživatelů použijeme modul pam_pwdfile a ten bude uživatelské
účty hledat v souboru /etc/vsftpd/passwd
. Prostředek
account
, který slouží například k dočasnému zablokování účtů
není dostupný z modulu pam_pwdfile, tak jej nadefinujeme pomocí
modulu pam_permit, který vždy vrací PAM_SUCCESS
.
Teď si již můžeme do souboru /etc/vsftpd/passwd
nadefinovat
nějaké virtuální uživatele. S výhodou můžeme použít program
htpasswd
(při prvním spuštění s parametrem -c
, aby
nám vytvořil soubor s účty), který je distribuován společně se serverem Apache.
htpasswd -c /etc/vsftpd/passwd tachec htpasswd /etc/vsftpd/passwd ondra
Pozor, pokud budeme chtít hesla šifrovat pomocí MD5, tak jsem zjistil, že modul pam_pwdfile neakceptuje Apache variantu MD5, takže pak je zapotřebí využít jiný program než htpasswd
, např. openssl
(openssl passwd -1 tachec
).
Nezapomeneme na bezpečně nastavená práva na souboru s hesly:
chmod 600 /etc/vsftpd/passwd
Zbývá nám poslední krok konfigurace a tím je nadefinování virtuálních
uživatelů v konfiguračním souboru serveru VSFTPD, tedy v souboru
/etc/vsftpd/vsftpd.conf
:
anonymous_enable=NO local_enable=YES guest_enable=YES guest_username=virtualftp chroot_local_user=YES pam_service_name=ftp local_root=/data/virtualftp/$USER user_sub_token=$USER
Volbou anonymous_enable=NO
jsem vypnul podporu anonymních
uživatelů a volbou local_enable=YES
jsem zapnul podporu
lokálních uživatelů, protože ta musí být v případě konfigurace virtuálních
uživatelů povolena.
Volba guest_enable=YES
mapuje všechna neanonymní přihlášení
na "guest" přihlášení, kde jsem "guest" přihlášení pomocí direktivy
guest_username=virtualftp
namapoval na dříve vytvořeného
systémového uživatele virtualftp
.
Volbou chroot_local_user=YES
jsem virtuální uživatele
omezil pouze na pohyb v jejich adresáři a zamezil jim v pohybu
po jiných (např. systémových) adresářích.
Volba local_root=/data/virtualftp/$USER
definuje, kde
budou ležet adresáře virtuálních uživatelů. Pozor, tyto adresáře
je zapotřebí pro každého virtuálního uživatele ručně vytvořit a přiřadit
jim příslušného vlastníka (v mém případě virtualftp
)
a příslušná práva. Pokud některému virtuálnímu uživateli zapomeneme
tento adresář vytvořit, tak pokus o přihlášení tohoto uživatele skončí
s následující chybou:
500 OOPS: cannot change directory:/data/virtualftp/ondra
Adresář pro daného virtuálního uživatele vytvoříme například takto:
mkdir /data/virtualftp/ondra chown virtualftp:virtualftp /data/virtualftp/ondra chmod 750 /data/virtualftp/ondra
Poslední volba user_sub_token=$USER
slouží k nahrazení
proměnné $USER
za daného konkrétního virtuálního uživatele
pod kterým se přihlašujeme, což je například využito při generování cest
domovských adresářů, viz volba
local_root=/data/virtualftp/$USER
. Bez této
volby by pokus o přihlášení na FTP server skončil s touto chybou:
500 OOPS: cannot change directory:/data/virtualftp/$USER
Pokud chceme virtuálním uživatelům povolit zápis do jejich adresáře,
tak povolíme volbu write_enable=YES
a anon_upload_enable=YES
a případně přenastavíme masku
nově vytvářených adresářů a souborů: anon_umask=0022
.
Vytváření adresářů povolíme pomocí volby
anon_mkdir_write_enable=YES
. Mazání souborů a adresářů můžeme
povolit pomocí volby anon_other_write_enable=YES
.
pam_userdb
Tento PAM modul slouží k autentizování uživatelů a hesel uložených v
Berkeley databázi a je standardní součástí balíčku pam.
Knihovny Berkeley databáze nalezneme v balíčku db4
a nástroje pro její správu v balíčku db4-utils
. Tyto balíčky
jsou obvykle součástí systému, takže je pravděpodobně nebude
potřeba instalovat.
Nejprve si vytvoříme klasický textový soubor do kterého uložíme uživatelská
jména a hesla. Textovým editorem vytvořím soubor, např. s názvem
db.txt
s tímto obsahem:
tachec dsjkJHDS83 ondra OfdjIUJeqrei6
Liché řádky v souboru obsahují uživatelská jména a sudé řádky potom jejich
hesla, takže uživatel tachec
má heslo dsjkJHDS83
a uživatel ondra
má heslo OfdjIUJeqrei6
.
Z výše uvedeného souboru vytvoříme databázi pomocí následujícího příkazu:
db_load -T -t hash -f db.txt /etc/vsftpd/passwd.db
Hesla v tomto souboru nejsou nijak zašifrována, tak nesmíme zapomenout na nastavení přístupových práv tak, aby tento soubor mohl číst pouze uživatel root.
chmod 600 /etc/vsftpd/passwd.db
Dalším krokem bude vytvoření PAM souboru díky kterému bude zajištěna
autentizace uživatele. Využijeme PAM modul pam_userdb, který bude číst data
o uživatelích (jméno a heslo) z námi dříve vytvořeného DB souboru
/etc/vsftpd/passwd.db
. Konfiguraci uložím do souboru
/etc/pam.d/ftp
a v souboru /etc/vsftpd/vsftpd.conf
si nastavím direktivu pam_service_name=ftp
. Obsah souboru
/etc/pam.d/ftp
bude vypadat následovně:
auth required /lib/security/pam_userdb.so db=/etc/vsftpd/passwd account required /lib/security/pam_userdb.so db=/etc/vsftpd/passwd
Stejně jako v předchozí konfiguraci (modul pam_pwdfile), tak i při použití modulu pam_userdb jsou virtuální uživatelé mapováni na systémového uživatele. Tzn. pokud tohoto uživatele ještě nemáme vytvořeného, tak jej vytvoříme následujícím příkazem:
useradd virtualftp -m -c "Virtual FTP user" -d /data/virtualftp -s /sbin/nologin
Ve finále zbývá už jen upravit konfigurační soubor VSFTPD démona /etc/vsftpd/vsftpd.conf
. Abych se s konfigurací pořád neopakoval, tak tentokrát
nebudu vytvářet pro každého uživatele jeho vlastní adresář ve kterém bude
uzavřen (chrootován), ale vytvořím jeden společný adresář
(/data/virtualftp
) pro všechny virtuální uživatele pouze
s podporou čtení.
anonymous_enable=NO local_enable=YES guest_enable=YES guest_username=virtualftp chroot_local_user=YES pam_service_name=ftp write_enable=NO anon_upload_enable=NO anon_mkdir_write_enable=NO anon_other_write_enable=NO