Предисловие
Вечерком воскресенья в середине марта мне поступил телефонный звонок, суть которого заключалась а том, что 200+ человек не приедут в понедельник в офис, а переводятся на «удалёнку». Фраза: одни на «удаленку», а админы на «продлёнку», завертелась у меня в голове.
Нельзя сказать, что удаленного доступа к внутренним ресурсам у нас не было совсем, но мы использовали IPSEC VPN на связке Shrew soft VPN client + Pfsense для экстренного доступа некоторых IT специалистов к вмененным им в поддержку информационным системам. У Shrew soft VPN client проявлялась особенность, заключавшаяся в том, что после некоторого количества успешных соединений перестают работать ipv4 маршруты. Лечилась данная ситуация перезапуском Windows служб или перезагрузкой конечного устройства. Перспектива объяснять коллегам этот нюанс неопределенное количество раз в день вызывала нервный тик и тремор конечностей одновременно.
Муки выбора
Я определил следующие требования к решению для организации VPN до офисных систем:
- Простота настройки. В надежде, что некоторые справятся самостоятельно;
- Наличие клиента для популярных операционных систем;
- Поддержка парольной авторизации Active Directory; Срочный Выпуск ключей(сертификатов) не входил в мои планы
- Двухфакторная аутентификация. Желательно бесплатно;
- Минимальные вложения, а лучше бесплатно, поскольку бюджет 2020 на IT-оборудование не предполагал затрат на шлюз удаленного доступа;
- И предсказуемая стабильность и производительность;
Новомодный WireGuard работает на ключах, openvpn-gui, имхо, имеет не самый дружелюбный интерфейс клиента, пару лет назад я пробовал SoftEther VPN, но остался недоволен производительностью, про Shrew soft писал выше. Openconnect VPN Server + OpenConnect SSL VPN Client — настройка клиента 1 строкой поддержка всех популярных платформ, возможность работать только по tcp, поддержка духфакторной аутентификации, интеграция с LDAP, то что надо! Еще и совместимость с Cisco Anyconnect client :)
Настройка
Настройку сервера я производил на базе ОС Centos 8. При установке Centos 8 в минимальной конфигурации я постоянно сталкиваюсь с некорректной работы русской локали, которая решается установкой glibc-langpack-en, и заменой системного шрифта>
dnf install glibc-langpack-en
setfont UniCyr_8x16
Меняем в /etc/vconsole.conf FONT="UniCyr_8x16"
Настройка межсетевого экрана:
#Устанавливаем зону trusted по-умолчанию для всех сетевых интерфейсов
#В связи с переходом на nftables есть проблема с работой Firewalld в части правил в цепочке Forward. Пока рекомендуют использовать зону trusted
firewall-cmd --set-default-zone=trusted
#Добавляем новую службу в firewalld - ocserv (используются порты 443/tcp 443/udp)
firewall-cmd --permanent --new-service=ocserv
firewall-cmd --permanent --service=ocserv --set-description="OpenConnect SSL VPN Server"
firewall-cmd --permanent --service=ocserv --add-port=443/tcp
firewall-cmd --permanent --service=ocserv --add-port=443/udp
#Внешнему интерфейсу(в моем случае ens192) назначаем зону drop
firewall-cmd --zone=drop --change-interface=ens192 --permanent
firewall-cmd --reload
#В зону drop добавляем разрешающее правило для созданной службы ocserv
firewall-cmd --zone=drop --permanent --add-service=ocserv
firewall-cmd --reload
OpenConnect SSL VPN Server может использовать для авторизации механизм pam. Для «сквозной» авторизации клиентов Active Directory добавим наш новый сервер в домен:
#Установим необходимые пакеты
dnf install realmd sssd oddjob oddjob-mkhomedir adcli samba-common samba-common-tools krb5-workstation
realm discover mydomain.ru
mydomain.ru
type: kerberos
realm-name: MYDOMAIN.RU
domain-name: mydomain.ru
configured: no
server-software: active-directory
client-software: sssd
required-package: oddjob
required-package: oddjob-mkhomedir
required-package: sssd
required-package: adcli
required-package: samba-common-tools
#Подключение к домену Active Directory
realm join mydomain.ru -U Username
Автоматически будет сформирован конфигурационный файл службы SSSD (System Security Services Daemon) /etc/sssd/sssd.conf. Необходимо добавить пока еще не установленную службу VPN сервера ocserv в настройки. Параметр use_fully_qualified_names отвечает за формат имени пользователя.
domains = mydomain.ru
config_file_version = 2
services = nss, pam
default_domain_suffix = mydomain.ru
[domain/mydomain.ru]
ad_domain = mydomain.ru
ad_gpo_map_remote_interactive = +ocserv
krb5_realm = MYDOMAIN.RU
realmd_tags = manages-system joined-with-adcli
cache_credentials = True
id_provider = ad
krb5_store_password_if_offline = True
default_shell = /bin/bash
ldap_id_mapping = True
use_fully_qualified_names = True
fallback_homedir = /home/%u@%d
access_provider = ad
Включим и запустим службу SSSD
systemctl enable sssd
systemctl start sssd
Существует возможность ограничивать набор пользователей имеющих право подключения. В данном случае я разрешил всем пользователям подключаться к серверу.
realm permit --all
На данном этапе должна заработать аутентификация по ssh на сервер для пользователей домена.
Выбирая модуль для реализации двухфакторной двухэтапной аутентификации я посмотрел на стоимость поддерживаемого из коробки Duo security и выбрал TOTP (Time-based One-time Password) в лице Google Authenticator. В этой реализации критическим важным является момент синхронизации времени сервера службами точного времени. Проверить корректность работы демона chronyd можно командой: chronyc sources
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^- ntp1.vniiftri.ru 1 6 17 1 -171us[ -171us] ± 2166us
^* ntp2.vniiftri.ru 1 6 17 1 -237us[ -57us] ± 2494us
Установка Google Authenticator:
dnf install epel-release
dnf install google-authenticator qrencode-libs
Далее необходимо из под учетной записи пользователя на сервере(sudo su DomainUser) выполнить команду google-authenticator и ответив в положительно на все вопросы получить индентификатор/qr-код для приложения Google Authenticator на смартфоне пользователя (IOS, Google play)
Установка Openconnect VPN Server:
dnf install ocserv
#Включим автозапуск сервера при загрузке
systemctl enable ocserv
#IPv4 внешний адрес на котором работает служба
listen-host = 1.1.111.1
tcp-port = 443
udp-port = 443
run-as-user = ocserv
run-as-group = ocserv
socket-file = ocserv.sock
chroot-dir = /var/lib/ocserv
isolate-workers = true
max-clients = 0
#Ограничение на кол-во сессий с одинаковым логином
max-same-clients = 1
keepalive = 32400
dpd = 90
mobile-dpd = 1800
switch-to-tcp-timeout = 25
try-mtu-discovery = true
#LetsenCrypt сертификаты для шифрования
server-cert = /etc/letsencrypt/live/vpn.mydomain.ru/fullchain.pem
server-key = /etc/letsencrypt/live/vpn.mydomain.ru/privkey.pem
########################
cert-user-oid = 0.9.2342.19200300.100.1.1
compression = true
tls-priorities = "@SYSTEM"
auth-timeout = 240
idle-timeout = 1200
mobile-idle-timeout = 2400
min-reauth-time = 300
max-ban-score = 50
ban-reset-time = 300
cookie-timeout = 300
deny-roaming = false
rekey-time = 172800
rekey-method = ssl
use-occtl = true
pid-file = /var/run/ocserv.pid
device = vpns
predictable-ips = true
default-domain = vpn.mydomain.ru
#Адрес сети для VPN клиентов
ipv4-network = 192.168.178.0/24
#Настройка маршрутизации DNS-запросов
tunnel-all-dns = true
dns = 192.168.1.1
########################
ping-leases = false
#Маршрутизация VPN клиента к внутренним сетям
route = 192.168.1.0/255.255.255.0
route = 192.168.2.0/255.255.255.0
########################
cisco-client-compat = true
dtls-legacy = true
user-profile = profile.xml
Получаем сертификаты LetsEncrypt для шифрования VPN трафика. Поднимать веб сервер для этого вовсе не обязательно. Создавать задание на регулярный перевыпуск сертификатов я не стал, полагая, что 3-х месяцев хватит для разрешения ситуации с COVID-19 в том или ином ключе.
firewall-cmd --zone=drop --add-service=http
curl -O https://dl.eff.org/certbot-auto
mv certbot-auto /usr/local/bin/certbot-auto
chown root /usr/local/bin/certbot-auto
chmod 0755 /usr/local/bin/certbot-auto
certbot-auto certonly --standalone --preferred-challenges http -d vpn.mydomain.ru
firewall-cmd --zone=drop --remove-service=http
Включаем двухфакторную аудентификацию и запускаем службу VPN сервера
sed '/^#%PAM-1.0$/a auth required pam_google_authenticator\.so' /etc/pam.d/ocserv
systemctl start ocserv
systemctl start ocserv
Включаем возможность пересылки трафика между интерфейсами
echo "net.ipv4.ip_forward=1">/etc/sysctl.d/0-ocserv.conf
sysctl -w net.ipv4.ip_forward=1
Клиентам предлагаем установить openconnect-gui. В настройках профиля указываем наш сервер vpn.mydomain.ru
При подключении на запрос Password от клиента необходимо заполнять OTP из Google Authenticator. На запрос Password1 пароль пользователя Active Directory.
Три недели полет нормальный...
edo1h
что-то чем дальше, тем больше я сомневаюсь, что использовать доменные пароли вне сети предприятия — хорошая идея.
слишком легко они утекают, слишком болезненна утечка, если мы используем доменную авторизацию для многих служб
mrdoger Автор
Я и сам не в восторге от этой идеи. Добавили 2 этап авторизации для повышения безопасности и защиты от брута. Задача была срочная и связана с обеспечением работы предприятия в форс-мажорной ситуации.
blind_oracle
Их везде используют, от этого никуда не денешься.
Использование Single Sign On слишком удобно чтобы от него отказывались.
edo1h
тут же sso не пахнет
blind_oracle
Ну тут смотря какие у клиентов девайсы. Если корпоративные лаптопы в домене… то Kerberos и вот это всё.
Да и даже если и нет — использование одного аккаунта для VPN/почты/всего остального крайне удобно.