Thread (1 message) 1 message, 1 author, 2023-08-08

Re: [Linux Bug Report] Binding to IP address using bind(2) seems to leak traffic to other interfaces

From: Yu Yat Ho <hidden>
Date: 2023-08-08 15:57:44

Didn't realise I was supposed to file a bug report to the Linux
distribution I was using instead of directly emailing you.
Terribly sorry for taking up your precious time.

Just in case you are interested, the bug report I filed is at
https://bugzilla.redhat.com/show_bug.cgi?id=2229902.

Best regards,
Yat


On Tue, 8 Aug 2023 at 11:34, Yu Yat Ho [off-list ref] wrote:
Hi all,

I hope this is the correct place to report the bug I am experiencing.

The problem I am seeing is that data sent through a socket bound using bind(2) seems to be leaking to other network interfaces in the system. Here are some brief steps to demonstrate the problem, it works using wget too:

Set up a Linux VM (I am using Fedora 38 on VirtualBox) that has one NAT interface (has Internet access) and one host-only interface (no Internet access).
Try to send a request using curl that is bound to the host-only interface using its interface name. It should fail to connect as expected.

$ curl --interface enp0s8 icanhazip.com

Try to send another request, this time bind to the host-only interface using IP address. It will somehow successfully get a response.

$ curl --interface 192.168.56.103 icanhazip.com

The tcpdump output shows that the packets were originated from the NAT interface (enp0s3 is the NAT interface), but they have the source IP of the host-only interface:

# tcpdump -i any -nn host icanhazip.com
tcpdump: data link type LINUX_SLL2
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
10:56:34.264997 enp0s3 Out IP 192.168.56.103.57656 > 104.18.114.97.80: Flags [S], seq 2864717259, win 64240, options [mss 1460,sackOK,TS val 1169355339 ecr 0,nop,wscale 7], length 0
10:56:35.320888 enp0s3 Out IP 192.168.56.103.57656 > 104.18.114.97.80: Flags [S], seq 2864717259, win 64240, options [mss 1460,sackOK,TS val 1169356395 ecr 0,nop,wscale 7], length 0
10:56:37.368625 enp0s3 Out IP 192.168.56.103.57656 > 104.18.114.97.80: Flags [S], seq 2864717259, win 64240, options [mss 1460,sackOK,TS val 1169358443 ecr 0,nop,wscale 7], length 0
10:56:40.726550 enp0s3 In  IP 104.18.114.97.80 > 192.168.56.103.57656: Flags [S.], seq 64001, ack 2864717260, win 65535, options [mss 1460], length 0
10:56:40.726609 enp0s3 Out IP 192.168.56.103.57656 > 104.18.114.97.80: Flags [.], ack 1, win 64240, length 0
10:56:40.727387 enp0s3 Out IP 192.168.56.103.57656 > 104.18.114.97.80: Flags [P.], seq 1:77, ack 1, win 64240, length 76: HTTP: GET / HTTP/1.1
10:56:40.728146 enp0s3 In  IP 104.18.114.97.80 > 192.168.56.103.57656: Flags [.], ack 77, win 65535, length 0
10:56:40.739934 enp0s3 In  IP 104.18.114.97.80 > 192.168.56.103.57656: Flags [P.], seq 1:550, ack 77, win 65535, length 549: HTTP: HTTP/1.1 200 OK
10:56:40.739977 enp0s3 Out IP 192.168.56.103.57656 > 104.18.114.97.80: Flags [.], ack 550, win 63691, length 0
10:56:40.742079 enp0s3 Out IP 192.168.56.103.57656 > 104.18.114.97.80: Flags [F.], seq 77, ack 550, win 63691, length 0
10:56:40.742822 enp0s3 In  IP 104.18.114.97.80 > 192.168.56.103.57656: Flags [.], ack 78, win 65535, length 0
10:56:40.751004 enp0s3 In  IP 104.18.114.97.80 > 192.168.56.103.57656: Flags [F.], seq 550, ack 78, win 65535, length 0
10:56:40.751038 enp0s3 Out IP 192.168.56.103.57656 > 104.18.114.97.80: Flags [.], ack 551, win 63691, length 0
^C
13 packets captured
17 packets received by filter
0 packets dropped by kernel

Here are some more info that you may be interested in:

My uname -a output:

Linux f38-test 6.4.7-200.fc38.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Jul 27 20:01:18 UTC 2023 x86_64 GNU/Linux

My curl -V output:

curl 8.0.1 (x86_64-redhat-linux-gnu) libcurl/8.0.1 OpenSSL/3.0.9 zlib/1.2.13 brotli/1.0.9 libidn2/2.3.4 libpsl/0.21.2 (+libidn2/2.3.4) libssh/0.10.5/openssl/zlib nghttp2/1.52.0
Release-Date: 2023-03-20
Protocols: dict file ftp ftps gopher gophers http https imap imaps ldap ldaps mqtt pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: alt-svc AsynchDNS brotli GSS-API HSTS HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM NTLM_WB PSL SPNEGO SSL threadsafe TLS-SRP UnixSockets

When --interface is specified, curl binds using SO_BINDTODEVICE when given an interface name, and bind(2) when given an IP address.
https://github.com/curl/curl/issues/11599#issuecomment-1667391636

My ifconfig output (enp0s3 is the NAT interface, enp0s8 is the host-only interface):

enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.2.15  netmask 255.255.255.0  broadcast 10.0.2.255
        inet6 fe80::a00:27ff:fec5:2755  prefixlen 64  scopeid 0x20<link>
        ether 08:00:27:c5:27:55  txqueuelen 1000  (Ethernet)
        RX packets 20  bytes 2450 (2.3 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 35  bytes 3150 (3.0 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

enp0s8: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.56.103  netmask 255.255.255.0  broadcast 192.168.56.255
        inet6 fe80::a00:27ff:fe2f:7c6  prefixlen 64  scopeid 0x20<link>
        ether 08:00:27:2f:07:c6  txqueuelen 1000  (Ethernet)
        RX packets 147  bytes 14330 (13.9 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 256  bytes 33720 (32.9 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

I will gladly provide more information should you need them, please let me know.

Best regards,
Yat
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help