准备工作
登录 Let’s Encrypt 官网 (letsencrypt.org),阅读文档,对于拥有 Shell 权限的用户,可以直接使用 Certbot 自动化配置工具。
那么,我们再去访问 Certbot 官网 (certbot.eff.org),如下图所示。我们可以选择自己服务器的版本和所使用的 Web 软件。以 Nginx 和 CentOS 7 为例。
服务器环境
- 服务器 CentOS 7
- Nginx
开始安装
安装 EPEL
yum -y install yum-utils
yum-config-manager --enable rhui-REGION-rhel-server-extras rhui-REGION-rhel-server-optional
安装 Cerbot
yum install python2-certbot-nginx
使用 Certbot 申请证书
现在开始进行配置,以下命令二选一即可。
# 自动配置
sudo certbot --nginx
# 手动配置(我们选择这个方式)
sudo certbot --nginx certonly
(这一步如果遇到错误,请按照文末的解决方法进行尝试。)
如果一切正常,那么将会提示输入联系邮箱: z@zenkr.com
(请输入自己的联系邮箱)
[root@zenkr ~]# sudo certbot --nginx certonly
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx
Enter email address (used for urgent renewal and security notices) (Enter 'c' to cancel): z@zenkr.com
下面,需要输入是否同意条款,必须同意: A
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must agree in order to register with the ACME server at https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel: A
下面询问是否要接收邮件,我不希望接收: N
( Y
/N
都可以,根据自己需要)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: N
下面选择需要绑定的域名,如果在列表里,直接选择相应编号就好了: 1
如果有多个域名,我们输入需要申请的域名数字序号就好了。
(这一步之前,一定要提前将域名解析到服务器)
Which names would you like to activate HTTPS for?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: www.zenkr.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel): 1
需要等一小会,就成功生成了 SSL 证书啦。(申请时间长短根据服务器网络状况决定)
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for www.zenkr.com
Waiting for verification...
Cleaning up challenges
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/www.zenkr.com/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/www.zenkr.com/privkey.pem
Your cert will expire on 2018-12-12. To obtain a new or tweaked version of this certificate in the future, simply run certbot again. To non-interactively renew *all* of your certificates, run "certbot renew"
- Your account credentials have been saved in your Certbot 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 Certbot so making regular backups of this folder is ideal.
- If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
现在,证书的存储路径是
/etc/letsencrypt/live/www.zenkr.com/fullchain.pem
/etc/letsencrypt/live/www.zenkr.com/privkey.pem
配置 Nginx
到这里已经成功一大半了,只需要配置 Nginx 支持刚刚生成的证书。而且这个配置有最佳实践可以参考,访问:Mozilla SSL Configuration Generator,这是 Mozilla 搞得一个 HTTPS 配置文件自动生成器,支持 Apache,Nginx 等多种服务器。按照这个配置文件,选择 Intermediate 的兼容性。这里生成的配置文件是业界最佳实践和结果,让 Nginx 打开了各种增加安全性和性能的参数。
如果不知道软件版本,下面是查看各软件版本的命令:
# 查看 Nginx 版本
[root@gjyljs www.gjyljs.com]# nginx -v
nginx version: nginx/1.12.2
[root@gjyljs www.gjyljs.com]# openssl version
OpenSSL 1.0.2k-fips 26 Jan 2017
[root@gjyljs www.gjyljs.com]# cat /etc/centos-release
CentOS Linux release 7.5.1804 (Core)
下面的文件,是我根据生成的代码,根据自己的配置的修改,并将此文件保存为 www.zenkr.com.conf
:
server {
listen 80 ;
server_name zenkr.com www.zenkr.com;
# 将 HTTP 链接强制定向到 HTTPS 链接
return 301 https://$host$request_uri;
}
server {
listen 443;
server_name www.zenkr.com;
ssl on;
ssl_certificate /etc/letsencrypt/live/www.zenkr.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.zenkr.com/privkey.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
# Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
# intermediate configuration. tweak to your needs.
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
ssl_prefer_server_ciphers on;
# HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
add_header Strict-Transport-Security max-age=15768000;
# OCSP Stapling ---
# fetch OCSP records from URL in ssl_certificate and cache them
ssl_stapling on;
ssl_stapling_verify on;
## verify chain of trust of OCSP response using Root CA and Intermediate certs
ssl_trusted_certificate /etc/letsencrypt/live/www.zenkr.com/root_ca_cert_plus_intermediates;
# 这里将域名解析服务商的 DNS 地址写在这里
resolver vip1.alidns.com vip2.alidns.com;
root /YOUR_SITE_PATH/www.zenkr.com-20180920/public;
location / {
index index.php index.html index.htm;
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
重启 Nginx: systemctl restart nginx.service
自动更新证书
申请的证书,有90天的有效期。为了方便起见,最好能让服务器自动更新证书的授权。
先运行测试命令:
certbot renew --dry-run
如果上面的命令可以正常运行,那么,现在就可以把它加入到系统定时任务 cron 当中去了。编辑 Crontab,将下面的代码插入到最后一行,运行: crontab -e
0 0,12 * * * python -c 'import random; import time; time.sleep(random.random() * 3600)' && certbot renew
好了以后保存。
补充一: 可能遇到的错误及解决方案
错误 ImportError: No module named ‘requests.packages.urllib3’
运行 certbot --nginx certonly
命令以后,可能会遇到如下错误:
Traceback (most recent call last):
File "/bin/certbot", line 9, in <module>
load_entry_point('certbot==0.26.1', 'console_scripts', 'certbot')()
File "/usr/lib/python2.7/site-packages/pkg_resources/__init__.py", line 570, in load_entry_point
return get_distribution(dist).load_entry_point(group, name)
File "/usr/lib/python2.7/site-packages/pkg_resources/__init__.py", line 2751, in load_entry_point
return ep.load()
File "/usr/lib/python2.7/site-packages/pkg_resources/__init__.py", line 2405, in load
return self.resolve()
File "/usr/lib/python2.7/site-packages/pkg_resources/__init__.py", line 2411, in resolve
module = __import__(self.module_name, fromlist=['__name__'], level=0)
File "/usr/lib/python2.7/site-packages/certbot/main.py", line 18, in <module>
from certbot import account
File "/usr/lib/python2.7/site-packages/certbot/account.py", line 18, in <module>
from acme import messages
File "/usr/lib/python2.7/site-packages/acme/messages.py", line 7, in <module>
from acme import challenges
File "/usr/lib/python2.7/site-packages/acme/challenges.py", line 11, in <module>
import requests
File "/usr/lib/python2.7/site-packages/requests/__init__.py", line 58, in <module>
from . import utils
File "/usr/lib/python2.7/site-packages/requests/utils.py", line 32, in <module>
from .exceptions import InvalidURL
File "/usr/lib/python2.7/site-packages/requests/exceptions.py", line 10, in <module>
from .packages.urllib3.exceptions import HTTPError as BaseHTTPError
File "/usr/lib/python2.7/site-packages/requests/packages/__init__.py", line 95, in load_module
raise ImportError("No module named '%s'" % (name,))
ImportError: No module named 'requests.packages.urllib3'
解决方法:
pip install --upgrade --force-reinstall 'requests==2.6.0' urllib3
错误 pkg_resources.DistributionNotFound
继续,如果还遇到下面问题
Traceback (most recent call last):
File "/bin/certbot", line 5, in <module>
from pkg_resources import load_entry_point
File "/usr/lib/python2.7/site-packages/pkg_resources/__init__.py", line 3138, in <module>
@_call_aside
File "/usr/lib/python2.7/site-packages/pkg_resources/__init__.py", line 3122, in _call_aside
f(*args, **kwargs)
File "/usr/lib/python2.7/site-packages/pkg_resources/__init__.py", line 3151, in _initialize_master_working_set
working_set = WorkingSet._build_master()
File "/usr/lib/python2.7/site-packages/pkg_resources/__init__.py", line 666, in _build_master
return cls._build_from_requirements(__requires__)
File "/usr/lib/python2.7/site-packages/pkg_resources/__init__.py", line 679, in _build_from_requirements
dists = ws.resolve(reqs, Environment())
File "/usr/lib/python2.7/site-packages/pkg_resources/__init__.py", line 867, in resolve
raise DistributionNotFound(req, requirers)
pkg_resources.DistributionNotFound: The 'urllib3<1.23,>=1.21.1' distribution was not found and is required by requests
解决方法: 需要先更新一下 pip
,之后再重新运行一下
pip install --upgrade pip
pip install --upgrade --force-reinstall 'requests==2.6.0' urllib3
补充二: 添加 DNS CAA 认证
部署好了 SSL,现在可以登录 www.ssllabs.com 网站进行测评。其实已经能够得到 A+ 的好分数了。
不过,细心的人,可能还注意到下面的详情里有一项: DNS CAA 还是红色的。为了消除它,那么再努力一点。去域名解析中,添加 0 issue "letsencrypt.org"
和 0 iodef "mailto:z@zenkr.com"
。
这样就大功告成了,重新去测评一下 SSL 。现在可以看到:
现在,尽情浏览你的网站吧~