最近偶尔发现一个比较奇怪的现象,netstat 查看监听的服务端口时,却只显示了 tcp6 的监控, 但是服务明明是可以通过 tcp4 的 ipv4 地址访问的,那为什么没有显示 tcp4 的监听呢?

以 sshd 监听的 22 端口为例:

# netstat -tlnp | grep :22
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1444/sshd
tcp6 0 0 :::22 :::* LISTEN 1444/sshd

可以看到,netstat 显示表示 sshd 既监听在 ipv4 的地址,又监听在 ipv6 的地址。

而再看看 httpd 进程:

# netstat -tlnp | grep :80
tcp6 0 0 :::80 :::* LISTEN 19837/httpd

却发现只显示了监听在 ipv6 的地址上 ,但是,通过 ipv4 的地址明明是可以访问访问的。

下面来看下怎样解释这个现象。

首先,关闭 ipv6 并且重启 httpd:

# sysctl net.ipv6.conf.all.disable_ipv6=1
# systemctl restart httpd

现在,看下 httpd 监听的地址:

# netstat -tlnp | grep :80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 33697/httpd

可以看到,已经只监听到 ipv4 地址了。

那为什么在 ipv6 开启的时候,netstat 只显示了 tcp6 的监听而非像 sshd 那样既显示 tcp 又显示 tcp6 的监听呢?

我们下载 httpd 的源码看一看,在代码 server/listen.c 的 open_listeners() 函数中, 有相关注释:

/* If we have the unspecified IPv4 address (0.0.0.0) and
* the unspecified IPv6 address (::) is next, we need to
* swap the order of these in the list. We always try to
* bind to IPv6 first, then IPv4, since an IPv6 socket
* might be able to receive IPv4 packets if V6ONLY is not
* enabled, but never the other way around.
* ... 省略 ...
*/

上面提到,ipv6 实际上是可以处理 ipv4 的请求的当 V6ONLY 没有开启的时候,反之不然; 那么 V6ONLY 是在什么时候开启呢?

继续 follow 代码到 make_sock() 函数,可以发现如下代码:

#if APR_HAVE_IPV6
#ifdef AP_ENABLE_V4_MAPPED
int v6only_setting = 0;
#else
int v6only_setting = 1;
#endif
#endif

在这个函数中,可以看到如果监听的地址是 ipv6,那么会去设置 IPV6_V6ONLY 这个 socket 选项, 现在,关键是看 AP_ENABLE_V4_MAPPED 是怎么定义的。

在 configure(注意,如果是直接通过代码数获取的,可能没有这个文件,而只有 configure.ac/in 文件)文件中, 可以找到:

# Check whether --enable-v4-mapped was given.
if test "${enable_v4_mapped+set}" = set; then :
enableval=$enable_v4_mapped;
v4mapped=$enableval else case $host in
*freebsd5*|*netbsd*|*openbsd*)
v4mapped=no
;;
*)
v4mapped=yes
;;
esac
if ap_mpm_is_enabled winnt; then
v4mapped=no
fi fi if test $v4mapped = "yes" -a $ac_cv_define_APR_HAVE_IPV6 = "yes"; then $as_echo "#define AP_ENABLE_V4_MAPPED 1" >>confdefs.h

所以,在 Linux 中,默认情况下,AP_ENABLE_V4_MAPPED 是 1,那么 httpd 就会直接监听 ipv6, 因为此时 ipv6 的 socket 能够处理 ipv4 的请求;另外,bind() 系统调用会对用户空间的进程透明处理 ipv6 没有开启的情况,此时会监听到 ipv4。

而如果我们在编译 httpd 的时候使用 --disable-v4-mapped 参数禁止 ipv4 mapped,那么默认情况下, httpd 会分别监听在 ipv4 和 ipv6,而非只监听 ipv6,如下所示:

# netstat -tlnp | grep :80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 40576/httpd
tcp6 0 0 :::80 :::* LISTEN 40576/httpd

而,如果在 /etc/httpd/conf/httpd.conf 中将 Listen 设置为只监听 ipv6 地址,如下:

Listen :::80

那么,将可以看到 netstat 只显示 tcp6 的监听:

# systemctl restart httpd
# netstat -tlnp | grep :80
tcp6 0 0 :::80 :::* LISTEN 40980/httpd

并且,你会发现现在不能通过 ipv4 地址访问 httpd 了。

# telnet 192.168.1.100 80
Trying 192.168.1.100...
telnet: Unable to connect to remote host: Connection refused

所以,netstat 只是很真实的显示监听的端口而已,但是需要注意 ipv6 实际上在 Linux 上也支持 ipv4。

为什么 netstat 对某些服务只显示了 tcp6 监听端口的更多相关文章

  1. linux用netstat查看服务及监听端口

    [root@localhost ~]# netstat -nlp netstat命令各个参数说明如下: -t : 指明显示TCP端口 -u : 指明显示UDP端口 -l : 仅显示监听套接字(所谓套接 ...

  2. Linux对外提供服务 网络操作 端口操作 1.开启服务监听端口 2.设置防火墙,放行访问端口的包 iptables&netfilter 四表五链和通堵策略

    主题: Linux服务器上软件提供服务 1.网络操作 2.端口操作 1.网络操作 本机必须能够ping通目标主机(本地虚拟机或者远程主机) 2.端口操作 1.开启服务监听端口 2.设置防火墙,放行访问 ...

  3. Android软键盘的隐藏显示、事件监听的代码

    把开发过程中重要的一些内容片段做个珍藏,如下资料是关于Android软键盘的隐藏显示.事件监听的内容,应该是对小伙伴们有所用途. public class ResizeLayout extends L ...

  4. linux上使用netstat查看当前服务和监听端口

    netstat这个命令常用在网络监控方面.利用这个命令,可以查看当前系统监听的服务和已经建立的服务,以及相应的端口.协议等信息. netstat参数说明 netstat参数虽然很多,但是常用的不多,主 ...

  5. 功能整合(一):滚动条的变相隐藏、js控制div的渐变显示、滚动条监听

    1.滚动条的变相隐藏 思路: 1.  把body的横向,纵向的超出部分隐藏,宽设置100%:高设置100%.就没有body的滚动条了, 2.  然后把最外层的div的宽设置的比body的宽宽一点,把d ...

  6. Android EditText软键盘显示隐藏以及“监听”

    一.写此文章的起因 本人在做类似于微信.易信等这样的聊天软件时,遇到了一个问题.聊天界面最下面一般类似于如图1这样(这里只是显示了最下面部分,可以参考微信等),有输入文字的EditText和表情按钮等 ...

  7. java实现服务端守护进程来监听客户端通过上传json文件写数据到hbase中

    1.项目介绍: 由于大数据部门涉及到其他部门将数据传到数据中心,大部分公司采用的方式是用json文件的方式传输,因此就需要编写服务端和客户端的小程序了.而我主要实现服务端的代码,也有相应的客户端的测试 ...

  8. Android Edittext 显示光标 获取焦点 监听焦点

    Edittext java 代码控制获取焦点 EditText mEditText = (EditText) findViewById(R.id.et); mEditText.setFocusable ...

  9. 修改ftp服务的监听端口

    需求说明: 今天在做一个项目的时候,低端的端口都给屏蔽掉了,需要进行修改为高端端口才能访问,在此记录下. 操作过程: 1.修改ftp的配置文件vsftpd.conf,增加以下的配置 listen_po ...

随机推荐

  1. HTML5基础 实例

    <!DOCTYPE html><html> <head> <title>李清照简介</title> </head> <bo ...

  2. Ceph 架构以及原理分析

    一.架构 Ceph在一个统一的系统中独特地提供对象,块和文件存储. Ceph高度可靠,易于管理且免费. Ceph的强大功能可以改变您公司的IT基础架构以及管理大量数据的能力. Ceph提供了非凡的可扩 ...

  3. iSensor APP 之 摄像头调试 MT9D001 MT9P031 测试小结 200万像素和500万像素摄像头

    iSensor APP 之 摄像头调试  MT9D001 MT9P031 测试小结 iSensor app 非常适合调试各种摄像头,已测试通过的sensor有: l  OV7670.OV7725.OV ...

  4. Linux-tac、diff、tree、echo、seq、重定向

    1.tac  方向输出文件,最后一行放在第一行的位置输出 2.diff  比较文件的内容 vimdiff:在vim中比较 3. tree  树状图显示目录内容 -d 只显示目录   -L  树状 目录 ...

  5. Happy Birthday! 今天我 1 周岁生日啦!

    2018.09.28,我第 1 天分享文章. 2019.09.28,我连续分享的第 365 天. 今天我 1 周岁啦! 生日意味着一个新的开端, 意味着重新把握生活的机会. 新的一岁,从新头像开始 愿 ...

  6. UWP 中的全局异常处理

    问题 在开发一款应用的过程中,我们开发者很难考虑到所有问题,往往会忘记处理一些可能发生的异常.随之而来的结果就是用户使用过程中接连不断的崩溃.所以,我们有必要处理所有未被我们处理的异常. 本文介绍了 ...

  7. 【Git】本地分支

    [Git]本地分支 转载:https://www.cnblogs.com/yangchongxing/p/10221382.html 目录 ============================== ...

  8. NodeJS2-4环境&调试----global变量

    global全局对象,希望把全局访问到的对象,属性和方法等挂到global对象上,除了用户自定义的方法外,global本身默认带着一些常用的属性和方法的 CommonJS Buffer.process ...

  9. java—将数据库读取的list转tree

    一.引言 有时候我们从数据库中读取出了一个表的数据,比如存储的是中国的省市县的ID.名称与父节点ID,读出来的数据并不是前台想要的,这个时候我们要想法处理一下都出来的list,将它变为一个树. 比如直 ...

  10. Git打包指定分支所提交的文件

    原文内容来自于LZ(楼主)的印象笔记,如出现排版异常或图片丢失等问题,可查看当前链接:https://app.yinxiang.com/shard/s17/nl/19391737/da7e233a-c ...