AF_INET6
Sockets Can Accept Connections From IPv4 Addresses
In Problems When Setting Up WriteFreely Part 2: Firewall, I posed an unanswered question:
Why did netstat not show me processes listening to port 80 & 443, yet I was able to make an HTTP request to port 80?
In that post, I showed a netstat
output as follows:
[email protected]:~$ netstat -t4lpn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:33060 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN -
I wanted to confirm that my WriteFreely instance was listening to port 80 & 443. But, the above output didn't give me the answer I sought. I didn't see anything listening on port 80, yet I was able to connect to that port successfully!
I only focused on IPv4 at the time because I thought I was connecting to the IPv4 interface of my server. After all, my server wasn't assigned a public IPv6 address. teddyh.dev
only has an A
record containing the IPv4 address of my server.
Later, I did more research on this seemingly odd phenomenon. I stumbled upon this SO post. Apparently, AF_INET6
sockets can receive connections from IPv4 addresses!
Had I used sudo netstat -tlpn
instead, I would have seen the following output:
[email protected]:~$ sudo netstat -tlpn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN 459/systemd-resolve
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 707/sshd: /usr/sbin
tcp 0 0 127.0.0.1:33060 0.0.0.0:* LISTEN 644/mysqld
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN 644/mysqld
tcp6 0 0 :::22 :::* LISTEN 707/sshd: /usr/sbin
tcp6 0 0 :::443 :::* LISTEN 140750/writefreely
tcp6 0 0 :::80 :::* LISTEN 140750/writefreely
This output gave way more insights than the netstat -t4lpn
. The last 2 lines showed that WriteFreely was listening to :::80
& :::443
. That would have given me some clue about this probable relationship between IPv6 sockets and IPv4 client addresses.
To further demonstrate this compatibility, I used telnet
to open a TCP connection to my server.
My home PC:
╭─teddy@teddy-ubuntu ~
╰─$ telnet teddyh.dev 443 130 ↵
Trying 54.151.219.0...
Connected to teddyh.dev.
Escape character is '^]'.
My blog server:
[email protected]:~$ sudo netstat -t6apn
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp6 0 0 :::22 :::* LISTEN 707/sshd: /usr/sbin
tcp6 0 0 :::443 :::* LISTEN 140750/writefreely
tcp6 0 0 :::80 :::* LISTEN 140750/writefreely
tcp6 0 0 172.31.29.106:443 A.B.C.D:36134 ESTABLISHED 140750/writefreely
I have redacted my home IP address above to A.B.C.D
. Notice that both the local & foreign addresses are IPv4. 172.31.29.106
is the private IPv4 address of my server, NAT'ed from the public IPv4 address 54.151.219.0
shown in the output of the telnet
command.
The above experiment proves that AF_INET6
sockets are compatible with IPv4 addresses. That said, that compatibility can be overridden by setting the IPV6_V6ONLY
option, as pointed out in the linked SO post.