Назад | Перейти на главную страницу

VPN через средний / переходный сервер

Вот примерная картина того, что я пытаюсь сделать:

клиент -> | VPN | -> сервер A -> | VPN | -> сервер B -> Интернет.

Сервер A и сервер B находятся в общедоступном Интернете с общедоступными IP-адресами, также у меня есть root-доступ к обоим серверам. Клиент находится за брандмауэром, но может подключиться к серверу A. Клиент НЕ МОЖЕТ подключиться к серверу B напрямую. Сервер A может подключиться к серверу B. Сервер B - это то место, откуда я хочу, чтобы пакеты выходили в Интернет. Мне нужно зашифровать как сообщения от клиента к A, так и от A к B, поскольку A и B не находятся в общей локальной сети, поэтому трафик между A и B проходит через общедоступную инфраструктуру.

Мне удалось настроить сервер IPSec VPN на A и подключиться к нему. Но я не могу понять, как правильно установить другую VPN от A к B и перенаправить трафик, приходящий к A от клиента к B.

Подсказки?

p.s. изначально я думал об использовании туннелей SSH для соединения A и B, а затем маршрутизации соответствующего пакета от клиента, прибывающего в A, к B через такой туннель. Но, как люди отмечали в комментариях, это не очень хорошая идея. Так что я открыт для любых предложений. Спасибо!

РЕДАКТИРОВАТЬ # 1

Служба VPN на сервере A настроена с помощью strongswan, который обрабатывает любое соединение между клиентами и сервером A. Я сделал это через ipsec.conf:

# ipsec.conf - strongSwan IPsec configuration file

# basic configuration
config setup
        charondebug="ike 2, knl 2, cfg 2, net 2, esp 2, dmn 2, mgr 2"
        strictcrlpolicy=no
        uniqueids=yes
        cachecrls=no
conn ipsec-ikev2-vpn
      auto=add
      compress=no
      type=tunnel  # defines the type of connection, tunnel.
      keyexchange=ikev2
      fragmentation=yes
      forceencaps=yes
      dpdaction=clear
      dpddelay=300s
      rekey=no
      left=%any
      leftid=47.112.200.xxx    # if using IP, define it without the @ sign
      leftcert=vpn-server.cert.pem  # reads the VPN server cert in /etc/ipsec.d/certs
      leftsendcert=always
      leftsubnet=0.0.0.0/0
      right=%any
      rightid=%any
      rightauth=eap-mschapv2
      rightsourceip=10.10.10.0/24  # IP address Pool to be assigned to the clients
      rightdns=1.1.1.1,8.8.8.8  # DNS to be assigned to clients
      rightsendcert=never
      eap_identity=%identity  # defines the identity the client uses to reply to an EAP Identity request.

С участием ufw (в руководстве, которому я следовал, использовался ufw, но я могу работать с базовыми iptables правила) настройки в /etc/ufw/before.rules; Я пропустил часть, автоматически сгенерированную ufw, также я вручную разрешил udp на порте 500/4500 и tcp на порту 22:

#
# rules.before
#
# Rules that should be run before the ufw command line added rules. Custom
# rules should be added to one of these chains:
#   ufw-before-input
#   ufw-before-output
#   ufw-before-forward
#

# Don't delete these required lines, otherwise there will be errors
*nat
-A POSTROUTING -s 10.10.10.0/24 -o eth0 -m policy --pol ipsec --dir out -j ACCEPT
-A POSTROUTING -s 10.10.10.0/24 -o eth0 -j MASQUERADE
COMMIT

*mangle
-A FORWARD --match policy --pol ipsec --dir in -s 10.10.10.0/24 -o eth0 -p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1361:1536 -j TCPMSS --set-mss 1360
COMMIT

*filter
:ufw-before-input - [0:0]
:ufw-before-output - [0:0]
:ufw-before-forward - [0:0]
:ufw-not-local - [0:0]
# End required lines


-A ufw-before-forward --match policy --pol ipsec --dir in --proto esp -s 10.10.10.0/24 -j ACCEPT
-A ufw-before-forward --match policy --pol ipsec --dir out --proto esp -d 10.10.10.0/24 -j ACCEPT

Вот как далеко я зашел. Отдельная попытка настроить межсайтовый VPN через strongswan IPSec между A и B не удалась из-за того, что порты 500 и 4500 заблокированы / ограничены: клиент может связаться с A через 500/4500, A не может связаться с B через 500/4500 и Я выставил все порты B, чтобы открыть Интернет для тестирования.

РЕДАКТИРОВАТЬ 2

На данный момент единственный туннель, который мне удалось проложить между A и B, - это SSH socks (ssh -N -f -4 -D 1080 [server B ip] с сервера A). Я думаю о перенаправлении трафика, выходящего из A, чей пункт назначения не является моим клиентским устройством, на B через этот SSH-туннель.

Что-то вроде:-A OUTPUT -p tcp --dport 443 -j REDIRECT --to-ports 1080 в ufw / iptables. (на самом деле это не работает, IP-адрес сервера A все еще отображается в программе проверки IP, а заблокированные веб-сайты по-прежнему недоступны)

Если вы используете IPSec в Linux (StrongSwan), маршрутизация политики выполняется с использованием ip xfrm policy: политики с dir out используются, чтобы решить, в какой туннель пересылать пакеты, а политики с dir in и dir fwd используются, чтобы решить, разрешить или отбросить пакет.

Предполагать serverA имеет публичный IP 192.0.2.1 и частный IP 10.0.10.1 (вы можете прикрепить его к петлевому устройству), serverB имеет публичный IP 198.51.100.1 и частный IP 10.0.20.1, а VPN-клиенты получают IP-адрес в сети 10.0.30.0/24. Вы можете установить туннель, используя swanctl.conf на serverA вот так:

connections {
  serverB {
    version = 2
    local_addrs=192.0.2.1
    remote_addrs=198.51.100.1
    local {
        # serverA auth parameters
    }
        # serverB auth parameters
    }
    children {
      tunnel {
        local_ts = 10.0.10.0/24
        remote_ts = 10.0.20.0/24
        start_action = start
        reqid = 10
        priority = 1000
      }
    }
  }
}

а на serverB аналогичная конфигурация с local* и remote* перевернутый.

Обратите внимание, что reqid и priority параметры фиксированы, поэтому их можно использовать в политиках. Это невозможно сделать в ipsec.conf.

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

  1. Разрешить зашифрованный трафик с IP-адресов в 10.0.30.0/16 на любой IP. Это делается автоматически, если вы установите local_ts = 0.0.0.0/0 в конфигурации подключения VPN-клиентов.
  2. Разрешить зашифрованный трафик для 10.0.30.0/24 из туннеля с serverB:

    ip xfrm policy add src 0/0 dst 10.0.30/24 \
        dir fwd priority 2000 \
        tmpl src 198.51.100.1 dst 192.0.2.1 \
        proto esp reqid 10 mode tunnel
    

    Это работает аналогично ACCEPT править в FORWARD цепочка IP.

  3. Перенаправить трафик из 10.0.30.0/24 на serverB:

    ip xfrm policy add src 10.0.30/24 dst 0/0 \
        dir out priority 2000 \
        tmpl src 192.0.2.1 dst 198.51.100.1 \
        proto esp reqid 10 mode tunnel
    

Приоритеты выше, чем автоматически устанавливаемые StrongSwan, поэтому, если эти политики установлены, пересылка разрешена. Если вы удалите эти политики, установленные StrongSwan будут разрешать трафик только между 10.0.10.0/24 и 10.0.20.0/24. На serverB вы можете использовать те же политики, просто замените dir out с участием dir fwd.

PS: Конечно, вам также нужны некоторые правила iptables, чтобы serverA и serverB разрешали трафик ESP и IKE:

iptables -I INPUT -p esp -j ACCEPT
iptables -I INPUT -p udp -m multiport --dports 500,4500 -m comment --comment "IKE" -j ACCEPT

и некоторые правила отбрасывания, чтобы пакеты не выходили незашифрованными, если туннель выходит из строя:

iptables -A OUTPUT -o <external_interface> -s 10.0.0.0/16 -m policy --dir out --policy ipsec -j ACCEPT
iptables -A OUTPUT -o <external_interface> -s 10.0.0.0/16 -j DROP

редактировать: Поскольку вы используете ipsec.conf и эквивалентная конфигурация для вышеупомянутого swanctl.conf является:

conn servers {
    left=192.0.2.1
    right=198.51.100.1
    # The appropriate authentication leftauth, leftid, ...
    leftsubnet = 10.0.10.0/24
    rightsubnet = 10.0.20.0/24
    auto = start
    reqid = 10
}

С уважением к swanctl.conf он имеет то преимущество, что он работает без изменений на обоих хостах, но не позволяет устанавливать priority политик, поэтому вам нужно будет проверить, что StrongSwan выбирает для установки более высокого приоритета.

Расширяю мою подсказку в комментарии.

Я знаю, как создавать туннели в OpenVPN, так как использую его для подключения к сети IPv6, но идея должна быть такой же для IPSec.

Я начну с того, с чем я знаком (это IPv6), и покажу, как его можно преобразовать в IPv4.

Хотя дружеский отказ от ответственности:

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


Сервер A - версия IPv6

На моем сервере сетевой интерфейс туннеля OpenVPN называется tun0.

На Сервер А редактировать /etc/iproute2/rt_tables, поэтому у вас есть следующая запись:

200     openvpn

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

Таблица openvpn будет обрабатывать все пакеты, которые отправляются восходящим потоком (вы -> Интернет), в то время как таблица маршрутизации main будет обрабатывать весь нисходящий трафик (Интернет -> вы).

ip -6 rule add priority 32000 iif tun0 to 2000::/3 table openvpn
ip -6 route add default via <ipv6 address> dev tun1 table openvpn

Обратите внимание, что вам нужно будет добавить правила для любого диапазона IP-адресов, который принадлежит вам.

Предполагая, что диапазон IPv6 2001: db8: cafe :: / 48 принадлежит вам, и у вас есть следующие настройки:

  • ссылка клиента vpn находится на 2001: db8: cafe: 1 :: / 64 с клиентом, имеющим IP-адрес 2001: db8: cafe: 1 :: 100
  • клиентская локальная сеть - 2001: db8: cafe: 100 :: / 64, что даст правила:
ip -6 route add unreachable 2001:db8:cafe::/48 table main
ip -6 route add 2001:db8:cafe:100::/64 via 2001:db8:cafe:1::100 dev tun0

Сервер A - версия IPv4

Версия IPv4 будет:

Нам по-прежнему нужна выделенная таблица маршрутизации, потому что нам нужно маршрутизировать трафик на основе происхождения, поэтому /etc/iproute2/rt_tables еще нужна запись:

200     openvpn

Предполагая, что правила IPv4 в значительной степени аналогичны IPv6, вы получаете следующие команды для таблицы маршрутизации openvpn:

ip rule add priority 32000 iif tun0 to 0.0.0.0/0 table openvpn
ip route add default via <ipv4 address> dev tun1 table openvpn

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


Сервер B - версия IPv6

Вот два подхода к перенаправлению трафика IPv6 в Интернет:

  • Если вы получили маршрутизируемый пул IPv6 от интернет-провайдера, подключенного к Server B, тогда молодец. Таблица маршрутизации по умолчанию main вероятно, может сделать все за вас.

  • Если у вас есть блок IPv6 от, скажем, Hurricane Electric, вам в основном потребуется та же настройка, что и на Server A со специальной таблицей маршрутизации для восходящего потока и с использованием таблицы маршрутизации по умолчанию для нисходящего.

Сервер B - версия IPv4

Здесь, наверное, проще всего лечить Server B как NAT, поэтому вам необходимо замаскировать все пакеты, поступающие из вашей сети, перед их отправкой в ​​Интернет.