在 1 台 Debian Pi 上运行 2 个 SSL 服务器,两个 FQDN,1 个 Nginx 1 个 apache,证书错误,这是 SNI 问题吗?

在 1 台 Debian Pi 上运行 2 个 SSL 服务器,两个 FQDN,1 个 Nginx 1 个 apache,证书错误,这是 SNI 问题吗?

我被迫在 a.ddns.net 上使用 Nginx,在 b.ddns.net 上使用 Apache(由于已建立的设置,反向代理解决方案过于棘手)。编辑了真实服务器名称,但都验证为解析到相同的 IP,并且 SSL 证书已使用 OpenSSL 验证。

现有设置分别使用 IP 虚拟主机:

server {
            listen 192.168.1.174:443 ssl;          
            server_name a.ddns.net;
            root /var/www/html/a.ddns.net/;
            add_header Strict-Transport-Security "max-age=31536000";

            ssl on;
            ssl_session_cache builtin:1000 shared:SSL:10m;
            ssl_protocols TLSv1 TLSv1.1 TLSv1.2 ;
            ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
            ssl_prefer_server_ciphers on;
    ssl_certificate /etc/letsencrypt/archive/a.ddns.net/cert1.pem;
    ssl_certificate_key /etc/letsencrypt/archive/a.ddns.net/privkey1.pem;

Apache2.4 站点可用/a.ddns.net.conf

SSLStrictSNIVHostCheck on
<VirtualHost 192.168.1.173:443>
        ServerAdmin webmaster@localhost
        ServerName b.ddns.net
        DocumentRoot /var/www/html/
        Alias /test /media/data/RPi1-Pictures
/media

    <IfModule mod_headers.c>
        Header always set Strict-Transport-Security "max-age=15768000; includeSubDomains; preload"
    </IfModule>

        SSLEngine on
        SSLCertificateFile /etc/letsencrypt/live/b.ddns.net/fullchain.pem
        SSLCertificateKeyFile /etc/letsencrypt/live/b.ddns.net/privkey.pem
        Include /etc/letsencrypt/options-ssl-apache.conf
        SSLVerifyClient none

dnsmasq(Pi-hole)和 /hosts 设置域名如下:

127.0.0.1 a.ddns.net b.ddns.net raspberrypi3.home localhost
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
192.168.1.174 a.ddns.net
192.168.1.173 b.ddns.net

......

在 LAN 中,它可以按预期工作,因为 a 和 b 域出现在 dnsmasq/hosts 文件中,但是当我尝试使用 dig/curl 等进行外部测试时,我遇到了 SSL 证书问题,这似乎表明 a.ddns.net (Nginx) 实际上并未得到解析:-

curl https://a.ddns.net -v                         *   Trying 92.106.xxx.xx:443...                         * TCP_NODELAY set
* Connected to a.ddns.net (92.106.xxx.xx) port 443 (#0)
* ALPN, offering h2                                     * ALPN, offering http/1.1
* successfully set certificate verify locations:        *   CAfile: /data/data/com.termux/files/usr/etc/tls/cert.pem                                                      CApath: none
* TLSv1.3 (OUT), TLS handshake, Client hello (1):       * TLSv1.3 (IN), TLS handshake, Server hello (2):        * TLSv1.2 (IN), TLS handshake, Certificate (11):        * TLSv1.2 (IN), TLS handshake, Server key exchange (12):* TLSv1.2 (IN), TLS handshake, Server finished (14):    * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):                                                       * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):                                                     * TLSv1.2 (OUT), TLS handshake, Finished (20):          * TLSv1.2 (IN), TLS handshake, Finished (20):           * SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256                                                    * ALPN, server accepted to use http/1.1
ALPN, server accepted to use http/1.1
* Server certificate:
*  subject: CN=b.ddns.net
*  start date: Oct 13 13:27:18 2019 GMT
*  expire date: Jan 11 13:27:18 2020 GMT
*  subjectAltName does not match a.ddns.net
* SSL: no alternative certificate subject name matches target host name 'a.ddns.net'
* Closing connection 0
* TLSv1.2 (OUT), TLS alert, close notify (256):
curl: (60) SSL: no alternative certificate subject name matches target host name   

我认为上述设置比创建复杂的反向代理更容易修复,因为我知道 Apache 和 Nginx 上带有 SNI 的 dnsmasq 能够从客户端 URL 解析正确的服务器。我遗漏了什么?

是否有替代或更简单的解决方案来使用 SAN 编辑 SSL 证书,即将 a.ddns.net 添加到 b.ddns.net?

感谢任何指导

答案1

我认为您的设置中缺少了一个重要部分。虽然您展示了服务器的内部配置(两个服务器具有不同的内部 IP 地址),并解释了两个域具有相同 IP 地址的外部配置,但您没有解释如何完成从外部 IP 地址到正确的内部 IP 地址的映射。

我的猜测是,你做了一个简单的端口转发,从外部 IP 地址到其中一个服务器的内部 IP 地址(对于 b.ddns.net,即 Apache)。因此,它将始终只访问没有针对 a.ddns.net 进行配置的 Apache。

解决此问题的一种方法是只将端口转发到 nginx,然后对两个域进行配置。由于您需要为一个域使用 Apache,因此可以将 nginx 配置为该域的反向代理,并将所有内容转发(而不是重定向!)到内部 Apache。

相关内容