无法访问通过 Docker 公开的 80 端口(nginx),其他端口可以正常访问

无法访问通过 Docker 公开的 80 端口(nginx),其他端口可以正常访问

(我最初创建了这个问题在 StackOverflow 上但它被关闭了,说它属于 ServerFault)

我想在我的 Raspberry PI(机器 A)上使用 Docker 容器作为特定网站的 VPN 代理,并从同一本地网络上的另一台机器(机器 B)访问该容器。为此,我使用了一个设置了 openvpn 并在其上安装 Nginx 的容器。

我使用 docker-compose 来设置容器:

version: '2'
services:
 transmission:
  build:
    context: .
  cap_add:
    - NET_ADMIN
  devices:
    - "/dev/net/tun"
  restart: always
  ports:
    - "80:80"
    - "443:443"
  dns:
    - 8.8.8.8
    - 8.8.4.4

容器中的 Nginx 配置如下所示:

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    root /var/www/html;
    index index.html index.htm index.nginx-debian.html;

    server_name _ cool;

    location / {
        resolver 8.8.8.8;

        proxy_ssl_server_name on;
        proxy_http_version 1.1;
        proxy_pass https://coolwebsite.org$request_uri;
        proxy_pass_request_body on;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
    }
}

然后,如果我启动容器并在 PI 主机(机器 A)的 /etc/hosts 中添加以下行:

127.0.0.1      cool

我可以通过执行以下操作来接收目标网站的内容:

curl http://cool

不幸的是,如果我从机器 B 运行相同的 curl 命令,即使在其 hosts 文件中添加了条目后,这也不起作用cool(尽管 ping 确实有效):

me@home:~$ telnet cool 80
Trying 192.168.1.35...
telnet: Unable to connect to remote host: Connection timed out
me@home:~$ curl http://cool
curl: (28) Failed to connect to cool port 80: Connection timed out
me@home:~$ ping cool
PING cool (192.168.1.35) 56(84) bytes of data.
64 bytes from cool (192.168.1.35): icmp_seq=1 ttl=63 time=7.10 ms

来自机器 A 的更多诊断:

# netstat -tulnp | sort
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -
tcp6       0      0 :::22                   :::*                    LISTEN      -
tcp6       0      0 :::443                  :::*                    LISTEN      -
tcp6       0      0 :::8080                 :::*                    LISTEN      -
tcp6       0      0 :::80                   :::*                    LISTEN      -

上面列出的端口 8080 对应于另一个容器的端口绑定,可以从机器 B 正常访问。

此外,如果我停止容器并运行sudo nc -l -p 80以启动临时 Web 服务器,则机器 B 可以curl http://cool成功运行。这就是为什么我认为 Docker 设置有问题,但是什么呢?我看到一些 SO 答案提到使用,network_mode: host但如果我的容器与其主机共享相同的 IP,那么它就违背了我通过 VPN 的目的。

如果我可以提供更多信息,请告诉我。

答案1

想法 1 您确定没有主机进程已驻留在端口 80 上吗?

思想2 你的 docker-compose 缺少有关网络模式的任何信息-它是连接到默认网桥还是其他东西?

尝试将网络部分添加到组合中以创建新的自定义桥接。请注意,永远不要使用默认桥接,因为它功能受限。因此,对于您来说,情况如下:

version: '3'
services:
 transmission:
  build:
    context: .
  cap_add:
    - NET_ADMIN
  devices:
    - "/dev/net/tun"
  restart: always
  ports:
    - "80:80"
    - "443:443"
  dns:
    - 8.8.8.8
    - 8.8.4.4
  networks:
      - Transmission_Network

networks:
  - Transmission_Network

想法 3 你的 nginx 看起来有点不对,例如它server_name cool;不应该是 `server_name _ cool;

这也不应该是你的默认服务器。试试这个

server {
    listen 80;
    listen [::]:80;

    server_name cool;

    location / {
        resolver 8.8.8.8;
        proxy_set_header                        Host $http_host;
        proxy_set_header                        Upgrade $http_upgrade;
        proxy_set_header                        Connection "upgrade";
        proxy_http_version                      1.1;
        proxy_set_header                        X-Forwarded-Host $http_host;
        proxy_connect_timeout                   60s;
        proxy_send_timeout                      60s;
        proxy_read_timeout                      60s;
        proxy_http_version                      1.1;
        proxy_pass                              https://coolwebsite.org;
    }
}

注意,我包含了常见的所需代理 set_headers,因为如果您有一个标头设置,则位置将不会从 http 部分中的任何设置继承。

相关内容