LINUX.ORG.RU
ФорумAdmin

iptalbes SNAT multiple sources + multiple destinations (NAT)

 , , ,


0

2

Коллеги, добрый день.

Есть задача по предоставлению отдельного внешнего ip адреса для каждой отдельной виртуальной машины в локальной сети через NAT.

Т.е. конкретно:

192.168.77.40 -> NAT -> 29.15.19.178
192.168.77.41 -> NAT -> 29.15.19.179
192.168.77.42 -> NAT -> 29.15.19.180
.......
192.168.77.49 -> NAT -> 115.64.12.142

Машина которая раздает интернет: ubuntu 20.04 LTS Клиенты: виртуальные машины c Windows 10

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

На самой машине gateway с ubuntu интернет настроен корректно, проверял вот так:

curl --interface 29.15.19.179 https://ifconfig.me
29.15.19.179

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

IP адреса 2 провайдера выдают как Static IP с маской 29.

IP адреса настроены через netplan. Конфиг под катом. ens18 - локальная сеть ens19 - Провайдер 1 ens20 - провайдер 2

# This is the network config written by 'subiquity'
network:
    version: 2
    ethernets:
      ens18:
        dhcp4: no
        addresses:
         - 192.168.77.28/24
        routes:
         - to: default
           via: 192.168.77.1
           metric: 150
        nameservers:
          addresses: [192.168.77.1,192.168.77.251,192.168.77.252]
      ens19:
        dhcp4: no
        addresses:
          - 29.15.19.178/29
          - 29.15.19.179/29
          - 29.15.19.181/29
          - 29.15.19.182/29
        nameservers:
          addresses: [77.88.8.8,77.88.8.1,1.1.1.1]
        routes:
          - to: default
            via: 29.15.19.177
            metric: 100
      ens20:
        dhcp4: no
        addresses:
          - 115.64.12.138/29
          - 115.64.12.139/29
          - 115.64.12.140/29
          - 115.64.12.141/29
          - 115.64.12.142/29
        nameservers:
          addresses: [77.88.8.8,77.88.8.1,1.1.1.1]
        routes:
          - to: default
            via: 115.64.12.137
            metric: 110

Вывод ip a под катом.

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: ens18: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether d6:56:70:4c:c5:d9 brd ff:ff:ff:ff:ff:ff
    inet 192.168.77.28/24 brd 192.168.77.255 scope global ens18
       valid_lft forever preferred_lft forever
3: ens19: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether c6:f5:ee:cb:c6:f3 brd ff:ff:ff:ff:ff:ff
    inet 29.15.19.178/29 brd 29.15.19.183 scope global ens19
       valid_lft forever preferred_lft forever
    inet 29.15.19.179/29 brd 29.15.19.183 scope global secondary ens19
       valid_lft forever preferred_lft forever
    inet 29.15.19.181/29 brd 29.15.19.183 scope global secondary ens19
       valid_lft forever preferred_lft forever
    inet 29.15.19.182/29 brd 29.15.19.183 scope global secondary ens19
       valid_lft forever preferred_lft forever
4: ens20: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 06:e1:2a:b1:84:ab brd ff:ff:ff:ff:ff:ff
    inet 115.64.12.138/29 brd 115.64.12.143 scope global ens20
       valid_lft forever preferred_lft forever
    inet 115.64.12.139/29 brd 115.64.12.143 scope global secondary ens20
       valid_lft forever preferred_lft forever
    inet 115.64.12.140/29 brd 115.64.12.143 scope global secondary ens20
       valid_lft forever preferred_lft forever
    inet 115.64.12.141/29 brd 115.64.12.143 scope global secondary ens20
       valid_lft forever preferred_lft forever
    inet 115.64.12.142/29 brd 115.64.12.143 scope global secondary ens20
       valid_lft forever preferred_lft forever

Вывод sysctl под катом. net.ipv4.ip_forward = 1 включен.

sysctl -p
net.ipv4.ip_forward = 1
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1

Вывод iptables -L -n -v

root@socks5:~# iptables -L -n -v
Chain INPUT (policy DROP 290K packets, 16M bytes)
 pkts bytes target     prot opt in     out     source               destination
21969 2383K ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0
2687K 3426M ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
 145K 5436K ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0            icmptype 8 ctstate NEW
 195K   56M ACCEPT     all  --  ens18  *       0.0.0.0/0            0.0.0.0/0

Chain FORWARD (policy ACCEPT 43937 packets, 2312K bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 3064K packets, 3410M bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain DOCKER-USER (0 references)
 pkts bytes target     prot opt in     out     source               destination

Вывод iptables -t nat -L -n -v

root@socks5:~# iptables -t nat -L -n -v
Chain PREROUTING (policy ACCEPT 696K packets, 86M bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain INPUT (policy ACCEPT 167K packets, 8641K bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 45411 packets, 2962K bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain POSTROUTING (policy ACCEPT 54303 packets, 3430K bytes)
 pkts bytes target     prot opt in     out     source               destination
    1    52 SNAT       all  --  *      ens20   0.0.0.0/0            0.0.0.0/0            to:115.64.12.138

Собственно проблема заключается в следующем, правило SNAT почему-то не работает.

iptables -t nat -A POSTROUTING -o ens20 -j SNAT --to-source 115.64.12.138


Последнее исправление: lext55 (всего исправлений: 1)

Ответ на: комментарий от Anoxemian

Вывод ip r s

root@socks5:~# ip r s
default via 29.15.19.177 dev ens19 proto static metric 100
default via 115.64.12.137 dev ens20 proto static metric 110
default via 192.168.77.1 dev ens18 proto static metric 150
29.15.19.176/29 dev ens19 proto kernel scope link src 29.15.19.178
192.168.77.0/24 dev ens18 proto kernel scope link src 192.168.77.28
115.64.12.136/29 dev ens20 proto kernel scope link src 115.64.12.138
lext55
() автор топика
Ответ на: комментарий от Anoxemian

Это не принципиально. Интернет есть на каждом из gateway.

192.168.77.1 - GW для локальной сети 29.15.19.177 - GW провайдера 1 115.64.12.137 - GW провайдера 2

Сейчас шлюз ходит через Провайдер 1

root@socks5:~# traceroute ya.ru
traceroute to ya.ru (77.88.55.242), 30 hops max, 60 byte packets
 1  29.15.19.177 (29.15.19.177)  0.634 ms  0.604 ms  0.786 ms
 2  92.42.214.113 (92.42.214.113)  10.322 ms  10.546 ms  10.520 ms
 3  178.209.118.57 (178.209.118.57)  1.185 ms  1.161 ms  1.353 ms
 4  asr1.westcall.ru (195.94.226.120)  2.185 ms  2.133 ms  1.837 ms
 5  asr-m9.westcall.ru (195.94.226.102)  2.940 ms asr-m9.westcall.ru (195.94.226.67)  2.385 ms asr-m9.westcall.ru (195.94.226.102)  2.890 ms
 6  asr-m9.westcall.ru (195.94.226.102)  3.067 ms  3.515 ms marionetka.yndx.net (195.208.209.1)  4.564 ms
 7  sas-32z3-ae1.yndx.net (87.250.239.183)  16.470 ms sas-32z1-ae2.yndx.net (87.250.239.179)  10.488 ms sas-32z1-ae1.yndx.net (87.250.239.177)  11.315 ms
 8  * sas-32z3-ae2.yndx.net (87.250.239.185)  15.357 ms  15.609 ms^[[A
 9  * * *
10  * * *
11  * * *
12  * * *
13  * * *
14  * * *
15  * * *
16  * * *
17  * * *
18  * * *
19  * * *
20  * * *
21  * * *
22  * * *
23  * * *
24  * * *
25  * * *
26  * * *
27  * * *
28  * * *
29  * * *
30  * * *
lext55
() автор топика
Ответ на: комментарий от lext55
network:
    version: 2
    ethernets:
      ens18:
        dhcp4: no
        addresses:
         - 192.168.77.28/24
        routes:
         - to: default
           via: 192.168.77.1
           metric: 150
        nameservers:
          addresses: [192.168.77.1,192.168.77.251,192.168.77.252]
      ens19:
        dhcp4: no
        addresses:
          - 29.15.19.178/29
          - 29.15.19.179/29
          - 29.15.19.181/29
          - 29.15.19.182/29
        nameservers:
          addresses: [77.88.8.8,77.88.8.1,1.1.1.1]
        routes:
          - to: default
            via: 29.15.19.177
            table: 10
        routing-policy:
          - from: 29.15.19.176/29
            table: 10
      ens20:
        dhcp4: no
        addresses:
          - 115.64.12.138/29
          - 115.64.12.139/29
          - 115.64.12.140/29
          - 115.64.12.141/29
          - 115.64.12.142/29
        nameservers:
          addresses: [77.88.8.8,77.88.8.1,1.1.1.1]
        routes:
          - to: default
            via: 115.64.12.137
            table: 20
        routing-policy:
          - from: 115.64.12.136/29
            table: 20
Anoxemian ★★★★★
()
Ответ на: комментарий от lext55

На виртуальных машинах я укажу gateway 192.168.77.28 специально для раздачи IP адресов на требуемые виртуальные машины c Windows 10

lext55
() автор топика
Последнее исправление: lext55 (всего исправлений: 1)
Ответ на: комментарий от lext55

Чего-то все равно не хватает.

Вот проверяю так с виртуальной машины 192.168.77.42 ( на ней прописан шлюз 192.168.77.28)

C:\Users\admin>telnet ifconfig.me 443
Подключение к ifconfig.me...Не удалось открыть подключение к этому узлу, на порт 443: Сбой подключения

В этот момент на gateway c ubuntu запущен tcpdump

root@socks5:~# tcpdump host ifconfig.me
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens18, link-type EN10MB (Ethernet), capture size 262144 bytes
13:08:39.948771 IP 192.168.77.42.51917 > 145.111.160.34.bc.googleusercontent.com.https: Flags [S], seq 2202751072, win 64240, options [mss 1460,nop,wscale 8,nop,nop,sackOK], length 0
13:08:40.940149 IP 192.168.77.42.51917 > 145.111.160.34.bc.googleusercontent.com.https: Flags [S], seq 2202751072, win 64240, options [mss 1460,nop,wscale 8,nop,nop,sackOK], length 0
13:08:42.955849 IP 192.168.77.42.51917 > 145.111.160.34.bc.googleusercontent.com.https: Flags [S], seq 2202751072, win 64240, options [mss 1460,nop,wscale 8,nop,nop,sackOK], length 0
13:08:46.956196 IP 192.168.77.42.51917 > 145.111.160.34.bc.googleusercontent.com.https: Flags [S], seq 2202751072, win 64240, options [mss 1460,nop,wscale 8,nop,nop,sackOK], length 0
^[[C^[[C13:08:54.956883 IP 192.168.77.42.51917 > 145.111.160.34.bc.googleusercontent.com.https: Flags [S], seq 2202751072, win 64240, options [mss 1460,nop,wscale 8,nop,nop,sackOK], length 0^[[D^[[A^[[D^C
5 packets captured
8 packets received by filter
0 packets dropped by kernel

Т.е. в принципе трафик приходит на gateway.

Но если поставить фильтр в tcpdump только на исходящий интерфейс - трафика нет

root@socks5:~# tcpdump -i ens20 host ifconfig.me
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens20, link-type EN10MB (Ethernet), capture size 262144 bytes
^[[D^[[A^[[C^[[B^[[D^[[C^[[B^[[A^[[A^C
0 packets captured
0 packets received by filter
0 packets dropped by kernel
lext55
() автор топика
Последнее исправление: lext55 (всего исправлений: 1)
Ответ на: комментарий от Anoxemian

В таблице PREROUTING использование SNAT невозможно.

root@socks5:~# iptables -t nat -A PREROUTING -s 192.168.77.42 -j SNAT --to-source 115.64.12.139
iptables: Invalid argument. Run `dmesg' for more information.

Вот вывод DMESG

[ 2516.653827] x_tables: ip_tables: SNAT target: used from hooks PREROUTING, but only usable from INPUT/POSTROUTING

Хотя помогло

iptables -t nat -A POSTROUTING -s 192.168.77.42 -j SNAT --to-source 115.64.12.139

Спасибо.

lext55
() автор топика
Ответ на: комментарий от lext55

Вообще за использование конструкций вида

iptables -t nat -A POSTROUTING -s 192.168.77.42 -j SNAT --to-source 115.64.12.139

Можно получить по голове, т.к. таблица POSTROUTING не предназначена для целей firewall.

Сейчас причешу правила с FORWARD, выложу сюда.

lext55
() автор топика

кхм….озхренеть ты гений. для начала давай погугли, «nat это НЕ фаервол». второй момент а кто тебе сказал что пустив l2 до вендовых машин ты не сможешь фильтровать транзитный трафик на своей убунте? ну и что что она его не маршрутизирует, фильтрация л3 в мостах тоже возможна. третее, ну это блядское извращение, ты замудохаешся с этим конфигом тебе придется прибить все гвоздями так как привязываешся к исходящему ипу.

Можно получить по голове, т.к. таблица POSTROUTING не предназначена для целей firewall.

набей уже татуху «nat не фаервол» на лбу. а где еще то его прописывать? весь нат в мире так работает.

antech
()
Ответ на: комментарий от Anoxemian

Странно вообще-то, в pfsense для этих целей используется именно таблица FORWARD. и наборот кучу хэйта словишь если через таблицу NAT будешь что-то ограничивать. Ладно не суть важно, работает и хорошо.

Вот причесанный кусок iptables-save в итоге:

# Generated by iptables-save v1.8.4 on Fri Nov  3 14:30:20 2023
*nat
:PREROUTING ACCEPT [1341:232176]
:INPUT ACCEPT [247:13269]
:OUTPUT ACCEPT [30:1800]
:POSTROUTING ACCEPT [30:1800]
# miniPC
-A POSTROUTING -s 192.168.77.40/32 -j SNAT --to-source 115.64.12.138
# miniPC
-A POSTROUTING -s 192.168.77.41/32 -j SNAT --to-source 115.64.12.139
# miniPC
-A POSTROUTING -s 192.168.77.42/32 -j SNAT --to-source 115.64.12.140
# miniPC 
-A POSTROUTING -s 192.168.77.43/32 -j SNAT --to-source 115.64.12.141
COMMIT
# Completed on Fri Nov  3 14:30:20 2023
# Generated by iptables-save v1.8.4 on Fri Nov  3 14:30:20 2023
*filter
:INPUT DROP [1026:66188]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [12945:13952126]
:DOCKER-USER - [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -i ens18 -j ACCEPT
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i ens18 -m conntrack --ctstate NEW,RELATED,ESTABLISHED -j ACCEPT
COMMIT
# Completed on Fri Nov  3 14:30:20 2023
lext55
() автор топика
Ответ на: комментарий от lext55

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

antech
()
Ответ на: комментарий от lext55

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

Anoxemian ★★★★★
()
Ответ на: комментарий от Anoxemian

сама идея кривая

Идея соответствует задаче. К этим виртуальным машинам подключаются пользователи из локальной сети ( сотрудники), и в зависимости какой им IP адрес нужен, той машиной и пользуются. Сотрудники не IT специалисты. Глупо возлагать на их плечи конроль за Firewall на машине с Windows. Поэтому намного безопаснее спрятать эти виртуалки за NAT. А уже на gateway ubuntu рулить Firewall-ом.

айпишники отдать виртуалкам напрямую

Тут еще в чем вопрос, на gateway ubuntu установлен Socks5 прокси сервер danted, по-моему 9 экземпляров, по экземпляру на каждый внешний IP адрес. Используется разработчиками, что-бы что-то там парсерить в несколько потоков. Поэтому эти IP адреса одновременно должны использоваться и для виртуальных машин для технически неподкованных пользователей, и для разработчиков, которые парсят в несколько потоков.

Т.е. и пользователи и разработчики находятся внутри локальной сети 192.168.77.0/24 . И тем и тем нужны разные IP для решения разных задач.

DNAT забыл

Нет проброс портов внутрь явно не нужен, достаточно правил RELATED,ESTABLISHED.

P.S.: Экономия должна быть экономной.

lext55
() автор топика
Ответ на: комментарий от lext55

Глупо возлагать на их плечи конроль за Firewall на машине с Windows.

Именно решение этой задачи я выше описал. Разница подходов - у тебя нат и дабл routing decision на каждый пакет, т.е. ты просто греешь воздух в смысле расходования вычислительных ресурсов, а при корректной архитектуре этого нет. Ну, задачу решил и ладно, обращайся.

Anoxemian ★★★★★
()
Ответ на: комментарий от antech

Вот возьмем классическую схему:

LAN: 192.168.0.1/24 WAN: 1.1.1.1/30 (Static IP)

По умолчанию во всех таблицах ACCEPTED.

Чтобы расшарить интернет я делаю

iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j SNAT --to-source 1.1.1.1

ВСЕ! этого достаточно.

Теперь идем дальше мне требуется выдать доступ к интернету только отдельным IP адресам.

Поэтому я запрещаю пересылку пакетов по умолчанию

iptables -P FORWARD DROP

И далее уже рулю в таблице FORWARD запрещающими и разрешающими правилами.

#Пользователю с IP 192.168.0.10 - можно
iptables -A FORWARD -s 192.168.0.10/32 -j ACCEPT
#Пользователю с IP 192.168.0.20 - можно
iptables -A FORWARD -s 192.168.0.10/32 -j ACCEPT

Для всех остальных сработает FORWARD DROP по-умолчанию.

Но вот если я начну писать правила вот так

iptables -t nat -A POSTROUTING -s 192.168.0.10/32 -j SNAT --to-source 1.1.1.1
iptables -t nat -A POSTROUTING -s 192.168.0.20/32 -j SNAT --to-source 1.1.1.1

То получу кучу хейта о том что таблица nat POSTROUTING не предназначена для запрещающих/разрешающих правил, она не для этого.

ЧЯДНТ?

lext55
() автор топика
Последнее исправление: lext55 (всего исправлений: 1)
Ответ на: комментарий от lext55

Это разные ситуации. Ты описал один статичный внешний ip. У тебя же хурма внешних ip от разных провайдеров, да еще и bind к конкретным виртуалкам. Ну предложи, что ты там в forward хочешь намутить и как это должно работать? О_о

Anoxemian ★★★★★
()
Ответ на: комментарий от antech

в данном случае правильней говорить о том, что должна осуществляться фильтрация по источнику пакета при NAT иначе у нас весь трафик уйдёт по бороде тупо по маске «*». это типовая же грабля с NAT.))

ну и да, тащить в пингвинарий чужой устав сетевого стека - это сильно! вместо того, чтобы просто почитать описание как в Linux это работает. тогда бы и таких дурацких идей не было, что дяди заругают за правило в POSTROUTING.

mumpster ★★★★★
()
Ответ на: комментарий от lext55

А вот оно что, ну у тебя и фантазия, этож еще додуматся надо ТАК фильтровать. Тут проблема в том что /24 пакетами срать наружу будет со своим серым адресом. Фильтрации то нет, это просто кривая настройка.

antech
()