Recently occasionally found a more strange phenomenon, netstat view the listening service port, but only show the TCP6 monitoring, but the service is clearly accessible through TCP4 IPv4 address, then why does not display TCP4 monitoring it?
Take the 22-port sshd Listener as an example:
grep :tcp 0 00.0. 0.0: 0.0. 0.0:* LISTEN 1444/sshdtcp6 0 0 :::22 :::* LISTEN 1444/sshd
As you can see, the netstat display indicates that sshd listens to both the address of the IPv4 and the address of the IPv6.
And then look at the httpd process:
1 grep :2 tcp6 0 0 ::: + :::* LISTEN 19837/httpd
But found that only the listener on the IPv6 address, but through the IPv4 address is clearly accessible.
Let's see how to explain this phenomenon.
First, turn off IPv6 and restart httpd:
1 # sysctl net.ipv6.conf.all.disable_ipv6=12 # systemctl Restart httpd
Now, look at the address of the HTTPD listener:
1 grep :2 tcp 0 00.0. 0.0: 0.0. 0.0:* LISTEN 33697/httpd
As you can see, only the IPv4 address has been heard.
Why is it that when the IPv6 is turned on, netstat only shows the listener of TCP6 instead of displaying both TCP and TCP6 in the same way as sshd?
We download httpd source code to take a look, in the server/listen.c
open_listeners () function, there are related comments:
1 /* If we have the unspecified IPv4 address (0.0.0.0) and 2 * the unspecified IPv6 address (::) is next, we need to 3 * swap the order of these in the list. We always try to 4 * bind to IPV6 first and then IPv 4, since an IPV6 socket 5 * might being able to rece Ive IPV4 packets If v6only is not 6 * enabled, But never the other around. 7 * ... Omit ... 8 */
As mentioned above, IPv6 is actually able to handle IPv4 requests when v6only is not turned on, and vice versa; So when does v6only start?
Continue with the follow code to the Make_sock () function, you can find the following code:
1 #if Apr_have_ipv62#ifdef ap_enable_v4_mapped3 int0; 4 #else 5 int 1 ; 6 #endif 7 #endif
In this function, you can see if the address of the listener is IPv6, then to set ipv6_v6only this socket option, now, the key is to see how ap_enable_v4_mapped is defined.
In Configure (note that if it is obtained directly by code number, there may not be this file, but only the configure.ac/in file) file, you can find:
1# Check whether--enable-v4-mapped was given.2 ifTest"${enable_v4_mapped+set}"= set; Then :3Enableval=$enable _v4_mapped;4V4mapped=$enableval5 6 Else7 8 Case$hostinch9*freebsd5*|*netbsd*|*openbsd*)TenV4mapped=No One ;; A*) -V4mapped=Yes - ;; the Esac - ifap_mpm_is_enabled Winnt; Then -V4mapped=No - fi + - fi + A at ifTest $v 4mapped ="Yes"-a $ac _cv_define_apr_have_ipv6 ="Yes"; Then - -$as _echo"#define AP_ENABLE_V4_MAPPED 1">>confdefs.h
Therefore, in Linux, by default, ap_enable_v4_mapped is 1, then httpd will listen directly to IPv6, because at this time the IPv6 socket can handle the IPv4 request, in addition, the bind () system calls the process of user space Ming processing IPv6 not open, at this time will hear IPv4.
And if we use parameters to suppress IPv4 mapped when compiling httpd, --disable-v4-mapped
by default httpd will listen to IPv4 and IPv6, instead of just listening to IPv6, as follows:
1 grep :2 tcp 0 00.0. 0.0: 0.0. 0.0:* LISTEN 40576/httpd3 tcp6 0 0 :::+ :::* LISTEN 40576/httpd
Instead, if you /etc/httpd/conf/httpd.conf
Listen
set it to only listen for the IPv6 address, the following:
1 Listen:::
Then, you will see that netstat only shows TCP6 monitoring:
1 # systemctl Restart httpd 2 grep :3 tcp6 0 0 ::: + :::* LISTEN 40980/httpd
And, you'll find that you can't access httpd now through the IPv4 address.
1 192.168. 1.100 the 2 192.168. 1.100 ... 3 telnet:unable to connect to remote Host:connection refused
So, Netstat is just a real display of listening ports, but it's important to note that IPv6 actually supports IPv4 on Linux.
Transferred from: http://www.chengweiyang.cn/2017/03/05/why-netstat-not-showup-tcp4-socket/
Why netstat shows only tcp6 listening ports for some services