Ubuntu

Netstat not displaying all listening ports when using IPv4 and IPv6

Asked by Michael Warren on 2010-10-09

I am running a machine with both IPv4 and IPv6.

I noticed earlier that when doing a 'netstat -anl4' (or just grepping through 'netstat -an' output) that not all listening IPv4 ports are displayed. Example:

# netstat -anl4 | grep external_ipv4_address | grep 80

Yet, it is definitely listening:

> telnet external_ipv4_address 80
Trying external_ipv4_address...
Connected to external_ipv4_address.
Escape character is '^]'.

It definitely seems like for applications that listen on both IPv4 and IPv6 that only the IPv6 listening socket is displayed, as if they are aggregated together. This is a problem because we can no longer trust netstat to properly display all listening sockets.

I would suggest that netstat always show every port that is listening on both the IPv4 and IPv6 stack. Having more data seems like a good thing here since netstat is the primary tool for determining which ports a machine is listening on.

Distributor ID: Ubuntu
Description: Ubuntu 10.04.1 LTS
Release: 10.04
Codename: lucid

Question information

Language:
English Edit question
Status:
Solved
For:
Ubuntu net-tools Edit question
Assignee:
No assignee Edit question
Solved by:
Michael Warren
Solved:
2012-05-11
Last query:
2012-05-11
Last reply:
2010-10-10
Thomas Krüger (thkrueger) said : #1

That's easy to explain. You filtered out the processes that are listening to all addresses (0.0.0.0) with grep.
And BTW the -l option is not required when using -a.

Michael Warren (mike-ef) said : #2

Thomas,

Thanks for your response. The port isn't displayed _at all_, it is not a grep problem. I just didn't want to dump my IP addresses on a public forum.

This is the complete output:

# netstat -anl4
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:222 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN
tcp 0 0 10.70.0.136:53 0.0.0.0:* LISTEN
tcp 0 0 public_ipv4_addr:53 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:953 0.0.0.0:* LISTEN
tcp 0 0 10.70.0.136:222 10.255.255.22:58091 ESTABLISHED
udp 0 0 0.0.0.0:514 0.0.0.0:*
udp 0 0 10.70.0.136:53 0.0.0.0:*
udp 0 0 public_ipv4_addr:53 0.0.0.0:*
udp 0 0 127.0.0.1:53 0.0.0.0:*

Yet:
# telnet public_ipv4_address 80
Trying public_ipv4_address...
Connected to public_ipv4_address.
Escape character is '^]'.

Michael Warren (mike-ef) said : #3

FYI: Just upgraded this machine to 10.10 and the problem still exists.

Michael Warren (mike-ef) said : #4

This bug still exists in 11.04.

Michael Warren (mike-ef) said : #5

After doing more research, I believe this is because Apache is not using the IPV6_V6ONLY flag when it binds to port 80. This allows the IPv6 socket to serve both IPv4 and IPv6 traffic. Since there is technically only one listening socket, this is why netstat only shows the IPv6 socket.

Historically we could use netstat to see exactly what is listening, but in the case of IPV6_V6ONLY, it's entirely possible that an IPv6 socket could handle IPv4 traffic and netstat would never show it.

Here is the README from the netbase package:

# When disabled, IPv6 sockets will also be able to send and receive IPv4
# traffic with addresses in the form ::ffff:192.0.2.1 and daemons listening
# on IPv6 sockets will also accept IPv4 connections.
#
# When IPV6_V6ONLY is enabled, daemons interested in both IPv4 and IPv6
# connections must open two listening sockets.
# This is the default behaviour of almost all modern operating systems.

IPV6_V6ONLY is controlled by the sysctl net.ipv6.bindv6only.

Jeff Loughridge (jeffl-v) said : #6

The incorrect netstat output is not helpful to the user. Whether or not the IPV6_V6ONLY flag is set, netstat *should* show the correct address family/port pairs. The see the same problem when I tried on a debian squeeze VM.

Mike's suggestion should be implemented in future Ubuntu releases.