为什么 netstat 对某些服务只显示了 tcp6 监听端口
最近偶尔发现一个比较奇怪的现象,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 监听端口相关推荐
- mysql服务在tcp6_为什么 netstat 对某些服务只显示了 tcp6 监听端口
最近偶尔发现一个比较奇怪的现象,netstat 查看监听的服务端口时,却只显示了 tcp6 的监控, 但是服务明明是可以通过 tcp4 的 ipv4 地址访问的,那为什么没有显示 tcp4 的监听呢? ...
- Linux的ipv6不监听端口,netstat查看服务端口监听在ipv6但是通过ipv4地址可正常访问...
在Linux系统中,会发现一个有趣的现象,通过 netstat 查看监听的服务端口时,发现有些服务 Proto(protocol协议) 项只显示了 tcp6(代表监听服务端口在IPv6协议), 没有 ...
- netstat linux查看监听端口号,linux用netstat查看服务及监听端口
[root@localhost ~]# netstat -nlp netstat命令各个参数说明如下: -t : 指明显示TCP端口 -u : 指明显示UDP端口 -l : 仅显示监听套接字(所谓套接 ...
- linux系统中ntp服务监听端口是,Linux系统下测试UDP端口是否正常监听的办法
TCP端口,比如80端口,可使用 telnet 主机ip 80,来验证端口是否正常监听,那UDP端口是否可同样测试呢?关于UDP端口怎样测试监听的问题, 下面我们来进行测试,如:123端口是服务器 A ...
- Oracle单机报监听不支持服务,(转)oracle 启动监听 报“监听程序不支持服务” 解决...
转自 http://www.51testing.com/html/99/478599-842622.html 今天安装了oracle后,启动监听,报错如下: 启动tnslsnr: 请稍候... TNS ...
- linux监听端口丢失,linux – 如果没有监听端口,则为Systemd重启服务
我建议你采用不同的方法,并使用专用的监控工具来实现这一目标. 我最喜欢的监控工具,允许重新启动服务,以防它们崩溃,或者不再在其配置的端口上监听,这是monit:https://packages.deb ...
- centos oracle 修改监听服务名_Oracle-Oracle DB、监听和oem开机启动
1.Windows Oracle提供了伴随操作系统自动重启的功能,在Windows中,可以修改"我的电脑-->管理-->服务-->OracleService$ORACLE_ ...
- c#web页面显示弹窗_C#监听IE文档加载完成、弹窗、JS弹窗、页面跳转
这个Demo在早段时间有个网友需要做一个相关方面的软件,我给做出来的.很方面,在JS弹窗监听上耗了不少时间.现在均已解决!请勿用作非法商业用途,该软件产生的后果与作者本人无关,特此声明. 由于需要对H ...
- python socket监听端口_Python 用socket模块实现检测端口和检测web服务
检测端口 check_tcp_port.py #!/usr/bin/env python import socket import re import sys def check_server(add ...
最新文章
- c语言 自动测试,C语言测试。自己实现scandir 函数
- 算法设计与分析——回溯法——n皇后问题
- Linux ubuntu对于cmake的版本更新
- stl:queue 源码_C ++ STL中的queue :: empty()和queue :: size()
- [Swift通天遁地]一、超级工具-(13)使用PKHUD制作各种动态提示窗口
- 【多题合集】线段覆盖1、2、3
- UVa 808 (建坐标系、找规律) Bee Breeding
- 动易Ajax登陆调用
- django 日志多个服务连接_Django多进程日志文件问题
- ping不同的网卡方法
- 使用sp_addlinkedserver、sp_dropserver 、sp_addlinkedsrvlogin和sp_droplinkedsrvlogin 远程查询数据...
- 浪潮服务器显示一个红色闪电图标,华为手机开不了机,只显示一个红色圆圈里面一个红色闪电符号...
- Unity3d随机数生成
- Ubuntu安装wine
- 《谁动了我的奶酪》感悟
- Android Hierarchy Viewer
- 在家享受专业跑道,安全跑步高效健身,华为智选赤兔跑步机H1体验
- 如何参与到开源优测-积微速成计划任务
- Verilog基础语法--运算符【常用的几种】
- layui tree 对节点进行搜索