Предисловие


Вечерком воскресенья в середине марта мне поступил телефонный звонок, суть которого заключалась а том, что 200+ человек не приедут в понедельник в офис, а переводятся на «удалёнку». Фраза: одни на «удаленку», а админы на «продлёнку», завертелась у меня в голове.


Нельзя сказать, что удаленного доступа к внутренним ресурсам у нас не было совсем, но мы использовали IPSEC VPN на связке Shrew soft VPN client + Pfsense для экстренного доступа некоторых IT специалистов к вмененным им в поддержку информационным системам. У Shrew soft VPN client проявлялась особенность, заключавшаяся в том, что после некоторого количества успешных соединений перестают работать ipv4 маршруты. Лечилась данная ситуация перезапуском Windows служб или перезагрузкой конечного устройства. Перспектива объяснять коллегам этот нюанс неопределенное количество раз в день вызывала нервный тик и тремор конечностей одновременно.


Муки выбора


Я определил следующие требования к решению для организации VPN до офисных систем:

  1. Простота настройки. В надежде, что некоторые справятся самостоятельно;
  2. Наличие клиента для популярных операционных систем;
  3. Поддержка парольной авторизации Active Directory; Срочный Выпуск ключей(сертификатов) не входил в мои планы
  4. Двухфакторная аутентификация. Желательно бесплатно;
  5. Минимальные вложения, а лучше бесплатно, поскольку бюджет 2020 на IT-оборудование не предполагал затрат на шлюз удаленного доступа;
  6. И предсказуемая стабильность и производительность;

Новомодный 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

Проверим доступность инфрастуктуры Active Directory
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 отвечает за формат имени пользователя.
Листинг /etc/sssd/sssd.conf
[sssd]
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

Вывод chronyc sources
210 Number of sources = 2
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

Конфигурационный файл /etc/ocserv/ocserv.conf
auth = «pam»
#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.







Три недели полет нормальный...