Сервер OpenVPN с LDAP-авторизацией и multiline
По умолчанию сервер OpenVPN авторизует подключающихся пользователей через сертификаты, но существует возможность использовать вместо сертификата логин и пароль, как в PPP и PPTP, а логин и пароль проверять с помощью LDAP.
В свою очередь, для подключения к LDAP можно использовать разные инструменты:
- плагин openvpn-auth-ldap,
- внешний сценарий.
Вариант с плагином более производителен и безопасен, но не устроил нас по двум причинам:
- настройка занимает немного больше времени,
- отсутствует необходимая нам гибкость.
Для проверки через внешний сценарий настройки VPN-сервера должны содержать следующие строки:
auth-user-pass-verify "/etc/openvpn/auth-script" via-env
script-security 3
client-cert-not-required
username-as-common-name
Кроме того, требуется установить пакет ldap-utils.
Сценарий auth-script принимает логин и пароль в переменных окружения “username” и “password”. Если он завершается с ненулевым кодом возврата, OpenVPN считает, что авторизация не прошла, и разрывает соединение.
Таким образом, от сценария требуется:
- попытаться подключиться к LDAP-серверу с полученным логином-паролем,
- проверить, что ответ успешен.
Итого:
#!/bin/sh
SERV="ipa.example.org"
BASE="ou=People,dc=example,dc=org" # 389DS
BASE="cn=users,cn=accounts,dc=example,dc=org" # FreeIPA
FULL="uid=${username%:*},$BASE"
ldapsearch -h "$SERV" -D "$FULL" -w "$password" -b "$BASE" -LLL "(uid=${username%:*})" dn 2>&1 |
grep -q "^dn: $FULL$"
Примечание: хотя FreeIPA основан на LDAP-сервере 389DS, схемы объектов в них отличаются. Из двух строк “BASE=...” оставьте нужную.
Multiline
Зачем вместо “$username” мы используем “${username%:*}”? Формально это означает «отрезать из переменной все символы после последнего двоеточия». Таким образом, имена “vasya:home” и “vasya:office” будут проверяться в LDAP как “vasya”.
В то же время, OpenVPN будет видеть их как два разных аккаунта и выдаст им разные IP. Это позволит устанавливать одному пользователю несколько подключений одновременно.
Как показывает опыт, такая возможность является весьма востребованной, потому что пользователи регулярно забывают разрывать предыдущее VPN-соединение и оно мешает новому (например, офисное домашнему или наоборот). Для пользователя это выглядит как регулярное зависание и обрыв соединения каждые несколько минут.