LNMP环境配置SSL证书实现https访问

Centos7下默认安装的Python版本是2.7.5,由于我LNMP环境使用的openssl版本和Python中使用的openssl版本不一致,具体版本查看方法:
查看系统环境中openssl的版本:

openssl version

显示版本结果如下:

OpenSSL 1.0.2j  26 Sep 2016

查看Python使用的openssl版本:

python -c "import ssl; print ssl.OPENSSL_VERSION"

显示结果如下:

OpenSSL 1.0.1e-fips 11 Feb 2013

版本不一致会造成SSL加密解密失败,需要重新编译Python的SSL扩展的版本,顺便升级以下Python,Python2.X稳定版本是2.7.12,我选择将Python升级至2.7.12版本。
Python升级方法如下:

1、更新Python:

通过官网Python下载链接下载Python2.7.12源码:

cd ~ && wget https://www.python.org/ftp/python/2.7.12/Python-2.7.12.tgz
①、解压Python:
tar -zxvf Python-2.7.12.tgz
②、进入目录:
cd Python-2.7.12/
③、安装Python:

安装Python时需要更新SSL扩展,所以需要修改Setup文件:

vi Modules/Setup.dist 

修改以下内容:

# Socket module helper for socket(2)
_socket socketmodule.c timemodule.c

# Socket module helper for SSL support; you must comment out the other
# socket line above, and possibly edit the SSL variable:
SSL=/usr/local/ssl
_ssl _ssl.c \
       -DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \
       -L$(SSL)/lib -lssl -lcrypto
# Andrew Kuchling's zlib module.
# This require zlib 1.1.3 (or later).
# See http://www.gzip.org/zlib/
zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib -lz

保存文件后开始编译安装Python:

./configure
make all && make install
make clean

安装完成之后需要配置环境,

2、让系统默认使用Python2.7.12:

需要将原来环境中的Python移除:

mv /usr/bin/python /usr/bin/python2.7.5

然后建立新的链接:

ln -s /usr/local/bin/python2.7 /usr/bin/python

这时输入python -V查看Python版本,显示结果如下:

Python 2.7.12

再查看Python的SSL扩展的版本:

python -c "import ssl; print ssl.OPENSSL_VERSION"

显示结果如下:

OpenSSL 1.0.2j  26 Sep 2016

这样就说明Python的SSL扩展已经更新了。
yum默认使用的是Python2.7.5,为了避免使用yum时出错,需要修改/usr/bin/yum/usr/libexec/urlgrabber-ext-down文件:

vi /usr/bin/yum

修改首行内容:

#!/usr/bin/python

改为以下内容:

#!/usr/bin/python2.7.5

python下的setuptools带有一个easy_install的工具,在安装python的每三方模块、工具时很有用,也很方便。
安装setuptools:

cd ~ && wget https://pypi.python.org/packages/dc/37/f01d823fd312ba8ea6c3aea906d2d6ac9e9e8bf9e7853e34f296e94b0d0d/setuptools-32.0.0.tar.gz
tar -zxvf setuptools-32.0.0.tar.gz
cd setuptools-32.0.0
python setup.py install

检查心脏滴血漏洞的方法:

cd ~ && git clone https://github.com/Lekensteyn/pacemaker.git
cd pacemaker && python ssltest.py ip地址

如果没有漏洞就会收到如下提示:

No heartbeat response received, server likely not vulnerable

如果不是这样的话请升级OpenSSL版本。

3、使用LetsEncrypt生成免费的证书:

生成教程:LetsEncrypt证书生成教程,生成结束在/etc/letsencrypt/live/xxx.com/存放路径下可以看到四个证书:

    cert.pem
    chain.pem
    fullchain.pem
    privkey.pem

关于证书更新问题:

LetsEncrypt虽然是永久免费,但是目前要每3个月更新一下,所以需要配合Crontab来执行证书更新操作,执行的命令参考上述教程

4、配置Nginx服务器,使服务器支持SSL访问

我的服务器是LNMP环境,访问接下来就该配置Nginx服务器了,使Nginx支持ssl访问,四个证书中,如果服务器是Apache就选1-3;Nginx就选1+4,我是Nginx服务器,就选择cert.pemprivkey.pem,我这里单独写Nginx的配置:

①、创建SSL设置的配置文件:
vi /usr/local/nginx/conf/ssl.conf

ssl.conf中的内容如下:

ssl on;
add_header Strict-Transport-Security "max-age=31536000;includeSubdomains; preload;";
ssl_certificate /etc/letsencrypt/live/xxx.com/cert.pem;
ssl_certificate_key /etc/letsencrypt/live/xxx.cm/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ALL:!DH:!EXPORT:!RC4:+HIGH:+MEDIUM:!LOW:!aNULL:!eNULL;
ssl_session_cache    builtin:1000 shared:SSL:20m;
ssl_session_timeout  20m;
②、设置Nginx强制跳转https:

首先配置rewrite.conf

vi /usr/local/nginx/conf/rewrite.conf

修改内容如下:

if ($scheme = http) {
        return 301 https://$server_name$request_uri;
}
if ($server_port = 80) {
        return 301 https://$server_name$request_uri;
}
error_page 301 https://$server_name$request_uri;
error_page 497 https://$server_name$request_uri;
③、修改虚拟站点的配置文件:
vi /etc/nginxhost/default.conf

修改内容如下:

server {
        listen  80;
        listen  443 ssl http2;
        server_name  xxx.com;
        ## Don't show the nginx version number, a security best practice
        server_tokens off;
        #charset koi8-r;
        root   html;
        index  index.php index.html index.htm;
        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        if (!-e $request_filename) {
                rewrite ^(.*)$ /index.php$1 last;
        }
        add_header X-Frame-Options SAMEORIGIN;
        location ~ .*\.php(\/.*)*$ {
                fastcgi_pass   127.0.0.1:9000;
                fastcgi_index  index.php;
                fastcgi_intercept_errors    on;
                fastcgi_hide_header X-Powered-By;
                include /usr/local/nginx/conf/fastcgi.conf;
        }
        include rewrite.conf;
        include ssl.conf;
        include proxy.conf;
        include pagespeed.conf;
        #error_page  404              /404.html;
        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
        access_log  /var/log/nginx/host.access.log  main;
        error_log   /var/log/nginx/host.error.log;

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }

保存并重启Nginx,这样就使用http访问时就会强制使用https访问,具体配置优化可以参考文章:Nginx 下部署 HTTPS 与安全调优

5、配置防火墙:

如果发现访问时无法使用https,有可能是防火墙导致的:

firewall-cmd --zone=public --add-port=443/tcp --permanent
firewall-cmd --zone=public --add-service=https --permanent
firewall-cmd --reload

版权声明:本文为w670328683原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。