IPtables-маршрут некоторый трафик через туннель

Допустим, у нас есть машины с двумя интерфейсами: ens160 и wg0.

Допустим, у нас есть маршруты как ниже:

172.29.248.128/25 dev ens160 proto kernel scope link src 172.29.248.134
192.168.2.0/24 dev wg0 proto kernel scope link src 192.168.2.2

Наша первая машина имеет ips: 172.29.248.134, 192.168.2.2

вторая машина:

endpoint: 172.29.244.20:51820
allowed ips: 192.168.2.1/32

первая машина может соединиться с второй машиной на обоих IPs, 172.29.244.20 и 192.168.2.1.

теперь, то, что я хочу достичь, когда первая машина пытается достичь 172.29.244.20, он должен пройти через wg0 взаимодействие. Что-то вроде назначения IP переписать для этого конкретного IP, от 172.29.244.20 до 192.168.2.1

возможно ли это?
Если да, можем ли мы также переписать его на второй машине, так что если он получает что-нибудь на wg0 интерфейс из 192.168.2.2, исходный ip должен быть изменен обратно на 172.29.248.134 и передан в ens160?

можно ли это сделать чисто с ip route? Или нам нужно iptables?

@dirkt
Спасибо, что нормально сработало и я попробовал, но похоже ситуация немного сложнее. На самом деле все сложнее, потому что я пытаюсь настроить шифрование между машинами для кластера Kubernetes, но из-за проблем с сетевым плагином (Calico), более прозрачным способом, чем непосредственно с помощью 192.168.2.0/24. В основном существует инкапсуляция IP-in-IP через VPN-туннель уровня 3 и множество правил iptables. wg0 интерфейс Wireguard (VPN), оно имеет подсеть 192.168.2.0/24. Я использую 192.168.2.1/32, чтобы указать один IP для VPN, потому что я хочу создайте сетчатую сеть. Я не могу указать 192.168.2.0/24 для разрешенных IP-адресов, потому что wireguard не разрешает одну и ту же подсеть для нескольких одноранговых узлов.

теперь я вижу, что перенаправление всех trafic на этот ip через wg0 может быть глупая идея, потому что я вижу tcpdump на машине отправка пинга работает корректно (ICMP запросы видны), но ничего не показывает на принимающей машине wg0.

я спросил об этом на wireguard IRC и проблема, вероятно есть:

The problem is that outgoing traffic to the other wireguard endpoint is no longer routed over ens160.
But looped into the wireguard interface.

хорошо, но здесь может быть решение, от wireguard документация .

FwMark — a 32-bit fwmark for outgoing packets. If set to 0 or "off", this option is disabled. May be specified in hexadecimal by prepending "0x". Optional.

нашел статьи об этой "рекурсивной проблеме VPN", но мои сетевые навыки довольно бедны.
Что делать, чтобы направить трафик на 172.29.244.20/32 via 192.168.2.2 dev wg0 за исключением пакетов, помеченных определенным fwmark?

9
задан Adiqq
13.12.2022 17:05 Количество просмотров материала 3405
Распечатать страницу

2 ответа

вы пропустили полное описание вашей сети, поэтому я предполагаю, что хост A (первый) и хост B (второй) напрямую подключены к одному и тому же сегменту на wg0 на хосте A с 192.168.2.2/24, и хост B с 92.168.2.1/?? (том /32 у вас, скорее всего, ошибка - у каждого хоста на сегменте должна быть одна и та же маска подсети, поэтому, скорее всего, вы имеете в виду /24). Если это не так, отредактируйте свой вопрос с описанием сети, маской сети и IP-адресами по адресу конечная точка.

далее, Если вы хотите, чтобы направить, использовать функции маршрутизации ядра. Я не знаю, почему так много людей думают, что iptables для маршрутизации. Это не так, независимо от того, что Вы читаете в интернете. Если обычной маршрутизации недостаточно, используйте маршрутизацию политики. Если политика маршрутизации не достаточно, то вы можете думать о делать смешные вещи с iptables.

функции маршрутизации ядра оптимизированы для быстрого принятия решений о маршрутизации. Это неправда для iptables.

(извините за громкие слова, но это моя любимая мозоль).

так что в вашем случае, все, что вам нужно сделать, это добавить маршрут на Сказать, что он следует по маршруту через 192.168.2.2 при попытке связаться с 72.29.244.20:

ip route add 72.29.244.20/32 via 192.168.2.2 dev wg0

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

вы можете даже подумать о расширении 72.29.244.20/32 to 72.29.244.0/24 или что-то еще, если есть другие хосты в этом диапазоне, которые могут быть более удобно достигнуты по этому маршруту.

0
отвечен dirkt 2022-12-15 00:53

задача и цель

наличие пакетов часть WireGuard envelope (пакеты UDP, транспортирующие зашифрованные полезные данные), не подлежащие инкапсуляции туннеля сами несмотря на использование того же IP внутри туннеля как вне туннеля.

метод

поскольку стек маршрутизации (IP-маршрут, правило ip...) работает на уровне 3 (IP), а не на уровне 4 (UDP, используемый конвертом), это не может быть решено только со стеком маршрутизации без дополнительной помощи отличить пакеты конверта от пакетов" данных".

к счастью, можно пометить пакет меткой (чисто внутренне, на skbuff пакета, конечно, не на проводе). Затем тег можно повторно использовать в качестве fwmark для стека маршрутизации. Средства (я знаю), способные пометить пакеты, являются iptables, nftables ... и WireGuard себя.

в виду того что Wireguard однако может маркировать пакеты после заключения никакая потребность использовать iptables / nftables как дополнительная помощь для маршрутизации.

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

AllowedIps = 172.29.244.0/25,172.29.248.128/25

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

решение

различать пакеты конвертов и туннелированные пакеты с пометкой. Там даже не нужно указывать, какой UDP-порт он должен быть, WireGuard обрабатывает эту часть. Используйте эту метку, чтобы сделать" исключение для исключения " для маршрута выбор.

выбор

согласно комментарию OP, нет необходимости в пересылке пакетов, поэтому пересылка не была проверена.

выбор, сделанный здесь, чтобы отметить пакеты, которые не войдут в туннель с помощью WireGuard (другой рабочий раствор, с помощью iptables вместо WireGuard пометить пакеты, может сделать наоборот и помечать пакеты въезда в туннель).

- инструкции

настройки пример:

# ip -4 -br addr show dev ens160
ens160@if7       UP             172.29.248.132/25 
# ip route
default via 10.0.3.1 dev eth0 
10.0.3.0/24 dev eth0 proto kernel scope link src 10.0.3.147 
172.29.244.0/25 via 172.29.248.129 dev ens160 
172.29.248.128/25 dev ens160 proto kernel scope link src 172.29.248.132 

# wg show wg0
interface: wg0
  public key: 7FsVTBuIDNQsWj9flHWwMt+kCaE8urEE9bCwcvz6CBM=
  private key: (hidden)
  listening port: 51820

peer: +NJdQr+piwid1iuC58rbnXFgGo/vZ9d8Gs3xvl3/TxI=
  endpoint: 172.29.248.134:51820
  allowed ips: (none)
  transfer: 14.74 KiB received, 34.35 KiB sent

peer: KrZWEupjHGoHTywwWhg4XXQSyFl/disav7/pyhOK/1Q=
  endpoint: 172.29.244.20:51820
  allowed ips: (none)
  transfer: 11.06 KiB received, 15.65 KiB sent

так как в конце концов все может пройти через туннель, повторно используя те же IP-адреса, сеть 192.168.2.0 / 24 больше не используется. Поскольку ни одно правило маршрутизации не будет ссылаться на эти IP-адреса, их можно даже удалить: wg0 будет иметь нулевой IP-адрес (по-прежнему можно сохранить их при желании):

# ip addr flush dev wg0

настроить wg0 для пометки пакетов конвертов произвольно выбранным значением (здесь 9):

# wg set wg0 fwmark 9

настроить каждый WireGuard принимать в IP конечной точки в туннеле, вот цель:

# wg show wg0|awk 'BEGIN { RS="\n\n" } /^peer/ { printf "wg set wg0 peer %s allowed-ips %s\n",, }'|cut -d: -f1 | sh

теперь:

# wg show wg0
interface: wg0
  public key: 7FsVTBuIDNQsWj9flHWwMt+kCaE8urEE9bCwcvz6CBM=
  private key: (hidden)
  listening port: 51820
  fwmark: 0x9

peer: +NJdQr+piwid1iuC58rbnXFgGo/vZ9d8Gs3xvl3/TxI=
  endpoint: 172.29.248.134:51820
  allowed ips: 172.29.248.134/32
  transfer: 14.74 KiB received, 34.35 KiB sent

peer: KrZWEupjHGoHTywwWhg4XXQSyFl/disav7/pyhOK/1Q=
  endpoint: 172.29.244.20:51820
  allowed ips: 172.29.244.20/32
  transfer: 11.06 KiB received, 15.65 KiB sent

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

...либо только один раз, маршруты для обеих локальных сетей, но это потребует использования WireGuard для любого IP-трафика с любым узлом в локальных сетях:

# localip=$(ip -4 -br addr show dev ens160|awk '{ print  }'|cut -d/ -f1)
# ip route add 172.29.244.0/25   dev wg0 table 200 src $localip
# ip route add 172.29.248.128/25 dev wg0 table 200 src $localip

что дает:

# ip route show table 200
172.29.244.0/25 dev wg0 scope link src 172.29.248.132 
172.29.248.128/25 dev wg0 scope link src 172.29.248.132 

...либо добавьте на одноранговые маршруты:

# localip=$(ip -4 -br addr show dev ens160|awk '{ print  }'|cut -d/ -f1)
# wg show wg0|awk 'BEGIN { RS="\n\n" } /^peer/ { printf "ip route add %s dev wg0 table 200 src %s\n",gensub(":.*$","",1,),localip }' localip=$localip | sh

который дает вместо этого здесь:

# ip route show table 200
172.29.244.20 dev wg0 scope link src 172.29.248.132 
172.29.248.134 dev wg0 scope link src 172.29.248.132 

исправьте заранее проблемы с курицей и яйцом, которые будут введены правилом после этого, используя непосредственно основную таблицу маршрутизации для пакетов, отмеченных WireGuard (те 51820 / UDP-пакеты):

# ip rule add priority 32000 fwmark 9 lookup main

"вставить" после поиска в таблице 200. Фактически только пакеты с маршрутами, установленными выше для WireGuard, будут совпадать и будет использовать туннель через wg0, остальные пакеты продолжат (обычную) главную таблицу:

# ip rule add priority 32100 lookup 200

это правило 32100 и таблица 200, которые заменяют обычную маршрутизацию, выполненную внутри wg0, когда на ней установлены IP-адреса.

теперь:

# ip rule
0:  from all lookup local 
32000:  from all fwmark 0x9 lookup main 
32100:  from all lookup 200 
32766:  from all lookup main 
32767:  from all lookup default 

увы, фильтр обратного пути теперь срабатывает для входящего трафика без WireGuard, поступающего из обычного интерфейса (здесь ens160), когда теперь ожидается wg0. Это включает пакеты ответа ARP необходимо найти сверстников в той же локальной сети, а также шлюз в другую локальную сеть (у меня нет хорошего объяснения по этому поводу). Так rp_filter должен быть установлен в свободный режим для нормального интерфейса (здесь ens160):

echo 2 > /proc/sys/net/ipv4/conf/ens160/rp_filter

С этими настройками, повторенными на других узлах, все узлы теперь могут взаимодействовать друг с другом, используя свой собственный IP, как если бы не было туннеля (в сетке, потенциально использующей до n*(n-1)/2 туннелей).

пример: хост получает одиночный пинг и отвечает:

# tcpdump -n -s0 -i wg0 -p
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on wg0, link-type RAW (Raw IP), capture size 262144 bytes
05:22:51.553463 IP 172.29.244.20 > 172.29.248.132: ICMP echo request, id 2083, seq 1, length 64
05:22:51.553525 IP 172.29.248.132 > 172.29.244.20: ICMP echo reply, id 2083, seq 1, length 64

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

# tcpdump -n -s0 -i br248 -p
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on br248, link-type EN10MB (Ethernet), capture size 262144 bytes
05:22:51.553317 ARP, Request who-has 172.29.248.132 tell 172.29.248.129, length 28
05:22:51.553358 ARP, Reply 172.29.248.132 is-at 2e:02:6e:cf:6d:4f, length 28
05:22:51.553383 IP 172.29.244.20.51820 > 172.29.248.132.51820: UDP, length 128
05:22:51.553583 IP 172.29.248.132.51820 > 172.29.244.20.51820: UDP, length 128
05:22:51.554112 IP 172.29.248.132.51820 > 172.29.244.20.51820: UDP, length 148
05:22:51.555198 IP 172.29.244.20.51820 > 172.29.248.132.51820: UDP, length 92
05:22:51.555748 IP 172.29.248.132.51820 > 172.29.244.20.51820: UDP, length 32
0
отвечен A.B 2022-12-15 03:10

Постоянная ссылка на данную страницу: [ Скопировать ссылку | Сгенерировать QR-код ]

Ваш ответ

Опубликуйте как Гость или авторизуйтесь

Имя

Похожие вопросы про тегам:

iptables
linux
networking
routing
vpn
Вверх