申请Let’s Encrypt用于https的证书

Let’s Encrypt是通过执行certbot-auto来申请证书,certbot-auto是一个程序,通过git可以复制到本地。
一共有这几种模式:apache、nginx、webroot、standalone、DNS plugins和manual。
我用的是standalone模式,以下是讲的是standalone模式的操作过程。

==========================================================

前提条件:
1、执行certbot-auto当前主机80端口被公网访问;
2、如要申请www.mysite.com的证书,则保证公网上访问http://www.mysite.com是指向到你这台主机的80端口;
3、执行certbot-auto前,先停止当前主机原先监听80端口的进程。
总之一句话就是你执行certbot-auto的主机就是你网站所在主机,执行前先停止你的web server。

原因是certbot-auto执行standalone模式时,会启动一个webserver监听80端口,并在该webserver的根目录生成一个文件/.well-known/acme-challenge/XXXXX(XXXXX是一串随机字符),用于给letsencrypt验证所申请证书的域名所有权,即letsencrypt验证服务器会访问http://www.mysite.com/.well-known/acme-challenge/XXXXX这个URL来验证,你所申请的域名的管理权是否真的在你手上,这种方法跟绑定域名验证所有权是一样的,只是letsencrypt搞成自动完成。
顺便吐槽下网上很多教程在这一步就是一条命令略过,估计也是照抄别人而不知道所以然。所以当你执行certbot-auto的主机跟你网站主机不是同一台时,怎么搞都不会通过,因为letsencrypt会一直访问http://www.mysite.com/.well-known/acme-challenge/XXXXX这个URL,而你网站主机上其实并没有这个路径,就会一直失败,对于很多人来说都是只有一台主机做网站,所以很少会遇到这种问题。

恰巧我就不只一台主机,偏偏我就在另外一台主机操作申请证书,折腾了好久,最终还是回到部署网站的那台主机操作才成功。

执行certbot-auto失败结果如下:

[root@dakvm letsencrypt]# ./certbot-auto certonly –standalone –email admin@siteht.com -d www.mysite.com
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator standalone, Installer None
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for www.mysite.com
Waiting for verification…
Challenge failed for domain www.mysite.com
http-01 challenge for www.mysite.com
Cleaning up challenges
Some challenges have failed.

IMPORTANT NOTES:
– The following errors were reported by the server:

Domain: www.mysite.com
Type: unauthorized
Detail: Invalid response from
http://www.mysite.com/.well-known/acme-challenge/PHE_EJP_Fp72rMGOClgXTEivTFEmj6yWcTiMwnd2GzA
[111.111.111.111]: “<!DOCTYPE HTML PUBLIC \”-//IETF//DTD HTML
2.0//EN\”>\n<html><head>\n<title>404 Not
Found</title>\n</head><body>\n<h1>Not Found</h1>\n<p”

To fix these errors, please make sure that your domain name was
entered correctly and the DNS A/AAAA record(s) for that domain
contain(s) the right IP address.
==========================================================

先理清上面所说的事情,正式流程如下:

一、安装letsencrypt
git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt
./certbot-auto certonly –standalone –email admin@siteht.com -d www.mysite.com

二、申请证书
[root@da2 letsencrypt]# ./certbot-auto certonly –standalone –email admin@siteht.com -d www.mysite.com

详细过程,会自动安装一些python组件,一直同意就行了:

Bootstrapping dependencies for RedHat-based OSes that will use Python3… (you can skip this with –no-bootstrap)
yum is /usr/bin/yum
yum is hashed (/usr/bin/yum)
Loaded plugins: fastestmirror
Setting up Install Process
Loading mirror speeds from cached hostfile
* base: centos.mirror.constant.com
* epel: epel.mirror.constant.com
* extras: centos.mirror.constant.com
* updates: centos.mirror.constant.com
Package gcc-4.4.7-23.el6.x86_64 already installed and latest version
Package openssl-1.0.1e-57.el6.x86_64 already installed and latest version
Package openssl-devel-1.0.1e-57.el6.x86_64 already installed and latest version
Resolving Dependencies
–> Running transaction check
—> Package augeas-libs.x86_64 0:1.0.0-10.el6 will be installed
—> Package ca-certificates.noarch 0:2017.2.14-65.0.1.el6_9 will be updated
—> Package ca-certificates.noarch 0:2018.2.22-65.1.el6 will be an update
—> Package libffi-devel.x86_64 0:3.0.5-3.2.el6 will be installed
—> Package python34.x86_64 0:3.4.10-1.el6 will be installed
–> Processing Dependency: python34-libs(x86-64) = 3.4.10-1.el6 for package: python34-3.4.10-1.el6.x86_64
–> Processing Dependency: libpython3.4m.so.1.0()(64bit) for package: python34-3.4.10-1.el6.x86_64
—> Package python34-devel.x86_64 0:3.4.10-1.el6 will be installed
–> Processing Dependency: python-rpm-macros for package: python34-devel-3.4.10-1.el6.x86_64
–> Processing Dependency: python3-rpm-macros for package: python34-devel-3.4.10-1.el6.x86_64
—> Package python34-tools.x86_64 0:3.4.10-1.el6 will be installed
–> Processing Dependency: python34-tkinter = 3.4.10-1.el6 for package: python34-tools-3.4.10-1.el6.x86_64
—> Package redhat-rpm-config.noarch 0:9.0.3-51.el6.centos will be installed
–> Running transaction check
—> Package python-rpm-macros.noarch 0:3-14.el6 will be installed
–> Processing Dependency: python-srpm-macros for package: python-rpm-macros-3-14.el6.noarch
—> Package python3-rpm-macros.noarch 0:3-14.el6 will be installed
—> Package python34-libs.x86_64 0:3.4.10-1.el6 will be installed
—> Package python34-tkinter.x86_64 0:3.4.10-1.el6 will be installed
–> Processing Dependency: libX11.so.6()(64bit) for package: python34-tkinter-3.4.10-1.el6.x86_64
–> Processing Dependency: libtcl8.5.so()(64bit) for package: python34-tkinter-3.4.10-1.el6.x86_64
–> Processing Dependency: libtk8.5.so()(64bit) for package: python34-tkinter-3.4.10-1.el6.x86_64
–> Running transaction check
—> Package libX11.x86_64 0:1.6.4-3.el6 will be installed
–> Processing Dependency: libX11-common = 1.6.4-3.el6 for package: libX11-1.6.4-3.el6.x86_64
–> Processing Dependency: libxcb.so.1()(64bit) for package: libX11-1.6.4-3.el6.x86_64
—> Package python-srpm-macros.noarch 0:3-14.el6 will be installed
—> Package tcl.x86_64 1:8.5.7-6.el6 will be installed
—> Package tk.x86_64 1:8.5.7-5.el6 will be installed
–> Processing Dependency: libfreetype.so.6()(64bit) for package: 1:tk-8.5.7-5.el6.x86_64
–> Processing Dependency: libfontconfig.so.1()(64bit) for package: 1:tk-8.5.7-5.el6.x86_64
–> Processing Dependency: libXrender.so.1()(64bit) for package: 1:tk-8.5.7-5.el6.x86_64
–> Processing Dependency: libXft.so.2()(64bit) for package: 1:tk-8.5.7-5.el6.x86_64
–> Running transaction check
—> Package fontconfig.x86_64 0:2.8.0-5.el6 will be installed
—> Package freetype.x86_64 0:2.3.11-17.el6 will be installed
—> Package libX11-common.noarch 0:1.6.4-3.el6 will be installed
—> Package libXft.x86_64 0:2.3.2-1.el6 will be installed
—> Package libXrender.x86_64 0:0.9.10-1.el6 will be installed
—> Package libxcb.x86_64 0:1.12-4.el6 will be installed
–> Processing Dependency: libXau.so.6()(64bit) for package: libxcb-1.12-4.el6.x86_64
–> Running transaction check
—> Package libXau.x86_64 0:1.0.6-4.el6 will be installed
–> Finished Dependency Resolution

Dependencies Resolved

==============================================================================================================================================================================
Package Arch Version Repository Size
==============================================================================================================================================================================
Installing:
augeas-libs x86_64 1.0.0-10.el6 base 314 k
libffi-devel x86_64 3.0.5-3.2.el6 base 18 k
python34 x86_64 3.4.10-1.el6 epel 51 k
python34-devel x86_64 3.4.10-1.el6 epel 186 k
python34-tools x86_64 3.4.10-1.el6 epel 426 k
redhat-rpm-config noarch 9.0.3-51.el6.centos base 60 k
Updating:
ca-certificates noarch 2018.2.22-65.1.el6 base 930 k
Installing for dependencies:
fontconfig x86_64 2.8.0-5.el6 base 186 k
freetype x86_64 2.3.11-17.el6 base 361 k
libX11 x86_64 1.6.4-3.el6 base 587 k
libX11-common noarch 1.6.4-3.el6 base 171 k
libXau x86_64 1.0.6-4.el6 base 24 k
libXft x86_64 2.3.2-1.el6 base 55 k
libXrender x86_64 0.9.10-1.el6 base 24 k
libxcb x86_64 1.12-4.el6 base 180 k
python-rpm-macros noarch 3-14.el6 epel 6.6 k
python-srpm-macros noarch 3-14.el6 epel 5.8 k
python3-rpm-macros noarch 3-14.el6 epel 5.4 k
python34-libs x86_64 3.4.10-1.el6 epel 8.3 M
python34-tkinter x86_64 3.4.10-1.el6 epel 337 k
tcl x86_64 1:8.5.7-6.el6 base 1.9 M
tk x86_64 1:8.5.7-5.el6 base 1.4 M

Transaction Summary
==============================================================================================================================================================================
Install 21 Package(s)
Upgrade 1 Package(s)

Total download size: 15 M
Is this ok [y/N]: y
Downloading Packages:
(1/22): augeas-libs-1.0.0-10.el6.x86_64.rpm | 314 kB 00:00
(2/22): ca-certificates-2018.2.22-65.1.el6.noarch.rpm | 930 kB 00:00
(3/22): fontconfig-2.8.0-5.el6.x86_64.rpm | 186 kB 00:00
(4/22): freetype-2.3.11-17.el6.x86_64.rpm | 361 kB 00:00
(5/22): libX11-1.6.4-3.el6.x86_64.rpm | 587 kB 00:00
(6/22): libX11-common-1.6.4-3.el6.noarch.rpm | 171 kB 00:00
(7/22): libXau-1.0.6-4.el6.x86_64.rpm | 24 kB 00:00
(8/22): libXft-2.3.2-1.el6.x86_64.rpm | 55 kB 00:00
(9/22): libXrender-0.9.10-1.el6.x86_64.rpm | 24 kB 00:00
(10/22): libffi-devel-3.0.5-3.2.el6.x86_64.rpm | 18 kB 00:00
(11/22): libxcb-1.12-4.el6.x86_64.rpm | 180 kB 00:00
(12/22): python-rpm-macros-3-14.el6.noarch.rpm | 6.6 kB 00:00
(13/22): python-srpm-macros-3-14.el6.noarch.rpm | 5.8 kB 00:00
(14/22): python3-rpm-macros-3-14.el6.noarch.rpm | 5.4 kB 00:00
(15/22): python34-3.4.10-1.el6.x86_64.rpm | 51 kB 00:00
(16/22): python34-devel-3.4.10-1.el6.x86_64.rpm | 186 kB 00:00
(17/22): python34-libs-3.4.10-1.el6.x86_64.rpm | 8.3 MB 00:00
(18/22): python34-tkinter-3.4.10-1.el6.x86_64.rpm | 337 kB 00:00
(19/22): python34-tools-3.4.10-1.el6.x86_64.rpm | 426 kB 00:00
(20/22): redhat-rpm-config-9.0.3-51.el6.centos.noarch.rpm | 60 kB 00:00
(21/22): tcl-8.5.7-6.el6.x86_64.rpm | 1.9 MB 00:00
(22/22): tk-8.5.7-5.el6.x86_64.rpm | 1.4 MB 00:00
——————————————————————————————————————————————————————————
Total 14 MB/s | 15 MB 00:01
warning: rpmts_HdrFromFdno: Header V3 RSA/SHA256 Signature, key ID 0608b895: NOKEY
Retrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6
Importing GPG key 0x0608B895:
Userid : EPEL (6) <epel@fedoraproject.org>
Package: epel-release-6-8.noarch (@/epel-release-6-8.noarch)
From : /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6
Is this ok [y/N]: y
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
Installing : python34-libs-3.4.10-1.el6.x86_64 1/23
Installing : python34-3.4.10-1.el6.x86_64 2/23
Installing : freetype-2.3.11-17.el6.x86_64 3/23
Installing : fontconfig-2.8.0-5.el6.x86_64 4/23
Installing : 1:tcl-8.5.7-6.el6.x86_64 5/23
Installing : libXau-1.0.6-4.el6.x86_64 6/23
Installing : libxcb-1.12-4.el6.x86_64 7/23
Installing : libX11-common-1.6.4-3.el6.noarch 8/23
Installing : libX11-1.6.4-3.el6.x86_64 9/23
Installing : libXrender-0.9.10-1.el6.x86_64 10/23
Installing : libXft-2.3.2-1.el6.x86_64 11/23
Installing : 1:tk-8.5.7-5.el6.x86_64 12/23
Installing : python34-tkinter-3.4.10-1.el6.x86_64 13/23
Installing : python3-rpm-macros-3-14.el6.noarch 14/23
Installing : python-srpm-macros-3-14.el6.noarch 15/23
Installing : python-rpm-macros-3-14.el6.noarch 16/23
Installing : python34-devel-3.4.10-1.el6.x86_64 17/23
Installing : python34-tools-3.4.10-1.el6.x86_64 18/23
Installing : augeas-libs-1.0.0-10.el6.x86_64 19/23
Updating : ca-certificates-2018.2.22-65.1.el6.noarch 20/23
Installing : redhat-rpm-config-9.0.3-51.el6.centos.noarch 21/23
Installing : libffi-devel-3.0.5-3.2.el6.x86_64 22/23
Cleanup : ca-certificates-2017.2.14-65.0.1.el6_9.noarch 23/23
Verifying : python34-3.4.10-1.el6.x86_64 1/23
Verifying : freetype-2.3.11-17.el6.x86_64 2/23
Verifying : fontconfig-2.8.0-5.el6.x86_64 3/23
Verifying : 1:tcl-8.5.7-6.el6.x86_64 4/23
Verifying : python-srpm-macros-3-14.el6.noarch 5/23
Verifying : python34-tools-3.4.10-1.el6.x86_64 6/23
Verifying : libffi-devel-3.0.5-3.2.el6.x86_64 7/23
Verifying : python34-libs-3.4.10-1.el6.x86_64 8/23
Verifying : python3-rpm-macros-3-14.el6.noarch 9/23
Verifying : python34-tkinter-3.4.10-1.el6.x86_64 10/23
Verifying : redhat-rpm-config-9.0.3-51.el6.centos.noarch 11/23
Verifying : libX11-common-1.6.4-3.el6.noarch 12/23
Verifying : libXrender-0.9.10-1.el6.x86_64 13/23
Verifying : ca-certificates-2018.2.22-65.1.el6.noarch 14/23
Verifying : augeas-libs-1.0.0-10.el6.x86_64 15/23
Verifying : libX11-1.6.4-3.el6.x86_64 16/23
Verifying : libXau-1.0.6-4.el6.x86_64 17/23
Verifying : libXft-2.3.2-1.el6.x86_64 18/23
Verifying : python-rpm-macros-3-14.el6.noarch 19/23
Verifying : libxcb-1.12-4.el6.x86_64 20/23
Verifying : python34-devel-3.4.10-1.el6.x86_64 21/23
Verifying : 1:tk-8.5.7-5.el6.x86_64 22/23
Verifying : ca-certificates-2017.2.14-65.0.1.el6_9.noarch 23/23

Installed:
augeas-libs.x86_64 0:1.0.0-10.el6 libffi-devel.x86_64 0:3.0.5-3.2.el6 python34.x86_64 0:3.4.10-1.el6 python34-devel.x86_64 0:3.4.10-1.el6
python34-tools.x86_64 0:3.4.10-1.el6 redhat-rpm-config.noarch 0:9.0.3-51.el6.centos

Dependency Installed:
fontconfig.x86_64 0:2.8.0-5.el6 freetype.x86_64 0:2.3.11-17.el6 libX11.x86_64 0:1.6.4-3.el6 libX11-common.noarch 0:1.6.4-3.el6
libXau.x86_64 0:1.0.6-4.el6 libXft.x86_64 0:2.3.2-1.el6 libXrender.x86_64 0:0.9.10-1.el6 libxcb.x86_64 0:1.12-4.el6
python-rpm-macros.noarch 0:3-14.el6 python-srpm-macros.noarch 0:3-14.el6 python3-rpm-macros.noarch 0:3-14.el6 python34-libs.x86_64 0:3.4.10-1.el6
python34-tkinter.x86_64 0:3.4.10-1.el6 tcl.x86_64 1:8.5.7-6.el6 tk.x86_64 1:8.5.7-5.el6

Updated:
ca-certificates.noarch 0:2018.2.22-65.1.el6

Complete!
Creating virtual environment…
Installing Python packages…
Installation succeeded.
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator standalone, Installer None

– – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –
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

– – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –
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: Y
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for www.mysite.com
Waiting for verification…
Cleaning up challenges

IMPORTANT NOTES:
– Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/www.mysite.com/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/www.mysite.com/privkey.pem
Your cert will expire on 2019-08-07. To obtain a new or tweaked
version of this certificate in the future, simply run certbot-auto
again. To non-interactively renew *all* of your certificates, run
“certbot-auto 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

执行完成后生成如下2个文件:
/etc/letsencrypt/live/www.mysite.com/fullchain.pem;
/etc/letsencrypt/live/www.mysite.com/privkey.pem;

三、配置nginx

1、nginx.conf加入证书路径;
ssl on;
ssl_certificate /etc/letsencrypt/live/www.mysite.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.mysite.com/privkey.pem;
2、监听80端口的要重定向到https;
3、若使用了反向代理,监听443端口的要在location中加入add_header Content-Security-Policy upgrade-insecure-requests;,
否则访问网站js文件无法正常加载,现象是网站的样式异常排版错乱。
完整版如下:

server {
listen 80;
server_name www.mysite.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443;
ssl on;
ssl_certificate /etc/letsencrypt/live/www.mysite.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.mysite.com/privkey.pem;
server_name www.mysite.com;
access_log logs/siteht.com.log main;
location / {
root html;
index index.htm;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header Content-Security-Policy upgrade-insecure-requests;
proxy_pass http://my_site;
}location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|js|css)$
{
expires 24h;
proxy_cache_valid 200 304 7d;
proxy_cache_valid 301 302 1m;
proxy_cache_valid any 1m;
proxy_cache www_cache;
proxy_cache_key $host$uri$is_args$args;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://my_site;
gzip on;
gzip_min_length 1024;
gzip_buffers 4 8k;
gzip_http_version 1.0;
gzip_comp_level 3;
gzip_types text/text text/plain text/xml text/css application/x-javascript application/javascript image/jpeg image/gif image/png;
}
}

重启nginx
kill -HUP nginxpid

验证访问https://www.mysite.com

四、定时续期letsencrypt

查看所申请证书的域名列表
[root@da2 letsencrypt]# ./certbot-auto certificates
Saving debug log to /var/log/letsencrypt/letsencrypt.log

– – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –
Found the following certs:
Certificate Name: www.mysite.com
Domains: www.mysite.com
Expiry Date: 2019-08-07 09:37:54+00:00 (VALID: 89 days)
Certificate Path: /etc/letsencrypt/live/www.mysite.com/fullchain.pem
Private Key Path: /etc/letsencrypt/live/www.mysite.com/privkey.pem
– – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –

设置crontab定时任务,依然是通过certbot-auto进行更新,因默认90天后过期,可以设置每2个月更新一次。
更新证书依然跟申请证书时的验证流程一样,所以需要写脚本先停止nginx,更新证书后,再启动nginx。

renew_cert.sh
##########################################################
#!/bin/bash
nginxpid=`ps -ef|grep ‘nginx: master’|grep -v grep|awk ‘{print $2}’`
echo $nginxpid
kill -QUIT $nginxpid
sleep 10s
/root/letsencrypt/certbot-auto renew
/usr/local/nginx/bin/nginx
##########################################################

设置crontab
0 0 * */2 * sh /root/renew_cert.sh