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).