从Apache迁移到Nginx后SSL证书修正

从Apache迁移到Nginx后SSL证书修正

这里讨论的是网站从Apache迁移到Nginx之后,使用python访问网站出现下面的问题:

<urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed

关于如何从Apache迁移到Nginx,请参看How to migrate Apache to Nginx by converting VirtualHosts to Server Blocks

使用Python访问网站代码:

try:
      url='https://www.360converter.com'
      tmpfile = '/tmp/utest.html'
      urlretrieve( url, tmpfile )
except Exception as e:
    print( 'Failed: ' + str( e ))

迁移之后,在浏览器中访问正常,但是Python就有上面的问题。

下面是Apache和nginx配置文件中关于证书配置的部分,

Apache:
SSLCertificateFile /path/to/my.crt
SSLCertificateKeyFile /path/to/my.key
SSLCertificateChainFile /path/to/CA.crt

Nginx
ssl_certificate /path/to/my.crt;
ssl_certificate_key /path/to/my.key;

可以看出Apache中有SSLCertificateChainFile这个指示符号,而nginx则没有,我们简单的做法就是直接将它丢弃。结果就导致了上面的问题,为了解决这个问题,就是my.crt和ca.crt合并。直接ca.crt的内容,里面的所有内容,包括BEGIN和END行添加到my.crt文件的后面,像下面这样:

合并CRT
—–BEGIN CERTIFICATE—–
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
—–END CERTIFICATE—–
—–BEGIN CAbundle CERTIFICATE—–
YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
—–END CAbundle CERTIFICATE—–

这里简单说一下,为什么浏览器可以,为什么python?这是因为浏览器一般都默认安装了这些根证书,而python则没有。 为什么apache可以,nginx(使用没有合并的crt文件)不可以?这是因为在apache中我们配置了 SSLCertificateChainFile, 因此客户端访问的时候apache会把SSLCertificateChainFile指定的根证书同时发送给客户端,而nginx没有。而我们合并crt之后,nginx就会发送根证书了。

Reference

How To Compile Nginx from Source on a CentOS 6.4 x64 VPS
Building Nginx and OpenSSL from Source
How to enable SSL on NGINX
How to properly configure your nginx for TLS

    分享到:

留言

你的邮箱是保密的 必填的信息用*表示