30 September 2019

OpenVPN и Active Directory (Kerberos без пользовательских сертификатов)

Configuring LinuxSystem administration*nix
From Sandbox
Про OpenVPN написано много гайдов, в том числе и про авторизацию через Active Directory. Большинство из них сводится к использованию LDAP, подхода с использованием Kerberos, оформленного в полноценную статью, я не нашел. Впрочем, чего-то нового тут изобретено не будет, я лишь скомпилировал уже сделанное до меня, PAM отлично работает с Kerberos, а OpenVPN имеет нативный плагин для PAM. Также я решил отказаться от пользовательских сертификатов и советы, где рекомендуют просто всем пользователям выдавать один сертификат, меня не устроили, поэтому было найдено другое решение, работающее на всех клиентах.



Немного об NSS


В своем случае я использовал Centos 7 в связке с sssd. Впрочем, ничто не мешает использовать winbind. Главное, иметь машину в домене и тикет Kerberos. Я не буду писать о том, как это делается, т.к. не скажу ничего нового, в сети много хороших мануалов.

Будет необходимо сменить настройки /etc/nsswitch.conf, если этого не было сделано ранее. В зависимости от того, какой модуль использовался, нужно вместо module_name вписать sss или winbind соответственно. Описание параметров можно прочесть с помощью man nsswitch.conf.

Следующих настроек должно быть достаточно:

passwd:           files module_name
shadow:           files module_name
group:            files module_name

В случае с sssd не забываем, кроме всего прочего, что в /etc/sssd/sssd.conf в блоке [sssd] должен быть упомянут nss:

services = nss, pam

Насчет winbind мне сложно что-то сказать, я его не использовал.

Конечная цель получить правильный результат от getent. Проверяем, что машина может получать сведения о доменных пользователях и группах:

> getent passwd kanlas
kanlas:*:14123583:1257570:Kanlas Kanlasovich:/home/kanlas@example.com:/bin/bash
> getent group VPN
vpn:*:13821391:kanlas,igor,marina

Примечание
Если вы использовали sssd и данные о пользователе получаются только с указанием полного имени (т.е. kanlas@example.com), добавьте в sssd.conf в блоке домена параметр use_fully_qualified_names = False

Настраиваем PAM


Теперь необходимо создать свой PAM модуль. Чтобы не использовать системный access.conf, сделаем отдельный файл, откуда будет читаться группа доступа. Я не так хорош в модулях PAM, поэтому не могу сказать, нужны ли все строки в примере, который будет ниже. В общем-то, нас интересует только строка account required pam_listfile.so onerr=fail item=group sense=allow file=/etc/openvpn/auth/access-groups.

Самый простой вариант, взять, например, модуль login и добавить в него нужную строку. Что и было сделано.

Получаем:

	
#%PAM-1.0
auth [user_unknown=ignore success=ok ignore=ignore default=bad] pam_securetty.so
auth       substack     system-auth
auth       include      postlogin
account    required     pam_listfile.so onerr=fail item=group sense=allow file=/etc/openvpn/auth/access-groups
account    include      system-auth
password   include      system-auth
session    required     pam_selinux.so close
session    required     pam_loginuid.so
session    optional     pam_console.so
session    required     pam_selinux.so open
session    required     pam_namespace.so
session    optional     pam_keyinit.so force revoke
session    include      system-auth
session    include      postlogin
-session   optional     pam_ck_connector.so

Кладем его в /etc/pam.d, назвав по своему усмотрению.

В /etc/openvpn/auth/access-groups, указанный в модуле, у нас и будет записана группа доступа, можете указать свой путь при желании. Нужно будет указать имя группы (Common Name) с доменом. В моем случае я записал туда VPN@example.com.

Осталось объяснить OpenVPN, что ему необходимо использовать PAM. Кладем в конфигурацию сервера следующие строки:

plugin /usr/lib64/openvpn/plugins/openvpn-plugin-auth-pam.so имя_модуля_pam
username-as-common-name

В разных дистрибутивах пути могут отличаться! Проверьте наличие файла по пути, либо используйте find.

Использование параметра username-as-common-name связано с тем, что в ином случае после выполнения auth-user-pass у клиента, серверу отправится имя, указанное в сертификате.

В конфиге клиента необходимо добавить строку

auth-user-pass

На этом настройка закончена, можно тестировать.

Убираем сертификат пользователя


Теперь у нас есть авторизация через домен и сертификат пользователя бесполезен, отказаться от него кажется логичным решением. Но мобильные клиенты имеют с этим проблемы, просто не принимая такую конфигурацию, а десктопные хоть и работают, но злостно ругаются. Во-первых, изменим конфигурацию на сервере, чтобы он перестал требовать сертификат.

verify-client-cert none

Далее в конфигурацию клиентов добавляем

setenv CLIENT_CERT 0

Все, теперь клиенты не будут ругаться на сертификат. Забавно, что этот параметр спрятан в разделе вопросов-ответов для iOS. Я не тестировал на iOS, но Android, а так же MacOS (бета клиент) и Windows принимают эти настройки на ура. Только сторонний OpenVPN-клиент на Android пока этого не умеет (к моменту написания статьи уже могли поправить).
Tags: openvpn kerberos active directory linux pam
Hubs: Configuring Linux System administration *nix
+15
7.7k 75
Comments 8
Ads