iptables NAT с сетевым мостом, контейнерами и systemd-networkd: пересылка отсутствует
У меня есть некоторые проблемы при настройке iptables NAT на CentOS 7. В настоящее время клиент за NAT может подключаться к внешнему IP, но не к внешней сети.
Я следовал этому руководству, чтобы настроить NAT, зная, что он хорошо работает на Gentoo и Arch:
http://www.revsys.com/writings/quicktips/nat.html
схематизировать мою проблему:
- eth0 (внешний) = 192.168.1.1/24
- eth1 (внутренний) = 192.168.2.1/24
когда я пинг с 192.168.2.2:
- пинг 192.168.1.1: ОК
- пинг 192.168.1.2: NOK
- пинг 8.8.8.8: NOK
Обратите внимание, что я также установил правило переадресации портов с 192.168.1.1:80 до 192.168.2.2:80. Это хорошо работает, согласно Wireshark, мои пакеты успешно пересылаются на 192.168.2.2. Затем 192.168.2.2 отвечает, но пакет отбрасывается, поэтому я вижу множественные повторные передачи TCP. Нет никаких сообщений, запрещенных администратором.
Вот сообщения dropwatch, когда я пытаюсь подключиться к 192.168.2.2:80 извне:
1 drops at ip_error+68 (0xffffffff815c47d8)
1 drops at ip_error+68 (0xffffffff815c47d8)
1 drops at ip_error+68 (0xffffffff815c47d8)
1 drops at ip_error+68 (0xffffffff815c47d8)
1 drops at tcp_rcv_state_process+1b0 (0xffffffff815e5030)
1 drops at ip_error+68 (0xffffffff815c47d8)
1 drops at tcp_rcv_state_process+1b0 (0xffffffff815e5030)
1 drops at ip_error+68 (0xffffffff815c47d8)
2 drops at ip_error+68 (0xffffffff815c47d8)
1 drops at tcp_v4_do_rcv+80 (0xffffffff815ef160)
1 drops at ip_error+68 (0xffffffff815c47d8)
1 drops at tcp_v4_do_rcv+80 (0xffffffff815ef160)
1 drops at ip_error+68 (0xffffffff815c47d8)
2 drops at ip_error+68 (0xffffffff815c47d8)
1 drops at tcp_v4_do_rcv+80 (0xffffffff815ef160)
2 drops at ip_error+68 (0xffffffff815c47d8)
1 drops at tcp_v4_do_rcv+80 (0xffffffff815ef160)
1 drops at ip_error+68 (0xffffffff815c47d8)
Пожалуйста, кто-нибудь имеет представление о том, что я сделал не так? Спасибо вам всем.
РЕДАКТИРОВАТЬ:
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i eth1 -o eth0 -j ACCEPT
-A FORWARD -d 192.168.2.2/32 -p tcp -m tcp --dport 80 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
Chain PREROUTING (policy ACCEPT 1270 packets, 123K bytes)
pkts bytes target prot opt in out source destination
30 1696 DNAT tcp -- eth0 any anywhere anywhere tcp dpt:http to:192.168.2.2:80
Chain INPUT (policy ACCEPT 347 packets, 42272 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 6 packets, 431 bytes)
pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 30 packets, 1696 bytes)
pkts bytes target prot opt in out source destination
6 431 MASQUERADE all -- any eth0 anywhere anywhere
РЕДАКТИРОВАТЬ:
Да, IP-пересылка настроена правильно. Когда я пинг с 192.168.2.2 до 192.168.1.2, я не вижу ни одного пакета, поступающего с Wireshark на 192.168.1.2. Также я не вижу пакетов, выходящих из eth0 при использовании Wireshark.
Любопытно, что когда я успешно пингую 192.168.1.1 из 192.168.2.2, я не вижу ни одного ICMP-пакета, поступающего на eth0.
Я думаю, что должен добавить кое-что, что я не раскрыл, потому что я не нашел это актуальным. На самом деле я пытаюсь NAT сетевой мост с именем br0 (мой eth1 здесь) к локальной сети. Мой сервер 192.168.2.2 находится в контейнере с сетью, подключенной к мосту.
Я не знаю, должен ли я отредактировать весь свой пост, чтобы лучше отразить ситуацию. Я думал, что моя проблема была чисто допустимой ошибкой, но кажется, что что-то не так в сетевом стеке, потому что я должен видеть входящие пакеты ICMP при пинге 192.168.1.1.
Когда я сказал, что уже установил эту настройку в Gentoo и Arch, это было и с контейнерами, использующими LXC. Сейчас я пытаюсь использовать systemd-nspawn. Селинукс настроен как разрешительный. Пинг 192.168.2.2 с моего хоста CentOS в порядке, принуждение к использованию eth0 не работает, но это нормальное поведение.
маршруты хозяина:
default via 192.168.1.254 dev eth0 proto static metric 100
192.168.2.0/24 dev br0 proto kernel scope link src 192.168.2.1
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.1 metric 100
Контейнер маршрутов:
default via 192.168.2.1 dev host0 proto static
192.168.2.0/24 dev host0 proto kernel scope link src 192.168.2.2
1 ответ
Наконец я нашел решение после сильной головной боли...
Я использовал systemd-networkd для настройки моего моста. Хотя net.ipv4.ip_forward был правильно настроен на 1, а я также настроил net.ipv4.conf.all.forwarding на 1, похоже, systemd-networkd не принял во внимание мои настройки по умолчанию при установке моста.
Это закончилось тем, что net.ipv4.conf.br0.forwarding был установлен на 0. Я просто установил его на 1, и теперь он работает.
Для всех, кто сталкивался с подобной проблемой, выполните эту команду:
sysctl -a | grep "\.forwarding" | grep ipv4
Убедитесь, что на всех ваших интерфейсах включена пересылка.
Хорошего дня.