Certbot 生成 ssl 证书

certbot 是用来申请 Let's Encrypt 免费 SSL 证书

一般的免费 SSL 证书,好像都是使用 Let's Encrypt 颁发的证书。官网地址:
	https://letsencrypt.org/

Let's Encrypt 使用 ACME 协议来认证我们域名,并颁发证书。要获取 Let's Encrypt 证书,我们需要选择一个 ACME 客户端软件。官方推荐的是 Certbot。

Certbot 官网地址:
	https://certbot.eff.org

安装 certbot,我们可以查看官方文档:
	https://certbot.eff.org/docs/install.html

简述下安装步骤:
	最好的方式是:
		使用官方给我们提供的 Certbot 包,在官网首页可以下载,选择对应的 web 服务和系统。例如,我的是:
			Nginx + CentOS 7

		然后下方就会给出我们详细的安装步骤:

		/*
			下面主要是官网的一些翻译
		 */

		安装
			Certbot 是打包在 EPEL(Extra Packages for Enterprise Linux)。要使用 Certbot,我们必须首先启用 EPEL 仓库。在 RHEL 或 Oracle Linux,我们还必须开启可选的通道。
				注意:
					如果我们正在 EC2 上使用 EHEL,我们可以通过运行下面的命令来启用可选通道:
						$ yum -y install yum-utils
						$ yum-config-manager --enable rhui-REGION-rhel-server-extras rhui-REGION-rhel-server-optional

			之后,我们可以运行下面的命令来安装 Certbot:
				$ sudo yum install certbot python2-certbot-nginx

			安装 DNS 插件
				Certbot 的 DNS 插件可用于我们的系统。这些插件可用于自动从 Let's Encrypt 的 ACMEv2 服务器获取通配符证书。要使用其中一个插件,我们必须为要获取证书的域名配置 DNS,该证书适用于 Certbot 具有插件的 DNS 提供程序。可以在链接('https://certbot.eff.org/docs/using.html#dns-plugins')找到插件列表,以及关于使用它们的更多信息。要安装插件,运行上面的安装命令,但需要将命令中 certbot python2-certbot-nginx 替换为 python2-certbot-dns-PLUGIN,其中 PLUGIN 是要安装的插件的名称。例如,对于 RFC2136 插件,命令应该是 python2-certbot-dns-rfc2136。

		开始使用
			Certbot 有一个 Nginx 插件, 在许多平台上都支持, 并自动进行证书安装。
				$ sudo certbot --nginx

			运行该命令,可以让我们获得一个证书, 而且 Certbot 会自动编辑我们的 Nginx 配置来提供服务。如果我们希望自己手动来配置 Nginx,可以使用 certonly 子命令:
				$ sudo certbot --nginx certonly

			如果我们想要使用 Let's Encrypt 新的 ACMEv2 服务,来获取一个 '通配符' 证书,我们还需要安装 Certbot 的 DNS 插件。确保我们已经通过上面的 '安装 DNS 插件' 说明,安装了 DNS 服务,并运行下面的命令:
				$ sudo certbot -a DNS插件名 -i nginx -d "*.example.com" -d example.com --server https://acme-v02.api.letsencrypt.org/directory

			自动续订
				Certbot 可以配置为,在证书过期之前自动续订。因为 Let's Encrypt 证书的有效期是 90 天,因此我们需要在过期前,重新续订。可以运行下面的命令来测试证书的自动续订:
					$ sudo certbot renew --dry-run

				如果上面命令没有报错,我们可以通过添加一个 cron job 或 systemd timer 运行下面的命令,来支持自动续订:
					certbot renew

					注意:
						如果我们配置了一个 cron 或 systemd job,建议每天运行2次(在我们的证书续订或撤销之前,它不会执行任何操作。但定期运行,将使我们的网站有机会保持在线状态,以防 Let's Encrypt 由于某种原因异常触发了撤销)。

				下面是一个 cron job 示例,每天的中午和半夜运行:
					0 0,12 * * * python -c 'import random; import time; time.sleep(random.random() * 3600)' && certbot renew 

		DNS 插件
			如果想要从 Let's Encrypt 上获取通配符证书,或在目标 Web 服务器以外的计算机上运行 certbot,可以使用 Certbot 的 DNS 插件之一。

			这些插件不包含在默认的 Certbot 安装中,必须单独安装。虽然 DNS 插件当前不能与 certbot-auto 一起使用,但它们在许多 OS 包管理器和 Docker 镜像中都可以使用。访问 https://certbot.eff.org,了解我们系统上使用 DNS 插件的最佳方法。

			安装完成后,我们可以在下方的链接中,找到关于如何使用每个插件的文档:
				...
				文档列表
				...

			手动插件(manual)
				如果想要在目标 web 服务器以外的机器上运行 certbot 来获取证书,或者自己执行域名验证步骤,我们可以使用 'manual' 插件。没有图形化界面,我们可以通过在命令行上指定 certbot 和 --manual,使用该插件来获取证书。这要求我们复制和粘贴命令到另一个终端会话,该会话可能在另一台机器上。

				manual 插件可以使用 http 或 dns challenge(挑战)。我们可以使用 --preferred-challenges 选项来指定我们想要的 challenge

				http challenge 要求我们,将包含指定名称和指定内容的文件,直接放到顶级目录(web 根目录)下的 '/.well-known/acme-challenge/' 目录。本质上,同 webroot 插件一样,但是不是自动的。

				当使用 dns challenge 时,certbot 将要求我们在域名下,放置一条包含了指定内容的 TXT DNS 记录。包含我们希望颁发证书的主机名,由 '_acme-challenge' 预先设置。

				例如,对于 example.com 域名,文件条目如下所示:
					_acme-challenge.example.com. 300 IN TXT "gfj9Xq...Rg85nM"

				此外,我们可以通过使用 --manual-auth-hook 和 --manual-cleanup-hook 标志,指定脚本,用于准备验证&执行身份认证程序,和(/或)在其后进行清理。这在钩子部分中有更深入的描述。

			结合插件
				有时候我们可能想要将不同的身份认证程序和安装器程序结合起来。为此,我们可以使用 --authenticator 或 -a 来指定身份认证插件,使用 --installer 或 -i 来指定安装器插件

				例如,我们可以使用,用于身份认证的 webroot 插件,和用于安装的 apache 插件,来生成证书。
					certbot run -a webroot -i apache -w /var/www/html -d example.com

				或者,我们可以使用,用于身份认证的 manual 插件,和用于安装的 nginx 插件,来生成证书。
					certbot run -a manual -i nginx -d example.com

			第三方插件
				其他开发人员也提供了许多针对客户端的第三方插件。许多是测试/实验版本,但有些已经广泛使用
					...
					第三方插件列表
					...
	certbot-auto(简单了解下)
		安装 certbot-auto
			https://certbot.eff.org/docs/install.html#id6

		如果上面安装 certbot 的方法不可用,才使用 certbot-auto,它会在我们的系统上自动安装 Certbot:
			系统要求:
				Python 2.7 或 3.4+,运行在类 unix 系统					

				默认需要 root 权限,因为要写入到 /etc/letsencrypt, /var/log/letsencrypt, /var/lib/letsencrypt。绑定到 80 和 443 端口(如果使用 standalone 插件),读取并修改 web 服务器配置(如果使用 apache 或 nginx 插件)。

				如果避免用 root 用户来运行 ACME 客户端,可以选择 letsencrypt-nosudo(https://github.com/diafygi/letsencrypt-nosudo) 或 simp_le(https://github.com/zenhack/simp_le)

				Apache 插件当前需要 augeas 1.0 版本的操作系统;当前支持基于 Debian, Fedora, SUSE, Gentoo 和 Darwin 的现代操作系统.

				此外,可以通过验证 certbot-auto 脚本的数字签名来验证它是否完整。这需要安装 gpg2,在许多 Linux 分发版中存在,以 gnupg 或 gnupg2 命名。

				使用 certbot-auto 安装,需要 512MB 的 RAM,来构建依赖。通过预构建的系统包来安装,可以避免该问题。我们也可以临时设置一个交换文件(swap file)。查看下面的 'Python 虚拟环境问题' 获取更多信息。

			安装 certbot-auto:
				wget https://dl.eff.org/certbot-auto
				sudo mv certbot-auto /usr/local/bin/certbot-auto
				sudo chown root /usr/local/bin/certbot-auto
				chmod 0755 /usr/local/bin/certbot-auto
				/usr/local/bin/certbot-auto --help

					
			检查脚本完整性:
				wget -N https://dl.eff.org/certbot-auto.asc
				gpg2 --keyserver pool.sks-keyservers.net --recv-key A2CFB51FA275A7286234E7B24D17C995CD9775F2
				gpg2 --trusted-key 4D17C995CD9775F2 --verify certbot-auto.asc /usr/local/bin/certbot-auto

			certbot-auto 命令自动更新到最新的客户端版本。由于 certbot-auto 是 certbot 的包装器,它接受与 certbot 完全一样的标志和参数。更多信息,查看 certbot 命令行选项(https://certbot.eff.org/docs/using.html#command-line-options)

			要获得完整的命令行帮助,可以输入:
				./certbot-auto --help all

	看文档,外加查找资料,最终配置成功。这里记录下每一个步骤,以后按照这个步骤安装、配置即可:
		1.安装 certbot
			访问首页:https://certbot.eff.org,选择我们使用的 web 服务和操作系统,然后会给出默认的安装命令

			这里以 'nginx' 和 'centos7' 为例:
				yum -y install yum-utils

				在 RHEL 或 Oracle Linux 上,还需要执行(我们使用的 centos 不需要):
					yum-config-manager --enable rhui-REGION-rhel-server-extras rhui-REGION-rhel-server-optional
					yum install certbot python2-certbot-nginx

				// 注意,这里安装的是 nginx 插件
				yum install certbot python2-certbot-nginx

		2.通过 certbot 生成证书
			certbot --nginx certonly [-d 域名1,域名2]

			1>参数解析,很重要:
				--nginx - 表示我们之前选择的 nginx 服务

				certonly - 默认 certbot 会自动修改我们 nginx 的配置,添加上 ssl 配置,我们想要手动配置 ssl,就需要设置该选项

				-d - 指定域名,可以同时指定多个,以 ',' 分隔

			2>此外,直接运行上述命令,可能会报错:
				Error while running nginx -c /usr/local/nginx/nginx.conf -t

				原因:
					找不到 nginx 配置文件,默认 certbot 会找 /etc/nginx/nginx.conf 配置文件
					我们配置的 nginx 位置可能不同,需要改成自己的 nginx 路径

				解决方法:
					查看 certbot 帮助,应该提供了修改路径的选项

					certbot -h 			// certbot 命令帮助

					certbot -h nginx 	// nginx 插件帮助
						提供了2个选项:
							--nginx-server-root
								nginx 服务根目录,默认是 '/etc/nginx'

								/*
									这里还是个坑,因为 certbot 好像只是找 nginx.conf,所以,当我们的配置文件,不是放在 nginx 的根目录,仍然找不到

									所以,这里应该是 'nginx 配置文件所在的目录'

									例如,我的 nginx 配置路径是:
										/usr/local/nginx/conf/
								 */

							--nginx-ctl
								nginx 命令二进制文件名,默认是 'nginx'

				所以,我们最终的命令是:
					certbot --nginx certbot --nginx-server-root /usr/local/nginx/conf/


			3>执行可能还会报错:
				ImportError: No module named 'requests.packages.urllib3'

				原因:
					requests库版本问题

				解决方法:
					sudo pip install requests urllib3 pyOpenSSL --force --upgrade
					sudo pip install --upgrade --force-reinstall 'requests==2.6.0'

			4>期间可能还会发生报错:
				UnicodeDecodeError: 'ascii' codec can't decode byte 0xe7 in position 1: ordinal not in range(128)

				原因:
					nginx.conf 出现特殊字符

				解决方法:
					参考:https://github.com/certbot/certbot/issues/5236
					grep -r -P '[^\x00-\x7f]' /usr/local/nginx/conf/nginx.conf
					或
					grep -r -P '[^\x00-\x7f]' /usr/local/nginx/conf/vhosts/xxx.conf(虚拟主机配置)

					上面的命令是,查看有没有 \x00-\x7f 的特殊字符,有的话,将特殊字符删除(中文就是一种特殊字符)

		3.续订证书
			certbot renew 						// 续订所有证书
			certbot renew --cert-name 证书名 	// 续订 '指定证书'

			// 查看 renew 子命令
			certbot -h renew 

		4.自动续订证书
			因为 Let's Encrypt 证书有效期为 3 个月,我们不可能实时查看,需要配置一个计划任务,在过期前,自动续订:
				0 0,12 * * * python -c 'import random; import time; time.sleep(random.random() * 3600)' && certbot renew

		5.申请 '通配符' 证书
			上面的流程,只能申请指定域名的证书。如果我们想要申请 '通配符' 证书,还需要安装额外的 ' DNS 插件'。

			插件列表在 'https://certbot.eff.org/docs/using.html#dns-plugins' 可以查看到

			里面列出的插件基本都是国外的,我们可能都不适用。

			官方也提供了一个 'manual - 手动认证插件'(这个我没自己测试)
				certbot certonly --nginx -d 通配符域名(*.xxx.com) --manual --preferred-challenges dns --server https://acme-v02.api.letsencrypt.org/directory

			但是手动的方式,有问题,就是自动续订,过期了,还需要 '手动认证'...,没法做到自动生成

			但是,官方提供了 '--manual-auth-hook' 和 '--manual-cleanup-hook' 2个钩子,我们可以写脚本来实现自动生成(参考下方笔记 6)

		6.在网上找了个文章,写的非常好,推荐下:
			https://www.cnblogs.com/redirect/p/10140248.html

			它里面提到了一个 'manual' dns 插件脚本,可以帮我们自动订阅 '通配符' 证书,地址:
				https://github.com/ywdblog/certbot-letencrypt-wildcardcertificates-alydns-au

			里面需要注意的是
				1>文档使用的是 certbot-auto,我们安装的是 certbot,两者命令是一致的。certbot-auto 是对 certbot 的封装。

				2>au.sh 脚本,我们需要配置下
					1>我服务器是 '腾讯云',需要配置 '腾讯云' 的 APP_KEY(key) 和 APP_SECRET(token)
					2>我使用的是 php 脚本,配置下 php 命令路径

			列出所有命令:
				1>安装
					cd ~ && mkdir src && cd src
					git clone https://github.com/ywdblog/certbot-letencrypt-wildcardcertificates-alydns-au
					cd certbot-letencrypt-wildcardcertificates-alydns-au
					chmod 0777 au.sh 

				2.配置 DNS API 秘钥
					需要在不同的云平台申请(见文档)

				3.配置 au.sh
					key
					token
					php_cmd

				4.测试申请证书(有 --dry-run 选项)
					certbot certonly  -d *.xxx.com --manual --preferred-challenges dns --dry-run --manual-auth-hook "/root/src/certbot-letencrypt-wildcardcertificates-alydns-au/au.sh php txy add" --manual-cleanup-hook "/root/src/certbot-letencrypt-wildcardcertificates-alydns-au/au.sh php txy clean"

				5.测试无误,正式申请证书(去除 --dry-run 选项)
					certbot certonly  -d *.xxx.com --manual --preferred-challenges dns --manual-auth-hook "/root/src/certbot-letencrypt-wildcardcertificates-alydns-au/au.sh php txy add" --manual-cleanup-hook "/root/src/certbot-letencrypt-wildcardcertificates-alydns-au/au.sh php txy clean"

				6.配置自动续订,加入命令到 crontab
					# 注意只有成功renew证书,才会重新启动nginx
					1 1 */1 * * root certbot renew --manual --preferred-challenges dns --deploy-hook "service nginx restart" --manual-auth-hook "/root/src/certbot-letencrypt-wildcardcertificates-alydns-au/au.sh php txy add" --manual-cleanup-hook "/root/src/certbot-letencrypt-wildcardcertificates-alydns-au/au.sh php txy clean" 

参考文章:
	https://www.cnblogs.com/redirect/p/10140248.html(非常不错)
	https://www.seanzhao.me/2018/06/21/certbot-manual.html#%E4%BF%AE%E6%94%B9%E6%9B%B4%E6%96%B0%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6					
	https://blog.csdn.net/diyiday/article/details/82791663
	https://www.seanzhao.me/2018/06/21/certbot-manual.html#%E4%BF%AE%E6%94%B9%E6%9B%B4%E6%96%B0%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6

 

你可能感兴趣的:(服务器,nginx)