Настройка OpenVPN с двухфакторной аутентификацией 2FA / TOTP и сертификатами X.509
Использование только клиентских сертификатов X.509 создает риски компрометации при утере или краже ноутбука сотрудника:
- Невозможно оперативно заблокировать доступ сотрудника без перевыпуска CRL (Certificate Revocation List).
- Отсутствие второго фактора аутентификации (MFA/2FA) нарушает требования стандартов PCI-DSS, ISO 27001 и HIPAA.
- Ошибки скрипта верификации паролей:
AUTH_FAILEDпри корректном сертификате. - Рассинхронизация времени сервера и мобильных приложений генерации кодов TOTP (Clock Skew).
1. Установка модуля PAM Google Authenticator на сервере
# Debian / Ubuntu:
apt update && apt install -y openvpn libpam-google-authenticator easy-rsa
# Генерация ключа TOTP для пользователя (выполняется из-под учетной записи пользователя):
su - vpnuser
google-authenticator -t -d -f -r 3 -R 30 -W -q
# Сохраните сгенерированный QR-код и аварийные scratch-коды!2. Настройка PAM конфигурации (/etc/pam.d/openvpn)
# Проверка системного пароля:
@include common-auth
# Проверка второго фактора TOTP:
auth required pam_google_authenticator.so forward_pass nullok3. Конфигурация сервера OpenVPN (/etc/openvpn/server.conf)
proto udp
port 1194
dev tun
# Сертификаты (Фактор 1 - Владение):
ca /etc/openvpn/easy-rsa/pki/ca.crt
cert /etc/openvpn/easy-rsa/pki/issued/server.crt
key /etc/openvpn/easy-rsa/pki/private/server.key
dh /etc/openvpn/easy-rsa/pki/dh.pem
# Интеграция с PAM (Фактор 2 - Знание пароля и Генератор TOTP):
plugin /usr/lib/x86_64-linux-gnu/openvpn/plugins/openvpn-plugin-auth-pam.so openvpn
# Требовать и сертификат, и успешную аутентификацию через плагин:
verify-client-cert require
username-as-common-name
server 10.8.0.0 255.255.255.0
cipher AES-256-GCM
auth SHA256
keepalive 10 120
persist-key
persist-tun4. Конфигурация клиента (.ovpn)
client
dev tun
proto udp
remote vpn.company.com 1194
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
cipher AES-256-GCM
# Запрос ввода логина и пароля+TOTP у пользователя:
auth-user-pass
<ca>
-----BEGIN CERTIFICATE-----
MIID... (CA cert)
-----END CERTIFICATE-----
</ca>
<cert>
-----BEGIN CERTIFICATE-----
MIID... (User cert)
-----END CERTIFICATE-----
</cert>
<key>
-----BEGIN PRIVATE KEY-----
MIIE... (User key)
-----END PRIVATE KEY-----
</key> Частые вопросы (FAQ)
Как пользователь вводит пароль и одноразовый код TOTP?
В диалоговом окне OpenVPN клиента пользователь вводит свой стандартный пароль, к которому в конец без пробелов приписывает 6 цифр из приложения-аутентификатора (например: MyPassword123456789).
Почему OpenVPN отклоняет правильный TOTP код (AUTH_FAILED)?
Наиболее частая причина — рассинхронизация времени на сервере. Алгоритм TOTP чувствителен к расхождению часов более чем на 30 секунд. Настройте демон Chrony/NTP на VPN-сервере.
Что делает директива username-as-common-name?
Она заставляет OpenVPN использовать имя пользователя, переданное в процессе PAM-аутентификации, вместо поля Common Name (CN) из сертификата X.509 для создания контекста сессии и поиска ccd-файлов.
Можно ли использовать push-уведомления вместо ручного ввода TOTP?
Да, для этого PAM-модуль заменяют на интеграцию с облачными провайдерами идентификации (Duo Security, YubiKey API, FreeIPA или Keycloak).