Każdy administrator ma swoje zdanie na temat przechowywania użytkowników w bazie danych. Jedni będą twierdzić, że to bardzo głupi pomysł, ponieważ wprowadzamy dodatkową warstwę pomiędzy klientem a serwerem, natomiast drudzy zobaczą w tym wygodę i automatyzację. Wyobraźmy sobie taką sytuację, nasi klienci czy znajomi posiadają na naszym serwerze konta WWW, my im podpieliśmy domenę, założyliśmy konto shell, uruchomiliśmy serwer FTPd i podaliśmy im namiary. Każdy korzysta z konta na swój sposób, ale przychodzi moment, kiedy ktoś musi zmienić hasło… dzwoni więc do nas i prosi o zmianę hasła, my logujemy się, wpisujemy passwd $user i wszystko jest fajnie. Kolejnego dnia dzwoni ktoś inny i mówi, że wygasła mu domena, a nie chciał jej przedłużać bo udało mu się zarejestrować inną i prosi nas o zmianę wpisów w serwerze DNS, znów logujemy się na serwer i edytujemy pliki named’a… Wytrzymamy to, jeśli takich telefonów nie będzie 10 dziennie. Administratorzy to leniwy naród ;-) i automatyzują/upraszczają wszystko co się da. Tak naprawdę idealnym rozwiązaniem tej sytuacji jest posiadania centralnej bazy danych użytkowników/klientów/znajomych, w której będą umieszczone zarówno domeny, hasła i wszystko inne co może nam się przydać w przyszłości. Spróbujmy więc na początek uruchomić serwer FTPd działający w oparciu o autoryzację użytkowników bezpośrednio z bazy danych MySQL.
Osobiście preferuję do prostszych zastosowań serwer vsftpd, posiada wszystko co jest mi niezbędne, wsparcie SSL/TLS, chroot, umask, dodatkowo wykorzystam bazę danych MySQL, chyba najbardziej popularną wśród darmowych rozwiązań.
Instalacja VSFTPd (Ubuntu)
root@iDev:/home/jamzed# apt-get install vsftpd libpam-mysql mysql-server mysql-client
Czytanie list pakietów… Gotowe
Budowanie drzewa zależności
Odczyt informacji o stanie… Gotowe
Zostaną zainstalowane następujące dodatkowe pakiety:
libdbd-mysql-perl libdbi-perl libhtml-template-perl libmysqlclient15off libmysqlclient16 libnet-daemon-perl libplrpc-perl mysql-client-5.1 mysql-common
mysql-server-5.1 mysql-server-core-5.1 ssl-cert update-inetd
Sugerowane pakiety:
dbishell libipc-sharedcache-perl tinyca mailx
Zostaną zainstalowane następujące NOWE pakiety:
libdbd-mysql-perl libdbi-perl libhtml-template-perl libmysqlclient15off libmysqlclient16 libnet-daemon-perl libpam-mysql libplrpc-perl mysql-client
mysql-client-5.1 mysql-common mysql-server mysql-server-5.1 mysql-server-core-5.1 ssl-cert update-inetd vsftpd
0 aktualizowanych, 17 nowo instalowanych, 0 usuwanych i 25 nieaktualizowanych.
Konieczne pobranie 24,5MB archiwów.
Po tej operacji zostanie dodatkowo użyte 58,2MB miejsca na dysku.
Prawdopodobnie zostaniemy poproszeni o ustawienie hasła do serwera MySQL (o ile nie był już zainstalowany).
Po instalacji niezbędnych pakietów możemy zalogować się do bazy danych i stworzyć bazę naszych użytkowników.
root@iDev:/home/jamzed# mysql -u root -p
Hasło podajemy te, które było ustawione przed chwilą.
Tworzymy strukturę bazy danych:
CREATE DATABASE vsftpd;
GRANT ALL PRIVILEGES ON vsftpd.* TO ‘vsftpd’@'localhost’ IDENTIFIED BY ‘ftpdpass’;
USE vsftpd;
CREATE TABLE `tb_users` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`login` VARCHAR (25) NOT NULL ,
`password` VARCHAR (41) NOT NULL ,
UNIQUE ( `login` )
) ;
Powinniśmy już mieć stworzoną zarówno bazę danych vsftpd jak i założoną strukturę tabeli tb_users. Następny krok to przygotowanie serwera vsftpd tak by poprawnie współpracował z bazą danych, serwer ten sam w sobie nie potrafi obsługiwać bazy danych MySQL, ale mamy PAM’a (jest to zestaw bibliotek, które umożliwiają korzystanie z różnych metod autoryzacji w programach), którego własnie wykorzystamy.
Konfiguracja serwera vsftpd znajduje się w pliku: /etc/vsftpd.conf, zróbmy jego kopię i stwórzmy nową własną konfigurację:
root@iDev:/home/jamzed# mv /etc/vsftpd.conf /etc/vsftpd.conf.orig
root@iDev:/home/jamzed# vi /etc/vsftpd.conf
Minimalna konfiguracja naszego serwera:
listen=YES
anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
dirmessage_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
nopriv_user=ftp
chroot_local_user=YES
pam_service_name=vsftpd
guest_enable=YES
guest_username=vsftpd
local_root=/home/vsftpd/$USER
user_sub_token=$USER
virtual_use_local_privs=YES
- listen = YES – oznacza, że nasz serwer będzie działał jako standalone, jeśli damy NO, serwer uruchomi się dopiero jako daemon z inetd/xinetd
- anonymous_enable = NO – wyłączamy dostęp użytkownikowi anonymous
- local_enable = YES – zezwalamy na logowanie się lokalnych użytkowników (passwd)
- write_enable = YES – zezwalamy na zapis, serwer może przyjmować pliki
- local_umask = 022 – po załadowaniu pliku ustawiane będą uprawnienia 755
- dirmessage_enable = YES = włączamy powitanie użytkowników (plik podawany określamy poprzez message_file)
- xferlog_enable = YES – włączamy format logowania wu-ftpd
- connect_from_port_20 = YES – włączamy połączenia aktywne
- nopriv_user = ftp – nazwa użytkownika używanego przez vsftpd w momencie kiedy chce zrzucić uprawnienia
- chroot_local_user = YES – chrootuj użytkowników lokalnych (użytkownik nie wyjdzie wyżej do katalogu niż jego HOME)
- pam_service_name = vsftpd – nazwa usługi podczas autoryzacji pam.d (/etc/pam.d/vsftpd)
- guest_enable = YES – włączamy konto gościa
- guest_username = vsftpd – będzie nim użytkownik vsftpd
- local_root = /home/vsftpd/$USER – określamy katalog do którego vsftpd będzie robił chdir()
- user_sub_token = $USER – chrootujemy użytkowników do ich katalogów (przydatne dla wirtualnych użytkowników)
- virtual_use_local_privs = YES – włączamy identyczne traktowanie użytkowników wirtualnych jak i lokalnych
Przejdźmy teraz do konfiguracji pam.d:
root@iDev:/home/jamzed# mv /etc/pam.d/vsftpd /etc/pam.d/vsftpd.orig
root@iDev:/home/jamzed# vi /etc/pam.d/vsftpdMinimalna zawartość pam.d/vsftpd:
auth required pam_mysql.so user=vsftpd passwd=ftpdpass host=localhost db=vsftpd table=tb_users usercolumn=login passwdcolumn=password crypt=2
account required pam_mysql.so user=vsftpd passwd=ftpdpass host=localhost db=vsftpd table=tb_users usercolumn=login passwdcolumn=password crypt=2
Pozostaje dodanie użytkownika vsftpd:
# useradd -d /home/vsftpd -g nogroup -m -s /bin/false vsftpd
Po tych zmianach, możemy wystartować/zrestartować nasz serwer vsftpd:
root@iDev:/home/jamzed# /etc/init.d/vsftpd restart
Przed założeniem użytkownika w bazie załóżmy strukturę katalogów na filesystemie i ustawmy uprawnienia:
root@iDev:/home/jamzed# mkdir /home/vsftpd
root@iDev:/home/jamzed# mkdir /home/vsftpd/jamzed
root@iDev:/home/jamzed# chown -R vsftpd:nogroup /home/vsftpd/
Teraz możemy już założyć użytkownika w bazie:
root@iDev:/home/jamzed# mysql -uvsftpd -pftpdpass vsftpd
mysql> INSERT INTO tb_users VALUES(”,’jamzed’,PASSWORD(‘eftep’));dla sprawdzenia wykonajmy:
mysql> select * from tb_users;
+—-+——–+——————————————-+
| id | login | password |
+—-+——–+——————————————-+
| 1 | jamzed | *483A665E1F29FE18A8DD3C658F812A9FC13C1104 |
+—-+——–+——————————————-+
1 row in set (0,00 sec)
Pozostaje generalny test, czyli zalogowanie się:
jamzed@makufka:~$ ncftp -ujamzed 192.168.1.194
NcFTP 3.2.2 (Sep 04, 2008) by Mike Gleason (http://www.NcFTP.com/contact/).
Connecting to 192.168.1.194…
(vsFTPd 2.2.0)
Logging in…
Password requested by 192.168.1.194 for user „jamzed”.Please specify the password.
Password: *****
Login successful.
Logged in to 192.168.1.194.
ncftp / > ls -la
drwxr-xr-x 2 105 114 4096 Mar 02 20:15 .
drwxr-xr-x 2 105 114 4096 Mar 02 20:15 ..
ncftp / >
Wszystko poszło bez problemów, nasz serwer FTPd współpracuje z bazą danych, pozostaje już tylko stworzyć formatkę do zmiany haseł i problem z telefonami znika.
PS. Dziękuję Rafałowi ‘gwn‘ za zgłoszenie błędu w konfiguracji (brak użytkownika vsftpd w systemie oraz włączenie konta gościa).





[...] pisałem o spięciu vsftpd wraz z MySQL’em, kolejnym etapem ułatwiania sobie życie może być spięcie naszego serwera WWW z bazą danych, [...]
[...] systemu autentykacji poprzez przechowywanie użytkowników w bazie danych potrafi bardzo uprościć zarządzanie dostępem. Pierwsza konfiguracja wymaga stworzenia bazy [...]
Jak wygląda kwestia Quoty w takim rozwiązaniu?
Nie miałem nigdy potrzeby użycia vsftpd + mysql + quota, ale domyślam się, że quota nie działa, ponieważ system nie wie nic o tych użytkownikach.