【问题标题】:Apache reverse proxy to Nginx forward proxy with TLS certificate使用 TLS 证书的 Apache 反向代理到 Nginx 正向代理
【发布时间】:2020-01-07 05:51:58
【问题描述】:

我们的一个客户想要通过他的服务器运行一个网站到我们的网络服务器,所以该网站有他的服务器的公共 IP,而不是我们的。这在 http 上运行良好,但在 https 上一切都变得疯狂。

客户端的服务器使用 Apache 运行 Virtualmin,我们的服务器使用 php-fpm 运行 Nginx。我们尝试为客户端服务器和我们的网络服务器设置相同的证书,但此站点一直显示握手错误。

两台服务器使用完全相同的证书。

客户的 Apache 配置:

ProxyPass / http://1.2.3.4:8123/
ProxyPassReverse / http://1.2.3.4:8123/
SSLProxyEngine on
    SSLProxyCheckPeerCN on
    SSLProxyCheckPeerExpire on
SSLEngine on
SSLCertificateFile /foo/bar/ssl.cert
SSLCertificateKeyFile /foo/bar/ssl.key
SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLCACertificateFile /foo/bar/ssl.ca

我们的 Nginx 配置:

server {
  listen 8123;
  server_name some.site wwww.some.site;

  ssl_certificate /foo/bar/ssl.crt;
  ssl_certificate_key /foo/bar/ssl.crt
  ssl_prefer_server_ciphers on;

  root /var/www/some.site/public;
  index index.php;
  charset utf-8;

  location ~ /\. {
    deny all;
  }

  location / {
    try_files $uri $uri/ /index.php?$args;
  }

  location ~ \.php$ {
    fastcgi_pass unix:/var/run/php/php7.1-fpm.sock;
    fastcgi_index index.php;
    include /etc/nginx/fastcgi_params;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header Host $host;
  }
}

我们希望它能够正常工作,以便我们可以使用 https://1.2.3.4:8123/ 作为代理地址,以避免 MITM 攻击并能够通过 https://some.site 为网站提供服务。

【问题讨论】:

    标签: php apache nginx proxy


    【解决方案1】:

    在 nginx 中创建一个单独的 vhost,我发现证书设置不正确。 curl -I -L https://1.2.3.4:8483 返回curl: (60) SSL certificate problem: unable to get local issuer certificate。运行 openssl verify ssl.crt 会引发错误,而 openssl verify -CAfile ssl.ca-bundle ssl.crt 没有,这证实了 ca-bundle 丢失 (source of verify commands)。

    作为stated,nginx 不支持单独的ca 文件,所以我创建了一个新文件ssl.combined 并将其添加到ssl_certificate 指令中:cp ssl.crt ssl.combined; cat ssl.ca-bundle >> ssl.combined。卷毛现在很开心。

    Apache 也有同样的问题,但确实支持 ca 文件。我使用SSLCertificateChainFile 添加了ssl.ca-bundle

    最后,有了sample configuration,我找到了罪魁祸首:ProxyPreserveHost On 是一切正常工作所必需的,这导致 Apache 发送正确的Host-header over Proxy,这反过来又使握手工作正常进行。

    作为其他人的参考,我在下面添加了我的最终配置:

    对于 Apache(客户端的服务器,反向代理):

    [...]
    SSLEngine on
    SSLCertificateFile /foo/bar/ssl.cert
    SSLCertificateKeyFile /foo/bar/ssl.key
    SSLCertificateChainFile /foo/bar/ssl.ca
    
    ProxyRequests off
    ProxyPreserveHost On
    SSLProxyEngine on
    SSLProxyCheckPeerCN on
    SSLProxyCheckPeerExpire on
    
    ProxyPass / https://1.2.3.4:8483/
    ProxyPassReverse / https://1.2.3.4:8483/
    
    <Proxy *>
      allow from all
    </Proxy>
    [...]
    
    

    对于 nginx(我们的服务器,转发代理):

    server {
      listen 8483 ssl;
      server_name site.url www.site.url;
    
      ssl on;
      ssl_certificate /foo/bar/ssl.combined;
      ssl_certificate_key /foo/bar/ssl.key;
      ssl_stapling on;
      ssl_stapling_verify on;
    
      root /var/www/site.url/public
      index index.php;
      charset utf-8;
    
      location ~ /\. {
        deny all;
      }
    
      location / {
        try_files $uri $uri/ /index.php?$args;
      }
    
      location ~ \.php$ {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Host $host;
        fastcgi_pass unix:/var/run/php/php7.1-fpm.sock;
        fastcgi_index index.php;
        include /etc/nginx/fastcgi_params;
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2017-06-15
      • 2021-07-06
      • 2010-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-14
      • 1970-01-01
      • 2020-01-05
      相关资源
      最近更新 更多