Pull to refresh

Аутентификация пользователей в Ubuntu с помощью PostgreSQL

Приветствую всё хабрасообщество!
Встала у меня как-то раз задача организовать авторизацию пользователей в Ubuntu по PostgreSQL-базе.
На просторах Интернета много информации по настройке авторизации через MySQL, а вот по PostgreSQL — информации крайне мало, и поэтому, кое-что пришлось адаптировать.
Не секрет, что Linux можно заставить авторизоваться через что угодно, хоть через фейсбук или вконтакт, и служат для этого модули авторизации PAM и NSS.
Рассмотрим на примере Ubuntu 10.04 как настроить такую авторизацию.


Итак — приступим.

1. Ставим PAM и NSS модули авторизации:
sudo apt-get install libpam-pgsql libnss-pgsql

2. Создаём таблицы в PostgreSQL, которые будут содержать наших пользователей и группы. Таблицы повторяют структуры системных файлов groups, passwd и shadow.

-- Группы
CREATE TABLE sysauth_groups
(
"name" character varying(128), -- Название группы
pass character varying(128), -- Пароль
gid integer, -- id группы
members character varying(512) -- члены группы
);

-- Пользователи
CREATE TABLE sysauth_passwd
(
"name" character varying(128), -- имя пользователя
pass character varying(128), -- Пароль (если используется система теневых паролей - должен содержать 'x'
gecos character varying(512), -- Информация о пользователе
home character varying(256), -- Домашняя директория
shell character varying(256), -- Оболочка
uid integer, -- ID пользователя
gid integer -- ID группы
)

-- Теневые пароли
CREATE TABLE sysauth_shadow
(
uid integer, -- id пользователя (в соответствии с таблицей passwd)
"name" character varying(128), -- имя пользователя
"password" character varying(128), -- пароль пользователя
last_changed integer, -- Дата последней смены пароля
min integer,
max integer,
warn integer,
inact integer,
expire integer, -- Срок истекания пароля
flag character varying(8)
);

3. Создадим тестового пользователя и группу. Пароль для тестового пользователя - 12345. Если не подойдёт - сгенерируйте его стандартным crypt'ом

insert into sysauth_groups(name, pass, gid, members) values ('test_group', 'x', 5000, '');
insert into sysauth_passwd(name, pass, gecos, home, shell, uid, gid) values ('test_user', 'x', ',,,,', '/home/test_user', '/bin/bash', 5000, 5000);
insert into sysauth_shadow(uid, name, password, last_changed, min, max, warn, inact, expire, flag) values (5000, 'test_user', '$6$P5jfk4Ufh33f$.Dc8H9jsWAl/igt4QPbYI/El28SyUEAoJPPHsLIGMKOymhC7AIaiizlW5W9hm7kU7PYMCySEhYtMqVPFsVTMK/', 14735, 0, 99999, 7, 0, 999999, '');


Теперь перейдем к настройке модулей авторизации.

4. Настраиваем NSS:

Файл/etc/nsswitch.conf:

# /etc/nsswitch.conf

#
# Example configuration of GNU Name Service Switch functionality.
# If you have the `glibc-doc-reference' and `info' packages installed, try:
# `info libc "Name Service Switch"' for information about this file.

passwd: compat pgsql
group: compat pgsql
shadow: compat pgsql

hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4
networks: files

protocols: db files
services: db files
ethers: db files
rpc: db files

netgroup: nis


Файл /etc/nss-pgsql.conf (должен иметь права на чтение для всех)

# Строка соединения с БД. Подставьте свои параметры
connectionstring = hostaddr=127.0.0.1 port=5432 dbname=postgres user=postgres password=postgres connect_timeout=15

# you can use anything postgres accepts as table expression

# Must return "usernames", 1 column, list
getgroupmembersbygid = SELECT name FROM sysauth_passwd ORDER BY name

# Must return passwd_name, passwd_passwd, passwd_gecos, passwd_dir, passwd_shell, passwd_uid, passwd_gid
getpwnam = SELECT name, pass, gecos, home, shell, uid, gid FROM sysauth_passwd WHERE name=$1

# Must return passwd_name, passwd_passwd, passwd_gecos, passwd_dir, passwd_shell, passwd_uid, passwd_gid
getpwuid = SELECT name, pass, gecos, home, shell, uid, gid FROM sysauth_passwd WHERE uid=$1

# All users
allusers = SELECT * FROM sysauth_passwd

# Must return group_name, group_passwd, group_gid
getgrnam = SELECT name, pass, gid, members FROM sysauth_groups WHERE name=$1

# Must return group_name, group_passwd, group_gid
getgrgid = SELECT name, pass, gid, members FROM sysauth_groups WHERE gid=$1

# Must return gid. %s MUST appear first for username match in where clause
# Другие группы пользователя
groups_dyn = select null
allgroups = select name, pass, gid, members from sysauth_groups

#groups_dyn = SELECT ug.gid FROM passwd_table JOIN usergroups USING (uid) where username = $1 and ug.gid <> $2
#allgroups = SELECT groupname, passwd, gid, ARRAY(SELECT username FROM usergroups WHERE usergroups.gid = group_table.gid) AS members FROM group_table


Файл /etc/nss-pgsql-root.conf (должен иметь права на чтение только для рута, используется для авторизации по теневым паролям)

connectionstring = hostaddr=127.0.0.1 port=5432 dbname=postgres user=postgres password=postgres connect_timeout=15

shadowbyname = SELECT name, password, last_changed, min, max, warn, inact, expire, flag FROM sysauth_shadow WHERE name = $1
shadow = SELECT name, password, last_changed, min, max, warn, inact, expire, flag FROM sysauth_shadow


Теперь — проверим, как оно работает, и работает ли вообще:

sudo getent group
sudo getent passwd
sudo getent shadow

Эти команды должны помимо стандартных юзеров и групп выдать нашего тестового пользователя из БД.

5. Настраиваем PAM (авторизация gdm и т.д.). Настройки PAM могут отличаться в разных системах

Файл /etc/pam_pgsql.conf

connect = hostaddr=127.0.0.1 port=5432 dbname=postgres user=postgres password=postgres connect_timeout=15

debug = 1

auth_query = select pass from sysauth_passwd where name = %u
acct_query = select false, false, false, false from sysauth_passwd where name = %u

# Это используется для смены пароля
pwd_query = update sysauth_shadow set password = %p where name = %u



Файл /etc/pam.d/common_auth

ищем
auth [success=2 default=ignore] pam_unix.so nullok_secure
auth [success=1 default=ignore] pam_winbind.so krb5_auth krb5_ccache_type=FILE cached_login try_first_pass


делаем

auth [success=3 default=ignore] pam_unix.so nullok_secure
auth [success=2 default=ignore] pam_pgsql.so try_first_pass
auth [success=1 default=ignore] pam_winbind.so krb5_auth krb5_ccache_type=FILE cached_login try_first_pass


Файл /etc/pam.d/common_account
ищем

account [success=2 new_authtok_reqd=done default=ignore] pam_unix.so
account [success=1 new_authtok_reqd=done default=ignore] pam_winbind.so


делаем

account [success=3 new_authtok_reqd=done default=ignore] pam_unix.so
account [success=2 new_authtok_reqd=done default=ignore] pam_pgsql.so
account [success=1 new_authtok_reqd=done default=ignore] pam_winbind.so


Чтоб хомяк юзера создавался автоматом — в файле
/etc/pam.d/common_session
добавляем куда-нибудь почти в конец
session required pam_mkhomedir.so umask=0022 skel=/etc/skel/ silent
Вроде всё, должно работать. Проверяем:

su test_user
Если смена пользователя прошла успешно — всё отлично, перезапускаем gdm, пытаемся залогиниться юзером из базы. Должно всё получиться.

Успехов!
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.