我对 Docker 和我的 ovh 服务器(ubuntu xenial)有一个恼人的问题。
我在我的服务器上运行 NGINX 官方 docker 镜像(15.x),并将一些端口从我的服务器转发到我的 docker 镜像(以在线托管服务器服务)。
从外部(使用 IPV4 或 IPV6)完成的所有 HTTP 请求都设法到达 NGINX。
但是,使用 IPV4 完成的 HTTPS 请求无法到达 NGINX(IPV6 HTPPS 就像一个魅力)。
我在我的服务器和 NGINX docker 容器中使用 tcdump tcpdump -i any port 443 -s0 -n
监听了端口 443
结果:我在我的服务器和 NGINX 容器中都看到了 IPV6 HTTPS 请求。
我只在我的服务器上看到 IPV4 https 请求,但在 NGINX 容器中没有看到。
=> 所以看起来,这不是一个“开放端口”的问题,因为我设法在我的服务器上看到了 IPV4 请求(并且我检查了 IPTables,443 被转发到 docker 代理)。
我认为这是我的服务器和 Docker 代理之间的端口转发 pb,仅用于使用 IPV6 完成的 HTTPS 请求。
这是我的容器配置:
nginx:
depends_on:
- my_php7
image: nginx:latest
volumes:
- "../:/usr/share/nginx/html:rw"
- "./nginx/var/log:/var/log/nginx:rw"
- "./nginx/nginx.template.conf:/etc/nginx/conf.d/nginx.template:rw"
- "./nginx/sites-available:/etc/nginx/sites-available:rw"
- "./nginx/sites-enabled:/etc/nginx/sites-enabled:rw"
links:
- my_php7:webstack_php
ports:
- "8080:8080"
- "8090:90"
- "8091:91"
- "8083:8083"
- "80:80"
- "443:443"
restart: always
command: /bin/bash -c "cp /etc/nginx/conf.d/nginx.template /etc/nginx/conf.d/nginx.conf && nginx -c /etc/nginx/conf.d/nginx.conf"
我还检查了 net.ipv6.bindv6only:
#> sysctl net.ipv6.bindv6onlynet.ipv6.bindv6only = 0
这是我的 nat 信息:
Proto Recv-Q Send-Q Adresse locale Adresse distante Etat PID/Program name
tcp 0 0 0.0.0.0:8081 0.0.0.0:* LISTEN 19671/node
tcp 0 0 91.121.101.165:914 0.0.0.0:* LISTEN 1696/openvpn-openss
tcp 0 0 91.121.101.165:915 0.0.0.0:* LISTEN 1724/openvpn-openss
tcp 0 0 0.0.0.0:8084 0.0.0.0:* LISTEN 22633/node
tcp 0 0 91.121.101.165:916 0.0.0.0:* LISTEN 1751/openvpn-openss
tcp 0 0 91.121.101.165:917 0.0.0.0:* LISTEN 1779/openvpn-openss
tcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 929/named
tcp 0 0 0.0.0.0:21 0.0.0.0:* LISTEN 947/vsftpd
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 943/sshd
tcp 0 0 127.0.0.1:953 0.0.0.0:* LISTEN 929/named
tcp 0 0 127.0.0.1:4040 0.0.0.0:* LISTEN 4765/ngrok
tcp6 0 0 :::8082 :::* LISTEN 12095/docker-proxy
tcp6 0 0 :::8083 :::* LISTEN 12837/docker-proxy
tcp6 0 0 :::2003 :::* LISTEN 12058/docker-proxy
tcp6 0 0 :::9300 :::* LISTEN 12006/docker-proxy
tcp6 0 0 :::85 :::* LISTEN 12070/docker-proxy
tcp6 0 0 ::1:53 :::* LISTEN 929/named
tcp6 0 0 :::22 :::* LISTEN 943/sshd
tcp6 0 0 :::3000 :::* LISTEN 12544/docker-proxy
tcp6 0 0 ::1:953 :::* LISTEN 929/named
tcp6 0 0 :::8090 :::* LISTEN 12861/docker-proxy
tcp6 0 0 :::443 :::* LISTEN 12885/docker-proxy
tcp6 0 0 :::8091 :::* LISTEN 12849/docker-proxy
tcp6 0 0 :::92 :::* LISTEN 12082/docker-proxy
tcp6 0 0 :::4000 :::* LISTEN 12532/docker-proxy
tcp6 0 0 :::9000 :::* LISTEN 12521/docker-proxy
tcp6 0 0 :::5000 :::* LISTEN 12106/docker-proxy
tcp6 0 0 :::3306 :::* LISTEN 12119/docker-proxy
tcp6 0 0 :::80 :::* LISTEN 12897/docker-proxy
tcp6 0 0 :::8080 :::* LISTEN 12873/docker-proxy
tcp6 0 0 :::9200 :::* LISTEN 12035/docker-proxy
tcp6 0 0 :::4400 :::* LISTEN 28319/node
udp6 3072 0 :::40195 :::* 1081/collectd
udp6 0 0 :::8124 :::* 12046/docker-proxy
udp6 0 0 ::1:53 :::* 929/named
udp6 0 0 ff18::efc0:4a42:25826 :::* 1081/collectd
对于那些想知道为什么 443 只显示 IPV6 转发的人:
我试图重建容器但没有成功。
我还尝试在另一个 docker 中打开 443 端口 => 它无法获得 IPV4 HTTPS 请求。
恢复:
有任何想法吗? :)
[编辑]
@leodotcloud
确定在这里(我用 xxxx 隐藏了服务器名称)
虚拟主机配置
server {
listen 443 ssl http2;
server_name www.xxx.com;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
ssl_certificate /etc/letsencrypt/live/xxx.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/xxxx.com/privkey.pem;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
ssl_session_timeout 10m;
ssl_session_cache shared:SSL:10m;
ssl_prefer_server_ciphers on;
charset utf-8;
location / {
proxy_pass http://node;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
}
}
SSL 的 nginx 配置
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
....
}
[编辑 2]
我试图将我的 docker-compose 配置从 "443:443"更改为 "0.0.0.0:443:443"以强制 ipv4 binding 。
我收到了这个错误:
Bind for 0.0.0.0:443 failed: port is already allocated
所以我有一些在 443 上使用我的 IPV4 连接的东西。
当我使用“443:443”语法绑定(bind)IPV6和IPV4时,docker绑定(bind)IPV6但不检查IPV4(可能是系统也关心绑定(bind)IPV4)。
现在我必须找到这项服务。问题:我在使用 netstat 时找不到它。有没有办法强制关闭套接字?
[编辑]
我尝试停止容器并直接在服务器上启动 nginx,在 443 +SSL IPV4/IPV6 上绑定(bind)并提供“hello”文件。
=> IPV6 工作,IPV4 不工作
=> 我将端口从 443 更改为 444 => IPV4 和 IPV6 工作
=> 我清除了 IPTABLE 并在所有内容上配置了 ACCEPT => IPV4 443 仍然存在同样的问题:(
因为 Nginx 设法绑定(bind)到 0.0.0.0:443 我想套接字是“免费的”。所以有些东西正在阻止或过滤来自 IPV4 443 的数据
[编辑] 最后,这是一个 IPTABLE 问题。我将我的答案标记为在 IPV4 中重新打开端口 443 的解决方案。我将在我的 NAT 表中查找导致此问题的规则,如果需要,我将打开一个新主题。
感谢大家的帮助!
最佳答案
我终于找到了让它工作的方法。只是 FLUSHED
nat 使用以下命令:
iptables -t nat -F
现在一切正常。 :)我真的不明白这个命令是做什么的。它刷新了
NAT
规则,但我看不出我的 IPTABLE
有什么不同。如果有人能告诉我这个“刷新”是否有风险(我从未在 IPTABLE 中更改过某些内容,只有 docker 更改了它)。
关于docker - ipv4 https请求未转发到docker容器,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52179746/