Openvpn iptables настройка linux

Обновлено: 06.07.2024

Часто возникает необходимость организовать VPN-туннель чтобы скрыть свой реальный IP-адрес, или находясь за NAT своего провайдера и имея "снаружи" сервер с реальным IP-адресом использовать преимущества этого адреса. Далее будет показано как можно решить эту задачу используя OpenVPN.

В качестве сервера мы будем использовать VDS от Gelihost с тарифом SmallVDS-VPN и установленной операционной системой Ubuntu 8.04. На этом тарифном плане нам дают два IP-адреса в разных сетях класса C.

Допустим что нам были выделены адреса 1.1.1.10 и 1.1.2.10. Первый мы используем как "точку входа" (к нему буду подключаться клиенты), а второй как "точку выхода" (в этот адрес мы будем транслировать адреса наших клиентов). Клиентам мы будем выдавать адреса из сети 172.17.255.0/24.

Для начала установим необходимое программное обеспечение:

Настройка iptables

Сразу настроим правила iptables, для этого создадим скрипт /usr/local/scripts/firewall.sh следующего содержания:

Применим эти правила:

И добавим строку вызова этого скрипта в файл /etc/rc.local. Затем добавим в файл /etc/sysctl.conf строку:

Эта строка разрешает пересылку пакетов в соответствии с правилами iptables в цепочке FORWARD таблицы filter. Применим эти изменения командой:

Настройка DNS-сервера

Теперь настроим DNS-сервер для клиентов (в качестве него мы будем использовать пакет maradns, установленный чуть раньше). Для этого открываем в редакторе файл /etc/maradns/mararc и первым делом меняем значение параметра "bind_address":

Затем разрешим использование сервера нашими клиентами добавив в конец файла строки:

Чтобы настройки вступили в силу перезапустим процесс:

Настройка OpenVPN-сервера

На этом приготовления закончены и можем приступить к настройке OpenVPN-сервера. Для начала подготовим структуру каталогов:

Переходим директорию /etc/openvpn/easy-rsa:

Редактируем файл "vars", указывая желаемые данные для генерируемых сертификатов после чего устанавливаем необходимые переменный окружения командой:

Генерируем основные ключи:

Генерируем сертификат сервера:

Далее для каждого из пользователей генерируем именной клиентский сертификат:

Закончив создание сертификатов приступаем к написанию файлов конфигурации. Создаём файл /etc/openvpn/server.conf следующего содержания:

Закончив написание основного файла конфигурации сервера создадим для каждого пользовательского сертификата соответствующий ему файл конфигурации. Между клиентом и сервером будет устанавливаться соединение "точка-точка". Для каждого клиента мы выделим подсеть с маской /30 из нашей виртуальной сети (172.17.255.0/24).

В каждой такой подсети один адрес будет принадлежать серверу, а другой - клиенту. Приведём сводную таблицу возможных адресов для нашего случая:

Сеть Адрес сервера Адрес клиента
172.17.255.0/30 172.17.255.1 172.17.255.2
172.17.255.4/30 172.17.255.5 172.17.255.6
172.17.255.8/30 172.17.255.9 172.17.255.10
172.17.255.12/30 172.17.255.13 172.17.255.14
172.17.255.16/30 172.17.255.17 172.17.255.18
172.17.255.20/30 172.17.255.21 172.17.255.22
172.17.255.24/30 172.17.255.25 172.17.255.26
172.17.255.28/30 172.17.255.29 172.17.255.30
172.17.255.32/30 172.17.255.33 172.17.255.34
172.17.255.36/30 172.17.255.37 172.17.255.38
172.17.255.40/30 172.17.255.41 172.17.255.42
172.17.255.44/30 172.17.255.45 172.17.255.46
172.17.255.48/30 172.17.255.49 172.17.255.50
172.17.255.52/30 172.17.255.53 172.17.255.54
172.17.255.56/30 172.17.255.57 172.17.255.58
172.17.255.60/30 172.17.255.61 172.17.255.62
172.17.255.64/30 172.17.255.65 172.17.255.66
172.17.255.68/30 172.17.255.69 172.17.255.70
172.17.255.72/30 172.17.255.73 172.17.255.74
172.17.255.76/30 172.17.255.77 172.17.255.78
172.17.255.80/30 172.17.255.81 172.17.255.82
172.17.255.84/30 172.17.255.85 172.17.255.86
172.17.255.88/30 172.17.255.89 172.17.255.90
172.17.255.92/30 172.17.255.93 172.17.255.94
172.17.255.96/30 172.17.255.97 172.17.255.98
172.17.255.100/30 172.17.255.101 172.17.255.102
172.17.255.104/30 172.17.255.105 172.17.255.106
172.17.255.108/30 172.17.255.109 172.17.255.110
172.17.255.112/30 172.17.255.113 172.17.255.114
172.17.255.116/30 172.17.255.117 172.17.255.118
172.17.255.120/30 172.17.255.121 172.17.255.122
172.17.255.124/30 172.17.255.125 172.17.255.126
172.17.255.128/30 172.17.255.129 172.17.255.130
172.17.255.132/30 172.17.255.133 172.17.255.134
172.17.255.136/30 172.17.255.137 172.17.255.138
172.17.255.140/30 172.17.255.141 172.17.255.142
172.17.255.144/30 172.17.255.145 172.17.255.146
172.17.255.148/30 172.17.255.149 172.17.255.150
172.17.255.152/30 172.17.255.153 172.17.255.154
172.17.255.156/30 172.17.255.157 172.17.255.158
172.17.255.160/30 172.17.255.161 172.17.255.162
172.17.255.164/30 172.17.255.165 172.17.255.166
172.17.255.168/30 172.17.255.169 172.17.255.170
172.17.255.172/30 172.17.255.173 172.17.255.174
172.17.255.176/30 172.17.255.177 172.17.255.178
172.17.255.180/30 172.17.255.181 172.17.255.182
172.17.255.184/30 172.17.255.185 172.17.255.186
172.17.255.188/30 172.17.255.189 172.17.255.190
172.17.255.192/30 172.17.255.193 172.17.255.194
172.17.255.196/30 172.17.255.197 172.17.255.198
172.17.255.200/30 172.17.255.201 172.17.255.202
172.17.255.204/30 172.17.255.205 172.17.255.206
172.17.255.208/30 172.17.255.209 172.17.255.210
172.17.255.212/30 172.17.255.213 172.17.255.214
172.17.255.216/30 172.17.255.217 172.17.255.218
172.17.255.220/30 172.17.255.221 172.17.255.222
172.17.255.224/30 172.17.255.225 172.17.255.226
172.17.255.228/30 172.17.255.229 172.17.255.230
172.17.255.232/30 172.17.255.233 172.17.255.234
172.17.255.236/30 172.17.255.237 172.17.255.238
172.17.255.240/30 172.17.255.241 172.17.255.242
172.17.255.244/30 172.17.255.245 172.17.255.246
172.17.255.248/30 172.17.255.249 172.17.255.250
172.17.255.252/30 172.17.255.253 172.17.255.254

Подобный список можно сгенерировать с помощью несложного скрипта на perl:

Таким образом к нашему серверу может подключиться до шестидесяти четырёх клиентов. Теперь для каждого клиента нужно создать файл с именем вроде "/etc/openvpn/ccd/username" (здесь имя файла совпадает с именем соответствующего сертификата) и примерно такого содержания:

Если вам лень писать отдельную конфигурацию для каждого клиента вы можете посмотреть в сторону опции ifconfig-pool-persist, подробнее о которой можно прочитать в документации OpenVPN или в примерах использования. Закончив написание файлов конфигурации перезапустим сервис командой:

Информацию о состоянии сервера можно получать в реальном времени читая файл "/var/run/openvpn.server.status".

Настройка клиента на машине под управлением Linux

На этом настройка сервера заканчивается и можно переходить к настройке клиентских машин. Для начала рассмотрим настройки клиентов, работающих в операционной системе Linux (на примере Ubuntu 9.10, однако в остальных дистрибутивах всё будет примерно так же).

Первым делом установим openvpn-клиент:

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

  • ca.crt
  • username.crt
  • username.key

А затем создадим файл "/etc/openvpn/client.conf", следующего содержания:

Разумеется что имена файлов ключей и адрес сервера нужно адаптировать под свой случай. Закончив конфигурирование клиента перезапустим процесс:

Проверить что соединение установлено можно проверив таблицу роутинга на машине командой:

Результат должен выглядеть примерно вот так:

Если что-то пойдёт не так - внимательно проверьте конфигурацию клиента.

Настройка клиента на машине под управлением Windows

Переходим к настройке клиента на машине под управлением Windows. Для начала нужно скачать последнюю версию клиента OpenVPN и проинсталлировать её.

По умолчанию клиент устанавливается в директорию "C:\Program Files\OpenVPN", в которой есть поддиректория "config". В эту поддиректорию нужно положить файлы ключей, а так же в ней нужно создать файл "client.ovpn", следующего содержания:

После этого нужно запустить приложение "OpenVPN GUI", в трее появится иконка с изображением двух красных мониторов. По этой иконке надо кликнуть правой кнопкой мыши и в выпавшем меню выбрать пункт "Connect".

Так же следует отметить что OpenVPN имеет проблемы с Windows 7, поэтому пользователям этой операционной системы нужно в свойствах файла "openvpn.exe" выставить режим совместимости с Windows Vista и поставить галочку "Запускать с правами администратора".

Работа клиентов через прокси

Если клиент находится за прокси, то нужно добавить в файл конфигурации клиента строку:

Здесь нужно указать адрес и порт прокси-сервера. Если используется прокси с авторизацией то настройка будет немного сложнее и подробнее об этом рекомендуется читать в документации OpenVPN.

Насколько я понял транзитный трафик нужно разрешить между всеми интерфейсами ?


тебе одного маскарада/snat не хватит?


Ну насколько я помню NAT-правила не обеспечивают форвардинг трафика между интерфейсами, они непосредственно имеют дело с перезаписыванием адресов отправителя/получателя и портов. Для продвижения трафика используется цепочка FORWARD таблицы filter


Какой странный маскарад.
-j SNAT --to-source tun0 не должно даже добавиться, т.к. tun0 не является ip-адресом. Если имелся ввиду именно адрес, то не должно работать, т.к. на выходе из интерфейса ppp0 адрес отправителя будет от tun0. Или это какой-то Хитрый План?
Прокидывание тоже непонятное. Разрешены соединения из интернетов к другим (openvpn) серверам через уже поднятый tun0.


гммм верно тогда так


сообственно вопрос еще -

Что необходимо FORWARD для работы VPN сервака (клиенты будут цеплятся с наружи и из локалки )?


По учебнику:
1. разрешаем пересылку:

2. разрешаем подключаться к openvpn-серверу с любой стороны: 3. разрешаем всем openvpn-клиентам соединение с интернетами: Если ip-адрес на ppp0 статический, то лучше будет так: Уже должно работать. Далее по парано^W безопасности:
разрешаем только установленные и связанные с ними соединения: И запрещаем всё, что не разрешено явно (в данном случае разрешены только входящие openvpn соединения):


Ссылку на учебник киньте пожалуйста





еще уточнить хочу


тут 192.168.0.3 - адрес этого самого клиента, который был не виден из инета напрямую.


Это был вопрос, или утверждение?


уже разобрался спасибо


3. разрешаем всем openvpn-клиентам соединение с интернетами:

Если уж всем клиентам, то тогда "-i tun+ -o ppp0 -j ACCEPT"


При dev tun на каждое соединение новый интерфейс на сервере поднимается? Я не помню, просто :) давно на tap перебрался, там такого точно нет.

а чтобы они улетали обратно, как прописать SNAT/MASQUERADE ?


Если (для клиентов) vpn-сервер ещё и шлюз по умолчанию, то не обязательно. Ответ в интернет всё равно будет происходить через vpn-сервер.

А в общем случае - всему, что будет вылезать из tun0 ставим <адрес_отправителя>=адрес_на_tun0:

А iptables tutorial всё-таки покури. Там всё это расписано так, что даже я понял.

При dev tun на каждое соединение новый интерфейс на сервере поднимается?

Не, у ТС мультиклиентский сервер, tun один должен быть. А вообще сколько конфигов в /etc/openvpn положил, - столько и интерфейсов поднимится.

Для удобства настройки заходим под суперпользователем:

Подготовка системы

Обновляем установленные пакеты:

Установим правильную временную зону:

timedatectl set-timezone Europe/Moscow

* в данном примере московское время.

Устанавливаем сервис для синхронизации времени:

yum install chrony

Разрешаем автозапуск службы chrony и запускаем ее:

systemctl enable chronyd --now

Чтобы Selinux не включился после перезагрузки, откроем данный файл:

И отредактируем строчку SELINUX=enforcing на:

Создаем правило для firewalld:

firewall-cmd --permanent --add-port=443/udp

* в данной инструкции мы настроим работу OpenVPN на порту 443 по UDP (по умолчанию, это 1194/UDP). Если в вашем случае необходим другие порт и протокол, меняем значения на соответствующие.

. и применяем его:

* если используется iptables, правило создаем командой iptables -I 1 INPUT -p udp --dport 443 -j ACCEPT, где 443 — порт, который мы будем использовать для openvpn.

Установка, настройка и запуск VPN-сервера

Установка OpenVPN

Устанавливаем репозиторий epel:

yum install epel-release

Устанавливаем необходимые пакеты следующей командой:

yum install openvpn easy-rsa

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

В основе идеи VPN лежит шифрование трафика, а значит для его работы необходимы сертификаты.

Переходим в каталог easy-rsa:

* в зависимости от версии easy-rsa, последний каталог может быть другим. Увидеть точное название каталога можно командой ls /usr/share/easy-rsa/.

Чтобы упростить и ускорить процесс создания ключей, создаем следующий файл:

* где KEY_CN и KEY_OU: рабочие подразделения (например, можно указать название отдела); KEY_NAME: адрес, по которому будет выполняться подключение (можно указать полное наименование сервера); KEY_ALTNAMES — альтернативный адрес.
* так как мы генерируем самоподписный сертификат, значения данных полей никак не повлияют на работу OpenVPN, однако, для удобства, лучше подставить реальные данные.

Если требуется обеспечить связь между локальными сетями, но оба маршрутизатора имеют серые ip-адреса — потребуется промежуточный сервер, у которого есть белый ip-адрес. Итак, у нас по-прежнему есть локальная сеть компании и локальная сеть филиала. Маршрутизатор gateway1 обеспечивает выход в интернет для компьютеров сети 192.168.150.0/24 , а маршрутизатор gateway2 — для компьютеров сети 192.168.250.0/24 .


Настройка маршрутизатора gateway1

Сначала настраиваем сетевые интерфейсы с помощью Netplan:

Применяем настройки и смотрим сетевые интерфейсы:

Сервер gateway1 должен обеспечивать выход в интернет для всех компьютеров из локальной сети 192.168.150.0/24 .

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

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


Устанавливаем пакет iptables-persistent , чтобы сохранить добавленные правила:

Настройка маршрутизатора gateway2

Сначала настраиваем сетевые интерфейсы с помощью Netplan:

Применяем настройки и смотрим сетевые интерфейсы:

Сервер gateway2 должен обеспечивать выход в интернет для всех компьютеров из локальной сети 192.168.250.0/24 .

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

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


Устанавливаем пакет iptables-persistent , чтобы сохранить добавленные правила:

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

Центр сертификации будет на сервере 123.123.123.123 , хотя это и неправильно (ЦС должен быть на отдельном сервере):

Создаем копию файла vars.example — это пример конфигурации. Ничего в нем изменять не будем, в этом случае EASYRSA_DN имеет значение по умолчанию cn_only (Common Name Only), требующий ввода только универсального имени (подробности здесь).

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

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

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

Ключи для сервера и клиентов

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

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

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

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

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

2. Создание ключей для клиента gateway1

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

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

3. Создание ключей для клиента gateway2

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

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

Настройка VPN-сервера

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

Теперь создаем файл конфигурации VPN-сервера (это предварительный вариант, мы его еще дополним чуть позже):

Директива server является макрокомандой и имеет синтаксис:

Она будет преобразована по следующему алгортиму:

В нашем случае это означает следующее:

Директива server с параметром nopool задает VPN-сеть без определения для нее пула ip-адресов. Затем с помощью директивы ifconfig-pool нужно самостоятельно задать пул ip-адресов для клиентов.

Чтобы VPN-клиенты видели друг друга, добавим директиву:

Теперь добавим маршруты в файл конфигурации сервера:

Директивы, которые будут выполнены при подключении клиента gateway1 :

Директивы, которые будут выполнены при подключении клиента gateway2 :

Обратите внимание, что только клиент gateway1 будет знать маршрут до сети 192.168.250.0/24 . И только клиент gateway2 будет знать маршрут до сети 192.168.150.0/24 . Если нужно, чтобы и другие клиенты знали о существовании этих сетей, нужно вынести директивы push "route …" в общий файл конфигурации сервера.

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

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

Настройка VPN-клиентов

1. Настройка клиента gateway1

Переходим к gateway1 и после установки пакета openvpn копируем ключи с сервера 123.123.123.123 :

Теперь создаем файл конфигурации VPN-клиента:

Директива client является макрокомандой и преобразуется в директивы:

Директива pull-filter позволяет отклонить директивы, отправленные сервером с помощью push :

Игнорировать изменение шлюза:

Если в шаблоне text есть пробел:

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

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

2. Настройка клиента gateway2

Переходим к gateway2 и после установки пакета openvpn копируем ключи с сервера 123.123.123.123 :

Теперь создаем файл конфигурации VPN-клиента:

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

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

Фильтрация пакетов между сетями

Чтобы пакеты могли ходить между подсетями, мы добавили в файл конфигурации сервера директиву client-to-client . Давайте закомментируем эту директиву и вместо этого разрешим пересылку пакетов между интерфейсами на сервере 123.123.123.123 .

Разрешаем пересылку пакетов между интерфейсами:

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

Разрешаем пакеты между двумя подсетями:

При использовании директивы client-to-client работать будет быстрее, потому что OpenVPN передает пакеты клиент-клиент внутри себя, не используя сетевой стек операционной системы. Но пересылка пакетов между интерфейсами позволяет задействовать всю мощь netfilter для фильтрации пакетов. Здесь важно то, что пакеты проходят через netfilter и мы можем управлять этим с помощью утилиты iptables .

С помощью команды ping и tcpdump проверим, что есть связь между gateway1 и gateway2 . На сервере 123.123.123.123 выполним команду tcpdump :

А на маршрутизаторе gateway1 — команду ping :

И на сервере 123.123.123.123 мы видим прохождение пакетов:

Редиректы используются маршрутизаторами, чтобы известить хост о наличии более удобного маршрута, ведущего к определенному пункту назначения. Но в нашем случае редиректы только мешают, так что давайте их запретим для интерфейса tun0 :

Опять выполним команду tcpdump на сервере, а с gateway1 будем пинговать gateway2 :

Здесь видно, что пакеты приходят на интерфейс tun0 сервера, проходят через netfilter (где мы их можем обработать), а потом покидают сервер все с того же интерфейса tun0 .

Давайте для примера запретим компьютеру pc3 доступ к серверу 192.168.150.254 :

Читайте также: