Jump to content

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


Recommended Posts

Задача простая, но хочу поделиться; может быть будет полезно новичкам, тем более что в Zyxel пришлось править настройки файрвола. Понадобится знание маршрутизации, iptables и Linux:)

У меня есть VPSка (с CentOS) на одном хостере в Восточной Европе, решил направить трафик на некоторые сети через нее с моего Keenetic Ultra. 

Выбирал между VPN на IPSec, OpenVPN и SSH Tunnel. Самый быстрый вариант наверное IPSec (потому что не заворачивается в userspace), но он самый сложный в настройке. В итоге остановился на OpenVPN и tun: tun это такой API в Linux когда траффик на виртуальный интерфейс сетевого уровня направляется в пользовательскую программу (OpenVPN в моем случае). Еще бывает tup, который эмулирует канальный уровень.

 

 

Сервер

На сервере поставил openvpn (``yum install openvpn``), настроил по https://openvpn.net/index.php/open-source/documentation/miscellaneous/78-static-key-mini-howto.html:

$ cat /etc/openvpn/server.conf

# хотим tun
dev tun

# IP сервера 172.16.1.1, IP клиента -- .2 (172.16. у нас приватная сетка)
ifconfig 172.16.1.1 172.16.1.2

# Будет слушать порт 443
port 443

# Будем работать по TCP
proto tcp-server

# Пингуем клиента каждые 10 секунд: если минуту не отвечает то считаем что отвалился
keepalive 10 60

# авторизироваться будем по ключу
secret static.key

 

Создал ключ в /etc/openvpn

$ openvpn --genkey --secret static.key

Запустил сервер (``systemctl enable openvpn@server && systemctl start openvpn@server``). У systemd юнита openvpn после собачки идет имя файла с конфигом.

 

Настройки iptables на centos хранятся в /etc/sysconfig/iptables, загружаются cat /etc/sysconfig/iptables | iptables-restore

Добавил в него NAT (тут написано что после роутинга, прямо перед отправкой пакета в Интернет (интерфейс venet) если он пришел из сети с VPN (см адрес) нужно поменять source на внешний IP ):

Получился обычный SNAT

*nat
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [1:76]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 172.16.1.0/24 -o venet+ -j SNAT --to [ВНЕШНИЙ_IP]

COMMIT
*filter
:INPUT DROP [83:5616]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [6911:1304844]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
...тут всякие мои правила
-A INPUT -s [ДОМАШНИЙ_МОЙ_ВНЕШНИЙ_IP] -m state --state NEW -p tcp --dport 443 -j ACCEPT

-A INPUT -i tun+ -j ACCEPT
-A FORWARD -i tun+ -o venet+ -j ACCEPT
-A FORWARD -i venet0 -o tun+ -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT

...и в filter: тут написано что с моего домашнего IP можно цепляться на порт 443, и что между внешним интерфейсом и tun (нашим VPN) можно пускать траффик: с VPN любой, а обратно только если он идет в ответ.

Zyxel

Скопировал себе static.key.

Поставил через opkg openvpn-ssl.

Настраиваем клиента /opt/etc/openvpn/openvpn.conf

remote [МОЙ_СЕРВЕР] 443 tcp-client
dev tun
ifconfig  172.16.1.2 172.16.1.1
connect-retry 15
connect-retry-max infinite
keepalive 10 60
resolv-retry infinite
route-up /opt/etc/openvpn/route.sh
secret /opt/etc/openvpn/static.key

Тут всё как на сервере, только мы tcp-client, пытаемся достучаться каждые 15 секунд (это важно, ведь у меня связь с провайдером по L2TP/IPSec, а оно иногда рвется!).

Так же указан ключик с секретом (скопированный!) и скрипт, который будет запускаться как только поднялся OpenVPN и будет править маршрутизацию.

На Zyxel systemd нету, так что у нас обычный systemV init: скрипт ``/opt/etc/init.d/S20openvpn`` поставится с Openvpn и будет запускаться при загрузке (ну или его можно start)

Запустил скрипт, в журнале увидел что соединение установлено, пошли пинги на интерфейс: ping 172.16.1.1

Тут началось интересное: маршрутизацией Zyxelевая прошивка управляет сама: она NATит весь траффик из локалки (интерфейс br0 -- видимо потому что bridge с другими ethernet портами на роутере) но по-умолчанию разрешает его только на ppp (то-есть на VPN с провайдером). Если добавить iptables -I INPUT -s [моя локалка] -j ACCEPT явно, то zyxel его перепишет.

Внести постоянные изменения можно через утилиту ndmc, или через UI.

Я пошел в UI и в сетевом экране для интерфейса Home добавил разрешение для TCP, UDP и ICMP куда угодно для 192.168.1.0/255.255.255.0 (такая у меня локалка)

Теперь с домашних компов пошли пинги на сервер интерфейса 172.16.1.1.

Осталось добавить маршруты в наш 

# /opt/etc/openvpn/route.sh

#!/bin/sh

# Network1
route add -net [СЕТКА_НА_КОТОРУЮ_Я_ХОЧУ_ХОДИТЬ_ЧЕРЕЗ_VPS] gw 172.16.1.1

route add -net [ЕЩЕ_СЕТКА_НА_КОТОРУЮ_Я_ХОЧУ_ХОДИТЬ_ЧЕРЕЗ_VPS] gw 172.16.1.1

Запустил скрипт и вуаля: иду на с домашнго компа на машину в той сети, и вижу что пришел туда не от своего провайдера, а со своего сервера:)

На всякий случай еще раз, вот как идет пакет:

1) С домашнего компа идет на роутер 

2) Роутер по маршрутизации понимает что его надо направить на VPS

3) Делает NAT (заменяет source адрес на 172.16.2.1)

4) Шлет его на сервер

5) Сервер опять меняет ему SRC на свой внешний IP

6) Шлет его в Интернет

7) В Интернет приходит мой пакет от имени моего сервера

Хорошо что не смотря на проприетарную прошивку, Zyxel это самый настоящий Linux роутер)

Теперь хочу сделать скрипт, который будет собирать список нужных мне сетей и выгружать их по cronу в route.sh. Если не хватит моих знаний sed/awk/shell, то придется ставить из opkg какой-то скриптовый язык. Вроде, там есть python:)

  • Upvote 1
Link to comment
Share on other sites

10 часов назад, IlyaK сказал:

тем более что в Zyxel пришлось править настройки файрвола. Понадобится знание маршрутизации, iptables и Linux:)

Это лишнее. Все делается по инструкции из этой темы средствами прошивки

 

Screenshot1.png

Screenshot2.png

Link to comment
Share on other sites

В 19.04.2018 в 04:12, IlyaK сказал:

Самый быстрый вариант наверное IPSec (потому что не заворачивается в userspace), но он самый сложный в настройке

Со стороны сервера - возможно. Со стороны роутера - в последних прошивках туннели уже упрощены максимально

В 19.04.2018 в 04:12, IlyaK сказал:

Еще бывает tup

tap

В 19.04.2018 в 04:12, IlyaK сказал:

# Будет слушать порт 443
port 443

# Будем работать по TCP
proto tcp-server

tcp/443 имеет смысл только если выходите в интернет через http-прокси или еще через какую-то "трудную" сеть. В остальных случаях лучше udp на любом нестандартном порту

В 19.04.2018 в 04:12, IlyaK сказал:

Поставил через opkg openvpn-ssl.

В последних прошивках уже давно есть OpenVPN из коробки

В 19.04.2018 в 04:12, IlyaK сказал:

Осталось добавить маршруты

... а маршруты были всегда. Маршруты через OPKG имеют смысл только при использовании ipset и прочей экзотики.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...