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

Странно вообще-то, в 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
()