Как отправлять пакеты с одного интерфейса на другой без использования локального стека - PullRequest
0 голосов
/ 06 августа 2020

У нас есть 2 интерфейса в системе CentOS 7 в разных сетях. Наша цель - отправить данные между этими интерфейсами, но заставить пакеты фактически покидать систему. (Конечная цель будет использовать около 150 различных интерфейсов)

firewalld отключен, а iptables показывает только ACCEPT

Мы достигли нашего лучшего результата, изменив таблицу маршрутизации.

  • Добавьте правило для каждого интерфейса, чтобы использовать другую таблицу маршрутизации
    ip rule add from $ipaddress table $table_id
  • Добавьте маршрут для сети и шлюзов по умолчанию в таблицу с более низким значением c в качестве основной таблицы
    ip route add table $table_id $netip/$netCIDR dev $iface src $ipaddress metric 20
    ip route add table $table_id default via $gateway dev $iface src $ipaddress metric 20
  • Удалить маршрут из локальной таблицы
    ip route del table local $ipaddress dev $iface

Результаты выглядят, например, так:

#--- Network Addresses ---
eth1 : 192.168.200.75 [broadcast:192.168.203.255 Network:192.168.200.0/22] Gateway:192.168.200.1
eth2 : 192.168.90.222 [broadcast:192.168.90.255 Network:192.168.90.0/24] Gateway:192.168.90.1
#--- ip route show table 1 ---
default via 192.168.200.1 dev eth1 src 192.168.200.75 metric 20 
192.168.200.0/22 dev eth1 scope link src 192.168.200.75 metric 20 
#--- ip route show table 2 ---
default via 192.168.90.1 dev eth2 src 192.168.90.222 metric 20 
192.168.90.0/24 dev eth2 scope link src 192.168.90.222 metric 20 
#--- ip route show table local ---
broadcast 127.0.0.0 dev lo proto kernel scope link src 127.0.0.1 
local 127.0.0.0/8 dev lo proto kernel scope host src 127.0.0.1 
local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1 
broadcast 127.255.255.255 dev lo proto kernel scope link src 127.0.0.1 
broadcast 192.168.90.0 dev eth2 proto kernel scope link src 192.168.90.222 
broadcast 192.168.90.255 dev eth2 proto kernel scope link src 192.168.90.222 
broadcast 192.168.200.0 dev eth1 proto kernel scope link src 192.168.200.75 
broadcast 192.168.203.255 dev eth1 proto kernel scope link src 192.168.200.75 
#--- ip route show table main ---
default via 192.168.90.1 dev eth2 proto static metric 100 
default via 192.168.200.1 dev eth1 proto dhcp metric 101 
192.168.90.0/24 dev eth2 proto kernel scope link src 192.168.90.222 metric 100 
192.168.200.0/22 dev eth1 proto kernel scope link src 192.168.200.75 metric 101 
#--- ip rule list ---
0:      from all lookup local 
32764:  from 192.168.90.222 lookup 2 
32765:  from 192.168.200.75 lookup 1 
32766:  from all lookup main 
32767:  from all lookup default 

С помощью ip route get мы видим, что используются правильные маршруты, и можем проверить с помощью tcpdump, что пакеты отправлены. tcpdump также показывает, что мы получаем ответ, когда пингуем шлюз. Но пинг по-прежнему показывает, что пакеты не получены.

#--- 192.168.200.75 -> Gateway ---
[]# ip route get from 192.168.200.75 192.168.200.1
192.168.200.1 from 192.168.200.75 dev eth1 table 1 uid 0 
    cache 
[]# ping -c 1 -I eth1 192.168.200.1
PING 192.168.200.1 (192.168.200.1) from 192.168.200.75 eth1: 56(84) bytes of data.

--- 192.168.200.1 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms
#--- 192.168.200.75 -> 192.168.90.222 ---
[]# ip route get from 192.168.200.75 192.168.90.222
192.168.90.222 from 192.168.200.75 via 192.168.200.1 dev eth1 table 1 uid 0 
    cache 
[]# ping -c 1 -I eth1 192.168.90.222
PING 192.168.90.222 (192.168.90.222) from 192.168.200.75 eth1: 56(84) bytes of data.

--- 192.168.90.222 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

С помощью небольшого python скрипта мы видим, что теперь в системе есть проблема привязки.

#!/bin/python
import socket

def test_bind(ip, interface=None):
    print('testing: %s' % ip)
    try: 
        s = socket.socket()
        if interface:
            s.setsockopt(socket.SOL_SOCKET, 25, interface+'\0')
        s.bind((ip, 6677))
        print("   success")
    except Exception as e:
        print("   failed:", e)

test_bind("192.168.200.75")
test_bind("192.168.90.222")
test_bind("192.168.200.75", interface='eth1')
test_bind("192.168.90.222", interface='eth2')
testing: 192.168.200.75
('   failed:', error(99, 'Cannot assign requested address'))
testing: 192.168.90.222
('   failed:', error(99, 'Cannot assign requested address'))
testing: 192.168.200.75
('   failed:', error(99, 'Cannot assign requested address'))
testing: 192.168.90.222
('   failed:', error(99, 'Cannot assign requested address'))

До сих пор мы также безуспешно пробовали следующее:

  • ip netns, позже у нас будет один процесс, использующий все интерфейсы
  • vrf, неверно настраивает
  • sysctl rp_filter, accept_local
  • Подобные вопросы StackOverflow за 8 лет go
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...