Openconnect emergency VPN server with two-factor authorization on Centos 8

Foreword


On the evening of Sunday in mid-March, I received a phone call, the essence of which was that 200+ people would not come to the office on Monday, but would be transferred to remote โ€™. The phrase: one on the "remote", and the admins on the "extended", spun in my head.


This is not to say that we did not have remote access to internal resources at all, but we used IPSEC VPN on a bunch of Shrew soft VPN client + Pfsense for emergency access of some IT specialists to the information systems imputed to them in support. The Shrew soft VPN client showed a peculiarity consisting in the fact that after a number of successful connections ipv4 routes ceased to work. This situation was treated by restarting Windows services or rebooting the end device. The prospect of explaining this nuance to colleagues an indefinite number of times a day caused nervous tic and tremor of the limbs at the same time.


Flour of choice


I have identified the following solution requirements for organizing a VPN to office systems:

  1. Easy setup. In the hope that some will cope on their own;
  2. Availability of a client for popular operating systems;
  3. Support for password authentication Active Directory; Urgent Issue of keys (certificates) was not in my plans
  4. Two-factor authentication. Preferably free;
  5. Minimum investment, and better for free, since the budget for IT equipment 2020 did not imply the cost of a remote access gateway;
  6. And predictable stability and performance;

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 can use the pam mechanism for authorization. For "end-to-end" authorization of Active Directory clients, add our new server to the domain:


#   
dnf install realmd sssd oddjob oddjob-mkhomedir adcli samba-common samba-common-tools krb5-workstation

Checking Active Directory Infrastructure Availability
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

The configuration file for the System Security Services Daemon SSSD /etc/sssd/sssd.conf will be automatically generated. You must add the ocserv server VPN service that has not yet been installed to the settings. The use_fully_qualified_names parameter is responsible for the username format.
Listing /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

Turn on and start the SSSD service

systemctl enable sssd
systemctl start sssd

It is possible to limit the number of users with the right to connect. In this case, I allowed all users to connect to the server.

realm permit --all

At this stage, ssh authentication to the server for domain users should work.

Choosing a module for implementing two - factor two - step authentication, I looked at the cost of Duo security supported from the box and chose TOTP (Time-based One-time Password) represented by Google Authenticator. In this implementation, the timing of server time synchronization by the exact time services is critical. You can check the correct operation of the chronyd daemon with the command: chronyc sources

Conclusion of 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

Install Google Authenticator:

dnf install epel-release
dnf install google-authenticator qrencode-libs

Next, you need to run the google-authenticator command from under the user account on the server (sudo su DomainUser) and answer all the questions positively to get the identifier / qr code for the Google Authenticator application on the user's smartphone ( 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.







...


All Articles