Установка OpenVPN на Ubuntu 18.04 LTS. Часть 10 из 12

04.08.2020

Теги: LinuxSSLUbuntuVPNКлиентКлючКонфигурацияЛокальнаяСетьМаршрутизацияНастройкаСерверУстановка

Давайте еще раз вернемся к примеру из пятой части, где мы обеспечивали связь двух локальных сетей, расположенных далеко друг от друга. Но добавим еще одну локальную сеть и обеспечим доступ к ресурсам этих сетей для удаленных сотрудников. Кроме того, аутентификация клиентов на сервере у нас будет не с использованием сертификатов, а по логину и паролю.

Аутентификация по логину и паролю

В файл конфигурации сервера нужно добавить директивы

# разрешить выполнение внешних скриптов (то есть verify.sh)
script-security 2
# путь к скрипту, который будет выполнять проверку логина-пароля
auth-user-pass-verify /etc/openvpn/auth/verify.sh via-file
# при проверке логина-пароля не запрашивать сертификат клиента
verify-client-cert none
# использовать UserName вместо CommonName сертификата клиента
username-as-common-name
# директория для временных файлов с логином и паролем клиента
tmp-dir /etc/openvpn/auth/tmp
Часто можно встретить директиву client-cert-not-required вместо verify-client-cert none — но так делать не рекомендуется. Директива client-cert-not-required уже устарела и будет удалена в следующих версиях OpenVPN. Кроме значения none директива verify-client-cert допускает значения optional и require. Другими словами, мы можем сделать двойную аутентификацию клиентов — по логину-паролю + по сертификату.

Когда клиент подключается к серверу, сервер запишет логин и пароль во временный файл, а затем выполнит скрипт verify.sh с аргументом пути к этому файлу. Временный файл содержит две строки: первая строка — логин, вторая срока — пароль. Если скрипт возвращает ноль — проверка пройдена успешно. Скрипт verify.sh может выглядеть примерно так

#!/bin/bash

username=`head -1 $1`
password=`tail -1 $1`

if [[ -z $username || -z $password ]]; then
    echo "Empty username or password"
    exit 1
fi

users=`cat /etc/openvpn/auth/users.pass`
for user in $users; do
    if [[ "$user" = "$username:$password" ]]; then
        exit 0
    fi
done

echo "User $username not found"
exit 1

В файл конфигурации клиента нужно добавить директиву

auth-user-pass

В этом случае клиент будет запрашивать у пользователя логин и пароль, передавая их на сервер по безопасному каналу TLS. Это не подходит для случаев, когда подключение клиента к серверу должно происходить без участия человека. Но директиве auth-user-pass можно передать имя файла с логином и паролем. Этот файл должен содержать две строки: первая строка — логин, вторая строка — пароль.

auth-user-pass /etc/openvpn/auth/user.pass

При использовании ovpn-файла имя пользователя и пароль задаются с помощью

<auth-user-pass>
sergey-ivanov
qwerty123456
</auth-user-pass>

Создание центра сертификаци

Нам по-прежнему нужен сертификат сервера — так что создаем на gateway1 центр сертификации, выпускаем корневой сертификат и сертификат сервера. Центр сертификации мы уже создавали много раз, так что без подробностей.

$ cd /home/evgeniy/
$ mkdir easy-rsa
$ wget https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.7/EasyRSA-3.0.7.tgz
$ tar xvf EasyRSA-3.0.7.tgz
$ cp -r EasyRSA-3.0.7/* easy-rsa/
$ cd /home/evgeniy/easy-rsa/
$ cp vars.example vars

Запускаем скрипт easyrsa с опцией init-pki для инициализации инфраструктуры:

$ ./easyrsa init-pki
init-pki complete; you may now create a CA or requests.
Your newly created PKI dir is: /home/evgeniy/easy-rsa/pki

Создаем корневой сертификат удостоверяющего центра:

$ ./easyrsa build-ca nopass
..........
Common Name (eg: your user, host, or server name) [Easy-RSA CA]: Some Company Auth Center
..........
Your new CA certificate file for publishing is at:
/home/evgeniy/easy-rsa/pki/ca.crt

Корневой сертификат — это файл pki/ca.crt, а приватный ключ — это файл pki/private/ca.key.

Создание ключей сервера

Создаем закрытый ключ и запрос на подпись сертификата для VPN-сервера:

$ ./easyrsa gen-req center-office-gw1 nopass
..........
Common Name (eg: your user, host, or server name) [center-office-gw1]: Enter

Keypair and certificate request completed. Your files are:
req: /home/evgeniy/easy-rsa/pki/reqs/center-office-gw1.req
key: /home/evgeniy/easy-rsa/pki/private/center-office-gw1.key

Подписываем сертификат VPN-сервера:

$ ./easyrsa sign-req server center-office-gw1
..........
Type the word 'yes' to continue, or any other input to abort.
  Confirm request details: yes
..........
Certificate created at: /home/evgeniy/easy-rsa/pki/issued/center-office-gw1.crt

Теперь создаем ключ Диффи-Хеллмана:

$ ./easyrsa gen-dh
..........
DH parameters of size 2048 created at /home/evgeniy/easy-rsa/pki/dh.pem

Это может занять несколько минут. Наконец, создаем ключ TLS для дополнительной защиты:

$ openvpn --genkey --secret ta.key

Копируем ключи и сертификаты в директорию /etc/openvpn/keys/:

$ sudo mkdir /etc/openvpn/keys/ # создаем директорию для ключей и сертификатов
$ sudo cp /home/evgeniy/easy-rsa/pki/ca.crt /etc/openvpn/keys/ # корневой сертификат
$ sudo cp /home/evgeniy/easy-rsa/pki/private/center-office-gw1.key /etc/openvpn/keys/ # закрытый ключ сервера
$ sudo cp /home/evgeniy/easy-rsa/pki/issued/center-office-gw1.crt /etc/openvpn/keys/ # открытый ключ сервера
$ sudo cp /home/evgeniy/easy-rsa/pki/dh.pem /etc/openvpn/keys/ # ключ Диффи-Хеллмана
$ sudo cp /home/evgeniy/easy-rsa/ta.key /etc/openvpn/keys/ # ключ Transport Layer Security

Файл конфигурации сервера

Тут для нас опять ничего нового, так что без подробностей:

$ sudo nano /etc/openvpn/server/config.conf
# включить режим сервера с многими клиентами
mode server

# использовать топологию subnet, вместо дефолтной net30
topology subnet
# сообщить клиентам, что используется топология subnet
push "topology subnet"

# назначить серверу первый адрес виртуальной сети
ifconfig 10.8.0.1 255.255.255.0
# 100 ip-адресов виртуальной сети выделить клиентам
ifconfig-pool 10.8.0.11 10.8.0.110 255.255.255.0
# для клиентов шлюзом по умолчанию будет сервер
push "route-gateway 10.8.0.1"

# установить для сервера маршрут до сети за клиентом gateway2
route 192.168.250.0 255.255.255.0 10.8.0.2
# установить для сервера маршрут до сети за клиентом gateway3
route 192.168.50.0 255.255.255.0 10.8.0.3

# разрешить клиентам общаться между собой, а не только с сервером
client-to-client

# сообщить всем клиентам маршрут до сети за сервером gateway1
push "route 192.168.150.0 255.255.255.0 10.8.0.1"
# сообщить всем клиентам маршрут до сети за клиентом gateway2
push "route 192.168.250.0 255.255.255.0 10.8.0.1"
# сообщить всем клиентам маршрут до сети за клиентом gateway3
push "route 192.168.50.0 255.255.255.0 10.8.0.1"

# одновременно могут быть подключены 100 клиентов
max-clients 100
# файл для хранения ip-адресов клиентов
ifconfig-pool-persist /var/log/openvpn/ipp.txt

# ip-адрес, на котором нужно принимать соединения от клиентов
local 123.123.123.123
# порт, на котором работает сервер
port 1194
# работа по протоколу UDP (для TCP нужно указать tcp-server)
proto udp4
# сетевой интерфейс TUN (или TAP)
dev tun

# включить TLS и при handshake представляться как сервер;
# TLS используется только для шифрования канала управления
tls-server

# корневой сертификат
ca /etc/openvpn/keys/ca.crt
# сертификат сервера
cert /etc/openvpn/keys/center-office-gw1.crt
# приватный ключ сервера
key /etc/openvpn/keys/center-office-gw1.key

# добавляет дополнительную подпись HMAC ко всем пакетам handshake для
# проверки целостности; любой пакет, не имеющий правильной HMAC-подписи,
# будет отброшен без дальнейшей обработки; это для доп.безопасности
tls-auth /etc/openvpn/keys/ta.key
# направление ключа: для сервера — 0, для клиента — 1
key-direction 0

# ключ Диффи-Хеллмана
dh /etc/openvpn/keys/dh.pem

# использовать алгоритм AES-256-GCM шифрования пакетов канала данных;
# на данный момент это самый безопасный и быстрый алгоритм шифрования
cipher AES-256-GCM
# отключить согласование шифров между клиентом и сервером; так делать нельзя,
# если есть старые клиенты, которые не поддерживают AES-256-GCM; кроме того,
# если согласование разрешено, сервер и клиент версии 2.4 и выше могут
# автоматически обновить алгоритм шифрования до более нового и безопасного
#ncp-disable

# алгоритм хеширования — для проверки целостности передаваемых пакетов
# канала данных и (если включено tls-auth) пакетов канала управления
auth SHA256

# читать файлы конфигураций клиентов в этой директории
client-config-dir /etc/openvpn/ccd

# использовать новый алгоритм сжатия
compress lz4-v2
# и сообщить об этом всем клиентам
push "compress lz4-v2"

# пользователь и группа с минимальными правами — для большей безопасности
user nobody
group nogroup

# не перечитывать файлы ключей при восстановлении туннеля после разрыва
persist-key
# оставлять без изменения устройства tun или tap при перезапуске службы
persist-tun

# каждые 10 секунд отправлять ping-запрос на удаленный узел; если нет
# ответа 60*2=120 секунд — перезапускать туннель
keepalive 10 60

# файл статуса, содержит текущие соединения; перезаписывается каждую минуту
status /var/log/openvpn/openvpn-status.log

# предупреждать клиентов, что сервер перезапускается, чтобы клиенты могли
# автоматически переподключиться (только при работе по протоколу UDP)
explicit-exit-notify 1

# разрешить выполнение внешних скриптов (то есть verify.sh)
script-security 2
# путь к скрипту, который будет выполнять проверку логина-пароля
auth-user-pass-verify /etc/openvpn/auth/verify.sh via-file
# при проверке логина-пароля не запрашивать сертификат клиента
verify-client-cert none
# использовать UserName вместо CommonName сертификата клиента
username-as-common-name
# директория для временных файлов с логином и паролем клиента
tmp-dir /etc/openvpn/auth/tmp

Здесь мы девять ip-адресов 10.8.0.2…10.8.0.10 резервируем для подключения филиалов, а еще 100 ip-адресов 10.8.0.11…10.8.0.110 выделяем для подключения сотрудников, которые работают удаленно. И сообщаем всем клиентам маршруты до сетей 192.168.150.0/24, 192.168.250.0/24 и 192.168.50.0/24.

С маршрутами получается такая ситуация. С одной стороны, мы должны всем клиентам предоставить маршруты до сетей 192.168.150.0/24, 192.168.250.0/24 и 192.168.50.0/24. Чтобы сотрудники, которые работают удаленно, могли получить доступ к ресурсам этих трех сетей. С другой стороны, VPN-клиенту gateway2 не нужен маршрут до сети 192.168.250.0/24, а VPN-клиенту gateway3 — не нужен маршрут до сети 192.168.50.0/24.

Эту проблему можно решить тремя способами:

  • Первый — сообщим клиентам маршруты в файлах конфигурации в директории client-config-dir. Тогда для gateway2 и gateway3 мы пропишем два маршрута, а для прочих клиентов — три (до каждой сети). А из файла конфигурации сервера уберем директивы push.
  • Второй — сообщим клиентам маршруты в файлах конфигурации самих клиентов. Тогда для gateway2 и gateway3 мы пропишем два маршрута, а для прочих клиентов — три (до каждой сети). А из файла конфигурации сервера уберем директивы push.
  • Третий — с помощью push в файле конфигурации сервера отправим всем клиентам три маршрута, а для клиентов gateway2 и gateway3 лишние маршруты отбросим в файлах конфигурации с помощью pull-filter. Этот способ и будем использовать.

Конфигурация клиентов на сервере

Создаем два файла в директории client-config-dir для двух VPN-клиентов — gateway2 и gateway3.

$ sudo nano /etc/openvpn/ccd/branch-office-gw2
# назначить клиенту gateway2 второй ip-адрес виртуальной VPN-сети
ifconfig-push 10.8.0.2 255.255.255.0
# сообщить серверу, что за этим клиентом есть сеть 192.168.250.0/24
iroute 192.168.250.0 255.255.255.0
$ sudo nano /etc/openvpn/ccd/branch-office-gw3
# назначить клиенту gateway3 третий ip-адрес виртуальной VPN-сети
ifconfig-push 10.8.0.3 255.255.255.0
# сообщить серверу, что за этим клиентом есть сеть 192.168.50.0/24
iroute 192.168.50.0 255.255.255.0

Скрипт аутентификации клиентов

Создаем скрипт проверки verify.sh и даем ему права на выполнение:

$ sudo mkdir -p /etc/openvpn/auth/tmp
$ sudo nano /etc/openvpn/auth/verify.sh
#!/bin/bash
username=`head -1 $1`
password=`tail -1 $1`
if [[ -z $username || -z $password ]]; then
    exit 1
fi
users=`cat /etc/openvpn/auth/users.pass`
for user in $users; do
    if [[ "$user" = "$username:$password" ]]; then
        exit 0
    fi
done
exit 1
$ sudo chmod a+x /etc/openvpn/auth/verify.sh

Предоставляем права на запись в директорию tmp-dir временного файла с логином и паролем — когда сервер уже будет работать от nobody и nogroup:

$ sudo chmod a+w /etc/openvpn/auth/tmp

И создаем файл users.pass для хранения логинов и паролей клиентов:

$ sudo nano /etc/openvpn/auth/users.pass
branch-office-gw2:abcdef123456
branch-office-gw3:fedcba654321

Все готово, можно запускать VPN-сервер:

$ sudo systemctl start openvpn-server@config.service

Добавим запуск сервера в автозагрузку:

$ sudo systemctl enable openvpn-server@config.service

Файлы конфигурации клиентов

Переходим на gateway2 и копируем с gateway1 следующие файлы:

$ sudo mkdir /etc/openvpn/keys/ # создаем директорию для ключей и сертификатов
$ sudo scp evgeniy@123.123.123.123:/home/evgeniy/easy-rsa/pki/ca.crt /etc/openvpn/keys/
$ sudo scp evgeniy@123.123.123.123:/home/evgeniy/easy-rsa/ta.key /etc/openvpn/keys/

Создаем файл конфигурации клиента:

$ sudo nano /etc/openvpn/client/config.conf
# работа по протоколу UDP (для TCP нужно указать tcp-client)
proto udp4
# сетевой интерфейс TUN (или TAP)
dev tun
# принимать от сервера команды push, например маршруты
pull

# ip-адрес и порт сервера
remote 123.123.123.123 1194

# если не удалось получить ip-адрес сервера от DNS, то через указанное
# количество секунд попытаться снова; infinite — повторять бесконечно
resolv-retry infinite

# использовать динамический порт для подключения к серверу (клиенту не
# требуется привязка к определенному порту)
nobind

# отбрасываем маршрут до сети, который не нужен клиенту gateway2
pull-filter ignore "route 192.168.250.0 255.255.255.0 10.8.0.1"

# включить TLS и при handshake представляться как клиент;
# TLS используется только для шифрования канала управления
tls-client

# корневой сертификат
ca /etc/openvpn/keys/ca.crt

# обратите внимание, что мы не указываем директивы cert и key
#cert /etc/openvpn/keys/branch-office.crt
#key /etc/openvpn/keys/branch-office.key

# для защиты от атаки «человек посередине», когда авторизованный клиент
# пытается подключиться к другому клиенту, выдавая себя за сервер; при
# указании этой директивы проверяется, что сертификат именно серверный
remote-cert-tls server

# добавляет дополнительную подпись HMAC ко всем пакетам handshake для
# проверки целостности; любой пакет, не имеющий правильной HMAC-подписи,
# будет отброшен без дальнейшей обработки; это для доп.безопасности
tls-auth /etc/openvpn/keys/ta.key
# направление ключа: для клиента — 1, для сервера — 0
key-direction 1

# использовать алгоритм AES-256-GCM шифрования пакетов канала данных;
# на данный момент это самый безопасный и быстрый алгоритм шифрования
cipher AES-256-GCM

# алгоритм хеширования — для проверки целостности передаваемых пакетов
# канала данных и (если включено tls-auth) пакетов канала управления
auth SHA256

# пользователь и группа с минимальными правами — для большей безопасности
user nobody
group nogroup

# не перечитывать файлы ключей при восстановлении туннеля после разрыва
persist-key
# оставлять без изменения устройства tun или tap при перезапуске службы
persist-tun

# логин и пароль клиента размещаем в файле — чтобы отправить их серверу
auth-user-pass /etc/openvpn/auth/user.pass

И создаем файл с логином и паролем:

$ sudo nano /etc/openvpn/auth/user.pass
branch-office-gw2
abcdef123456

Все готово, можно запускать VPN-клиент:

$ sudo systemctl start openvpn-client@config.service

Добавим запуск клиента в автозагрузку:

$ sudo systemctl enable openvpn-client@config.service

После этого переходим на gateway3 и делаем все точь-в-точь, как на gateway3 — копируем файлы ca.crt + ta.key, создаем файл конфигурации клиента, создаем файл user.pass с логином и паролем. Файл конфигурации будет отличаться только одной директивой:

# отбрасываем маршрут до сети, который не нужен клиенту gateway3
pull-filter ignore "route 192.168.50.0 255.255.255.0 10.8.0.1"

После этого можно запускать VPN-клиент:

$ sudo systemctl start openvpn-client@config.service

И добавим запуск клиента в автозагрузку:

$ sudo systemctl enable openvpn-client@config.service

Настройка gateway1

По умолчанию транзитный трафик отключен, так что редактируем файл /etc/sysctl.conf:

$ sudo nano /etc/sysctl.conf
# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1

Чтобы внесенные изменения вступили в силу, выполняем команду:

$ sudo sysctl -p
net.ipv4.ip_forward = 1

После этого настраиваем netfilter с помощью утилиты iptables:

$ sudo iptables -P FORWARD DROP
$ sudo apt install ipset
$ sudo ipset -N networks nethash # набор сетей, чтобы упростить правила
$ sudo ipset -A networks 192.168.250.0/24 # добавляем в набор первую сеть
$ sudo ipset -A networks 192.168.50.0/24 # добавляем в набор вторую сеть
$ sudo ipset -A networks 10.8.0.0/24 # добавляем в набор третью сеть
$ sudo iptables -A FORWARD -i enp0s8 -o enp0s3 -s 192.168.150.0/24 -m set ! --match-set networks dst -j ACCEPT # 1
$ sudo iptables -A FORWARD -i enp0s3 -o enp0s8 -d 192.168.150.0/24 -j ACCEPT # 2
$ sudo iptables -A FORWARD -i enp0s8 -o tun0 -s 192.168.150.0/24 -m set --match-set networks dst -j ACCEPT # 3
$ sudo iptables -A FORWARD -i tun0 -o enp0s8 -m set --match-set networks src -d 192.168.150.0/24 -j ACCEPT # 4

Получилось примерно так:

  1. пакеты из сети 192.168.150.0/24, не предназначеннные для трех сетей из набора — отправлять во внешний мир
  2. пакеты из внешнего мира, предназначенные для сети 192.168.150.0/24 — отправлять в сеть 192.168.150.0/24
  3. пакеты из сети 192.168.150.0/24, предназначенные для трех сетей из набора — отправлять в туннель
  4. пакеты из туннеля от трех сетей из набора, предназначеннные для 192.168.150.0/24 — отправлять в сеть 192.168.150.0/24
$ sudo iptables -L -v --line-numbers 
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts   bytes   target   prot   opt   in       out      source             destination

Chain FORWARD (policy DROP 0 packets, 0 bytes)
num   pkts   bytes   target   prot   opt   in       out      source             destination
1        0       0   ACCEPT   all    --    enp0s8   enp0s3   192.168.150.0/24   anywhere           ! match-set networks dst
2        0       0   ACCEPT   all    --    enp0s3   enp0s8   anywhere           192.168.150.0/24
3        0       0   ACCEPT   all    --    enp0s8   tun0     192.168.150.0/24   anywhere             match-set networks dst
4        0       0   ACCEPT   all    --    tun0     enp0s8   anywhere           192.168.150.0/24     match-set networks src

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts   bytes   target   prot   opt   in       out      source             destination

Теперь настроим SNAT (подмена адреса источника):

$ sudo iptables -t nat -A POSTROUTING -o enp0s3 -j MASQUERADE

Правила нужно сохранить и восстанавливать при перезагрузке:

$ sudo apt install iptables-persistent

Настройка gateway2

По умолчанию транзитный трафик отключен, так что редактируем файл /etc/sysctl.conf:

$ sudo nano /etc/sysctl.conf
# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1

Чтобы внесенные изменения вступили в силу, выполняем команду:

$ sudo sysctl -p
net.ipv4.ip_forward = 1

После этого настраиваем netfilter с помощью утилиты iptables:

$ sudo iptables -P FORWARD DROP
$ sudo apt install ipset
$ sudo ipset -N networks nethash # набор сетей, чтобы упростить правила
$ sudo ipset -A networks 192.168.150.0/24 # добавляем в набор первую сеть
$ sudo ipset -A networks 192.168.50.0/24 # добавляем в набор вторую сеть
$ sudo ipset -A networks 10.8.0.0/24 # добавляем в набор третью сеть
$ sudo iptables -A FORWARD -i enp0s8 -o enp0s3 -s 192.168.250.0/24 -m set ! --match-set networks dst -j ACCEPT # 1
$ sudo iptables -A FORWARD -i enp0s3 -o enp0s8 -d 192.168.250.0/24 -j ACCEPT # 2
$ sudo iptables -A FORWARD -i enp0s8 -o tun0 -s 192.168.250.0/24 -m set --match-set networks dst -j ACCEPT # 3
$ sudo iptables -A FORWARD -i tun0 -o enp0s8 -m set --match-set networks src -d 192.168.250.0/24 -j ACCEPT # 4

Получилось примерно так:

  1. пакеты из сети 192.168.250.0/24, не предназначеннные для трех сетей из набора — отправлять во внешний мир
  2. пакеты из внешнего мира, предназначенные для сети 192.168.250.0/24 — отправлять в сеть 192.168.250.0/24
  3. пакеты из сети 192.168.250.0/24, предназначенные для трех сетей из набора — отправлять в туннель
  4. пакеты из туннеля от трех сетей из набора, предназначеннные для 192.168.250.0/24 — отправлять в сеть 192.168.250.0/24
$ sudo iptables -L -v --line-numbers 
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts   bytes   target   prot   opt   in       out      source             destination

Chain FORWARD (policy DROP 0 packets, 0 bytes)
num   pkts   bytes   target   prot   opt   in       out      source             destination
1        0       0   ACCEPT   all    --    enp0s8   enp0s3   192.168.250.0/24   anywhere           ! match-set networks dst
2        0       0   ACCEPT   all    --    enp0s3   enp0s8   anywhere           192.168.250.0/24
3        0       0   ACCEPT   all    --    enp0s8   tun0     192.168.250.0/24   anywhere             match-set networks dst
4        0       0   ACCEPT   all    --    tun0     enp0s8   anywhere           192.168.250.0/24     match-set networks src

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts   bytes   target   prot   opt   in       out      source               destination

Теперь настроим SNAT (подмена адреса источника):

$ sudo iptables -t nat -A POSTROUTING -o enp0s3 -j MASQUERADE

Правила нужно сохранить и восстанавливать при перезагрузке:

$ sudo apt install iptables-persistent

Настройка gateway3

По умолчанию транзитный трафик отключен, так что редактируем файл /etc/sysctl.conf:

$ sudo nano /etc/sysctl.conf
# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1

Чтобы внесенные изменения вступили в силу, выполняем команду:

$ sudo sysctl -p
net.ipv4.ip_forward = 1

После этого настраиваем netfilter с помощью утилиты iptables:

$ sudo iptables -P FORWARD DROP
$ sudo apt install ipset
$ sudo ipset -N networks nethash # набор сетей, чтобы упростить правила
$ sudo ipset -A networks 192.168.150.0/24 # добавляем в набор первую сеть
$ sudo ipset -A networks 192.168.250.0/24 # добавляем в набор вторую сеть
$ sudo ipset -A networks 10.8.0.0/24 # добавляем в набор третью сеть
$ sudo iptables -A FORWARD -i enp0s8 -o enp0s3 -s 192.168.50.0/24 -m set ! --match-set networks dst -j ACCEPT # 1
$ sudo iptables -A FORWARD -i enp0s3 -o enp0s8 -d 192.168.50.0/24 -j ACCEPT # 2
$ sudo iptables -A FORWARD -i enp0s8 -o tun0 -s 192.168.50.0/24 -m set --match-set networks dst -j ACCEPT # 3
$ sudo iptables -A FORWARD -i tun0 -o enp0s8 -m set --match-set networks src -d 192.168.50.0/24 -j ACCEPT # 4

Получилось примерно так:

  1. пакеты из сети 192.168.50.0/24, не предназначеннные для трех сетей из набора — отправлять во внешний мир
  2. пакеты из внешнего мира, предназначенные для сети 192.168.50.0/24 — отправлять в сеть 192.168.50.0/24
  3. пакеты из сети 192.168.50.0/24, предназначенные для трех сетей из набора — отправлять в туннель
  4. пакеты из туннеля от трех сетей из набора, предназначеннные для 192.168.50.0/24 — отправлять в сеть 192.168.50.0/24
$ sudo iptables -L -v --line-numbers 
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts   bytes   target   prot   opt   in       out      source            destination

Chain FORWARD (policy DROP 0 packets, 0 bytes)
num   pkts   bytes   target   prot   opt   in       out      source            destination
1        0       0   ACCEPT   all    --    enp0s8   enp0s3   192.168.50.0/24   anywhere          ! match-set networks dst
2        0       0   ACCEPT   all    --    enp0s3   enp0s8   anywhere          192.168.50.0/24
3        0       0   ACCEPT   all    --    enp0s8   tun0     192.168.50.0/24   anywhere            match-set networks dst
4        0       0   ACCEPT   all    --    tun0     enp0s8   anywhere          192.168.50.0/24     match-set networks src

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts   bytes   target   prot   opt   in       out      source            destination

Теперь настроим SNAT (подмена адреса источника):

$ sudo iptables -t nat -A POSTROUTING -o enp0s3 -j MASQUERADE

Правила нужно сохранить и восстанавливать при перезагрузке:

$ sudo apt install iptables-persistent

Поиск: Linux • SSL • Ubuntu • VPN • Клиент • Ключ • Конфигурация • Локальная сеть • Маршрутизация • Настройка • Сервер • Установка • Сертификат

Каталог оборудования
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Производители
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Функциональные группы
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.