LINUX.ORG.RU
решено ФорумAdmin

iptables nat & kvm ping


0

1

Всем привет.

Есть проблема с натом. На машине запущены 2 виртуалки (kvm). На хосте сконфигурирован nat, для выхода этих виртуалок в инет. Одна виртуалка работает для другой маршрутизатором. Конфигурация следующая:

INET  <-- (eth0)[host](tap0) <-- [kvm1] <-- [kvm2]

или так:

             INET
              ^
              |
       192.168.0.178/24
            [host]
       192.168.100.2/24
              ^
              |
       192.168.100.1/24
            [kvm1]
       192.168.200.1/24
              ^
              |
       192.168.200.2/24
            [kvm2]

Конфигурация host:

host:~# iptables -V
iptables v1.4.10
host:~# uname -r
2.6.36.3-kvm64
host:~# cat /etc/issue
Debian GNU/Linux 5.0 \n \l

host:~# cat /proc/sys/net/ipv4/ip_forward
1

host:~# iptables-save
# Generated by iptables-save v1.4.10 on Thu Feb  3 15:53:45 2011
*nat
:PREROUTING ACCEPT [158:19117]
:INPUT ACCEPT [142:17947]
:OUTPUT ACCEPT [1273:77619]
:POSTROUTING ACCEPT [23:1515]
-A POSTROUTING -o eth0 -j MASQUERADE
COMMIT
# Completed on Thu Feb  3 15:53:45 2011
# Generated by iptables-save v1.4.10 on Thu Feb  3 15:53:45 2011
*filter
:INPUT ACCEPT [41870:22423799]
:FORWARD ACCEPT [1111:78128]
:OUTPUT ACCEPT [40741:4677024]
COMMIT
# Completed on Thu Feb  3 15:53:45 2011

host:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen
+1000
    link/ether 00:1c:23:9f:8f:7a brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.178/24 brd 192.168.0.255 scope global eth0
    inet6 fe80::21c:23ff:fe9f:8f7a/64 scope link
       valid_lft forever preferred_lft forever
3: wlan0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
    link/ether 00:1c:26:ac:50:fd brd ff:ff:ff:ff:ff:ff
4: tap0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN
+qlen 500
    link/ether 86:15:91:d2:a7:dd brd ff:ff:ff:ff:ff:ff
    inet 192.168.100.2/24 scope global tap0
    inet6 fe80::8415:91ff:fed2:a7dd/64 scope link
       valid_lft forever preferred_lft forever
5: tap2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN
+qlen 500
    link/ether 8e:ab:8b:d0:3e:bd brd ff:ff:ff:ff:ff:ff
    inet6 fe80::8cab:8bff:fed0:3ebd/64 scope link
       valid_lft forever preferred_lft forever
10: tap4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN
+qlen 500
    link/ether 5a:23:72:d4:41:2f brd ff:ff:ff:ff:ff:ff
    inet6 fe80::5823:72ff:fed4:412f/64 scope link
       valid_lft forever preferred_lft forever
12: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN
    link/ether 5a:23:72:d4:41:2f brd ff:ff:ff:ff:ff:ff
    inet6 fe80::5823:72ff:fed4:412f/64 scope link
       valid_lft forever preferred_lft forever

host:~# brctl show
bridge name     bridge id               STP enabled     interfaces
br0             8000.5a2372d4412f       no              tap2
                                                        tap4

kvm1 связывается с host через tap0 и с kvm2 через tap2 (br0). kvm2 связывается с kvm1 через tap4(br0). Конфигурация kvm1:

kvm1:~# cat /proc/sys/net/ipv4/ip_forward
1

kvm1:~# iptables-save
iptables-save v1.4.2: Unable to open /proc/net/ip_tables_names: No such file or
+directory

kvm1:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN
+qlen 1000
    link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff
    inet 192.168.100.1/24 brd 192.168.100.255 scope global eth0
    inet6 fe80::5054:ff:fe12:3456/64 scope link
       valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN
+qlen 1000
    link/ether 54:52:00:12:34:57 brd ff:ff:ff:ff:ff:ff
    inet 192.168.200.1/24 brd 192.168.200.255 scope global eth1
    inet6 fe80::5652:ff:fe12:3457/64 scope link
       valid_lft forever preferred_lft forever

kvm1:~# ip rou
192.168.100.0/24 dev eth0  proto kernel  scope link  src 192.168.100.1
192.168.200.0/24 dev eth1  proto kernel  scope link  src 192.168.200.1
default via 192.168.100.2 dev eth0

Конфигурация kvm2:

kvm2:~# iptables-save
iptables-save v1.4.2: Unable to open /proc/net/ip_tables_names: No such file or
+directory

kvm2:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN
+qlen 1000
    link/ether 54:52:00:12:34:60 brd ff:ff:ff:ff:ff:ff
    inet 192.168.200.2/24 brd 192.168.200.255 scope global eth0
    inet6 fe80::5652:ff:fe12:3460/64 scope link
       valid_lft forever preferred_lft forever

kvm2:~# ip rou
192.168.200.0/24 dev eth0  proto kernel  scope link  src 192.168.200.2
default via 192.168.200.1 dev eth0

Проблема в следующем. Пинги с kvm1 проходят нормально. Всё как и должно. А вот с kvm2 пинги не доходят. Пакеты с kvm2 попросту не натятся на host.

Пинг с kvm1:

host:~# grep 192.168.100.1 /proc/net/ip_conntrack
icmp     1 19 src=192.168.100.1 dst=8.8.8.8 type=8 code=0 id=20486 src=8.8.8.8
+dst=192.168.0.178 type=0 code=0 id=20486 mark=0 secmark=0 use=2

Пинг с kvm2:

host:~# grep 192.168.200.2 /proc/net/ip_conntrack
icmp     1 22 src=192.168.200.2 dst=8.8.8.8 type=8 code=0 id=62469 [UNREPLIED]
+src=8.8.8.8 dst=192.168.200.2 type=0 code=0 id=62469 mark=0 secmark=0 use=2

Для проверки добавил несколько правил в iptables и стало видно, что пакет от kvm2 проходит все цепочки, кроме nat POSTROUTING:

# iptables-save -c
# Generated by iptables-save v1.4.10 on Fri Feb  4 14:16:53 2011
*mangle
:PREROUTING ACCEPT [35:3531]
:INPUT ACCEPT [6:400]
:FORWARD ACCEPT [12:1008]
:OUTPUT ACCEPT [2:129]
:POSTROUTING ACCEPT [14:1137]
[12:1008] -A FORWARD -s 192.168.200.2/32 
[12:1008] -A POSTROUTING -s 192.168.200.2/32 
COMMIT
# Completed on Fri Feb  4 14:16:53 2011
# Generated by iptables-save v1.4.10 on Fri Feb  4 14:16:53 2011
*nat
:PREROUTING ACCEPT [12:1703]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [1:84]
[0:0] -A POSTROUTING -s 192.168.200.2/32 -o eth0 -j MASQUERADE 
[0:0] -A POSTROUTING -o eth0 -j MASQUERADE 
COMMIT
# Completed on Fri Feb  4 14:16:53 2011
# Generated by iptables-save v1.4.10 on Fri Feb  4 14:16:53 2011
*filter
:INPUT ACCEPT [6:400]
:FORWARD ACCEPT [12:1008]
:OUTPUT ACCEPT [2:129]
[12:1008] -A FORWARD -s 192.168.200.2/32 
COMMIT
# Completed on Fri Feb  4 14:16:53 2011

Что за мистика?

На хосте есть в таблице маршрутизации запись вида

192.168.200.0 mask 255.255.255.0 dev tap0 gw 192.168.200.1

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

Да, забыл показать маршруты на host:

[code]
host:~# ip rou
192.168.100.0/24 dev tap0 proto kernel scope link src 192.168.100.2
192.168.0.0/24 dev eth0 proto kernel scope link src 192.168.0.254
192.168.200.0/24 via 192.168.100.1 dev tap0
default via 192.168.0.1 dev eth0
[/code]

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

Подозреваю, что дело в том, что пакеты приходят не через тот интерфейс, через который вы предполагаете. Попробуйте добавить в правила FORWARD интерфейсы -i и -o. И посмотрите логи хоста и KVM1, нет ли там слов про martian source

Nastishka ★★★★★
()

Всё оказалось проще. Я стормозил, совсем забыл о bridge-nf-* переменных. Вот развёрнутый ответ в списке рассылки:

If the kernel was built with CONFIG_BRIDGE_NETFILTER=y (Debian kernels
are) and sysctl net.bridge.bridge-nf-call-iptables=1 (this is the kernel
default), then IP packets going through a bridge are passed to iptables
chains, as described in Documentation/networking/ip-sysctl.txt. This is
a nice feature when you want to set up a filtering bridge.

Granted, you don't have any iptables rules related to the bridge.
Indeed, but the description in ip-sysctl.txt is incomplete.
Bridge-netfilter does not actually pass packets to iptables chains but
to netfilter hooks, which in turn passes them to iptables chains - but
not only : it also passes them to conntrack (connection tracking). And
remember that NAT rules can be applied to a connection only the first
time it is seen by conntrack. Here the first time conntrack sees the
ping is when it goes through the bridge from tap4 to tap2. And this
time, there is no NAT operation.

Setting sysctl net.bridge.bridge-nf-call-iptables=0 to disable passing
bridged packets to netfilter shouldf fix the problem.

Всем спасибо.

Lego_12239 ★★
() автор топика

Подсказали способ, что б обойтись без bridge&tap для организации сети между виртуалками, что б ОС-хозяин не вмешивалась в процесс взаимодействия. Через Virtual Distributed Ethernet (vde2 пакет в debian). Позволяет создавать виртуальные свитчи, к которым подключаются через сокеты клиенты. kvm поддерживает vde. Документации на этот счёт мало, везде рассказывают про bridge&tap подход.

В общем, очень интересная вещь этот vde. Можно несколько свитчей виртульных на разных машиных соединять виртуальными кабелями через сеть и т.п.. Интересен вопрос быстродействия/нагрузки на cpu и надёжности vde в сравнении с bridge&tap.

Lego_12239 ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.