OpenVPN и Easy-RSA
Развертывание CA сервера (EasyRSA)
CA (Certification Authority) = ЦС (Центр Сертификации) = Удостоверяющий центр
В криптографии это сторона, чья честность неоспорима, а public key широко известен. Это компонент, отвечающий за управление криптографическими ключами юзеров.
Ее задача - подтверждать подлинность ключей шифрования с помощью сертификатов электронной подписи. Открытые ключи и др. инфа о юзерах хранится центрами сертификации в виде цифровых сертификатов.
[[Lets Encrypt]] - тот же CA.
sudo apt install easy-rsa -y
mkdir ${HOME}/easy-rsa
ln -s /usr/share/easy-rsa/* ${HOME}/easy-rsa/
sudo chown $USER ${HOME}/easy-rsa
chmod 700 ${HOME}/easy-rsa
cd ${HOME}/easy-rsa
./easyrsa init-pki
cp vars.example pki/vars
./easyrsa init-pki
создал директорию инфраструктуры открытых ключей (PKI - Public Key Infrastructure).
Все готово для создания CA - значит, пора создавать пару "секретный ключ и сертификат".
Сначала edit the vars (нужно для содержимого сертификата):
# OpenVPN и Easy-RSA
set_var EASYRSA_REQ_COUNTRY "RUS"
set_var EASYRSA_REQ_PROVINCE "Moscow"
set_var EASYRSA_REQ_CITY "Moscow"
set_var EASYRSA_REQ_ORG "SomeCompany"
set_var EASYRSA_REQ_EMAIL "admin@SomeCompany.net"
set_var EASYRSA_REQ_OU "LLC"
# Информация выше никак не влияет на функциональность CA,
# она будет отражена в содержимом сертификата
set_var EASYRSA_ALGO "ec"
set_var EASYRSA_DIGEST "sha512"
Build the CA:
./easyrsa build-ca
# Нужно будет ввести passphrase, остальная инфа возьмется из pki/vars
Появится pki/ca.crt - открытый ключ CA. Он будет использоваться клиентами и серверами для проверки при авторизации.
Его нужно будет доставить и на сервер OpenVPN, в нашем случае.
На этом с развертыванием CA сервера. Дальше на нем можно будет подписывать запросы сертификатов.
Подпись запроса серверных сертификатов (тип запроса: server)
./easyrsa sign-req server server
# Подпись request-а на серверный сертификат сервера "server"
Пример:
# Передача на CA сервер запроса, подпись там и возврат на VPN сервер
scp -P 2478 pki/reqs/server.req test@192.168.1.11:/home/test/easy-rsa/pki/reqs/
ssh test@192.168.1.11 -p 2478 "cd ${HOME}/easy-rsa && ./easyrsa sign-req server server"
scp -P 2478 test@192.168.1.11:${HOME}/easy-rsa/pki/issued/server.crt .
В чем смысл подписи?
Полученный файл server.crt
содержит открытый ключ шифрования сервера OpenVPN, а также новую подпись от сервера ЦС.
Смысл подписи состоит в том, чтобы сообщить всем, кто доверяет серверу ЦС, что они также могут доверять серверу OpenVPN при подключении к нему.
Подпись запроса клиентских сертификатов (тип запроса: client)
./easyrsa sign-req client SomeClient
# Подпись request-а на клиентский сертификат клиента "SomeClient"
Развертывание VPN сервера (OpenVPN)
У OpenVPN есть 3 вида аутентификации:
1. Предустановленный ключ
2. Аутентификация по сертификатам
Для шифрования соединения и клиент, и сервер юзают сертификаты
3. Аутентификация с помощью пары "логин и пароль"
Может использоваться без создания сертификата для клиента, но серверный сертификат всё равно нужен
Буду использовать аутентификацию по сертификатам - способ, который наиболее гибок в настройках.
sudo apt install easy-rsa openvpn -y
Здесь EasyRSA нужен чисто для создания запросов.
mkdir ${HOME}/easy-rsa
ln -s /usr/share/easy-rsa/* ${HOME}/easy-rsa/
sudo chown "$USER":"$USER" ${HOME}/easy-rsa
chmod 700 ${HOME}/easy-rsa
cd ${HOME}/easy-rsa
./easyrsa init-pki
Генерация запроса на серверный сертификат
./easyrsa gen-req server nopass
# Passphrase
Этой командой создадутся файл запроса на серверный сертификат (server.req) и секретный ключ (server.key).
!! Нужно передать этот запрос (server.req) на сервер CA, подписать там и забрать сертификат (server.crt) :
[[#Подпись запроса серверных сертификатов (тип запроса server)]]P.S. Это еще и безопасно тем, что запрос и подписанный сертификат не являются секретными данными - можно спокойно осуществлять передачу.
TLS Crypt
Для доп. защиты нужно создать доп. секретный ключ для аутентификации и шифрования данных, передаваемых между клиентом и сервером OpenVPN (что и зовется TLS Crypt):
openvpn --genkey secret ta.key
sudo chown $USER:$USER ta.key
Теперь нужно положить указанные файлы в папку с конфигами OpenVPN (/etc/openvpn/server/):
+ серверный сертификат (server.crt)
+ секретный ключ сервера (server.key)
+ сертификат CA (ca.crt)
+ секретный ключ для TLS Crypt (ta.key)
sudo cp path/to/server.crt path/to/server.key path/to/ca.crt path/to/ta.key /etc/openvpn/server
Генерация клиентских сертификатов
mkdir -p ${HOME}/clients/{keys,files}
chmod -R 700 ${HOME}/clients
cd ${HOME}/easy-rsa
./easyrsa gen-req SomeClient nopass
cp pki/private/SomeClient.key ${HOME}/clients/keys
\<Подпись запроса>
[[#Подпись запроса клиентских сертификатов (тип запроса client)]]
После подписи запроса:
cp path/to/ta.key path/to/SomeClient.crt path/to/SomeClient.key path/to/ca.crt ${HOME}/clients/keys
sudo chown "$USER":"$USER" ${HOME}/clients/keys
Конфигурация OpenVPN и системы (для работы VPN)
Соус server.conf:
/usr/share/doc/openvpn/examples/sample-config-files/server.conf
Содержимое моего конфига /etc/openvpn/server/server.conf:
port 1194
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key
dh none
server 10.8.0.0 255.255.255.0
keepalive 10 120
tls-crypt ta.key
cipher AES-256-GCM
auth SHA256
user nobody
group nogroup
persist-key
persist-tun
verb 3
explicit-exit-notify 1
ifconfig-pool-persist /var/log/openvpn/ipp.txt
status /var/log/openvpn/openvpn-status.log
log /var/log/openvpn/openvpn.log
Включение IPv4 forwarding (чтобы vpn работал):
echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
Firewall (ufw):
sudo ufw allow 1194/udp
sudo ufw reload
iptables.sh:
#!/usr/bin/env bash
eth="$1"
proto="$2"
port="$3"
# OpenVPN
iptables \
-A INPUT -i "$eth" -m state --state NEW \
-p "$proto" --dport "$port" -j ACCEPT
# Allow TUN interface connections to OpenVPN server
iptables -A INPUT -i tun+ -j ACCEPT
# Allow TUN interface connections to be forwarded through other interfaces
iptables -A FORWARD -i tun+ -j ACCEPT
iptables \
-A FORWARD -i tun+ -o "$eth" \
-m state --state RELATED,ESTABLISHED -j ACCEPT
iptables \
-A FORWARD -i "$eth" -o tun+ \
-m state --state RELATED,ESTABLISHED -j ACCEPT
# NAT the VPN client traffic to the internet
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o "$eth" -j MASQUERADE
Usage:
sudo ./iptables4openvpn.sh <net_interface_name> udp 1194
Запуск OpenVPN
sudo systemctl -f enable openvpn-server@server.service
sudo systemctl restart openvpn-server@server.service
sudo systemctl status openvpn-server@server.service
Клиентские конфиг-файлы (.ovpn)
Соус client.conf:
/usr/share/doc/openvpn/examples/sample-config-files/client.conf
Вот мой шаблон клиентского конфига client.conf:
client
dev tun
proto udp
remote remote_server_ip 1194
resolv-retry infinite
nobind
user nobody
group nogroup
persist-key
persist-tun
remote-cert-tls server
cipher AES-256-GCM
auth SHA256
key-direction 1
verb 3
;tls-crypt ta.key 1
Надо будет поменять remote_server_ip
на IP адрес VPN сервера:
VPN_SERVER_IP="$(dig +short myip.opendns.com @resolver1.opendns.com)"
sed -i "s/remote_server_ip/${VPN_SERVER_IP}/" client.conf
На digitalocean предоставили такой скрипт для создания клиентских конфигов (.ovpn файлов):
#!/usr/bin/env bash
# First argument: Client identifier
KEY_DIR=${HOME}/clients/keys
OUTPUT_DIR=${HOME}/clients/files
BASE_CONFIG=${HOME}/clients/client.conf
cat ${BASE_CONFIG} \
<(echo -e '<ca>') \
${KEY_DIR}/ca.crt \
<(echo -e '</ca>\n<cert>') \
${KEY_DIR}/${1}.crt \
<(echo -e '</cert>\n<key>') \
${KEY_DIR}/${1}.key \
<(echo -e '</key>\n<tls-crypt>') \
${KEY_DIR}/ta.key \
<(echo -e '</tls-crypt>') \
> ${OUTPUT_DIR}/${1}.ovpn
Usage:
./make_ovpn.sh SomeClient
Создастся конфиг ~/client-configs/files/SomeClient.ovpn, который содержит:
+ Сертификат CA сервера (ca.crt)
+ Клиентский сертификат (SomeClient.crt)
+ Клиентский секретный ключ (SomeClient.crt)
+ Секретный ключ для TLS Crypt (ta.key)
Всё, осталось его доставить на нужное устройство (которое хочет подключится к VPN) и импортировать этот .ovpn файл в клиентское приложение OpenVPN.
Отзыв сертификатов клиента
Соус: https://www.digitalocean.com/community/tutorials/how-to-set-up-and-configure-an-openvpn-server-on-ubuntu-20-04-ru#15
Troubleshoot
Если проблемы с tls-crypt: [[OpenVPN tls-crypt unwrap error]]
Соусы:
Скиллбокс - модуль 24
[[Нераздельная легкая установка OpenVPN + EasyRSA]]
Гайд от digitalocean
Гайд из github-а EasyRSA