Files
openvpn_infrastructure/README.md

152 lines
8.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Схема следующа. OpenVPN-сервер находится в РФ, к нему подключаютсся клиенты, а также шлюз, через который идёт весь трафик. Обязательно использование режима DCO (Data channel offloading) для OpenVPN-интерфейсов клиента и шлюза, т.к. при включении этого режима производительность увеличивается драматически. Поэтому использование готовых скриптов типа github/angristan нам не подходит, будем поднимать всё ручками. Для начала нам нужно два сервера - в РФ и в забугорище. Оба подготавливаем идентично.
## Подготовка.
```
apt update && apt dist-upgrade -y
```
Если произошёл апгрейд ядра, нужно обязательно перезагрузиться, т.к. в дальнейшем мы будем устанавливать расширения ядра.
```
reboot
```
Когда перезагрузились, устанавливаем необходимые пакеты:
```
apt install -y openvpn openvpn-dco-dkms easy-rsa
```
Далее включаем модуль openvpn-dco:
```
modprobe ovpn-dco-v2
```
Проверяем, включилось ли:
```
lsmod | grep ovpn
```
Если вывод пуст, разбираемся.
Если вывод что-то типа:
```
ovpn_dco_v2 86016 0
ip6_udp_tunnel 16384 1 ovpn_dco_v2
udp_tunnel 32768 1 ovpn_dco_v2
```
То всё хорошо, можно примменять на постоянку:
```
echo "ovpn-dco-v2" | sudo tee -a /etc/modules
```
```
update-initramfs -u -k all
```
Можно ещё раз перезагрузиться и проверить наличие dco-модуля после перезагрузки. `lsmod | grep ovpn`
## Настройка OpenVPN-сервера.
Инициализируем инфраструктуру открытых ключей и выпускаем сертификат сервера (без паролей для автозапуска):
```
make-cadir ~/openvpn-ca && cd ~/openvpn-ca
./easyrsa init-pki
./easyrsa build-ca nopass
./easyrsa gen-dh
# Генерация и подписание ключей сервера
./easyrsa gen-req server nopass
./easyrsa sign-req server server
# Генерация секретного ключа защиты от сканирования (TLS-Crypt)
openvpn --genkey secret tls-crypt.key
```
Копируем ключи в рабочую директорию OpenVPN-сервера:
```
cp pki/ca.crt pki/dh.pem pki/issued/server.crt pki/private/server.key tls-crypt.key /etc/openvpn/server/
```
Создаём конфиг сервера:
```
nano /etc/openvpn/server/server.conf
```
Вставляем следующее содержимое:
```
dev tun
proto udp
port 1194
server 10.210.0.0 255.255.255.0
topology subnet
# Сертификаты и секреты
ca /etc/openvpn/server/ca.crt
cert /etc/openvpn/server/server.crt
key /etc/openvpn/server/server.key
dh /etc/openvpn/server/dh.pem
tls-crypt /etc/openvpn/server/tls-crypt.key
# Максимальная скорость (Только AES-128-GCM, без сжатия)
data-ciphers AES-128-GCM
data-ciphers-fallback AES-128-GCM
# Логирование (минимум операций, разгрузка CPU)
verb 1
mute 20
# Тайм-ауты и папка индивидуальных настроек
keepalive 10 120
persist-key
persist-tun
client-config-dir /etc/openvpn/server/ccd
# Маршрут по умолчанию для клиентов
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 1.1.1.1"
```
Далее необходимо создать на сервере конфиг, в котором описаны директивы, затрагивающие конкретный клиент. Имя такого файла должно соответствовать сертификату клиента (без расширения) и находиться в client-config-dir (у нас /etc/openvpn/server/ccd). Это аналог Client Specific Overrides в pFsense. В нашем случае таким клиентом будет шлюз в забугорище. Присвоим ему адрес в конце нашего диапазона и обязательно отменим перенаправление трафика в туннелль:
```
sudo mkdir -p /etc/openvpn/server/ccd
echo "ifconfig-push 10.210.0.254 255.255.255.0" | sudo tee /etc/openvpn/server/ccd/special-gateway
echo 'push-remove "redirect-gateway def1 bypass-dhcp"' | sudo tee -a /etc/openvpn/server/ccd/special-gateway
```
Теперь "финт ушами". Существует опция iroute в client specific override которая позволяет завернуть весь трафик туннеля конкретному клиенту (iroute 0.0.0.0 0.0.0.0). НО!!! Эта опция конфликтует с DCO, который нам нужен для производительности. Поэтому нужно сделать default маршрут от сервера в сторону шлюза. Но только для интерфейса tun0. Остальной трафик должен имет default маршрут в сторону физического интерфейса (в нашем случае ens3). Для этого применим policy-based routing, который будет включаться вместе с сервисом openvpn-server@server.service:
```
nano /etc/systemd/system/vpn-policy-routing.service
```
```
[Unit]
Description=OpenVPN Policy Routing for Clients
After=network.target openvpn-server@server.service
Requires=openvpn-server@server.service
[Service]
Type=oneshot
RemainAfterExit=yes
# Применяем правила: сначала добавляем локальный маршрут подсети в таблицу 100, затем дефолтный на шлюз
ExecStart=/sbin/ip rule add from 10.210.0.0/24 table 100 ; /sbin/ip route add 10.210.0.0/24 dev tun0 proto kernel scope link table 100 ; /sbin/ip route add default via 10.210.0.254 dev tun0 table 100
# Корректно удаляем при остановке
ExecStop=/sbin/ip rule del from 10.210.0.0/24 table 100 ; /sbin/ip route del default via 10.210.0.254 dev tun0 table 100 ; /sbin/ip route del 10.210.0.0/24 dev tun0 table 100
[Install]
WantedBy=multi-user.target
```
```
systemctl daemon-reload
systemctl enable --now vpn-policy-routing.service
```
Ну а теперь самое время запустить сервер:
```
systemctl start openvpn-server@server.service
```
Проверяем, поднялся ли интерфейс и включился ли dco:
```
ip -details link show dev tun0 | grep dco
```
Вывод должен быть не пустой.
Проверяем, применился ли policy-based routing:
```
ip rule show | grep 100
```
Мы должны увидеть строчку `from 10.210.0.0/24 lookup 100`. Это значит, что весь трафик из VPN-сети отправляется в таблицу 100.
Далее посмотрим саму таблицу:
```
ip route show table 100
```
Мы должны увидеть 2 строчки:
`default via 10.210.0.254 dev tun0` - маршрут по-умолчанию через шлюз
`10.210.0.0/24 dev tun0 proto kernel scope link` - а где вообще искать нашу внутреннюю впн-подсеть. В дефолтную таблицу маршрутизации эта информация поступает автомматически, а в кастомную нужно добавлять вручную.
Можно создавать клиентов с помощью скрипта: `./gen-client.sh user1 user2 user3 ...`.
## Настройка клиента-шлюза
Если ещё не сделано, необходимо проделать все шаги из раздела **Подготовка**.