- Вопрос или проблема
- 1. Больше диагностики.
- 2. Анализ пакетов.
- 3. Проверьте правила фильтрации пакетов.
- 4. Версия netcat
- Правильное поведение (для справки)
- Примечания.
- Ответ или решение
- 1. Описание проблемы
- 2. Объяснение поведения
- a) Проблемы привязки адреса
- b) NAT и правила маршрутизации
- 3. Возможные решения
- a) Проверка конфигурации интерфейса
- b) Проверка правил iptables
- c) Изменение использования socat
- d) Использование Tcpdump
- 4. Заключение
Вопрос или проблема
Я использую socat для переадресации UDP-трафика с одного порта на другой с помощью следующей команды:
socat -T5 UDP4-LISTEN:12345,reuseaddr,fork UDP4:127.0.0.1:23456,bind=127.0.0.2,so-bindtodevice=lo
Для тестирования я использовал netcat, запустив nc -u -l -p 23456 -vv
и echo test | nc -u 127.0.0.1 12345
. Это дало мне следующий неожиданный результат:
listening on [any] 23456 ...
connect to [<myPublicIp>] from <hostname> [<myPublicIp>] 53995
test
Вместо того чтобы видеть <myPublicIp>
в качестве адреса источника, я ожидал увидеть 127.0.0.2
. Я неправильно понимаю что-то в сетевом взаимодействии или неправильно использую socat?
Пострадавший сервер работает на Debian 10, версия ядра Linux 4.19.0-13-amd64, версия socat 1.7.3.2.
ИЗМЕНЕНИЕ:
При использовании TCP выходные данные немного отличаются:
listening on [any] 23456 ...
connect to [127.0.0.1] from <hostname> [<myPublicIp>] 48520
test
По запросу, соответствующий вывод netstat -aun
Proto Recv-Q Send-Q Local Address Foreign Address State
udp 0 0 0.0.0.0:12345 0.0.0.0:*
udp 0 0 <myPublicIp>:23456 <myPublicIp>:54299 ESTABLISHED
udp 0 0 127.0.0.1:33156 127.0.0.1:12345 ESTABLISHED
ИЗМЕНЕНИЕ 2:
Я могу подтвердить, что это не происходит на чистой установке Debian. Кроме того, я попробовал еще несколько вещей:
Создание другого интерфейса с помощью tunctl и заставляя socat использовать этот интерфейс. Выполненные команды:
tunctl
ifconfig tap1 192.168.10.1 netmask 255.255.255.255 up
socat -T5 UDP4-LISTEN:12345,reuseaddr,fork UDP4:127.0.0.1:23456,bind=192.168.10.1,so-bindtodevice=tap1
Поведение, которое я наблюдал, точно такое же, как в примере с UDP выше; все запросы, кажется, происходят от <myPublicIp>
.
Кроме того, я пробовал использовать этот подход для создания дополнительных адресов обратной петли.
ifconfig lo:10 192.168.10.1 netmask 255.255.255.0 up
socat -T5 UDP4-LISTEN:12345,reuseaddr,fork UDP4:127.0.0.1:23456,bind=192.168.10.1
Это на самом деле сработало, запросы, кажется, происходят от 192.168.10.1
. Использование
socat -T5 UDP4-LISTEN:12345,reuseaddr,fork UDP4:127.0.0.1:23456,bind=192.168.10.2
(другой адрес привязки) не работает, запросы теперь происходят от 192.168.10.1
.
Создание нескольких псевдонимов для lo
также не срабатывает.
ifconfig lo:1 192.168.10.1 netmask 255.255.255.255 up
ifconfig lo:2 192.168.10.2 netmask 255.255.255.255 up
ifconfig lo:3 192.168.10.3 netmask 255.255.255.255 up
Попытка использовать любой из этих интерфейсов приводит к тому, что все запросы поступают от первого из созданных. В данном случае, 192.168.10.1
. Удаление lo:1
тогда приведет к тому, что все запросы поступят от 192.168.10.2
. После повторного добавления lo:1
запросы по-прежнему будут поступать от 192.168.10.2
, так как в данный момент lo:2
является “старейшим” интерфейсным псевдонимом.
ИЗМЕНЕНИЕ 3:
Правила брандмауэра (по запросу). enp35s0
является моим публичным интерфейсом.
# Generated by xtables-save v1.8.2 on Fri Jul 23 12:15:33 2021
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:DOCKER - [0:0]
:DOCKER-ISOLATION-STAGE-1 - [0:0]
:DOCKER-USER - [0:0]
:DOCKER-ISOLATION-STAGE-2 - [0:0]
-A INPUT -i enp35s0 -p udp -m state --state NEW -m udp --dport 1195 -j ACCEPT
-A INPUT -i tun+ -j ACCEPT
-A INPUT -i enp35s0 -p udp -m state --state NEW -m udp --dport 1195 -j ACCEPT
-A INPUT -i tun+ -j ACCEPT
-A INPUT -i enp35s0 -p udp -m state --state NEW -m udp --dport 1195 -j ACCEPT
-A INPUT -i tun+ -j ACCEPT
-A INPUT -i enp35s0 -p udp -m state --state NEW -m udp --dport 1195 -j ACCEPT
-A INPUT -i tun+ -j ACCEPT
-A INPUT -i enp35s0 -p udp -m state --state NEW -m udp --dport 1195 -j ACCEPT
-A INPUT -i tun+ -j ACCEPT
-A FORWARD -j DOCKER-USER
-A FORWARD -j DOCKER-ISOLATION-STAGE-1
-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o docker0 -j DOCKER
-A FORWARD -i docker0 ! -o docker0 -j ACCEPT
-A FORWARD -i docker0 -o docker0 -j ACCEPT
-A FORWARD -o br-d83e4273341d -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o br-d83e4273341d -j DOCKER
-A FORWARD -i br-d83e4273341d ! -o br-d83e4273341d -j ACCEPT
-A FORWARD -i br-d83e4273341d -o br-d83e4273341d -j ACCEPT
-A FORWARD -i tun+ -j ACCEPT
-A FORWARD -i tun+ -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i enp35s0 -o tun+ -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i tun+ -j ACCEPT
-A FORWARD -i tun+ -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i enp35s0 -o tun+ -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i tun+ -j ACCEPT
-A FORWARD -i tun+ -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i enp35s0 -o tun+ -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i tun+ -j ACCEPT
-A FORWARD -i tun+ -o enp35s0 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i enp35s0 -o tun+ -m state --state RELATED,ESTABLISHED -j ACCEPT
-A DOCKER -d 172.18.0.4/32 ! -i br-adf3fed056db -o br-adf3fed056db -p tcp -m tcp --dport 8048 -j ACCEPT
-A DOCKER -d 172.18.0.4/32 ! -i br-adf3fed056db -o br-adf3fed056db -p tcp -m tcp --dport 8008 -j ACCEPT
-A DOCKER -d 172.18.0.5/32 ! -i br-adf3fed056db -o br-adf3fed056db -p tcp -m tcp --dport 9005 -j ACCEPT
-A DOCKER -d 172.18.0.8/32 ! -i br-adf3fed056db -o br-adf3fed056db -p tcp -m tcp --dport 8080 -j ACCEPT
-A DOCKER -d 172.18.0.10/32 ! -i br-adf3fed056db -o br-adf3fed056db -p tcp -m tcp --dport 8080 -j ACCEPT
-A DOCKER -d 172.18.0.11/32 ! -i br-adf3fed056db -o br-adf3fed056db -p tcp -m tcp --dport 8090 -j ACCEPT
-A DOCKER -d 172.19.0.2/32 ! -i br-d83e4273341d -o br-d83e4273341d -p udp -m udp --dport 49172 -j ACCEPT
-A DOCKER -d 172.19.0.2/32 ! -i br-d83e4273341d -o br-d83e4273341d -p udp -m udp --dport 49171 -j ACCEPT
-A DOCKER -d 172.19.0.2/32 ! -i br-d83e4273341d -o br-d83e4273341d -p udp -m udp --dport 49170 -j ACCEPT
-A DOCKER -d 172.19.0.2/32 ! -i br-d83e4273341d -o br-d83e4273341d -p udp -m udp --dport 49169 -j ACCEPT
-A DOCKER -d 172.19.0.2/32 ! -i br-d83e4273341d -o br-d83e4273341d -p udp -m udp --dport 49168 -j ACCEPT
-A DOCKER -d 172.19.0.2/32 ! -i br-d83e4273341d -o br-d83e4273341d -p udp -m udp --dport 49167 -j ACCEPT
-A DOCKER -d 172.19.0.2/32 ! -i br-d83e4273341d -o br-d83e4273341d -p udp -m udp --dport 49166 -j ACCEPT
-A DOCKER -d 172.19.0.2/32 ! -i br-d83e4273341d -o br-d83e4273341d -p udp -m udp --dport 49165 -j ACCEPT
-A DOCKER -d 172.19.0.2/32 ! -i br-d83e4273341d -o br-d83e4273341d -p udp -m udp --dport 49164 -j ACCEPT
-A DOCKER -d 172.19.0.2/32 ! -i br-d83e4273341d -o br-d83e4273341d -p udp -m udp --dport 49163 -j ACCEPT
-A DOCKER -d 172.19.0.2/32 ! -i br-d83e4273341d -o br-d83e4273341d -p udp -m udp --dport 49162 -j ACCEPT
-A DOCKER -d 172.19.0.2/32 ! -i br-d83e4273341d -o br-d83e4273341d -p udp -m udp --dport 49161 -j ACCEPT
-A DOCKER -d 172.19.0.2/32 ! -i br-d83e4273341d -o br-d83e4273341d -p udp -m udp --dport 49160 -j ACCEPT
-A DOCKER -d 172.19.0.2/32 ! -i br-d83e4273341d -o br-d83e4273341d -p udp -m udp --dport 49159 -j ACCEPT
-A DOCKER -d 172.19.0.2/32 ! -i br-d83e4273341d -o br-d83e4273341d -p udp -m udp --dport 49158 -j ACCEPT
-A DOCKER -d 172.19.0.2/32 ! -i br-d83e4273341d -o br-d83e4273341d -p udp -m udp --dport 49157 -j ACCEPT
-A DOCKER -d 172.19.0.2/32 ! -i br-d83e4273341d -o br-d83e4273341d -p udp -m udp --dport 49156 -j ACCEPT
-A DOCKER -d 172.19.0.2/32 ! -i br-d83e4273341d -o br-d83e4273341d -p udp -m udp --dport 49155 -j ACCEPT
-A DOCKER -d 172.19.0.2/32 ! -i br-d83e4273341d -o br-d83e4273341d -p udp -m udp --dport 49154 -j ACCEPT
-A DOCKER -d 172.19.0.2/32 ! -i br-d83e4273341d -o br-d83e4273341d -p udp -m udp --dport 49153 -j ACCEPT
-A DOCKER -d 172.19.0.2/32 ! -i br-d83e4273341d -o br-d83e4273341d -p udp -m udp --dport 49152 -j ACCEPT
-A DOCKER -d 172.19.0.2/32 ! -i br-d83e4273341d -o br-d83e4273341d -p tcp -m tcp --dport 5349 -j ACCEPT
-A DOCKER -d 172.19.0.2/32 ! -i br-d83e4273341d -o br-d83e4273341d -p udp -m udp --dport 5349 -j ACCEPT
-A DOCKER -d 172.19.0.2/32 ! -i br-d83e4273341d -o br-d83e4273341d -p tcp -m tcp --dport 3478 -j ACCEPT
-A DOCKER -d 172.19.0.2/32 ! -i br-d83e4273341d -o br-d83e4273341d -p udp -m udp --dport 3478 -j ACCEPT
-A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -i br-d83e4273341d ! -o br-d83e4273341d -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -i br-adf3fed056db ! -o br-adf3fed056db -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -j RETURN
-A DOCKER-USER -j RETURN
-A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP
-A DOCKER-ISOLATION-STAGE-2 -o br-d83e4273341d -j DROP
-A DOCKER-ISOLATION-STAGE-2 -o br-adf3fed056db -j DROP
-A DOCKER-ISOLATION-STAGE-2 -j RETURN
COMMIT
# Завершено в пятницу, 23 июля 2021 года
# Сгенерировано xtables-save v1.8.2 в пятницу, 23 июля 2021 года
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:DOCKER - [0:0]
-A PREROUTING -p tcp -m tcp --dport 12348 -j DNAT --to-destination 10.9.0.11:62128
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
-A POSTROUTING -s 172.19.0.0/16 ! -o br-d83e4273341d -j MASQUERADE
-A POSTROUTING -s 172.18.0.0/16 ! -o br-adf3fed056db -j MASQUERADE
-A POSTROUTING -s 10.8.0.0/24 -o enp35s0 -j MASQUERADE
-A POSTROUTING -s 10.9.0.0/24 -o enp35s0 -j MASQUERADE
-A POSTROUTING -j MASQUERADE
COMMIT
# Завершено в пятницу, 23 июля 2021 года
# Сгенерировано xtables-save v1.8.2 в пятницу, 23 июля 2021 года
*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
COMMIT
# Завершено в пятницу, 23 июля 2021 года
Вывод 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
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp35s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether a8:a1:59:48:f5:da brd ff:ff:ff:ff:ff:ff
inet <myPublicIPv4>/26 brd 135.181.209.63 scope global enp35s0
valid_lft forever preferred_lft forever
inet6 <myPublicIPv6>/64 scope global
valid_lft forever preferred_lft forever
inet6 fe80::aaa1:59ff:fe48:f5da/64 scope link
valid_lft forever preferred_lft forever
5: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:f4:2e:c5:95 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:f4ff:fe2e:c595/64 scope link
valid_lft forever preferred_lft forever
6: br-adf3fed056db: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:4b:fd:ae:6f brd ff:ff:ff:ff:ff:ff
inet 172.18.0.1/16 brd 172.18.255.255 scope global br-adf3fed056db
valid_lft forever preferred_lft forever
inet6 fe80::42:4bff:fefd:ae6f/64 scope link
valid_lft forever preferred_lft forever
216865: veth225712d@if216864: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-d83e4273341d state UP group default
link/ether 32:65:78:a0:be:47 brd ff:ff:ff:ff:ff:ff link-netnsid 10
inet6 fe80::3065:78ff:fea0:be47/64 scope link
valid_lft forever preferred_lft forever
61: br-d83e4273341d: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:c4:38:c9:c5 brd ff:ff:ff:ff:ff:ff
inet 172.19.0.1/16 brd 172.19.255.255 scope global br-d83e4273341d
valid_lft forever preferred_lft forever
inet6 fe80::42:c4ff:fe38:c9c5/64 scope link
valid_lft forever preferred_lft forever
202134: tap0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 100
link/ether 36:e7:1a:1f:b5:c8 brd ff:ff:ff:ff:ff:ff
inet 10.9.0.1/24 brd 10.9.0.255 scope global tap0
valid_lft forever preferred_lft forever
inet6 fe80::34e7:1aff:fe1f:b5c8/64 scope link
valid_lft forever preferred_lft forever
202135: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 100
link/none
inet 10.8.0.1 peer 10.8.0.2/32 scope global tun0
valid_lft forever preferred_lft forever
inet6 fe80::cc13:3dec:ab8c:2e3b/64 scope link stable-privacy
valid_lft forever preferred_lft forever
88033: veth0949050@if88032: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-adf3fed056db state UP group default
link/ether 1e:e0:14:92:f3:ad brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::1ce0:14ff:fe92:f3ad/64 scope link
valid_lft forever preferred_lft forever
88035: veth5621bc2@if88034: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-adf3fed056db state UP group default
link/ether 66:a7:77:bd:d0:ca brd ff:ff:ff:ff:ff:ff link-netnsid 1
inet6 fe80::64a7:77ff:febd:d0ca/64 scope link
valid_lft forever preferred_lft forever
88037: veth00b963e@if88036: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-adf3fed056db state UP group default
link/ether e6:18:ec:30:5c:a6 brd ff:ff:ff:ff:ff:ff link-netnsid 3
inet6 fe80::e418:ecff:fe30:5ca6/64 scope link
valid_lft forever preferred_lft forever
88041: vethda3acd6@if88040: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-adf3fed056db state UP group default
link/ether 3a:ad:d7:6c:fa:cb brd ff:ff:ff:ff:ff:ff link-netnsid 4
inet6 fe80::38ad:d7ff:fe6c:facb/64 scope link
valid_lft forever preferred_lft forever
88043: veth2f937b7@if88042: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-adf3fed056db state UP group default
link/ether ea:9e:65:d9:9a:f3 brd ff:ff:ff:ff:ff:ff link-netnsid 5
inet6 fe80::e89e:65ff:fed9:9af3/64 scope link
valid_lft forever preferred_lft forever
88045: vethac132e2@if88044: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-adf3fed056db state UP group default
link/ether e2:46:7e:4f:71:52 brd ff:ff:ff:ff:ff:ff link-netnsid 6
inet6 fe80::e046:7eff:fe4f:7152/64 scope link
valid_lft forever preferred_lft forever
88049: vethe8f0958@if88048: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-adf3fed056db state UP group default
link/ether 9a:e9:40:f1:4d:6b brd ff:ff:ff:ff:ff:ff link-netnsid 7
inet6 fe80::98e9:40ff:fef1:4d6b/64 scope link
valid_lft forever preferred_lft forever
88053: vethf57e351@if88052: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-adf3fed056db state UP group default
link/ether 6a:52:e2:51:c5:7d brd ff:ff:ff:ff:ff:ff link-netnsid 2
inet6 fe80::6852:e2ff:fe51:c57d/64 scope link
valid_lft forever preferred_lft forever
88055: vethec5ddd0@if88054: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-adf3fed056db state UP group default
link/ether 76:69:ec:ce:e7:f8 brd ff:ff:ff:ff:ff:ff link-netnsid 8
inet6 fe80::7469:ecff:fece:e7f8/64 scope link
valid_lft forever preferred_lft forever
88057: veth473fda8@if88056: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-adf3fed056db state UP group default
link/ether 36:48:f4:47:26:81 brd ff:ff:ff:ff:ff:ff link-netnsid 9
inet6 fe80::3448:f4ff:fe47:2681/64 scope link
valid_lft forever preferred_lft forever
ИЗМЕНЕНИЕ 4:
Вывод на основе ответа Trolzen
# socat -d -d UDP-RECVFROM:23456,fork -2021/08/12 12:12:07 socat[4506] N receiving on AF=2 0.0.0.0:23456
2021/08/12 12:12:11 socat[4506] N receiving packet from AF=2 <myPublicIp>:47228
2021/08/12 12:12:11 socat[4506] N forked off child process 4510
2021/08/12 12:12:11 socat[4510] N reading from and writing to stdio
2021/08/12 12:12:11 socat[4510] N starting data transfer loop with FDs [5,5] and [0,1]
2021/08/12 12:12:11 socat[4510] N received packet with 5 bytes from AF=2 <myPublicIp>:47228
test
2021/08/12 12:12:11 socat[4510] N socket 1 (fd 5) is at EOF
2021/08/12 12:12:11 socat[4506] N receiving on AF=2 0.0.0.0:23456
2021/08/12 12:12:12 socat[4510] N exiting with status 0
2021/08/12 12:12:12 socat[4506] N receiving on AF=2 0.0.0.0:23456
# socat -d -d -T.5 UDP-LISTEN:23456,fork -
2021/08/12 12:15:20 socat[4811] N listening on UDP AF=2 0.0.0.0:23456
2021/08/12 12:15:23 socat[4811] N accepting UDP connection from AF=2 <myPublicIp>:55887
2021/08/12 12:15:23 socat[4811] N forked off child process 4817
2021/08/12 12:15:23 socat[4811] N listening on UDP AF=2 0.0.0.0:23456
2021/08/12 12:15:23 socat[4817] N reading from and writing to stdio
2021/08/12 12:15:23 socat[4817] N starting data transfer loop with FDs [5,5] and [0,1]
test
2021/08/12 12:15:23 socat[4817] N inactivity timeout triggered
2021/08/12 12:15:23 socat[4817] N exiting with status 0
2021/08/12 12:15:23 socat[4811] N childdied(): handling signal 17
# socat -d -d UDP-RECV:23456 -
2021/08/12 12:16:12 socat[4891] N reading from and writing to stdio
2021/08/12 12:16:12 socat[4891] N starting data transfer loop with FDs [5,5] and [0,1]
2021/08/12 12:16:15 socat[4891] N received packet with 5 bytes from AF=2 <myPublicIp>:42481
test
Вывод “Основной команды”
2021/08/12 12:22:37 socat[5435] N accepting UDP connection from AF=2 <myPublicIp>:40659
2021/08/12 12:22:37 socat[5435] N forked off child process 5482
2021/08/12 12:22:37 socat[5435] N listening on UDP AF=2 0.0.0.0:12345
2021/08/12 12:22:37 socat[5482] N opening connection to AF=2 127.0.0.1:23456
2021/08/12 12:22:37 socat[5482] N successfully connected from local address AF=2 127.0.0.2:36305
2021/08/12 12:22:37 socat[5482] N starting data transfer loop with FDs [5,5] and [6,6]
2021/08/12 12:22:42 socat[5482] N inactivity timeout triggered
2021/08/12 12:22:42 socat[5482] N exiting with status 0
2021/08/12 12:22:42 socat[5435] N childdied(): handling signal 17
Моя версия netcat не является проблемой. Netcat – это всего лишь пример приложения, которое я использую для тестирования, и я вижу эту проблему и в пакетных дампах тоже.
Попробуйте изменить область охвата интерфейса lo
– я думаю, вам нужно изменить его с host
на global
.
Вы можете сделать это в [/etc/network/interfaces][1]
, если используете Debian (нужно выполнить ifdown lo
и ifup lo
, чтобы изменения вступили в силу) или использовать команду ip addr set dev lo scope global
(как мне кажется).
Мне пришлось сделать это, чтобы запросы DNS, происходящие от localhost, имели правильный установленный адрес источника, чтобы они могли получать ответы от DNS-сервера, размещенного на localhost, который также был доступен на других интерфейсах.
Поскольку, как вы подтверждаете, это поведение не удалось воспроизвести, это не ваше недоразумение или неправильное использование socat
. Это что-то в вашей конкретной настройке: либо неправильная конфигурация, либо неверная диагностика со стороны nc
. Вот предложения по устранению неполадок.
Я буду использовать следующие термины для обозначения команд:
- Генератор, команда 1 (я добавил
-q0
, чтобыnc
не “висел”):echo test | nc -u -q0 127.0.0.1 12345
- Основная команда, команда 2:
socat -T5 UDP4-LISTEN:12345,reuseaddr,fork UDP4:127.0.0.1:23456,bind=127.0.0.2,so-bindtodevice=lo
- Приемник, команда для приема, команда 3:
nc -u -l -p 23456 -vv
1. Больше диагностики.
Замените команду приемника одной из следующих (они почти эквивалентны):
socat -d -d UDP-RECVFROM:23456,fork -
socat -d -d -T.5 UDP-LISTEN:23456,fork -
socat -d -d UDP-RECV:23456 -
Также добавьте -d -d
к основной команде.
Это позволит вам получить больше информации о том, что происходит.
2. Анализ пакетов.
Используйте какой-нибудь пакетный дампер и анализатор (Wireshark, tcpdump) на всех интерфейсах, чтобы захватить пакеты и выяснить, какие реальные пакеты отправляются.
3. Проверьте правила фильтрации пакетов.
Кроме правил фильтрации пакетов, которые вы предоставили, существует еще три таблицы, которые следует изучить:
sudo iptables -S -t nat
sudo iptables -S -t mangle
sudo iptables -S -t raw
4. Версия netcat
Какая версия nc
? Может быть, она содержит ошибки? Также оказывается, что есть две версии netcat: традиционная и версия OpenBSD.
$ nc -h 2>&1 | head -n 1
[v1.10-41.1]
Правильное поведение (для справки)
Команда 1:
$ echo test | nc -u -q0 127.0.0.1 12345
$
Команда 2:
$ sudo socat -T5 -d -d UDP4-LISTEN:12345,reuseaddr,fork UDP4:127.0.0.1:23456,bind=127.0.0.2,so-bindtodevice=lo
2021/07/23 01:49:48 socat[4617] N listening on UDP AF=2 0.0.0.0:12345
2021/07/23 01:51:12 socat[4617] N accepting UDP connection from AF=2 127.0.0.1:59877
2021/07/23 01:51:12 socat[4617] N forked off child process 4622
2021/07/23 01:51:12 socat[4617] N listening on UDP AF=2 0.0.0.0:12345
2021/07/23 01:51:12 socat[4622] N opening connection to AF=2 127.0.0.1:23456
2021/07/23 01:51:12 socat[4622] N successfully connected from local address AF=2 127.0.0.2:36338
2021/07/23 01:51:12 socat[4622] N starting data transfer loop with FDs [5,5] and [6,6]
2021/07/23 01:51:17 socat[4622] N inactivity timeout triggered
2021/07/23 01:51:17 socat[4622] N exiting with status 0
2021/07/23 01:51:17 socat[4617] N childdied(): handling signal 17
Команда 3:
vagrant@packer-debian-10-amd64:~$ socat -d -d UDP-RECVFROM:23456,fork -
2021/07/23 01:50:54 socat[4619] N receiving on AF=2 0.0.0.0:23456
2021/07/23 01:51:12 socat[4619] N receiving packet from AF=2 127.0.0.2:36338
2021/07/23 01:51:12 socat[4619] N forked off child process 4623
2021/07/23 01:51:12 socat[4623] N reading from and writing to stdio
2021/07/23 01:51:12 socat[4623] N starting data transfer loop with FDs [5,5] and [0,1]
2021/07/23 01:51:12 socat[4623] N received packet with 5 bytes from AF=2 127.0.0.2:36338
2021/07/23 01:51:12 socat[4619] N receiving on AF=2 0.0.0.0:23456
test
2021/07/23 01:51:12 socat[4623] N socket 1 (fd 5) is at EOF
2021/07/23 01:51:13 socat[4623] N exiting with status 0
2021/07/23 01:51:13 socat[4619] N receiving on AF=2 0.0.0.0:23456
Примечания.
-
Я думаю, что опция
so-bindtodevice=lo
в основной команде не нужна, так как вы уже привязываетесь к IP-адресу с помощьюbind=127.0.0.2
. -
Если ваша задача не заключается в изучении каждого аспекта поведения
socat
, а больше в том, чтобы выполнить задачу (например, переадресация специфического UDP-трафика между подсетями), я рекомендую вам использовать фильтр пакетов и его возможности NAT для этой задачи. Это был бы правильный способ сделать это, потому чтоsocat
работает на уровне приложений (L7), а фильтр пакетов работает на сетевом уровне (L3).
Ответ или решение
Как IT-эксперт, давайте разберемся с проблемой неправильного IP-адреса при использовании socat для перенаправления UDP-трафика. Вы привели команду socat и результаты ее работы, которые показывают, что вместо ожидаемого IP-адреса (127.0.0.2) в качестве источника трафика используется ваш публичный IP-адрес. Это поведение может быть вызвано несколькими факторами. В этой статье мы рассмотрим возможные причины такого поведения и способы их устранения.
1. Описание проблемы
Вы запустили следующую команду:
socat -T5 UDP4-LISTEN:12345,reuseaddr,fork UDP4:127.0.0.1:23456,bind=127.0.0.2,so-bindtodevice=lo
Команда предназначена для прослушивания UDP-трафика на порту 12345 и перенаправления его на локальный адрес 127.0.0.1:23456. Однако при тестировании с помощью netcat вы получили вывод, указывающий на то, что источником пакетов является ваш публичный IP-адрес.
2. Объяснение поведения
a) Проблемы привязки адреса
Вы используете опцию bind
, чтобы указать, что вы хотите использовать адрес 127.0.0.2
. Тем не менее, фактический источник пакетов, отправляемых от клиента, будет зависеть от маршрутизации, используемой на вашем сервере.
Когда ваш сервер принимает пакет от клиента (например, test
от echo
через netcat), этот пакет, скорее всего, будет принимаем на интерфейсе, и так как он создает новое соединение к 127.0.0.1, может происходить изменение адреса. Это может происходить из-за NAT или настроек маршрутизации. Ваша система может не учитывать, что пакет пришел от локального адреса, и вместо этого использует выходной адрес интерфейса.
b) NAT и правила маршрутизации
Вы также упомянули, что вы видите публичный IP-адрес в выводе netstat. Это говорит о том, что система маршрутизации или NAT (сетевой адресный перевод) может изменять адрес пакет при возврате.
3. Возможные решения
a) Проверка конфигурации интерфейса
Попробуйте изменить область действия интерфейса lo с "host" на "global". Вы можете сделать это следующим образом:
ip addr set dev lo scope global
После этого перезапустите интерфейс:
ifdown lo && ifup lo
b) Проверка правил iptables
Убедитесь, что правила iptables не изменяют адреса пакетов. Посмотрите на таблицы NAT и mangle:
sudo iptables -t nat -L -n -v
sudo iptables -t mangle -L -n -v
Возможно, карты маршрутизации или правила NAT влияют на поведение.
c) Изменение использования socat
Ты также можешь попробовать убрать so-bindtodevice=lo
, так как это может не быть необходимым, если вы уже используете bind=127.0.0.2
. Попробуйте следующую команду:
socat -T5 UDP4-LISTEN:12345,reuseaddr,fork UDP4:127.0.0.1:23456,bind=127.0.0.2
d) Использование Tcpdump
Запустите tcpdump, чтобы диагностировать реальные пакеты, отправляемые и принимаемые вашим сервером:
tcpdump -i any -n udp port 12345
tcpdump -i any -n udp port 23456
Это позволит вам увидеть, какие IP-адреса фактически присутствуют в заголовках пакетов.
4. Заключение
Сложности с сетевыми конфигурациями могут возникать по нескольким причинам, включая неправильные настройки маршрутизации и NAT. Следуя приведенным рекомендациям, вы сможете выявить источники проблемы и исправить их. Если указанные шаги не устраняют проблему, возможно, вам стоит рассмотреть использование более низкоуровневых инструментов, таких как iptables для решения задач перенаправления и маршрутизации.
Для более глубокого анализа и понимания сетевого поведения в вашей системе вы всегда можете обратиться к документации по socat, NAT и маршрутизации.