分类
服务器

解决 Nginx SSL 证书报错

闲来无事,查看了一下 nginx 的 error.log 日志文件,发现里面大量的报错信息:

cannot load certificate "data:": PEM_read_bio_X509_AUX() failed (SSL: error:0909006C:PEM routines:get_name:no start line:Expecting: TRUSTED CERTIFICATE) while SSL handshaking…

是 ssl 证书报错了,想了一下,整个服务器只有这个博客使用了 https ,理所当然的从博客的 nginx 配置文件和证书文件入手,历时三天也没找到原因,甚至一度把证书都更换了,从腾讯云的 SSL 证书换到了阿里云的 SSL 证书,结果还是报错,说明证书没问题。

就在快要放弃的时候,突然想到,之前为了屏蔽直接从 ip 来的请求,加了一些配置,屏蔽了http://iphttps://ip两种访问形式,而屏蔽 https+ip 也涉及到了 SSL 证书的问题,当时是通过 map 映射给了一个空证书,会不会是这个原因?

于是,为了验证这个猜想,把博客站点的错误日志和其它站点的分开,单独统计。过了一夜,第二天打开日志文件查看,果然,博客的错误日志中并没有此错误,只有 error.log 里面有,这就说明错误不是博客站点的 SSL 证书引起的,那么只可能是之前屏蔽 https+ip 的配置引起的。

找到了原因,那么解决起来就快了。

先帖一下之前的配置:

map "" $empty {
    default "";
}
server {
    listen 80 default_server;
    listen 443 ssl http2 default_server;
    listen [::]:80 default_server;
    listen [::]:443 ssl http2 default_server;
    server_name _;

    ssl_ciphers aNULL;
    ssl_certificate data:$empty;
    ssl_certificate_key data:$empty;
    return 444;
}

把上面的配置改成如下:

# 禁止直接通过IP访问网站
server {
    listen 80 default_server;
    server_name _;
    return 444;
}

删除了屏蔽 https+ip 的配置,只保留屏蔽 http+ip 的配置。然后在博客站点的 nginx 配置文件中添加如下代码:

# 通过 default_server 把博客站点设置为默认的 https 站点
listen 443 ssl http2 default_server;

if ($host != 'wujie.me') {
    rewrite ^/(.*)$ https://wujie.me/$1 permanent;
    break;
}

把直接从非域名来的请求(包括从 ip 来的请求)跳转到域名就可以了。

这样修改后,经过两天的观察,没有再出现错误,问题解决!