Двухфакторная аутентификация OpenVpn клиентов (OpenVpn + Google Authenticator) на CentOs 7/8

1. Устанавливаем необходимые компоненты для работы и настройки OpenVpn:

yum install epel-release
yum -y --enablerepo=epel install openvpn easy-rsa nano
cd /etc/openvpn/
mkdir ccd
mkdir clients

Для более удобной работы с easy-rsa копируем все его файлы в /etc/openvpn/easy-rsa/

cp -a /usr/share/easy-rsa/3.0.3 /etc/openvpn/easy-rsa

Важно! Если у вас CentOs 8 то в репозитории нет easy-rsa, устанавливается так:

yum -y install unzip zip wget
cd ~
wget https://github.com/OpenVPN/easy-rsa/archive/master.zip
unzip master.zip
cp -a easy-rsa-master/easyrsa3/ /etc/openvpn/easy-rsa/


2. Преднастраиваем переменные для всех генерируемых сертификатов:

nano /etc/openvpn/easy-rsa/vars
# Содержимое файла, настраивается по вкусу:
set_var EASYRSA_REQ_COUNTRY    "RU"
set_var EASYRSA_REQ_PROVINCE    "RU"
set_var EASYRSA_REQ_CITY    "Default City"
set_var EASYRSA_REQ_ORG    "SomeCompany.org"
set_var EASYRSA_REQ_EMAIL    "admin@admin.org"
set_var EASYRSA_REQ_OU        "IT"
set_var EASYRSA_KEY_SIZE    4096
set_var EASYRSA_ALGO        rsa
set_var EASYRSA_CA_EXPIRE    3650
set_var EASYRSA_CERT_EXPIRE    3650
set_var EASYRSA_CRL_DAYS    365
set_var EASYRSA_DIGEST        "sha256"

3. Создаём CA с crl и ключ для tls-аутентификации, в выделенной строке поменяйте vpn.server.example на CN вашего сервера:

cd /etc/openvpn
./easy-rsa/easyrsa init-pki
./easy-rsa/easyrsa build-ca
./easy-rsa/easyrsa gen-dh >/dev/null 2>&1 &
openvpn --genkey --secret pki/ta.key
./easy-rsa/easyrsa build-server-full vpn.server.example nopass
./easy-rsa/easyrsa gen-crl

4. Скачиваем и компилируем Google Authenticator pam модуль:

yum -y groupinstall "Development Tools"
yum -y install pam-devel
mkdir /usr/src
cd /usr/src
git clone https://github.com/google/google-authenticator-libpam
cd google-authenticator-libpam
./bootstrap.sh
./configure
make && make install

Настраиваем его:

nano /etc/pam.d/openvpn
#Содержимое файла:
auth        required    /usr/local/lib/security/pam_google_authenticator.so  forward_pass
account     required    pam_nologin.so
account     include     system-auth use_first_pass
password    include     system-auth
session     include     system-auth

Директива forward_pass указывает на то что одноразовый пароль будет передаваться в одной строке с паролем пользователя, т.к. клиент не может отдельным окном запросить его.
Со всеми опциями библиотеки можно ознакомиться тут: https://github.com/google/google-authenticator-libpam


5. Создаём конфигурационный файл OpenVpn, в выделенных строках поменяйте имена сертификатов сервера. Всё что касается двухфакторной аутентификации подключено в самом первом блоке, далее просто произвольный конфиг сервера:

cd /etc/openvpn/server/
nano server.conf
#Содержимое конфига:

# 2FA
plugin /usr/lib64/openvpn/plugins/openvpn-plugin-auth-pam.so openvpn

dev tun
proto udp
mode server
persist-key
persist-tun
keepalive 10 900
reneg-sec 10800
tls-server
username-as-common-name
client-to-client
verb 3
mute 10
log-append /var/log/openvpn.log
status openvpn-status.log


# crypto
cipher AES-256-CBC
auth SHA512
tls-auth /etc/openvpn/pki/ta.key 0


# certs
ca /etc/openvpn/pki/ca.crt
cert /etc/openvpn/pki/issued/vpn.server.example.crt
key /etc/openvpn/pki/private/vpn.server.example.key
dh /etc/openvpn/pki/dh.pem
crl-verify /etc/openvpn/pki/crl.pem

# networking
server 10.1.0.0 255.255.254.0
#push all traffic to openvpn-server
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"

# clients
ifconfig-pool-persist /etc/openvpn/ipp.txt
client-config-dir /etc/openvpn/ccd
max-clients 100

6. Для удобства подключения пользователей к серверу будем использовать шаблон и скрипт.
Создаём шаблон для конфига пользователя, меняем IP сервера на свой:

cd /etc/openvpn/
nano template-client.conf
#Содержимое файла:
client
auth-user-pass
auth-nocache
dev tun
proto udp
sndbuf 0
rcvbuf 0
remote 111.111.111.111 1194
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
auth SHA512
cipher AES-256-CBC
key-direction 1
verb 3

7. Создаём bash-скрипт для создания пользователя, генерации сертификатов и подключения пользователя к Google authenticator:

cd /etc/openvpn/
nano newuser.sh
#Содержимое файла
# set the variables we'll use later
DIR_CLIENT="/etc/openvpn/clients/$1"

# create the certificate and key
cd "/etc/openvpn"
/etc/openvpn/easy-rsa/easyrsa build-client-full "$1" nopass

# create a directory to save all the files
mkdir -p "${DIR_CLIENT}"

# copy certificate, key, tls auth and CA
cp -v "/etc/openvpn/pki/ca.crt" "$DIR_CLIENT/ca.crt"
cp -v "/etc/openvpn/pki/ta.key" "$DIR_CLIENT/ta.key"
cp -v "/etc/openvpn/pki/issued/$1.crt" "$DIR_CLIENT/"
cp -v "/etc/openvpn/pki/private/$1.key" "$DIR_CLIENT/"

# copy and customize the client configuration
cp -v "/etc/openvpn/template-client.conf" "${DIR_CLIENT}/$1.ovpn"

# inserting certs into ovpn
# ca
echo "<ca>" >> "${DIR_CLIENT}/$1.ovpn"
cat "$DIR_CLIENT/ca.crt" >> "${DIR_CLIENT}/$1.ovpn"
echo "</ca>" >> "${DIR_CLIENT}/$1.ovpn"
# cert
echo "<cert>" >> "${DIR_CLIENT}/$1.ovpn"
sed -n '/-----BEGIN CERTIFICATE-----/,$p' "$DIR_CLIENT/$1.crt" >> "${DIR_CLIENT}/$1.ovpn"
echo "</cert>" >> "${DIR_CLIENT}/$1.ovpn"
# key
echo "<key>" >> "${DIR_CLIENT}/$1.ovpn"
cat "$DIR_CLIENT/$1.key" >> "${DIR_CLIENT}/$1.ovpn"
echo "</key>" >> "${DIR_CLIENT}/$1.ovpn"
# tls
echo "<tls-auth>" >> "${DIR_CLIENT}/$1.ovpn"
sed -n '/-----BEGIN OpenVPN Static key V1-----/,$p' "$DIR_CLIENT/ta.key" >> "${DIR_CLIENT}/$1.ovpn"
echo "</tls-auth>" >> "${DIR_CLIENT}/$1.ovpn"

# create a new local user
PASS=$(head -n 4096 /dev/urandom | tr -dc a-zA-Z0-9 | cut -b 1-20)
useradd -m "$1"
echo "$PASS" | passwd --stdin $1
echo "$PASS" > ${DIR_CLIENT}/sshpass.txt

# run the google authenticator as the local user and save the code
su $1 -c "/usr/local/bin/google-authenticator -C -t -f -D -r 3 -Q UTF8 -R 30 -w3" > ${DIR_CLIENT}/authenticator_code.txt

8. Делаем скрипт исполняемым и создаем пользователя. Имя пользователя задаётся через пробел после вызова скрипта.

chmod +x newuser.sh
./newuser.sh client1

Необходимые пользователю файлы создаются в директории /etc/openvpn/clients/ в индивидуальной папке для каждого.
Отдельно сертификаты можно не передавать, они вшиты в ovpn файл конфигурации. Что пользователю понадобится:

  • client.ovpn — файл с настройками и сертификатами
  • sshpass.txt — пароль пользователя
  • authenticator_code.txt — файл с секретным ключом для подключения Google Authenticator

9. Чтобы при попытке аутентификации пользователя не было ошибки «Failed to read /home/username/.google_authenticator» необходимо снять защиту домашних директорий для сервиса openvpn-server

systemctl edit openvpn-server@server
#В открывшемся пустом файле прописываем:
[Service]
ProtectHome=false

10. Разрешаем маршрутизацию, настраиваем selinux и firewalld.

nano /etc/sysctl.conf
#Добавляем строку если её нет:
net.ipv4.ip_forward = 1
#Перезапускаем сеть:
systemctl restart network.service
#Настраиваем selinux
semanage port -a -t openvpn_port_t -p udp 1194
#Настраиваем firewalld
firewall-cmd --permanent --add-service openvpn

11. Разрешаем автозапуск openvpn-server и запускаем его:

systemctl enable openvpn-server@server
systemctl start openvpn-server@server

На этом всё, при подключении указываем имя пользователя и пароль+одноразовый пароль (в одном поле)

Как настроить исключения — Исключения для двухфакторной аутентификации OpenVpn

Использованы материалы из статьи https://velenux.wordpress.com/2019/03/12/openvpn-with-google-2-factor-authentication-on-centos-7/

0

Добавить комментарий

Ваш e-mail не будет опубликован.