为IP地址和域名申请SSL证书

1. 为域名申请SSL证书

本教程使用 acme.sh 工具从 ZeroSSL 生成免费的SSL/TLS证书。

1.1. HTTP验证方式申请证书

  1. 安装 acme.sh:
1
curl https://get.acme.sh | sh -s email=my@example.com

如果下载失败,尝试以下命令:

1
2
3
git clone https://ghp.ci/https://github.com/acmesh-official/acme.sh.git
cd acme.sh
./acme.sh --install -m my@example.com

安装完成后可以使用acme.sh --upgrade --auto-upgrade命令开启acme.sh的自动升级功能。

  1. 安装 socat 以使用独立模式申请证书:
1
sudo apt install socat
  1. 重新加载配置文件:

安装 acme.sh 的过程中会创建一个 alias 在用户配置文件中, 方便用户调用 acme.sh 命令, 但是需要重新加载用户配置文件或重启终端后生效:

1
2
3
4
source ~/.bashrc  # bash
source ~/.zshrc # zsh

acme.sh -v # 查看acme.sh版本
  1. 申请证书:
1
acme.sh --issue --standalone -d example.com

将 example.com 替换为要申请证书的域名即可, 但是需要确保80端口被防火墙放行并且没有被其他程序占用

如果acme.sh默认的调用的ZeroSSL无法下发证书, 可尝试切换CA机构:

1
2
3
4
5
6
7
8
# 切换到 Let's Encrypt
acme.sh --set-default-ca --server letsencrypt

# 切换到 Buypass
acme.sh --set-default-ca --server buypass

# 切换回 ZeroSSL
acme.sh --set-default-ca --server zerossl
  1. 应用证书

成功申请到证书后,密钥对文件会被放到~/.acme.sh/example.com目录下。不建议直接引用这些文件,因为~/.acme.sh/目录通常具有用户的权限,可能不够安全,并且证书自动更新后,服务器不会自动重载证书。正确的做法是使用 --install-cert 命令安装证书(实际上是复制证书到指定目录并自动重载证书)。

Nginx:

1
2
3
4
5
mkdir -p /var/www/certs/example.com/
acme.sh --install-cert -d example.com \
--fullchain-file /var/www/certs/example.com/fullchain.pem \
--key-file /var/www/certs/example.com/key.pem \
--reloadcmd "service nginx force-reload"

Apache:

1
2
3
4
5
6
mkdir -p /var/www/certs/example.com/
acme.sh --install-cert -d example.com \
--cert-file /var/www/certs/example.com/cert.pem \
--fullchain-file /var/www/certs/example.com/fullchain.pem \
--key-file /var/www/certs/example.com/key.pem \
--reloadcmd "service apache2 force-reload"

example.com替换为申请到证书的域名即可后再进行安装。成功安装后,acme.sh 会将安装证书的命令保存下来,下次更新证书时会自动执行安装命令。

有了证书文件后,就可以配置 Nginx 或 Apache 使用证书了,具体请参考官方文档:

  1. 更新证书

安装ac.me的时候会自动创建一个 cronjob, 每天会自动检测所有的证书, 如果快过期了, 会自动更新证书
使用crontab -l命令可以查看cronjob列表。如果需要提前更新证书,可以使用 --force 参数。

关于acme.sh的更多用法请查看acme.sh项目的wiki: https://github.com/acmesh-official/acme.sh/wiki/%E8%AF%B4%E6%98%8E

1.2. DNS验证方式申请证书

DNS验证方式无需无需占用服务器的80端口,也就是说不需要将待申请证书的域名解析到服务器上,但是需要获取能修改DNS记录的API权限。以Cloudflare为例,进入此链接页面:https://dash.cloudflare.com/profile/api-tokens

创建令牌:

alt text

使用“编辑区域DNS”模板:

alt text

参考下图编辑前3个选项,注意DNS区域权限必须为”编辑”(acme.sh申请证书过程依赖DNS编辑权限来自动添加和删除TXT记录):

alt text

编辑完成后点击底部的“继续以显示摘要”按钮,在新页面中继续点击”创建令牌”,此时便会在新页面中生成一个API令牌,复制保存下来:

alt text

再回到域名列表中,进入目标域名的概述页面,在右下角位置点击复制帐户ID:

alt text

回到服务器,将刚才获取到的API令牌和账户ID保存到环境变量中:

1
2
export CF_Token="API令牌"
export CF_Account_ID="账户ID"

成功申请到证书后,acme.sh 会自动将这2个变量保存到~/.acme.sh/account.conf文件中。

执行以下命令为域名申请证书:

1
acme.sh --issue --dns dns_cf -d example.com

将 example.com 替换为要申请证书的域名即可。如果要申请通配符证书,只需将example.com替换为'*.example.com'即可。注意,这里申请的通配符证书不包含裸域,例如*.example.com不会包含example.com

alt text

成功申请到证书之后后续的步骤和HTTP验证方式一致。注意使用域名前不要忘记将域名解析到服务器。

2. 为IP地址申请SSL证书

acme.sh 已不支持为纯IP地址申请SSL证书, 需要到ZeroSSL官网上去申请,免费账号有3次免费申请证书的资格。

  1. 进入 ZeroSSL 官网注册账号: https://app.zerossl.com/signup。

  2. 完成注册后在仪表板中点击 “New Certificate” 开始创建新证书:

1

  1. 在 “Domains” 项中填写自己要申请证书的IP地址, 在 “Validity” 项中选择90天的免费证书, 在 “CSR & Contact” 项中保持默认勾选 “Auto-Generate CSR”, 在 “CSR & Contact” 项中保持默认选择的免费计划, 然后点击下一步。

2

  1. 为IP地址申请证书只能使用 “HTTP File Upload” 的方式验证IP地址为自己所属。步骤如下:

点击 “Download Auth File” 下载验证文件并保存在指定目录中:

3

配置服务器软件, 这里演示使用 Nginx, 添加一个服务块:

1
2
3
4
5
6
7
8
9
10
server {
listen 80;
server_name 8.8.8.8; # 替换为要申请证书的IP地址

location ^~ /.well-known/pki-validation/ {
default_type "text/plain";
root /var/www; # 按实际情况修改
try_files $uri =404;
}
}

注意要确保 /var/www/.well-known/pki-validation/346C970CF06CA56D457E6228973FAB71.txt 路径和验证文件真实有效。

完成服务器配置后用浏览器访问自己的验证链接, 确保能看到验证字符串:

4

访问正常后即可点击下一步并点击开始验证:

5

验证通过后即可下载压缩包得到证书和私钥文件:

6

  1. 更新证书

证书快到期的时候会有邮件通知, 届时再去网页重复操作一遍即可续期。

3. 自签证书

如果不在乎TLS警告以及MITM, 也可以使用自签证书:

1
2
3
4
5
6
7
8
# 创建目录
mkdir -p /var/www/certs/selfsigned_certs

# 生成私钥
openssl ecparam -genkey -name prime256v1 -out /var/www/certs/selfsigned_certs/ca.key

# 生成证书
openssl req -new -x509 -days 36500 -subj "/CN=qq.com" -key /var/www/certs/selfsigned_certs/ca.key -out /var/www/certs/selfsigned_certs/ca.crt

4. 其他