Portainer:客户端向 HTTPS 服务器发送 HTTP 请求 - 尽管 URL 为 https://

Mic*_*ael 7 apache ssl docker portainer

我对主题服务器配置还很陌生,现在我在访问带有 ssl 证书的容器时遇到了问题。

我的设置是什么:

我有一个带有 docker 的树莓派。连接到端口 80 和 443 的容器是反向代理,它将传入的子域定向到不同的其他容器。示例:webserver.my-domain.com 指向 IP 192.168.178.69:8080。我通过此配置将其存档在文件夹中sites-enabled

<VirtualHost *:80>
 ServerName webserver.my-domain.com
 ProxyPreserveHost On 
 DocumentRoot /var/www/html
 ProxyPass /.well-known !
 ProxyPass / http://192.168.178.69:8080/
 ProxyPassReverse / http://192.168.178.69:8080/
RewriteEngine on
RewriteCond %{SERVER_NAME} =webserver.my-domain.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
Run Code Online (Sandbox Code Playgroud)

我还在反向代理容器内创建了一个让我们加密证书。这创建了一个附加文件webserver-le-ssl.conf

<IfModule mod_ssl.c>
<VirtualHost *:443>
 ServerName webserver.my-domain.com
 ProxyPreserveHost On 
 DocumentRoot /var/www/html
 ProxyPass /.well-known !
 ProxyPass / http://192.168.178.69:8080/
 ProxyPassReverse / http://192.168.178.69:8080/

SSLCertificateFile /etc/letsencrypt/live/my-domain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/my-domain.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>
Run Code Online (Sandbox Code Playgroud)

到目前为止,一切都很好。如果我尝试该 URL,我的内容就可用https://webserver.my-domain.com

我的问题是什么

我使用 Portainer 来管理我的 docker 容器,并且我希望 Portainer 可以通过portainer.my-domain.com. 这是里面的 portainer 配置sites-enabled

<VirtualHost *:80>
 ServerName portainer.my-domain.com
 ProxyPreserveHost On 
 DocumentRoot /var/www/html
 ProxyPass /.well-known !
 ProxyPass / http://192.168.178.69:9443/
 ProxyPassReverse / http://192.168.178.69:9443/
RewriteEngine on
RewriteCond %{SERVER_NAME} =portainer.my-domain.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
Run Code Online (Sandbox Code Playgroud)

还有 ssl 配置:

<IfModule mod_ssl.c>
<VirtualHost *:443>
 ServerName portainer.my-domain.com
 ProxyPreserveHost On 
 DocumentRoot /var/www/html
 ProxyPass /.well-known !
 ProxyPass / http://192.168.178.69:9443/
 ProxyPassReverse / http://192.168.178.69:9443/

SSLCertificateFile /etc/letsencrypt/live/my-domain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/my-domain.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>
Run Code Online (Sandbox Code Playgroud)

如果我打电话,192.168.178.69:9443/我可以毫无问题地到达集装箱。但如果我尝试访问该 URL,portainer.my-domain.com我就会收到消息:

Client sent an HTTP request to an HTTPS server.
Run Code Online (Sandbox Code Playgroud)

但在 URL 中显示:https://portainer.my-domain.com/。所以我不明白为什么会有 HTTP 请求,即使我的浏览器显示连接是 https 的。

有人可以向我解释一下并告诉我如何解决这个问题吗?

更新:我的解决方案 经过多次尝试,我找到了一个解决方案:当我将反向代理和 portainer 作为 docker 容器运行时,我使用 docker-compose 将这两个容器放入网络中:

version: "3.4"

services:
  apache:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /home/pi/reverse-proxy/:/etc/apache2
    networks:
      - homeserver

  portainer:
    image: portainer/portainer-ce:latest
    ports:
      - "8000:8000"
      - "9000:9000"
      - "9443:9443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - portainer_data:/data
    networks:
      - homeserver

networks:
  homeserver:

volumes:
  portainer_data:
Run Code Online (Sandbox Code Playgroud)

apache2的卷是完整的config文件夹/etc/apache2。之后我将 ProxyPass 的 IP 更改为容器的名称:

 ProxyPass / http://reverse-proxy_portainer_1:9000/
 ProxyPassReverse / http://reverse-proxy_portainer_1:9000/
Run Code Online (Sandbox Code Playgroud)

经过此更改后,它起作用了。

Luk*_*uba 5

我在 Apache2 代理后面使用 Portainer 2.13.1 时遇到了同样的问题。我通过运行带有启用端口9000(Portainer 的 HTTP 端口)选项的图像来解决这个问题。这假设您将在外部阻止端口 9000,并且只能通过受 HTTPS 保护的代理访问它。这是我的命令:

docker run -d -p 9000:9000 -p 8000:8000 -p 9443:9443 \
   --name portainer \
   --restart=always \
   -v /var/run/docker.sock:/var/run/docker.sock \
   -v portainer_data:/data 
   portainer/portainer-ce:latest
Run Code Online (Sandbox Code Playgroud)

然后我的 VirtualHost 文件指向端口 9000,如下所示:

<IfModule mod_ssl.c>
    <VirtualHost *:443>

            ProxyPreserveHost On
            Proxyrequests Off

            ServerName docker.<domain.tld>
            ServerAdmin admin@<domain.tld>

            ProxyPass / http://127.0.0.1:9000/
            ProxyPassReverse / http://127.0.0.1:9000/

            ErrorLog ${APACHE_LOG_DIR}/portainer-error.log
            CustomLog ${APACHE_LOG_DIR}/portainer-access.log combined

            SSLCertificateFile /etc/letsencrypt/live/docker.<domain.tld>/fullchain.pem
            SSLCertificateKeyFile /etc/letsencrypt/live/docker.<domain.tld>/privkey.pem
            Include /etc/letsencrypt/options-ssl-apache.conf

    </VirtualHost>
Run Code Online (Sandbox Code Playgroud)

确保使用 Linux 中的 ufw 等工具无法从外部访问端口 8000、9000 和 9443。


Ste*_*ich 2

所以根据你的问题,这似乎有效

ProxyPass / http://192.168.178.69:8080/
Run Code Online (Sandbox Code Playgroud)

但这并不:

ProxyPass / http://192.168.178.69:9443/
Run Code Online (Sandbox Code Playgroud)

请注意,在这两种情况下,即使涉及不同的端口,也都使用普通的 http:// 协议。端口号 9443 表明您应该使用 https:// 而不是 http:// 。如果是这种情况,这将解释您收到的错误消息:由于将协议设置为 http:// 而不是 https://,因此发送了普通 HTTP 请求。

但在URL中显示:https://portainer.my-domain.com/

这里的协议与客户端和 nginx 之间的连接有关,而不是 nginx 和内部服务器之间的连接。后一种取决于 ProxyPass URL 中给出的协议。