Let's Encrypt是国外一个公共的免费SSL项目,由 Linux 基金会托管。
它的来头不小,由Mozilla、思科、Akamai、IdenTrust和EFF等组织发起,目的就是向网站自动签发和管理免费证书,以便加速互联网由HTTP过渡到HTTPS,目前Facebook等大公司开始加入赞助行列。
Let's Encrypt已经得了 IdenTrust 的交叉签名,这意味着其证书现在已经可以被Mozilla、Google、Microsoft和Apple等主流的浏览器所信任,你只需要在Web 服务器证书链中配置交叉签名,浏览器客户端会自动处理好其它的一切,Let's Encrypt安装简单,目前看来推广的很顺利,确实帮助全球互联网快速进入HTTPS时代了。
这里介绍一下使用NGINX如何配置使用Let's Encrypt的证书。
- 更多Nginx攻略:https://www.bnxb.com/nginx/
一、安装NGINX
#yum -y install gcc gcc-c++ make libtool zlib zlib-devel openssl openssl-devel pcre pcre-devel
#cd /usr/local
#wget http://nginx.org/download/nginx-1.13.0.tar.gz
#tar –zxvf nginx-1.13.0.tar.gz
进入nginx 文件夹目录执行以下命令:
./configure --prefix=/usr/local/nginx1.13 --with-http_stub_status_module --with-http_ssl_module
加了两项编译参数,给nginx加上http_stub_status_module模块和http_ssl_module模块。
如果没有配置ssl模块,开启SSL参数后nginx会提示错误:nginx: [emerg] the “ssl” parameter requires ngx_http_ssl_module in /usr/local/nginx/conf/nginx.conf)。
- –prefix=PATH : 指定nginx的安装目录。默认 /usr/local/nginx
- –with-http_ssl_module : 使用https协议模块。默认情况下,该模块没有被构建。前提是openssl与openssl-devel已安装
- –with-http_stub_status_module : 用来监控 Nginx 的当前状态
配置后输入以下命令:
make && make install
二、如果你已经安装过nginx,只是没加入http_ssl_module,这个SSL模块,那可以这么操作。
1、切换到源码包:
#cd /usr/local/src/nginx-1.13.0
2、查看nginx原有的模块:
#/usr/local/nginx/sbin/nginx -V
在configure arguments:后面显示的原有的configure参数如下:
--prefix=/usr/local/nginx --with-http_stub_status_module
那么我们的新配置信息就应该这样写:
#./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_modul
运行上面的命令即可,等配置完。
配置完成后,运行命令:
#make
这里不要进行make install,否则就是覆盖安装。
然后备份原有已安装好的nginx。
#cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak
然后将刚刚编译好的nginx覆盖掉原有的nginx(这个时候nginx要停止状态)。
#service nginx stop
#cp ./objs/nginx /usr/local/nginx/sbin/
然后启动nginx,仍可以通过命令查看是否已经加入成功
#service nginx start
#/usr/local/nginx/sbin/nginx -V
三、开始配置Let‘s Encrypt
Let’s Encrypt官网推荐大家使用Certbot来安装。
- 系统要求:官方文档上已经写出支持python2.6或2.7的操作系统上,python3.x有望在未来支持,如果是2.7以上SSL证书会自动安装,不用手动的;需要使用Root账户安装,有写入文件/etc/letsencrypt, /var/log/letsencrypt, /var/lib/letsencrypt的权限,安装时需要使用80和443端口。
1、保证你申请SSL的域名和服务器的IP是一致的,即域名确实是解析到你的服务器上的,可以使用nslookup命令查询。
#nslookup www.yourwebsite.com
Let’s Encrypt在给你分配证书时,会检查你所在的服务器是否和域名解析的服务器一致。
2、安装Git 和bc ,并从github上将代码克隆到本地
#yum –y git bc
#git clone https://github.com/certbot/certbot /opt/certbot-master
3、安装环境支持
因为certbot对Debian系统支持最好,可以完成自动检测并安装相应的软件。如果你是使用其它的Linux系统,Redhat或CentOS 6可能需要配置EPEL软件源,Python需要2.7版本以上,如果发现运行第4步出错,可能就是没有安装支持环境,可以回来这里安装
# CentOS 6
yum install centos-release-SCL && yum update
yum install python27
scl enable python27 bash
yum install python27-python-devel python27-python-setuptools python27-python-tools python27-python-virtualenv
yum install augeas-libs dialog gcc libffi-devel openssl-devel python-devel
yum install python-argparse
# CentOS 7
yum install -y git python27
yum install -y augeas-libs dialog gcc libffi-devel openssl-devel python-devel
yum install python-argparse
4、安装开始,需要停掉nginx,因为需要用到80端口连接验证
#service nginx stop
#/opt/certbot-master/letsencrypt-auto --help
或者用指定域名和邮箱进行安装,省得设置。
#/opt/certbot-master/letsencrypt-auto certonly --standalone -email 邮箱地址(邮箱地址是用来接收紧急通知和找回密钥的) -d 域名
执行上述命令后,会弹出对话框,同意用户协议,然后按文字提示操作下去就行了,支持多域名,只需要在用空格或者英文逗号分隔就好了。如果使用国内 VPS,此处可能会由于 DNS 问题出错,可以尝试更换 VPS 的 DNS 为第三方,比如 8.8.8.8。
运行完成之后,你会看到下面这个提示:
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/bnxb.com/fullchain.pem. Your cert will
expire on 2017-08-16. To obtain a new version of the certificate in
the future, simply run Let's Encrypt again.
- Your account credentials have been saved in your Let's Encrypt
configuration directory at /etc/letsencrypt. You should make a
secure backup of this folder now. This configuration directory will
also contain certificates and private keys obtained by Let's
Encrypt so making regular backups of this folder is ideal.
- If you like Let's Encrypt, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
命令完成后,最新版本的证书位置:/etc/letsencrypt/live/域名/
每个域名一个目录,有以下文件:
- cert.pem 申请的服务器证书文件
- privkey.pem 服务器证书对应的私钥
- chain.pem 除服务器证书外,浏览器解析所需的其他全部证书,比如根证书和中间证书
- fullchain.pem 包含服务器证书的全部证书链文件
nginx 中用到的是fullchain.pem 和 privkey.pem 其他为apache使用的证书。
5、启用更安全的加密方式
默认是 SHA-1 形式,而现在主流的方案应该都避免 SHA-1,为了确保更强的安全性,我们可以采取迪菲-赫尔曼密钥交换。
#yum install openssl
#yum install openssl-devel
#openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
完整配置:
server {
#nginx 监听端口,443为默认https端口,ssl指使用https
listen 80 default backlog=2048;
listen 443 ssl;
# 服务器名称
server_name bnxb.com;
# https证书公钥
ssl_certificate /etc/letsencrypt/live/bnxb.com/fullchain.pem;
# https证书私钥 要注意保存!
ssl_certificate_key /etc/letsencrypt/live/域名/privkey.pem;
# 支持的加密协议
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
#nginx默认会使用Diffiel-Hellman交换密钥是1024位的,相对不安全,所以需要替换使用更安全的
ssl_dhparam /etc/ssl/certs/dhparam.pem;
# 支持的加密套件
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
# 定义session过期时间
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_stapling on;
ssl_stapling_verify on;
# 如果是全站 HTTPS 并且不考虑 HTTP 的话可以为响应头添加要求浏览器使用https重定向的 header
add_header Strict-Transport-Security max-age=15768000;
# 禁止外部站点iframe
add_header X-Frame-Options DENY;
# The rest of your server block
root /path/to/root;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
}
还可以再增加配置80端口跳转到HTTPS:
location / {
return 301 https://$server_name$request_uri;
}
通过此网址查询你的SSL状态:https://www.ssllabs.com/ssltest/analyze.html?d=域名
Let's Encrypt证书只有90天有效期,过期前需要续期。
- 手动续期:
#./letsencrypt-auto renew --force-renewal
- 可以通过配置脚本自动更新证书。
#!/bin/sh
# This script renews all the Let's Encrypt certificates with a validity < 30 days
if ! /opt/letsencrypt/letsencrypt-auto renew > /var/log/letsencrypt/renew.log 2>&1 ; then
echo Automated renewal failed:
cat /var/log/letsencrypt/renew.log
exit 1
fi
nginx -t && nginx -s reload
- 开启定时任务Cron。
#crontab -e
编辑任务内容
@daily /path/to/renewCerts.sh
完毕。