请教服务器端口只监听在 ipv6 ,为什么用 ipv4 却可以访问该端口?

2020-02-13 14:53:12 +08:00
 programV2
如下所示, 我 80 端口只监听在 ipv6 上,但本地用能访问服务器的 ipv4 的 80 端口( http 和 tcping 都 ok)
请问这是为什么? 还是说 ipv6 和 ipv4 只需要开一个监听端口?


root@abc:~# lsof -i:80
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
docker-pr 2471 root 4u IPv6 24351154 0t0 TCP *:http (LISTEN)

root@abc:~# netstat -tnlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:42303 0.0.0.0:* LISTEN 2835/containerd
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1999/sshd
tcp6 0 0 :::443 :::* LISTEN 2483/docker-proxy
tcp6 0 0 :::22 :::* LISTEN 1999/sshd
tcp6 0 0 :::80 :::* LISTEN 2471/docker-proxy
5972 次点击
所在节点    宽带症候群
13 条回复
cwbsw
2020-02-13 15:28:25 +08:00
systemd.socket
BindIPv6Only
dndx
2020-02-13 16:05:05 +08:00
https://en.wikipedia.org/wiki/IPv6#IPv4-mapped_IPv6_addresses

Linux 上需要 socket 开 `IPV6_V6ONLY` flag。不同软件不一样,对于 Nginx 可以 `listen [::]:8000 ipv6only=on;` 开启这个 flag。
programV2
2020-02-13 16:34:14 +08:00
@dndx
@cwbsw 谢谢两位指点. 就是说如果没有设置 BindIPv6Only 这个 tag 默认就是同时监听 ipv6 和 ipv4 端口吗? 另外还有一个疑问就是我用的容器,镜像中虽然映射了 80:80 和 443:443 端口, 但是我 nginx.conf 配置文件中只设置 listen 443; 为什么 80 端口还能访问( http 和 tcping 都 ok)??

docker-compose.yml 设置如下,
version: "3"
services:
nginx:
image: nginx:$NGINX_TAG
container_name: "${PROJECT_NAME}_nginx"
ports:
- 80:80
-443:443
dndx
2020-02-13 16:40:55 +08:00
不是同时监听,是内核默认会自动把 v4 过来的地址转换成特殊的 v6 地址。本意是为了方便开发双栈软件,这样软件只要支持 v6 一次就 v4 v6 通吃了。
programV2
2020-02-13 16:57:24 +08:00
@dndx 谢谢 V 友, 有两个疑问:1.刚进 nginx 容器内执行 netstat -tnlp, 发现 v4 的 80 和 443 都在监听, 我 nginx.conf 配置文件中只设置 listen 443;为什么还会监听 80 的端口呢??

2.内核默认会把 v4 过来的地址转换成特殊的 v6 地址, 但是我 nginx 容器内只监听 v4 的地址,那是不是说系统还得把这个特殊的 v6 地址再次转换成 v4 地址才能与容器内的 nginx 服务通信?
dndx
2020-02-13 17:00:30 +08:00
listen 443 本来就是两个都监听的。你试试 listen [::]:443 ipv6only=on; 就只监听 v6 了。
programV2
2020-02-13 17:13:02 +08:00
@dndx 谢谢!但是我进 nginx 容器内执行 netstat -tnlp, 只有 tcp 的记录,没看到 tcp6 的记录, 这是为什么?

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.11:42303 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 1/nginx: master pro
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
dndx
2020-02-13 17:15:28 +08:00
被 Docker 覆盖了?检查一下 `nginx.conf` 看看具体是怎么写的。如果正确可以 reload 一下确认使用的是对的配置。
programV2
2020-02-13 18:02:15 +08:00
@dndx 检查过了, 并且 docker 所有容器已经重启过了, 还有我进 nginx 容器内执行 netstat -tnlp, 发现 v4 的 80 和 443 都在监听, 但是我 nginx.conf 配置文件中只设置 listen 443;为什么还会监听 80 的端口呢??
nginx.conf`
server {
listen 443;
ssl on;
ssl_certificate /dir
dndx
2020-02-13 19:12:40 +08:00
说了很多次了,要写成 `listen [::]:443`,`[::]:` 部分不能省。
programV2
2020-02-13 20:20:35 +08:00
@programV2 抱歉,是不是我的表达有问题? 你就的`listen [::]:443`不是监听 V6 的 443 端口吗? 但我的问题是 nginx.conf 配置文件中只设置 listen 443;为什么还会监听 80 的端口呢???
programV2
2020-02-13 21:12:03 +08:00
@dndx 抱歉,请问你说的" listen [::]:443 "是监听 V6 的 443 端口吗?" listen 443 本来就是两个都监听的"意思是 v4 和 v6 的 443 都监听 ?

但我的问题是 nginx.conf 配置文件中只设置了 listen 443;为什么还会监听 80 的端口呢???
iUnix
2020-02-16 09:51:09 +08:00
ps -ef | grep nginx

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/644305

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX