最近偶尔发现一个比较奇怪的现象,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_MAPPEDint v6only_setting = 0;
#elseint 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=$enablevalelsecase $host in*freebsd5*|*netbsd*|*openbsd*)v4mapped=no;;*)v4mapped=yes;;esacif ap_mpm_is_enabled winnt; thenv4mapped=nofifiif 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。

转载于:https://www.cnblogs.com/wlzjdm/p/8684202.html

为什么 netstat 对某些服务只显示了 tcp6 监听端口相关推荐

  1. mysql服务在tcp6_为什么 netstat 对某些服务只显示了 tcp6 监听端口

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

  2. Linux的ipv6不监听端口,netstat查看服务端口监听在ipv6但是通过ipv4地址可正常访问...

    在Linux系统中,会发现一个有趣的现象,通过 netstat 查看监听的服务端口时,发现有些服务 Proto(protocol协议) 项只显示了 tcp6(代表监听服务端口在IPv6协议), 没有 ...

  3. netstat linux查看监听端口号,linux用netstat查看服务及监听端口

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

  4. linux系统中ntp服务监听端口是,Linux系统下测试UDP端口是否正常监听的办法

    TCP端口,比如80端口,可使用 telnet 主机ip 80,来验证端口是否正常监听,那UDP端口是否可同样测试呢?关于UDP端口怎样测试监听的问题, 下面我们来进行测试,如:123端口是服务器 A ...

  5. Oracle单机报监听不支持服务,(转)oracle 启动监听 报“监听程序不支持服务” 解决...

    转自 http://www.51testing.com/html/99/478599-842622.html 今天安装了oracle后,启动监听,报错如下: 启动tnslsnr: 请稍候... TNS ...

  6. linux监听端口丢失,linux – 如果没有监听端口,则为Systemd重启服务

    我建议你采用不同的方法,并使用专用的监控工具来实现这一目标. 我最喜欢的监控工具,允许重新启动服务,以防它们崩溃,或者不再在其配置的端口上监听,这是monit:https://packages.deb ...

  7. centos oracle 修改监听服务名_Oracle-Oracle DB、监听和oem开机启动

    1.Windows Oracle提供了伴随操作系统自动重启的功能,在Windows中,可以修改"我的电脑-->管理-->服务-->OracleService$ORACLE_ ...

  8. c#web页面显示弹窗_C#监听IE文档加载完成、弹窗、JS弹窗、页面跳转

    这个Demo在早段时间有个网友需要做一个相关方面的软件,我给做出来的.很方面,在JS弹窗监听上耗了不少时间.现在均已解决!请勿用作非法商业用途,该软件产生的后果与作者本人无关,特此声明. 由于需要对H ...

  9. python socket监听端口_Python 用socket模块实现检测端口和检测web服务

    检测端口 check_tcp_port.py #!/usr/bin/env python import socket import re import sys def check_server(add ...

最新文章

  1. c语言 自动测试,C语言测试。自己实现scandir 函数
  2. 算法设计与分析——回溯法——n皇后问题
  3. Linux ubuntu对于cmake的版本更新
  4. stl:queue 源码_C ++ STL中的queue :: empty()和queue :: size()
  5. [Swift通天遁地]一、超级工具-(13)使用PKHUD制作各种动态提示窗口
  6. 【多题合集】线段覆盖1、2、3
  7. UVa 808 (建坐标系、找规律) Bee Breeding
  8. 动易Ajax登陆调用
  9. django 日志多个服务连接_Django多进程日志文件问题
  10. ping不同的网卡方法
  11. 使用sp_addlinkedserver、sp_dropserver 、sp_addlinkedsrvlogin和sp_droplinkedsrvlogin 远程查询数据...
  12. 浪潮服务器显示一个红色闪电图标,华为手机开不了机,只显示一个红色圆圈里面一个红色闪电符号...
  13. Unity3d随机数生成
  14. Ubuntu安装wine
  15. 《谁动了我的奶酪》感悟
  16. Android Hierarchy Viewer
  17. 在家享受专业跑道,安全跑步高效健身,华为智选赤兔跑步机H1体验
  18. 如何参与到开源优测-积微速成计划任务
  19. Verilog基础语法--运算符【常用的几种】
  20. layui tree 对节点进行搜索

热门文章

  1. Golang 如何正确使用 Context
  2. 深度学习——感知机(perceptron)图文详解
  3. 网站反爬虫的策略有哪些
  4. cocos2dx梦幻西游开发日志(五)
  5. Linux 查看端口常用命令
  6. 这7个自动化办公模版 教你玩转表格数据自动化
  7. [转]一个初中生到程序员的辛酸经历
  8. RW-Tree: A Learned Workload-aware Framework for R-tree Construction(ICDE2021)
  9. Vim替换命令substitute介绍
  10. form表单提交json格式数据