V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
NGINX
NGINX Trac
3rd Party Modules
Security Advisories
CHANGES
OpenResty
ngx_lua
Tengine
在线学习资源
NGINX 开发从入门到精通
NGINX Modules
ngx_echo
watara
V2EX  ›  NGINX

Nginx 配置了基于 IP 的自签名证书后,原本配置的基于域名的证书失效

  •  1
     
  •   watara · 2020-02-24 18:21:22 +08:00 · 4757 次点击
    这是一个创建于 1494 天前的主题,其中的信息可能已经有所发展或是发生改变。

    因业务需要,先需要给 IP 配置自签名的证书,配置完后发现原本可以的网站打不开了,这个场景太少了,搜索了一天无果,问了几个朋友页没有头绪。所以上论坛来请教一下各位大神。 先贴上配置文件,下面这个是原本正常的网站配置文件domain.conf

    server {
        listen 80;
        server_name www.domain.com;
        return 301 https://www.domain.com$request_uri;
    }
    server {
        #listen 443 ssl;
        listen 443 ssl;
        server_name www.domain.com;
        access_log /data/logs/www.log main;
        add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
        ssl_certificate      /etc/nginx/ssl/fullchain.cer;
        ssl_certificate_key  /etc/nginx/ssl/fullchain.key;
        ssl_dhparam /etc/nginx/dhparam.pem;
        ssl_prefer_server_ciphers on;
        ssl_session_cache shared:SSL:10m;
        add_header X-Frame-Options SAMEORIGIN;
        add_header X-Content-Type-Options nosniff;
        add_header X-XSS-Protection "1; mode=block";
        ssl_protocols      TLSv1.3;
        ssl_ciphers TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+ECDSA+AES128:EECDH+aRSA+AES128:RSA+AES128:EECDH+ECDSA+AES256:EECDH+aRSA+AES256:RSA+AES256:EECDH+ECDSA+3DES:EECDH+aRSA+3DES:RSA+3DES:!MD5;
        return 222;
    }
    

    下面是基于 IP 的自签名证书的配置文件ipssl.conf

    server {
        listen 443 ssl http2;
        server_name 192.168.200.136;
        root /tmp/webroot/ip;
        index index.html;
        access_log  /data/logs/ip_access.log;
        ssl_certificate /etc/nginx/ssl/server.crt;
        ssl_certificate_key /etc/nginx/ssl/server.key;
        ssl_session_timeout 5m;
        ssl_protocols SSLv1.2 TLSv1.3;
        ssl_ciphers HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;
    }
    

    当没有ipssl.conf的时候,网站是可以正常打开的,但加了以后就打不开了,而且不同浏览器的提示不一样,Firefox 的提示是 image.png 同时这时候查看网站状态,发现并没有证书信息。 image1efb51297e36f639.png 而 Chrome 下的提示是下图,总之都是说我的证书不安全就是了。 imagec139933b8f03fa48.png

    搜索的时候参考了很多文档,比如 ququ 大神的这篇文章,还有其他,基本上确定应该是和 http2 有关,我把配置里面的 http2 去掉后,也确实可以打开网站了,但浏览器都提示说我的网站不安全,使用了脆弱的加密方式,如下图。 imagea639e573927682a4.png 问题是我并没有使用图片里的加密方式,也并没有使用 TLSv1.0。 同时 nginx 的日志里显示已经正确的把 222 状态返回给了客户端。 image9d69de7fa420ec5f.png 我对问题的探索的进度基本上到此为止了,我的一些想法是:

    • 这个肯定和 http2 有关
    • http2 不支持使用基于 IP 的证书,或者不支持基于 IP 的自签名证书。
    • 还可能和 SNI 有关,SNI 是一个 IP 下配置多个域名证书,我现在 IP 自己配置上了证书,那就会覆盖其他配置文件的设置。 ===================

    突然想到一点,如果我把 firefox 的about:config里的network.http.spdy.enabled.http2设置为 false,就可以打开网站,网址栏锁头标志上提示不安全,其中的详情和图 4 里的详情是一模一样的。 image79fde49e795fd223.png 所以,有前辈大神遇到过此类问题吗?或者有相关思路呢?

    第 1 条附言  ·  2020-02-25 21:16:10 +08:00

    刚准备脱敏打包的时候顺手又修改了一下配置文件,设置了一下,从线上服务器上把ssl_protocolsssl_ciphers改了下,结果发现都正常了。后续又加上了http2,还是正常的。 1ec1e8724450dae77ed82176bf713c28.png

    下面是我改版后的配置文件。修改过的只有ssl_protocolsssl_ciphers两个地方,但具体为啥,还是不理解。

    server {
        listen 80;
        server_name www.domain.com;
        return 301 https://www.domain.com$request_uri;
    }
    server {
        listen 443 ssl http2;
        server_name www.domain.com;
        add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
        ssl_certificate      /etc/nginx/ssl/fullchain.cer;
        ssl_certificate_key  /etc/nginx/ssl/fullchain.key;
        ssl_dhparam /etc/nginx/dhparam.pem;
        ssl_prefer_server_ciphers on;
        ssl_session_cache shared:SSL:10m;
        add_header X-Frame-Options SAMEORIGIN;
        add_header X-Content-Type-Options nosniff;
        add_header X-XSS-Protection "1; mode=block";
    
        ssl_protocols      TLSv1.1 TLSv1.2 TLSv1.3;
        ssl_ciphers        ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-CHACHA20-POLY1305:ECDHE+AES128:RSA+AES128:ECDHE+AES256:RSA+AES256:ECDHE+3DES:RSA+3DES;
        return 222;
    }
    

    ipssl.conf:

    server {
        listen 443 ssl http2;
        server_name 192.168.200.136;
        root /tmp/webroot/ip;
        index index.html;
        access_log  /data/logs/ip_access.log;
        ssl_certificate /etc/nginx/ssl/server.crt;
        ssl_certificate_key /etc/nginx/ssl/server.key;
        ssl_session_timeout 5m;
        ssl_prefer_server_ciphers on;
        ssl_protocols      TLSv1.1 TLSv1.2 TLSv1.3;
        ssl_ciphers        ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-CHACHA20-POLY1305:ECDHE+AES128:RSA+AES128:ECDHE+AES256:RSA+AES256:ECDHE+3DES:RSA+3DES;
    }
    
    24 条回复    2020-02-26 09:55:36 +08:00
    Kobayashi
        1
    Kobayashi  
       2020-02-24 19:11:04 +08:00   ❤️ 1
    我就想知道你 SSLv1.2 是怎么加进去的?这不启动报错吗?
    watara
        2
    watara  
    OP
       2020-02-24 19:32:37 +08:00
    @Kobayashi #1 贴配置文件的时候贴错了,是 TLSv1.2...
    Citrus
        3
    Citrus  
       2020-02-24 20:44:38 +08:00   ❤️ 1
    @watara 你的参考文章已经说明了,是 ssl_ciphers 的关系,那么你有尝试过修改这个配置么?结果呢?
    另外你说在去掉 http2 之后协商出了 TLS1.0,那么我觉得,你需要检查一下你的配置。注意,ssl_protocols 并不是一个真正的 per server 的配置,而是一定程度上是一个 per instance 的配置哦。
    zhizunzz
        4
    zhizunzz  
       2020-02-24 20:58:35 +08:00 via Android   ❤️ 1
    zhizunzz
        5
    zhizunzz  
       2020-02-24 21:02:22 +08:00 via Android   ❤️ 1
    @zhizunzz 直接去 release 下载编译好的就可以用
    watara
        6
    watara  
    OP
       2020-02-24 22:17:50 +08:00
    @Citrus #3 我修改过很多次这个配置,包括这篇文章里的,cloudflare 推荐的,还有 Mozilla wiki 推荐的,实际效果是一样的,但我没去抓包看。
    @zhizunzz #5 感谢,我去了解了解
    dorothyREN
        7
    dorothyREN  
       2020-02-24 22:49:56 +08:00
    单主机 多 https 配置会有问题。只有第一个能正常访问
    keyfunc
        8
    keyfunc  
       2020-02-24 23:30:24 +08:00   ❤️ 1
    可以做以下尝试
    1. ssl_prefer_server_ciphers on; 设置为 off
    2. ssl_protocols TLSv1.3; 调整为 TLSv1.2 TLSv1.3
    3. ssl_ciphers 做下调整 ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384

    简单分析一下,楼主可以使用 openssl ciphers -V 命令查看服务端支持所有的 CipherSuite, TLS13-XXX 这种写法我印象中已经从 openssl 已经移除了,所以你配置中的所有 1.3 的 CipherSuite 全是无效的,另外你启用了 ssl_prefer_server_ciphers,所以你配置里第一个可用的 CipherSuite 就是 RSA+AES128,被降级到 TLS1.0 很正常。
    另外我还怀疑楼主的 Openssl 版本压根不支持 TLS1.3 ..........

    SSL 的配置可以使用 Mozilla 提供的 SSL Configuration Generator [https://ssl-config.mozilla.org/] 工具生成配置文件,比较推荐。
    watara
        9
    watara  
    OP
       2020-02-24 23:36:31 +08:00
    @keyfunc #8 感谢,说实话我感觉和 ssl_ciphers 没关系,我做过这些尝试,也用过 Mozilla wiki 里推荐的设置,情况是一样的,这里最重要的一点还是 ip_ssl.conf 里配置,如果我把这个配置文件移除了,一切正常,但把这个加入进去,就不行了,和研发领导讨论了下,换方案的了,改接口,用常规域名+常规证书请求。
    keyfunc
        10
    keyfunc  
       2020-02-24 23:41:37 +08:00
    https://202.96.220.171/
    https://wiki.shca-inc.com/

    和你需求类似的示例,同一台主机,IP 配置了张自签的证书,域名使用 LE 的证书,理论上肯定是没问题的。
    也是 nginx
    watara
        11
    watara  
    OP
       2020-02-24 23:43:51 +08:00
    @keyfunc #10 一样的情况,方便贴一下你的配置文件吗? ssl 相关即可
    keyfunc
        12
    keyfunc  
       2020-02-24 23:54:03 +08:00
    SSH 端口外网访问不到,我们周三上班,不着急的话周三可以发给你。但是我还是觉得是你 ssl_ciphers 配置有问题。
    msg7086
        13
    msg7086  
       2020-02-25 04:21:22 +08:00 via Android
    多个 SSL 区都做自己的 SSL 设定,感觉很不靠谱啊,不考虑统一一下并拉到上一层吗?

    另外 tls1.3 的 cipher 并不能这么设置的。
    kof21411
        14
    kof21411  
       2020-02-25 08:22:24 +08:00
    楼主你要明白 https 通讯的原理,简单来说就是 ip 是优先过域名的,如果你要 ip 和域名同时使用,那只能两个独立 ip 而域名不能绑在要开通 https 的 ip 之下
    watara
        15
    watara  
    OP
       2020-02-25 08:59:45 +08:00
    @keyfunc #12 非常感谢,不着急的,哪怕换方案了,弄清楚这个也是值得的

    @msg7086 #13
    @kof21411 #14 这两天我才发现自己对 https 这块理解的却是很不透彻,大学的时候确实学过,但实际操作都是直接照着现有的文档抄的
    nieqibest
        16
    nieqibest  
       2020-02-25 10:06:49 +08:00 via Android
    @kof21411 ip 访问默认会给 default_server 处理,一般为了应对恶意解析,会封掉除了正常域名访问之外的其他请求,对吗?
    emeab
        17
    emeab  
       2020-02-25 12:00:54 +08:00
    开多一个 ip 吧
    Citrus
        18
    Citrus  
       2020-02-25 16:33:08 +08:00
    @watara 能否提供一个可用的最小完整配置复现这个问题?比如,把你 /etc/nginx 下所有的文件脱敏后上传一下。这样我们可以尝试搭建一个环境看看能不能复现你的问题。另外以防万一最好也提供一下 nginx 和 openssl 的版本。
    watara
        20
    watara  
    OP
       2020-02-25 16:38:31 +08:00
    @Citrus #18 非常感谢,我主贴上的环境其实就是本地虚拟机里的,我晚上回去脱敏后发一份出来。对了,
    @keyfunc #12 咱们的场景可以说是一模一样的,然后我刚刚想起来一个可能很重要的一点,我的常规域名的证书是泛域名通配符证书,你的是单域名证书。
    kof21411
        21
    kof21411  
       2020-02-25 19:04:55 +08:00
    开启 ip https 的访问默认的话,会封掉除该 ip 之下的所有正常域名的 https 访问
    watara
        23
    watara  
    OP
       2020-02-25 21:23:44 +08:00
    @Citrus #18
    @kof21411 #14
    @keyfunc #12
    @dorothyREN #7
    @zhizunzz #5
    @Kobayashi #1
    修改了下配置文件后可以了,具体配置详见 append,然后这里补充一下我的环境吧。
    系统:CentOS Linux release 7.7.1908
    nginx 是直接用 yum 直接一键安装的,具体的版本是 nginx/1.16.1,具体详情如下:
    ```
    [root@localhost conf.d]# nginx -V
    nginx version: nginx/1.16.1
    built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
    built with OpenSSL 1.0.2k-fips 26 Jan 2017
    TLS SNI support enabled
    configure arguments: --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --pid-path=/run/nginx.pid --lock-path=/run/lock/subsys/nginx --user=nginx --group=nginx --with-file-aio --with-ipv6 --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-stream_ssl_preread_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_stub_status_module --with-http_perl_module=dynamic --with-http_auth_request_module --with-mail=dynamic --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream=dynamic --with-stream_ssl_module --with-google_perftools_module --with-debug --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mtune=generic' --with-ld-opt='-Wl,-z,relro -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -Wl,-E'
    ```
    nginx 主配置文件没进行修改过,仅仅是添加了 ssl 相关文件以及上述到两个配置文件。
    keyfunc
        24
    keyfunc  
       2020-02-26 09:55:36 +08:00
    @watara TLS1.3 协议要 Openssl1.1.1 以后才支持,你压根不支持 1.3,估计 nginx 直接调默认配置了,按道理你启动肯定有警告信息的。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1155 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 23:02 · PVG 07:02 · LAX 16:02 · JFK 19:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.