Czy można pobierać dane o użytkownikach systemu z bazy danych, np. MySQL? Oczywiście!
Instalacja potrzebnych plików
W przypadku Debiania należy zainstalować następujący pakiet: libnss-mysql
apt-get install libnss-mysql
Struktura tabel obsługujących zapytania
Strukture potrzebnych tabel znajdziesz w pliku examples.sql w katalogu /usr/share/doc/libnss-mysql/examples. Dokumentacja ta jest instalowana razem z pakietem libnss-mysql.
Ogólnie sprawę ujmując potrzebujesz 3 tabel, które przechowują informację o użytkownikach, grupach oraz powiązaniach między grupami i użytkownikami.
mysql> desc user; +---------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +---------------+--------------+------+-----+---------+----------------+ | user_id | int(11) | | PRI | NULL | auto_increment | | user_name | varchar(50) | | | | | | realname | varchar(120) | | | | | | shell | varchar(20) | | | /bin/sh | | | password | varchar(40) | | | | | | status | char(1) | | | N | | | uid | int(11) | | | 65534 | | | gid | int(11) | | | 65534 | | | homedir | varchar(32) | | | /bin/sh | | | owner | int(11) | | | 0 | | | lastchange | varchar(50) | YES | | NULL | | | min | int(11) | YES | | 0 | | | max | int(11) | YES | | 0 | | | warn | int(11) | YES | | 7 | | | inact | int(11) | YES | | -1 | | | expire | int(11) | YES | | -1 | | +---------------+--------------+------+-----+---------+----------------+ mysql> desc user_group; +----------+---------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +----------+---------+------+-----+---------+-------+ | user_id | int(11) | | | 0 | | | group_id | int(11) | | | 0 | | +----------+---------+------+-----+---------+-------+ 2 rows in set (0.01 sec) mysql> desc groups; +----------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------------+--------------+------+-----+---------+----------------+ | group_id | int(11) | | PRI | NULL | auto_increment | | group_name | varchar(30) | | | | | | status | char(1) | YES | | A | | | group_password | varchar(64) | | | x | | | gid | int(11) | | | 0 | | | members | varchar(255) | YES | | NULL | | +----------------+--------------+------+-----+---------+----------------+ 6 rows in set (0.00 sec)
Kod tworzący te tabele można pobrać stąd.
Modyfikacja plików konfiguracyjnych Linuksa
cat /etc/nss-mysql.conf | grep -v "#" conf.version = 2; users.host = inet:localhost:3306; users.database = webadmin; users.db_user = root; users.db_password = tygrysekdupa; users.backup_host = users.table = user; users.where_clause = user.status = 'A'; users.user_column = user.user_name; users.password_column = user.password; users.userid_column = user.user_id; users.uid_column = user.uid; users.gid_column = user.gid; users.realname_column = user.realname; users.homedir_column = user.homedir; users.shell_column = user.shell; groups.group_info_table = groups; groups.where_clause = groups.status = 'A'; groups.group_name_column = groups.group_name; groups.groupid_column = groups.group_id; groups.gid_column = groups.gid; groups.password_column = groups.group_password; groups.members_table = user_group; groups.member_userid_column = user_group.user_id; groups.member_groupid_column = user_group.group_id;
cat /etc/nss-mysql-root.conf | grep -v "#" conf.version = 2; shadow.host = inet:localhost:3306; shadow.database = webadmin; shadow.db_user = root; shadow.db_password = tygrysekdupa; shadow.table = user; shadow.where_clause = user.status = 'A'; shadow.userid_column = user.user_id; shadow.user_column = user.user_name; shadow.password_column = user.password; shadow.lastchange_column = user.lastchange; shadow.min_column = user.min; shadow.max_column = user.max; shadow.warn_column = user.warn; shadow.inact_column = user.inact; shadow.expire_column = user.expire;
Poinformowanie systemu by korzystał z informacji zawartych również w bazie danych
cat /etc/nsswitch.conf # /etc/nsswitch.conf # # Example configuration of GNU Name Service Switch functionality. # If you have the `glibc-doc' and `info' packages installed, try: # `info libc "Name Service Switch"' for information about this file. passwd: compat mysql group: compat mysql shadow: compat mysql hosts: files dns networks: files protocols: db files services: db files ethers: db files rpc: db files netgroup: nis
Zauważmy, że taka konfiguracja pozwala najpierw wyszukać informacje o użytkownikach w plikach systemowych a później dopiero (jeżeli tam nie znajdzie informacji) w bazie danych. Umożliwia to dodanianie systemowych użytkowników przez system pakietów bez potrzeby ręcznego modyfikowania informacji o użytkownikach w bazie danych (o ile nie wymagają oni logowania do systemu 😉 ).
Sprawdzenie poprawności konfiguracji
Sprawdzenie poprawności konfiguracji możemy wykonać wydając polecenie id nazwa_uzytkownika_w_bazie:
debian:/usr/share/doc# debian:/etc# id kjozwiak uid=1119(kjozwiak) gid=100(users) groups=100(users)
W przypadku logowania zapytań do bazy danych w pliku logów pojawi się wpis świadczący o wykonaniu operacji na bazie danych:
44 Query select groups.group_name,groups.gid,groups.group_password, user.user_name from groups LEFT JOIN user_group on groups.group_id=user_group.group_id LEFT JOIN user on user_group.user_id=user.user_id and user.status = 'A' where 1 = 1 and groups.status = 'A'
Bezpieczeństwo rozwiązania
Podstawowym problemem jest bezpieczeństwo bazy danych, w której przechowywane są dane o użytkownikach, jest to jednak bardziej problem bezpieczeństwa MySQLa. Inna sprawa to fakt, iż hasła dostępowe do bazy danych są w plikach konfiguracyjnych podane w sposób niezakodowany, należy więc ograniczyć dostęp do nich tylko do superużytkownika:
chmod 600 /etc/nss-mysql-root.conf chmod 600 /etc/nss-mysql.conf
Hasła w bazie danych są zaszyfrowane więc nie ma obawy co do szybkiego ich wykorzystania nawet gdy hasła zostaną wykradzione.