Я могу пинговать между пространства имен, но не могу подключиться по TCP.

Вопрос или проблема

Я пытаюсь настроить два сетевых пространства имен для взаимодействия друг с другом. Я создал два пространства имен, ns0 и ns1, у каждого из которых есть пара veth, где не-национальная сторона veth подключена к мосту.

Я настроил это так:

ip link add veth0 type veth peer name brveth0
ip link set brveth0 up

ip link add veth1 type veth peer name brveth1
ip link set brveth1 up

ip link add br10 type bridge
ip link set br10 up

ip addr add 192.168.1.11/24 brd + dev br10

ip netns add ns0
ip netns add ns1

ip link set veth0 netns ns0
ip link set veth1 netns ns1



ip netns exec ns0    ip addr add 192.168.1.20/24 dev veth0
ip netns exec ns0    ip link set veth0 up
ip netns exec ns0    ip link set lo up

ip netns exec ns1    ip addr add 192.168.1.21/24 dev veth1
ip netns exec ns1    ip link set veth1 up
ip netns exec ns1    ip link set lo up


ip link set  brveth0 master br10
ip link set  brveth1 master br10

Как и ожидалось, я могу пинговать интерфейс в ns0 из ns1.

$ sudo ip netns exec ns1 ping -c 3  192.168.1.20
PING 192.168.1.20 (192.168.1.20) 56(84) bytes of data.
64 bytes from 192.168.1.20: icmp_seq=1 ttl=64 time=0.099 ms
64 bytes from 192.168.1.20: icmp_seq=2 ttl=64 time=0.189 ms

Но я не могу подключиться между ними по TCP.

Например, запуская сервер в ns0 :

$ sudo ip netns exec ns0 python3 -m http.server 8080
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...

Я ожидал, что смогу выполнить curl из ns1, но это приводит к ошибке:

$ sudo ip netns exec ns1 curl 192.168.1.20:8080
curl: (7) Не удалось подключиться к 192.168.1.20 порт 8080: Нет маршрута к хосту

Почему это происходит?

Я столкнулся с похожей ситуацией:На хостах k8s, использующих flannel, podA может пинговать podB на том же хосте, но tcp соединение сбрасывалось ICMP сбросом от cni0.
iptables-save показывает правила о k8s, и ни одно из них не выглядит неправильно.
nft list ruleset показывает правила созданные firewalld:

table inet firewalld {

    chain filter_FORWARD {
        type filter hook forward priority filter + 10; policy accept;
        ct state { established, related } accept
        ct status dnat accept
        iifname "lo" accept
        ip6 daddr { ::/96, ::ffff:0.0.0.0/96, 2002::/24, 2002:a00::/24, 2002:7f00::/24, 2002:a9fe::/32, 2002:ac10::/28, 2002:c0a8::/32, 2002:e000::/19 } reject with icmpv6 addr-unreachable
        jump filter_FORWARD_ZONES
        ct state invalid drop
        reject with icmpx admin-prohibited
    }

Все работает отлично после остановки службы firewalld:
systemctl stop firewalld
Поэтому, пожалуйста, проверьте, есть ли другие службы или модули ядра, которые также могут использовать netfilter.

Ответ или решение

Проблема с подключением TCP между пространствах имен в Linux

Ваша проблема заключена в том, что, несмотря на успешное выполнение команды ping между пространствами имен, вы не можете установить TCP-соединение. Давайте подробно разберем возможные причины и шаги по их устранению.

1. Общая схема настройки

На основании приведенной вами информации, вы успешно настроили два пространства имен ns0 и ns1, которые используют пары виртуальных Ethernet (veth) и подключены к мосту (bridge). У вас есть следующие IP-адреса:

  • ns0: 192.168.1.20
  • ns1: 192.168.1.21
  • Мост br10: 192.168.1.11

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

2. Настройки брандмауэра

Наиболее вероятной причиной ошибки "No route to host" при попытке подключения TCP является брандмауэр. Вы уже упомянули о iptables и nftables, которые могут блокировать трафик. Рекомендуется проверить следующие настройки:

  • Правила iptables: Используйте команду sudo iptables -L -v -n. Убедитесь, что в правилах нет блокировок, касающихся трафика между вашими пространствами имен.

  • Правила firewalld: Если вы используете firewalld, убедитесь, что в конфигурации нет правил, которые могли бы блокировать ваш TCP-трафик. Остановка firewalld, как вы уже сделали, подтверждает, что именно он мог быть проблемой.

3. Прослушивание на всех интерфейсах

Ваша команда для запуска сервера HTTP (python3 -m http.server 8080) по умолчанию настроена на прослушивание на всех интерфейсах (0.0.0.0). Убедитесь, что сервер действительно запущен в ns0 и работает без ошибок.

Попробуйте выполнить следующие команды для проверки:

sudo ip netns exec ns0 netstat -tuln | grep 8080

Эта команда покажет, прослушивает ли ваш сервер порт 8080 и на каких интерфейсах.

4. Проверка соединения с помощью telnet

Для более детального анализа попробуйте использовать утилиту telnet для тестирования TCP-соединения:

sudo ip netns exec ns1 telnet 192.168.1.20 8080

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

5. Проблемы с MTU

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

ip link show

6. Повторная проверка маршрутизации

Убедитесь, что маршрутизация настроена корректно. Для каждой сетевой namespace убедитесь, что есть доступ к маршруту по умолчанию и трафик направляется через нужные интерфейсы:

sudo ip netns exec ns0 ip route
sudo ip netns exec ns1 ip route

Заключение

Сложности с TCP-подключением между пространствами имен, несмотря на успешные ping-запросы, чаще всего возникают из-за проблем с брандмауэром, ошибками конфигурации маршрутизации или проблемами с прослушиванием серверных приложений. Рекомендуется проверять настройки брандмауэра и маршрутизации, а также убедиться в работоспособности приложения на всех требуемых интерфейсах.

Если указанные шаги не приведут к успеху, возможно, стоит подумать о других системных настройках или обратиться к документации для вашей операционной системы.

Оцените материал
Добавить комментарий

Капча загружается...