Как настроить маршрутизацию vpn
Перейти к содержимому

Как настроить маршрутизацию vpn

  • автор:

 

Записки IT специалиста

Организация VPN каналов между офисами. Маршрутизация

  • Автор: Уваров А.С.
  • 12.08.2015

VPN-route-000.jpgОрганизация каналов между удаленными сетями посредством VPN-соединения одна из самых популярных тем на нашем сайте. В тоже время, как показывает читательский отклик, наибольшие затруднения вызывает правильная настройка маршрутизации, хотя мы специально уделяли внимание этому моменту. Проанализировав наиболее часто задаваемые вопросы, мы решили посвятить теме маршрутизации отдельную статью. Есть вопросы? Надеемся, что после прочтения данного материала их станет меньше.

Научиться настраивать MikroTik с нуля или систематизировать уже имеющиеся знания можно на углубленном курсе по администрированию MikroTik. Автор курса, сертифицированный тренер MikroTik Дмитрий Скоромнов, лично проверяет лабораторные работы и контролирует прогресс каждого своего студента. В три раза больше информации, чем в вендорской программе MTCNA, более 20 часов практики и доступ навсегда.

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

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

Чтобы не быть голословными рассмотрим таблицу маршрутов самой обыкновенной рабочей станции. В Windows системах это можно сделать командой:

В итоге мы увидим следующую таблицу:

VPN-route-001.jpg

Все очень просто, нас интересует секция IPv4 таблица маршрута, первые две колонки содержат адрес назначения и маску сети, затем следует шлюз — узел которому следует перенаправить пакеты для указанного назначения, интерфейс и метрика. Если в колонке Шлюз указано On-link, то это означает что адрес назначения находится в одной сети с хостом и доступен без маршрутизации. Метрика определяет приоритет правил маршрутизации, если адрес назначения имеет в таблице маршрутов несколько правил, то используется тот, что имеет меньшую метрику.

VPN_route-4.png

Наша рабочая станция принадлежит к сети 192.168.31.0 и, согласно таблице маршрутов, все запросы к данной сети отправляет на интерфейс 192.168.31.175, что соответствует сетевому адресу это станции. Если адрес назначения находится в одной сети с адресом источником, то доставка информации происходит без использования IP-маршрутизации (сетевой уровень L3 модели OSI), на канальном уровне (L2). В противном случае пакет отправляется узлу, указанному в соответствующему сети назначения правилу таблицы маршрутов.

Если такого правила нет, то пакет отправляется по нулевому маршруту, который содержит адрес основного шлюза сети. В нашем случае это адрес роутера 192.168.31.100. Нулевым этот маршрут называется потому, что адресом назначения для него указывается 0.0.0.0. Этот момент является очень важным для дальнейшего понимания процесса маршрутизации: все пакеты, не принадлежащие данной сети и не имеющие отдельных маршрутов, всегда отправляются основному шлюзу сети.

Что сделает маршрутизатор, получив такой пакет? Прежде всего разберемся, чем отличается маршрутизатор от обычной сетевой станции. Если говорить крайне упрощенно, то маршрутизатором (роутером) является сетевое устройство, которое настроено передавать пакеты между сетевыми интерфейсами. В Windows это достигается включением службы Маршрутизация и удаленный доступ, в Linux заданием опции ip_forward.

Решение о передаче пакетов в этом случае также принимается на основании таблицы маршрутизации. Посмотрим, что содержит данная таблица на самом обычном роутере, например, описанном нами в статье: Ubuntu Server. Настраиваем роутер NAT + DHCP + Squid3. В Linux-системах получить таблицу маршрутов можно командой:

Как видим, наш роутер содержит маршруты к известным ему сетям 192.168.31.0 и 192.168.3.0, а также нулевой маршрут к вышестоящему шлюзу 192.168.3.1.

VPN-route-002.jpg

Адрес 0.0.0.0 в колонке шлюза (Gateway) обозначает, что адрес назначения доступен без маршрутизации. Таким образом все пакеты с адресами назначения в сетях 192.168.31.0 и 192.168.3.0 будут отправлены на соответствующий интерфейс, а все остальные пакеты будут переданы дальше по нулевому маршруту.

Следующий важный момент — адреса приватных (частных) сетей, они же «серые», к ним относятся три диапазона:

  • 10.0.0.0/8
  • 172.16.0.0/12
  • 192.168.0.0/16

Данные адреса могут свободно использоваться любым желающим и поэтому они не маршрутизируются. Что это значит? Любой пакет с адресом назначения принадлежащим одной из этих сетей будет отброшен маршрутизатором, если для него нет отдельной записи в таблице маршрутизации. Проще говоря, маршрут по умолчанию (нулевой) для таких пакетов маршрутизатором не применяется. Также следует понимать, что данное правило применяется только при маршрутизации, т.е. при передаче пакетов между интерфейсами, исходящий пакет с «серым» адресом будет отправлен по нулевому маршруту, даже если данный узел сам является маршрутизатором.

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

Самое время проверить, как это все работает. Попробуем с нашего узла 192.168.31.175 пропинговать узел 192.168.3.106, который находится в сети за роутером. Как видим, это нам удалось, хотя таблица маршрутов узла не содержит никаких сведений о сети 192.168.3.0.

VPN-route-003.jpg

Как это стало возможным? Так как узел-источник ничего не знает о сети назначения, то он отправит пакет на адрес шлюза. Шлюз проверит свою таблицу маршрутов, обнаружит там запись для сети 192.168.3.0 и отправит пакет на соответствующий интерфейс, в этом несложно убедиться выполнив команду трассировки, которая покажет весь путь нашего пакета:

VPN-route-004.jpg

Теперь попробуем выполнить пинг узла 192.168.31.175 с узла 192.168.3.106, т.е. в обратном направлении. У нас ничего не вышло. Почему?

VPN-route-005.jpg

Давайте внимательно посмотрим таблицу маршрутизации. Никаких записей для сети 192.168.31.0 она не содержит, поэтому пакет будет отправлен маршрутизатору 192.168.3.1, как основному шлюзу сети, который данный пакет отбросит, так как никаких данных о сети назначения не имеет. Как быть? Очевидно, что следует отправить пакет тому узлу, который содержит нужную информацию и может передать пакет по назначению, в нашем случае это роутер 192.168.31.100, который в данной сети имеет адрес 192.168.3.108.

Чтобы пакеты для сети 192.168.31.0 отправлялись именно ему, нам нужно создать отдельный маршрут.

В дальнейшем мы будем придерживаться такой записи маршрутов, что она значит? Все просто, пакеты для сети 192.168.31.0 с маской 255.255.255.0 следует отправлять узлу 192.168.3.108. В Windows маршрут можно добавить командой:

VPN-route-006.jpg

Давайте проанализируем результат, в таблице маршрутизации появился маршрут и все пакеты к сети 192.168.31.0 теперь отправляются роутеру этой сети, что видно из ответа команды ping, но до назначения не доходят. В чем дело? Самое время вспомнить, что одной из основных задач роутера является не только маршрутизация, но и функция сетевого экрана, который явно запрещает доступ из внешней сети внутрь. Если мы временно заменим данное правило разрешающим, то все будет работать.

VPN-route-007.jpg

Добавленные вышеуказанными командами маршруты сохраняются до перезагрузки узла, это удобно, даже если вы сильно накуролесили, достаточно просто выполнить перезагрузку, чтобы отменить внесенные изменения. Чтобы добавить постоянный маршрут в Windows выполните команду:

В Linux в /etc/network/interfaces, после описания интерфейса, следует добавить:

Кстати, это не единственный способ настроить доступ из сети 192.168.3.0 в сеть 192.168.31.0, вместо того, чтобы добавлять маршрут для каждого узла, можно «научить» правильно отправлять пакеты маршрутизатор.

VPN-route-008.jpg

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

Мы настоятельно рекомендуем самим потренироваться на аналогичных примерах, чтобы маршрутизация перестала быть для вас черным ящиком, а маршруты — китайской грамотой. После того как возникнет понимание, можно переходит ко второй части данной статьи.

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

Самый простой случай, когда VPN-сервер (клиент) и маршрутизатор сети располагаются на одном хосте. Рассмотрим схему ниже:

VPN-route-009.jpg

Так как теорию, надеемся, вы усвоили и закрепили на практике, проанализируем маршрут пакетов из сети офиса 192.168.31.0 в сеть филиала 192.168.44.0, такой пакет будет отправлен на шлюз по умолчанию, который является также VPN-сервером. Однако данный узел ничего не знает о сети назначения и должен будет откинуть данный пакет. В тоже время мы уже можем обратиться к маршрутизатору филиала по его адресу в VPN-сети 10.8.0.2, так как данная сеть доступна с маршрутизатора офиса.

Чтобы получить доступ к сети филиала нам нужно предать пакеты для этой сети узлу, который является частью этой сети или имеет маршрут к ней. В нашем случае это маршрутизатор филиала. Поэтом на маршрутизаторе офиса добавляем маршрут:

Теперь шлюз офиса, получив пакет для сети филиала, отправит его через VPN-канал маршрутизатору филиала, который, являясь узлом сети 192.168.44.0 доставит пакет по назначению. Для доступа из сети филиала в сеть офиса нужно прописать аналогичный маршрут на маршрутизаторе филиала.

Возьмем схему посложнее, когда маршрутизатор и VPN-сервер (клиент) являются разными узлами сети. Здесь возможны два варианта, передать нужный пакет непосредственно VPN-серверу (клиенту) или заставить это делать шлюз.

Сначала рассмотрим первый вариант.

VPN-route-010.jpg

Для того, чтобы пакеты для сети филиала попали в VPN-сеть мы должны добавить на каждый клиент сети маршрут к VPN-серверу (клиенту), в противном случае они будут отправлены шлюзу, который их отбросит:

Однако VPN-сервер ничего не знает о сети филиала, но может отправлять пакеты в пределах VPN-сети, где есть интересующий нас узел сети филиала, поэтому направим пакет туда, добавив на VPN-сервере (клиенте) маршрут:

Недостаток данной схемы — необходимость прописывать маршруты на каждом узле сети, что не всегда удобно. Его можно использовать если устройств в сети немного или требуется выборочный доступ. В остальных случаях задачу маршрутизации будет правильнее переложить на основной маршрутизатор сети.

VPN-route-011.jpg

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

Про задачу VPN-сервера (клиента) мы упоминали выше, он должен доставить пакеты тому узлу VPN-сети, который является частью сети назначения или имеет маршрут к ней.

Для доступа из сети филиала в сеть офиса потребуется добавить соответствующие маршруты на сетевые узлы филиала. Сделать это можно любым удобным способом, не обязательно также, как это сделано в офисе. Простой реальный пример: все компьютеры филиала должны иметь доступ к сети офиса, но не все компьютеры офиса должны иметь доступ в филиал. В таком случае в филиале добавляем маршрут к VPN-серверу (клиенту) на маршрутизаторе, а в офисе добавляем его только на нужные компьютеры.

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

Научиться настраивать MikroTik с нуля или систематизировать уже имеющиеся знания можно на углубленном курсе по администрированию MikroTik. Автор курса, сертифицированный тренер MikroTik Дмитрий Скоромнов, лично проверяет лабораторные работы и контролирует прогресс каждого своего студента. В три раза больше информации, чем в вендорской программе MTCNA, более 20 часов практики и доступ навсегда.

Дополнительные материалы:

Помогла статья? Поддержи автора и новые статьи будут выходить чаще:

Поддержи проект!

Или подпишись на наш Телеграм-канал: Подпишись на наш Telegram-канал

Автоматическое добавление статических маршрутов после подключения к VPN

date27.12.2022
useritpro
directoryWindows 10, Windows Server 2016
commentsкомментариев 11

В современных версиях Windows есть интересная возможность автоматического добавления статических маршрутов при активации определённого VPN подключения. Когда VPN подключение разрывается, данный маршрут автоматически удаляется из таблицы маршрутизации Windows. Для добавления IPv4 или IPv6 маршрута для VPN подключения используется PowerShell командлет Add-VpnConnectionRoute.

Допустим, вы хотите, чтобы через ваше VPN подключение маршрутизировались только пакеты для двух подсетей (192.168.111.24/ и 10.1.0.0/16), а весь основной трафик должен идти через вашего провайдера.

Откройте консоль PowerShell и выведите список всех настроенных VPN подключений в Windows:

Get-VpnConnection вывести список vpn подключений

В первую очередь нужно отключить опцию “Use default gateway in remote network” (Использовать основной шлюз в удаленной сети). Это можно сделать в свойствах VPN подключения в панели управления или командой:

Set-VpnConnection –Name workVPN -SplitTunneling $True

отключить опцию "Использовать основной шлюз в удаленной сети" для VPN подключений

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

Add-VpnConnectionRoute -ConnectionName «workVPN» -DestinationPrefix 192.168.111.0/24 –PassThru
Add-VpnConnectionRoute -ConnectionName «workVPN» -DestinationPrefix 10.1.0.0/16 –PassThru

Add-VpnConnectionRoute добавить статический маршрут для vpn подключения

Если у вас активно VPN подключение, вам нужно переподключиться, чтобы новые маршруты добавились в таблицу маршрутизации.

таблица маршрутизации при активном vpn в windows 10

Новые маршруты привязаны к VPN подключению и добавляются при его запуске. Когда вы отключаетесь от VPN сервера, маршруты автоматически удаляются.

Отключитесь от VPN и проверьте таблицу маршрутизации. Маршрут к вашей удаленной сети удалился автоматически, а Get-NetRoute вернет, что маршрут не найден:

маршут автоматически удаляется после отключения от vpn сервера в windows 10

Вывести список статических маршрутов для подключения:
(Get-VpnConnection -ConnectionName workVPN).Routes

Чтобы полностью удалить статических маршрут для VPN подключения, используйте команду:
Remove-VpnConnectionRoute -ConnectionName workVPN -DestinationPrefix 192.168.111.0/24 -PassThru

В предыдущих версиях Windows (Windows 7/ Server 2008R2) для динамического добавления маршрутов после установления VPN подключений приходилось использовать CMAK и различные скрипты с командами add route .

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

interface ipv4
add route prefix=192.168.111.24 interface=»workVPN» store=active
add route prefix=10.1.0.0/16 interface=»workVPN» store=active
exit

Данный файл нужно запускать через задание планировщика, которое срабатывает на событие установки VPN подключения в Event Viewer (RasMan 20225)

schtasks /create /F /TN «Add VPN routes» /TR «netsh -f C:\PS\vpn_route.netsh» /SC ONEVENT /EC Application /RL HIGHEST /MO «*[System[(Level=4 or Level=0) and (EventID=20225)]] and *[EventData[Data=’My VPN’]]»

Предыдущая статьяПредыдущая статья Следующая статья Следующая статья

Настройка VPN в Windows, изменение параметров маршрутизации

Часто бывает, когда нам требуется VPN соединение с рабочей сетью из дома. Для начала нам требуется создать этот самый VPN, конечно при условии, что есть сервер, к которому мы будем подключаться, а так же логин и пароль для авторизации. После того как мы создаём соединение в WINDOWS, подключаемся, кроме доступа к сети мы ещё и получаем интернет, который так же работает через рабочую сеть. А это по разным причинам может быть не всегда удобно, низкая скорость каналов, большие задержки ping, есть ограничения на доступ к ресурсам и т.д.

В этой статье коротко о том, как создать подключение к VPN. А так же как настроить маршрутизацию для туннеля, созданного стандартными средствами windows (7/8/10/2012/2016), так, что бы через него шёл только тот трафик, который нам необходим.

2016-11-20_14-24-10

1. Создание подключения.
1.1 Переходим в центр управления сетями и общим доступом. (нажать на значок сети правой кнопкой мыши)

1.2 Выбираем «Создание и настройка нового подключения или сети»

2016-11-21_14-29-01

1.3 Выбираем «Подключение к рабочему месту»

2016-11-21_14-29-18

1.4 Выбираем «Использовать мое подключение к интернету»

2016-11-21_14-29-46

1.5 Указываем IP адрес или доменное имя вашего сервера. Вводим название нашего подключения

2016-11-21_14-30-17

1.6 Далее (для win 8/10) нажимаем на панели задач на значок сети, выбираем подключение, нажимаем на него левой кнопкой мыши

2016-11-21_14-31-15

1.7 Находим подключение с нашим названием, нажимаем левой кнопкой мыши, нажимаем кнопку подключиться.

1.8 Вводим логин и пароль.

2016-11-21_14-32-35

После этого подключение должно работать.

Но что же делать, если нам надо пустить через VPN только какую-то часть трафика, например для определённых сетей?

2. Настройка маршрутизации для VPN подключения

2.1 Заходим снова в центр управления сетями и общим доступом. (нажать на значок сети правой кнопкой мыши)

2016-11-20_14-24-10

2.2 Выбираем раздел «Изменение параметров адаптера»

centr

2.3 Находим наше VPN подключение, нажимаем правой кнопкой мыши и выбираем пункт «Свойства»

2016-11-20_14-23-29

2.4 Переходим на вкладку «Сеть» и нажимаем кнопку «Свойства»

2016-11-20_14-22-59

2.5 Находим кнопку «Дополнительно»

2016-11-20_14-22-27

2.6 На вкладке «Параметры IP» убираем галочку «Использовать основной шлюз удалённой сети»

2016-11-20_14-21-55

Закрываем все окна, нажимая кнопку «ОК», пока не дойдём до окошка с вашим VPN. Как показано в пункте 1.6 подключаем соединение. Всё, теперь подключение установлено, но в удалённую сеть не будет идти никакой трафик, т.к мы отключили использование шлюза и ничего не добавили в маршрутизацию.

3. Настройка маршрутизации

 

3.1 Нажимаем снова на Ваше подключение правой кнопкой мыши, выбираем пункт «Подробно», если его нет, то «Состояние». Но тогда придётся сначала подключить Ваше VPN, зайти в состояние, посмотреть адрес шлюза и записать его.

3.2 В разделе «Подробно» смотрим на поле «Адрес сервера», записываем данные.

vpn_gw

3.3 Открываем поиск, в панели задач и вводим cmd (командная строка)

3.4 Вводим команду:

route add 192.168.0.0 MASK 255.255.255.0 172.239.0.1

192.168.0.0 — адрес Вашей рабочей сети.
MASK 255.255.255.0 -маска Вашей подсети
172.239.0.1 — шлюз

Как сделать VPN-туннель для недружественного почтового сервера

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

Введение

В статье предполагается, что на всех серверах установлена ОС Ubuntu 20.04, а в качестве почтового сервера используется Postfix. В целом, описанные здесь методы, скорее всего, будут применимы к любому дистрибутиву Linux, а также и к другим UNIX-подобным ОС (например, FreeBSD), но вам нужно будет сделать поправки в части используемого менеджера пакетов, фаервола и, возможно, настроек сетевой маршрутизации.

Добавлю также, что VPN-туннель между серверами можно использовать не только для почты, но и для проксирования любого другого протокола, где важно знать оригинальный IP-адрес клиента и где невозможно получить его каким-то иным способом, кроме как средствами нижележащего протокола транспортного уровня (TCP или UDP). Например, для HTTP достаточно простого обратного прокси, так как в нём реальный IP можно передавать с помощью заголовков X-Forwarded-For. В случае с SMTP также возможна настройка промежуточного почтового сервера (релея), но по сравнению с поднятием VPN это гораздо более трудоёмкая задача, поэтому рассматривать такой вариант мы здесь не будем.

Сценарий использования

Наш сценарий использования можно описать следующим образом. У нас есть основной сервер (назовём его mail.mydomain.com), который принимает и отправляет электронную почту. При этом существует определённый почтовый домен (например, unfriendly.org), MX-сервера которого не принимают входящие соединения от mail.mydomain.com из-за его «недружественности», не позволяя ему слать почту на адреса @unfriendly.org. Приём почты от @unfriendly.org тоже не работает по аналогичным причинам.

Мы арендуем дополнительный сервер-шлюз (назовём его vpn.mail.mydomain.com), который для MX unfriendly.org «недружественным» не является, и хотим установить между нашим шлюзом и основным сервером VPN-туннель, чтобы иметь возможность обмениваться почтой между @unfriendly.org и mail.mydomain.com.

Отдельно отметим, что мы НЕ хотим, чтобы все исходящие соединения с mail.mydomain.com шли через VPN — через наш шлюз должны идти соединения только при отправке на @unfriendly.org (и другие проблемные домены, если они есть), а все остальные соединения должны идти напрямую. В итоге должна получиться следующая схема:

(создано на скорую руку в app.diagrams.net)

(создано на скорую руку в app.diagrams.net)

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

Далее перемещаемся в папку /etc/openvpn/server и генерируем общий ключ для TLS-аутентификации (мы будем использовать его и на сервере, и на клиенте):

Теперь создадим файл конфигурации сервера server.conf в той же папке. Ниже привожу содержимое этого файла с дополнительными комментариями:

Чтобы установить статический IP-адрес в VPN-сети для нашего почтового сервера, создадим папку /etc/openvpn/server/ccd и добавим туда файл mail.mydomain.com со следующей строчкой:

Локальный IP-адрес сервера (vpn.mail.mydomain.com) будет 172.16.0.1, клиента (mail.mydomain.com) — 172.16.0.2.

Дополнительно вы можете жёстко задать параметры шифрования для использования эллиптических кривых, особенно если у вас другая ОС с более старой версией OpenSSL, где могут поддерживаться не все современные наборы шифров. Как это сделать, см. здесь (спасибо за материал пользователю @Maxim_Q).

Настройка фаервола

В Ubuntu 20.04 в качестве фаервола используется ufw , который является фронтендом для популярного в Linux iptables . Помимо правил, добавляемых с помощью команд, в ufw есть конфигурационные файлы, позволяющие прописывать дополнительные правила в формате iptables . Откроем файл /etc/ufw/before.rules и добавим в начало следующие строчки:

Здесь добавляется два правила в таблицу NAT:

-A PREROUTING . перенаправляет входящие TCP-соединения на 25-й порт с интерфейса eth0 на адрес 172.16.0.2 (то есть на наш почтовый сервер mail.mydomain.com).

-A POSTROUTING . разрешает исходящие соединения из локальной VPN-сети на интерфейс eth0 (в интернет) путём настройки SNAT для исходящих пакетов.

NB: Проверьте (например, через ifconfig ), что ваш основной сетевой интерфейс называется именно eth0 . Если это не так, укажите в правилах корректное название.

Дополнительно нужно включить и разрешить форвардинг IPv4-пакетов. Для этого сначала отредактируем /etc/sysctl.conf и раскомментируем в нём строчку net.ipv4.ip_forward=1 . Затем применим новые настройки с помощью команды:

Теперь в файле /etc/default/ufw находим строчку DEFAULT_FORWARD_POLICY=»DROP» и меняем DROP на ACCEPT. Осталось только включить ufw и разрешить через него входящие SMTP- и OpenVPN-соединения. Не забываем также разрешить и SSH-соединения, чтобы не заблокировать себе доступ:

NB: Не забудьте указать корректный номер порта OpenVPN вместо 6876, если вы используете другой порт (например, стандартый 1194).

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

Сначала на машину mail.mydomain.com нужно установить пакет OpenVPN — делаем это таким же способом, как на VPN-сервере. Затем копируем сгенерированный на предыдущем этапе общий ключ ta.key с VPN-сервера в папку /etc/openvpn/client . Далее создаём конфигурационный файл /etc/openvpn/client/client.conf :

Замечание

Если вы понижаете привилегии процесса OpenVPN, то при остановке клиента или сервера через systemctl или при перезагрузке системы будете наблюдать в логе сообщения вида:

Объясню, в чём дело: OpenVPN хочет удалить маршрут к VPN-подсети из системы, но не может этого сделать из-за пониженных привилегий (с добавлением маршрута проблем нет, так как привилегии понижаются не сразу, а после завершения начальной настройки). Но это не является чем-то критичным, так как маршрут всё равно пропадает автоматически после удаления туннельного сетевого интерфейса, что как раз и происходит при остановке OpenVPN.

Если вы всё же хотите избавиться от этих сообщений, можно попробовать сделать это, например, вот так. Я этот метод не пробовал, поэтому не могу сказать, будут ли здесь какие-то ещё проблемы, но лично мне этот вариант кажется не очень безопасным, так как он, по сути, сводится к разрешению выполнения команды ip для непривилегированных пользователей.

Выпуск сертификатов для аутентификации

Если вам лень возиться с настройкой собственного центра сертификации, можно попробовать использовать другой способ аутентификации — статический ключ. Вот здесь описывается, как это сделать. Вам нужно будет подправить конфигурацию и удалить все упоминания о сертификатах, а также убрать client-config-dir и прописать настройки IP-адресов вручную на стороне клиента и сервера. Убедитесь, что сервер запускается, путём выполнения команды:

Если что-то пошло не так, проверьте лог:

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

Если всё в порядке, то переходите к следующему разделу данного руководства «Настройка маршрутизации».

OpenVPN по умолчанию использует сертификатную аутентификацию. Это значит, что при подключении клиент и сервер должны обменяться X.509-сертификатами, подписанными доверенным удостоверяющим центром (УЦ). Такой центр мы создадим самостоятельно и сначала выпустим корневой сертификат, который установим и на сервер, и на клиент, а затем создадим и подпишем для них пользовательские сертификаты.

Почему мы не можем использовать для выпуска сертификата, например, сервис Let’s Encrypt? Всё просто: если наш VPN-сервер будет доверять УЦ Let’s Encrypt, то без дополнительных настроек кто угодно сможет запросить у них сертификат и использовать его для подключения к нашему VPN, чего мы, конечно же, не хотим. Поэтому мы развернём свой собственный центр сертификации, работу которого мы можем контролировать. В этом нам поможет пакет EasyRSA, представляющий собой обёртку над популярной утилитой OpenSSL.

Отметим также, что УЦ на базе EasyRSA необязательно устанавливать именно на VPN-сервер, более того, такой вариант менее безопасен, так как на сервере будет храниться приватный ключ вашего центра сертификации, которым можно подписывать пользовательские сертификаты и таким образом управлять доступом к вашему VPN-серверу. Оптимальный вариант — установить УЦ на ваш домашний компьютер, ноут и т.д. (если вы параноик, можете вообще отключить его от сети и передавать все данные на флешках).

Пакет EasyRSA используется не только для создания центра сертификации, но и для генерации приватных ключей и запросов на выпуск сертификатов. Работает это так:

На сервере vpn.mail.mydomain.com генерируем пару «приватный ключ» — «запрос на сертификат».

Отправляем файл запроса в УЦ.

УЦ создаёт и подписывает сертификат и отправляет его обратно на сервер.

Аналогичные операции проводим на машине mail.mydomain.com.

Обратите внимание, что ни один приватный ключ (в том числе ключ самого УЦ) не покидает машины, на которой он генерируется. Это одно из важных преимуществ использования криптосистемы с открытым ключом.

Установка центра сертификации

Как уже говорил ранее, этот шаг желательно выполнять на отдельной машине. Для упрощения будем полагать, что на ней также стоит Ubuntu 20.04.

Сначала установим пакет easy-rsa:

Теперь создадим в домашнем каталоге папку easyrsa , в которой будем хранить настройки, сертификат и приватный ключ нашего УЦ:

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

Начиная с версии 2.4, в OpenVPN возможно использование криптографии на эллиптических кривых, которая является более надёжной по сравнению с традиционным RSA. Чтобы использовать эллиптические кривые (в данном случае предлагается кривая secp521r1), создадим файл

/easyrsa/vars со следующим содержимым:

Далее выполняем команды:

На момент написания данного текста в версии OpenSSL в Ubuntu 20.04 есть небольшой баг, из-за которого при генерации ключей может появляться сообщение вида random number generator:RAND_load_file:Cannot open file (источник). Оно не свидетельствует о критической ошибке, но от него можно избавиться, создав указанный файл вручную:

Осталось инициализировать сам УЦ:

В ходе создания УЦ вас попросят ввести парольную фразу — рекомендуется сделать её достаточно сложной, чтобы её нельзя было подобрать. Также нужно будет задать имя (Common Name) для вашего УЦ — можно использовать в качестве него, например, имя хоста вашей машины. Если вы пропустите этот шаг, по умолчанию будет использоваться имя «Easy-RSA CA», не являющееся особо примечательным, поэтому рекомендую вместо него задать своё имя — тогда при проверке выпущенных сертификатов будет сразу понятно, что они подписаны именно вашим УЦ.

Выпуск сертификата для VPN-сервера

Теперь займёмся выпуском сертификата для OpenVPN-сервера на машине vpn.mail.mydomain.com. Для этого на неё сначала необходимо установить пакет EasyRSA и выполнить все команды до init-pki включительно (см. выше). Далее нам необходимо сгенерировать приватный ключ и запрос на сертификат, который мы отправим в наш УЦ:

Обратите внимание на параметр nopass — если его не указать, то EasyRSA попросит вас задать парольную фразу для генерируемого ключа, и VPN-сервер каждый раз при запуске будет её запрашивать (по очевидным причинам нам такой вариант не подходит). Также в ходе выполнения команды gen-req у вас снова запросят имя (Common Name), на этот раз для будущего сертификата — тут можно просто нажать Enter, чтобы использовать имя, которое вы указали в параметрах команды. В итоге у вас должны сгенерироваться два файла:

/easyrsa/pki/private/vpn.mail.mydomain.com.key — это приватный ключ. Его необходимо переместить в папку /etc/openvpn/server , предварительно сменив владельца на root :

/easyrsa/pki/reqs/vpn.mail.mydomain.com.req — это запрос на создание сертификата. Этот файл необходимо переместить на машину УЦ в любую папку (например, /tmp ), затем на ней же выполнить команды:

Убеждаемся, что Common Name в запросе на сертификат совпадает с именем хоста соответствующей машины (в данном случае vpn.mydomain.com) и, если всё верно, вводим «yes», после этого вас ещё попросят ввести парольную фразу, которую вы придумали ранее при создании УЦ. Сертификат будет сгенерирован по следующему пути:

/easyrsa/pki/issued/vpn.mail.mydomain.com.crt . Берём его вместе с корневым сертификатом УЦ, который находится в

/easyrsa/pki/ca.crt , и копируем на VPN-сервер в папку /etc/openvpn/server . Не забываем про настройки владельца и права доступа для этих файлов ( chown root:root и chmod 600 соответственно).

На данном этапе настройка VPN-сервера завершена. Чтобы запустить сервер, выполняем на нём команду:

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

Если при запуске возникла ошибка, посмотреть лог можно с помощью следующей команды:

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

Выпуск сертификата для VPN-клиента

Как и на VPN-сервере, на машине mail.mydomain.com тоже нужно установить пакет EasyRSA и выполнить init-pki . После этого создаём приватный ключ и запрос на сертификат:

Перемещаем сгенерированный приватный ключ из

/easyrsa/pki/private/mail.mydomain.com.key в папку /etc/openvpn/client , не забывая про смену владельца:

Затем отправляем файл запроса

/easyrsa/pki/reqs/mail.mydomain.com.req на машину УЦ (например, в /tmp ), импортируем, выпускаем сертификат:

Ещё раз вводим «yes» (предварительно убедившись, что Common Name совпадает с mail.mydomain.com) и парольную фразу. Как и в предыдущий раз, сертификат создаётся по пути:

/easyrsa/pki/issued/mail.mydomain.com.crt . Копируем его и корневой сертификат из

/easyrsa/pki/ca.crt на машину mail.mydomain.com в папку /etc/openvpn/client , в очередной раз не забывая про настройку прав доступа.

На этом, казалось бы, всё, и VPN-клиент готов к работе, но остаётся ещё один момент — маршрутизация. Не забыли про строчку up openvpn_routes.sh в конфигурации клиента? Сейчас мы с этим разберёмся.

Настройка маршрутизации на VPN-клиенте

Напомню, что наш сценарий заключается в том, что направлять через VPN мы хотим не весь интернет-трафик, а только определённые соединения. Здесь есть небольшая проблема, так как обычно для всех исходящих интернет-соединений используется шлюз по умолчанию, ассоциированный с основным сетевым интерфейсом (например, eth0 ). Напомню, что на VPN-сервере мы специально не включали SNAT для входящих IP-пакетов, так как при подключении к почтовому серверу нам важно видеть реальный IP-адрес удалённой стороны вместо локального адреса VPN-сервера (172.16.0.1). Если ничего не настраивать, то при входящем соединении через VPN ответ этому IP-адресу, согласно правилам маршрутизации, почтовый сервер отправит через основной сетевой интерфейс. Очевидно, что ни к чему хорошему это привести не может.

Решением данной проблемы является создание альтернативной таблицы маршрутизации и задание правил для её использования. Источником для написания данного раздела послужила эта статья.

Сначала нам нужно указать системе, что мы создаём новую таблицу маршрутизации. В данном руководстве она будет называться openvpn . Создадим файл /etc/iproute2/rt_tables.d/openvpn.conf с единственной строчкой:

Теперь создаём shell-скрипт /etc/openvpn/client/openvpn_routes.sh со следующим содержимым:

Не забываем сделать его исполняемым:

Согласно настройкам клиента, этот скрипт будет выполняться каждый раз после поднятия туннельного сетевого интерфейса. Давайте разберёмся, что здесь происходит:

Команда ip route add default . добавляет маршрут со шлюзом по умолчанию 172.16.0.1 (локальный IP нашего VPN-сервера) через интерфейс $dev в таблицу маршрутизации openvpn . Значение параметра $dev устанавливается самим клиентом OpenVPN перед запуском скрипта и содержит название туннельного интерфейса для VPN-соединения (обычно это tun0 ).

Команда ip rule add from . добавляет правило маршрутизации, предписывающее использовать таблицу openvpn для всех исходящих соединений с IP-адреса 172.16.0.2 (это локальный IP нашего VPN-клиента).

Команда ip rule add to . добавляет аналогичное правило маршрутизации, но оно относится уже к входящим соединениям.

Таким образом, после выполнения данного скрипта все соединения, где одной из конечных точек является локальный IP-адрес машины mail.mydomain.com в VPN-туннеле (т.е. 172.16.0.2), будут маршрутизироваться через этот туннель. Чтобы проверить это, сначала поднимаем клиент:

Рекомендую также добавить его в автозапуск:

Если клиент стартовал без ошибок, для начала рекомендую попинговать 172.16.0.1, чтобы убедиться, что соединение с сервером действительно есть. Теперь попробуем соединиться через VPN с сервисом telnetmyip.com, чтобы убедиться, что маршрутизация работает корректно. С помощью telnet это можно сделать так:

У меня этот сервис почему-то ничего не выводит, а просто закрывает соединение (возможно, из-за той же пресловутой «недружественности»). В этом случае можно попробовать ещё через curl :

Вы получите ответ вида:

Если WW.XX.YY.ZZ совпадает с внешним IP-адресом машины vpn.mail.mydomain.com, то поздравляю — всё настроено корректно! Замечу, что в случае некорректной настройки вам, скорее всего, вообще не удастся установить соединение.

Входящие соединения можно проверить, подключившись с помощью telnet к vpn.mail.mydomain.com на порт 25 с любой сторонней машины (например, с домашней — если, конечно, ваш интернет-провайдер не блокирует 25-й порт на выход). При этом в логах почтового сервера должен появиться ваш реальный внешний IP-адрес, а не локальный адрес VPN-сервера 172.16.0.1.

Настройка Postfix

Приём почты

Чтобы принимать в Postfix входящие соединения через VPN-туннель, вам не нужно менять никаких настроек — достаточно лишь добавить в DNS вторую MX-запись для вашего почтового домена, указав в ней имя хоста vpn.mail.mydomain.com. Рекомендуется поставить ей низкий приоритет (например, если для основной записи у вас приоритет 10, ставьте 100), чтобы соединения через VPN-шлюз шли только тогда, когда доступ к основному серверу заблокирован с удалённой стороны.

Единственное, что здесь стоит отметить — при соединении с vpn.mail.mydomain.com ваш сервер будет представляться как mail.mydomain.com. Это не должно повлиять на доставку почты, но если вы хотите сделать всё «по феншую», то нужно будет немного пошаманить с конфигурацией. Здесь есть два варианта, которые сводятся к тому, чтобы в /etc/postfix/master.cf создать дополнительный SMTP-сервер, который будет принимать соединения через VPN, и прописать ему нужное значение myhostname .

Первый вариант: привязать второй SMTP-сервер к IP-адресу в локальной VPN-сети, вот так это будет выглядеть в master.cf :

Проблема здесь в том, что если VPN-туннель не поднят, при запуске Postfix выдаст фатальную ошибку: «fatal: bind 172.16.0.2 port 25: Cannot assign requested address». Поэтому я считаю такой способ не очень надёжным (например, если OpenVPN почему-то откажется запускаться, то Postfix тоже не сможет стартовать). Но можно поступить чуть хитрее, а именно — создать сервер, привязанный к другому порту. В примере ниже используется порт 4925 вместо стандартного 25:

Чтобы это заработало, на VPN-сервере нужно отредактировать файл /etc/ufw/before.rules : в правиле -A PREROUTING . , которое мы создавали при настройке сервера, нужно поменять в конце порт 25 на 4925. Затем выполнить команду:

NB: Если после этого вы видите, что на стороне Postfix подключение идёт всё ещё на 25-й порт — попробуйте перезагрузить VPN-сервер.

Теперь при подключении к vpn.mail.mydomain.com сервер представится вам именно этим именем. Обратите внимание, что мы также указали для нового сервера syslog_service_name=postfix/vpn , чтобы в логе было видно, как маршрутизируется соединение:

Если вы используете postscreen и хотите отвечать корректным именем при подключении через VPN, то помимо второго SMTP-сервера нужен будет второй postscreen с соответствующими настройками. Выглядеть это будет так:

Дополнительно вам нужно будет настроить postscreen так, чтобы он обращался к файлу кэша через proxymap , иначе получите фатальную ошибку из-за невозможности эксклюзивной блокировки этого файла. Добавляем в /etc/postfix/main.cf :

Отправка почты

Для отправки почты через VPN-сервер в первую очередь, конечно, нужно убедиться, что разрешены исходящие соединения по 25-му порту и что у сервера всё в порядке с PTR, SPF и спам-листами. Если с этим проблем нет, то можно приступить к настройке.

Сначала создадим в /etc/postfix/master.cf отдельный SMTP-клиент и укажем ему значение smtp_bind_address , соответствующее локальному IP-адресу нашего почтовика в VPN-сети — в нашем случае это 172.16.0.2. По умолчанию, если Postfix не может выполнить биндинг на smtp_bind_address , он логирует предупреждение и повторяет попытку отправки уже с основного адреса. Postfix 3.7 содержит полезную настройку smtp_bind_address_enforce , которую мы можем включить для предотвращения подобного поведения: в этом случае, если VPN-туннель временно не работает, письмо просто вернётся в очередь для повторной отправки.

Теперь настроим выборочную отправку писем на определённые домены через VPN. В нашем примере мы хотим отправлять через VPN письма на @unfriendly.org. Создаём файл /etc/postfix/vpn_transport со следующей строчкой:

и добавляем в /etc/postfix/main.cf :

Далее выполняем команды:

и пробуем отправить письмо на любой адрес в домене unfriendly.org, затем убеждаемся, что при отправке этого письма вы видите в логе не postfix/smtp , а postfix/vpn/smtp . Аналогичным образом можно добавлять в /etc/postfix/vpn_transport другие почтовые домены, не забываем только каждый раз делать postmap и reload . Конечно, необязательно использовать именно формат hash для хранения транспортной таблицы — вы можете хранить эти данные в любом другом удобном вам формате (при условии, что он поддерживается в Postfix), в том числе в каком-нибудь MySQL/MariaDB.

Заключение

В данной статье мы рассмотрели простой способ создания альтернативного канала связи между почтовым сервером и внешним миром, который можно использовать, если по каким-то причинам (например, из-за «недружественности») связь с определёнными MX-хостами через основной канал не работает. Можно отметить следующие достоинства данного способа:

Простота настройки, особенно по сравнению с поднятием полноценного резервного почтового сервера (backup MX);

Возможность горизонтального масштабирования: при необходимости можно арендовать ещё один сервер и быстро поднять ещё один резервный канал — вследствие простоты настройки на это уйдёт совсем немного времени;

Никакие данные не хранятся на VPN-сервере, что особенно важно, если он расположен в РФ;

Для VPN-сервера можно выбирать самую дешёвую конфигурацию, так как OpenVPN не затрачивает большого количества ресурсов системы, если речь идёт об одном клиенте с небольшими объёмами трафика (что как раз применимо к нашему случаю).

Недостатком данного решения является привязка VPN-шлюза к конкретному почтовому серверу. Если ваша почтовая инфраструктура содержит несколько серверов, развёртывание туннеля может быть затруднено.

Ещё одной потенциальной проблемой, хоть и не связанной непосредственно с VPN, является ручная настройка списка «недружественных» почтовых доменов — при большом количестве пользователей на почтовом сервере это может быть просто неудобно. В теории можно попробовать автоматизировать этот процесс, написав свой собственный сервис, который будет пытаться устанавливать соединение с MX-серверами получателя с разных сетевых интерфейсов и, в зависимости от результатов, выбирать для передачи письма прямой SMTP-транспорт или VPN — но эта тема уже выходит за рамки данной статьи.

 

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *