记录一下DNS方式申请Let's Encrypt证书并使用Nginx部署步骤

Published: 2020-06-24

Tags: https

本文总阅读量

前两天申请的专用服务器不开放 80,443,8080 等常用网站端口,但是需要部署供小程序使用的接口,要上HTTPS,之前鼓捣博客的时候用过一键脚本鼓捣过,印象中是全自动的,但是依赖于域名已经绑定到了服务器,而且需要绑定80端口,网上搜索了一下,最后决定使用 DNS 方式申请证书。

记录一下,因为我昨天鼓捣的时候,用脚本申请证书很快就下来了,但是Nginx配置因为一个斜杠疏漏浪费了好多的时间排查问题,接下里我可能需要系统的学习一下 Nginx 的配置,每次用时都搜配置很不便捷。

不唠叨了。

安装脚本

我使用的是 acme.sh 自动化脚本

$ curl  https://get.acme.sh | sh

脚本被安装在了以下目录,同时脚本任何操作,产生的文件也都在这里,不会破坏系统环境。

$ ls ~/.acme.sh/
account.conf  acme.sh  acme.sh.csh  acme.sh.env  deploy  dnsapi  notify

创建别名方便使用

$ alias acme.sh=~/.acme.sh/acme.sh

申请证书

$ acme.sh --issue --dns -d app-api.yasking.org

遇到提示

[2020年 06月 23日 星期二 21:15:27 CST] It seems that you are using dns manual mode. Read this link first: https://github.com/acmesh-official/acme.sh/wiki/dns-manual-mode

意思是官方不推荐使用DNS方式进行验证,如果使用这种方式验证,请确保你知道其利弊,因为没80,所以我才选择的 DNS 方式验证,所以重新执行

$ acme.sh --issue -d app-api.yasking.org --dns \
 --yes-I-know-dns-manual-mode-enough-go-ahead-please

输出内容是让我们添加域名的解析记录,好完成域名使用者的校验

[2020年 06月 24日 星期三 21:57:10 CST] Creating domain key
[2020年 06月 24日 星期三 21:57:10 CST] The domain key is here: /root/.acme.sh/app-api.yasking.org/app-api.yasking.org.key
[2020年 06月 24日 星期三 21:57:10 CST] Single domain='app-api.yasking.org'
[2020年 06月 24日 星期三 21:57:10 CST] Getting domain auth token for each domain
[2020年 06月 24日 星期三 21:57:15 CST] Getting webroot for domain='app-api.yasking.org'
[2020年 06月 24日 星期三 21:57:15 CST] Add the following TXT record:
[2020年 06月 24日 星期三 21:57:15 CST] Domain: '_acme-challenge.app-api.yasking.org'
[2020年 06月 24日 星期三 21:57:15 CST] TXT value: 'WWnE3DibtYu_ph5fPpHUJqEfpXHy06YZ1Sj7BlZEuhM'
[2020年 06月 24日 星期三 21:57:15 CST] Please be aware that you prepend _acme-challenge. before your domain
[2020年 06月 24日 星期三 21:57:15 CST] so the resulting subdomain will be: _acme-challenge.app-api.yasking.org
[2020年 06月 24日 星期三 21:57:15 CST] Please add the TXT records to the domains, and re-run with --renew.
[2020年 06月 24日 星期三 21:57:15 CST] Please add '--debug' or '--log' to check more details.
[2020年 06月 24日 星期三 21:57:15 CST] See: https://github.com/acmesh-official/acme.sh/wiki/How-to-debug-acme.sh

添加DNS记录

重要的地方输出标绿了,需要在域名解析商处添加一条 TXT 记录。

本例也就是添加名为 “_acme-challenge.app-api” 的记录,其值为 “WWnE3DibtYu_ph5fPpHUJqEfpXHy06YZ1Sj7BlZEuhM”

添加完成可以访问 https://tool.lu/dns/index.html,输入 “_acme-challenge.app-api.yasking.org” 域名地址,查询记录是否生效

以上域名及记录值请自行替换为自己的

重新申请

注意这里的参数是 renew 而不是上边用的 issue

$ acme.sh --renew -d app-api.yasking.org \
  --yes-I-know-dns-manual-mode-enough-go-ahead-please

申请成功输出

[2020年 06月 23日 星期二 21:24:57 CST] Renew: 'app-api.yasking.org'
[2020年 06月 23日 星期二 21:25:00 CST] Single domain='app-api.yasking.org'
[2020年 06月 23日 星期二 21:25:00 CST] Getting domain auth token for each domain
[2020年 06月 23日 星期二 21:25:00 CST] Verifying: app-api.yasking.org
[2020年 06月 23日 星期二 21:25:06 CST] Success
[2020年 06月 23日 星期二 21:25:06 CST] Verify finished, start to sign.
[2020年 06月 23日 星期二 21:25:06 CST] Lets finalize the order, Le_OrderFinalize: https://acme-v02.api.letsencrypt.org/acme/finalize/81556248/3992312321
[2020年 06月 23日 星期二 21:25:09 CST] Download cert, Le_LinkCert: https://acme-v02.api.letsencrypt.org/acme/cert/04452335937cb9f595az7156560e1299a201
[2020年 06月 23日 星期二 21:25:10 CST] Cert success.
-----BEGIN CERTIFICATE-----
MIIFYTCCBEmgMwIBAgISBEUDNZN8ufWVr3FWVg4SmaICMA0GCSqGSIb3DQEBCwUA
MEoxCzAJBgNVBAYTAlVTMRYwFdYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0yMDA2MjMxMjI0MjJaFw0y
MDA5MjExMjI0MjJaMB8xHTAbBgNVBAMTFGppeGkuYXBwLnlhc2tpbmcub3JnMIIB
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs64OZgmHQ4yTpQycY4vq0IOn
deETgTPGNE4kIPd1MJ1rPctid0IvIZ/e3+Xfv9E3q8Ju9ggbhJr+oLKbWmGo/Hbj
SnrJEfMefMY8ZxaQCe0sXVS2q6wUnOk8nH4Rrgn6HKsgWBlJ1PofQ8bHuZknTe6s
AgslKY22Z4pQJTM3mLUIXJ0cS+EVF+rp75HZpmE+qJzcSbmYPMUmNXRyWgd8wu6G
wtUE8yMBcq5MhZgngKZL+cx2y9G98RtIhrQSkjAAGH+7cRDXaUHbsBzrrldbRM6k
2aY54jaIZZnLTxhqm6XmDrkjzCDiGGjCbbIClVK+f+qpTOgvollURDBIgZvp9QID
AQABo4ICajCCAmYwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMB
BggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBTRnQf/6Fz5DHzOgn2X
+gaBngQ/UTAfBgNVHSMEGDAWgBSoSmpjBH3duubRObemRWXv86jsoTBvBggrBgEF
BQcBAQRjMGEwLgYIKwYBBQUHMAGGImh0dHA6Ly9vY3NwLmludC14My5sZXRzZW5j
cnlwdC5vcmcwLwYIKwYBBQUHMAKGI2h0dHA6Ly9jZXJ0LmludC14My5sZXRzZW5j
cnlwdC5vcmcvMB8GA1UdEQcYMBaCFGppeGkuYXBwLnlhc2tpbmcub3JnMEwGA1Ud
IARFMEMwCAYGZ4EMAQIBMDcGCysGAQQBgt8TAQEBMCgwJgYIKwYBBQUHAgEWGmh0
dHA6Ly9jcHMubGV0c2VuY3J5cHQub3JnMIIBBQYKKwYBBAHWeQIEAgSB9gSB8wDx
AHcA5xLysDd+GmL7jskMYYTx6ns3y1YdESZb8+DzS/JBVG4AAAFy4VnexQAABAMA
SDBGAiEAwuysswE0nrTTLHmoQuJOEXUIGpkxFaPXm+QNfe//eYgCIQC0AkkICg8D
QxXqWX+WmHUOPy8AUg+ZX/egt2gkV/KLUQB2AAe3XBvlfWj/8bDGHSMVx7rmV3xX
lLdq7rxhOhpp06IcAAABcuFZ3vQAAAQDAEcwRQIgRNEmgGV44C6bev94M0w3byU3
nbuxRQij/Yg07nwqKKACIQCDOVVav6Ca0rJUUCm3Re41Pq+Pfhhry/nseeGqqGT9
LjANBgkqhkiG9w0BAQsFAAOCAQEATgPitc2+2ScNgKGUM7+Fpj6UB6BZ3VDehitn
HlTo05LTn7YC3NLkZKinA7yjdPlbj4ZdKmFQrftHzQu1hPxsnq/BfoecGtg6ww48
zHfVaAbiseuz5fRHP4lzJwG7tRRd3pPZu9XxmJzFu9SxjzWrLI/GnKh9NRLVPb9W
Y+E2EK4+eFeFC9c0fkhZE13M3WcOQbgoAqE7iky6AaxpeoS9fNIm8hqnmaajxtGW
gT1OsoeqpQETTOvfNqBwH4nrQa9A0B+wKsEtPjF6c+CSwDJyBrXUQ/2UJgRPRdx+
md/YZNm/uXdbAyVDEbTfghSu1Z3LW5DqhHMrCFDE3EORzycTzA==
-----END CERTIFICATE-----
[2020年 06月 23日 星期二 21:25:10 CST] Your cert is in  /root/.acme.sh/app-api.yasking.org/app-api.yasking.org.cer 
[2020年 06月 23日 星期二 21:25:10 CST] Your cert key is in  /root/.acme.sh/app-api.yasking.org/app-api.yasking.org.key 
[2020年 06月 23日 星期二 21:25:10 CST] The intermediate CA cert is in  /root/.acme.sh/app-api.yasking.org/ca.cer 
[2020年 06月 23日 星期二 21:25:10 CST] And the full chain certs is there:  /root/.acme.sh/app-api.yasking.org/fullchain.cer 

申请回来的证书保存的目录如下

$ ll ~/.acme.sh/app-api.yasking.org/
总用量 28
-rw-r--r--. 1 root root 1648 6月  23 21:25 ca.cer
-rw-r--r--. 1 root root 3575 6月  23 21:25 fullchain.cer
-rw-r--r--. 1 root root 1927 6月  23 21:25 app-api.yasking.org.cer
-rw-r--r--. 1 root root  588 6月  23 21:25 app-api.yasking.org.conf
-rw-r--r--. 1 root root  993 6月  23 21:25 app-api.yasking.org.csr
-rw-r--r--. 1 root root  215 6月  23 21:25 app-api.yasking.org.csr.conf
-rw-r--r--. 1 root root 1675 6月  23 21:20 app-api.yasking.org.key

稍后部署 Nginx 使用到的是 cer 及 key 证书文件

先将证书文件放置在目录

/opt/cert-home

创建 Nginx 配置文件

default.conf

server {
    listen 443 ssl;
    server_name app-api.yasking.org;
    ssl_certificate /opt/cert-home/app-api.yasking.org.cer;
    # 两个cer证书用哪个都可以。
    # ssl_certificate /opt/cert-home/fullchain.cer;
    ssl_certificate_key /opt/cert-home/app-api.yasking.org.key;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
    ssl_prefer_server_ciphers on;

    # 反向代理配置
    location / {
        # $host 代表转发服务器
        proxy_set_header Host $host;
        proxy_redirect off;
        # 记录真实IP
        proxy_set_header X-Real-IP $remote_addr;
        # 存储请求链路上各代理IP
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        # 连接超时时间
        proxy_connect_timeout 60;
        # nginx接收upstream server数据超时时间
        proxy_read_timeout 600;
        # nginx发送数据至upstream server超时时间
        proxy_send_timeout 600;
        # 反向代理
        proxy_pass http://xcx-api:8900/;
    }
}

简要说明:因为是容器内,所以此处容器内部监听的是 443 端口,外部物理机映射到 8443 就可以了,另外 proxy_pass 转发服务器上的 HTTP 接口,使其成为 HTTPS 接口,路径结尾不要忘记那个 “/”,xcx-api 是 API 接口服务容器名,我的接口服务和 Nginx 服务使用的相同网络,所以可以指定容器名访问。

将 Nginx 配置文件放在

/opt/https-proxy/default.conf

启动 Nginx 容器

sudo docker run -d --name https-proxy --net mynet -p 8443:443 -v /opt/cert-home:/opt/cert-home/ -v /opt/https-proxy/:/etc/nginx/conf.d/ -v /etc/localtime:/etc/localtime:ro --restart=unless-stopped nginx:alpine

Tips:Docker 创建网络命令

sudo docker network create -d bridge --subnet=172.99.0.0/16 --gateway=172.99.0.1 mynet

OK,打开浏览器,通过 https 访问 8443 端口,请求到的接口就是 http 的 8900 端口了,为端口加 HTTPS 完成。

排错流程

部署完成,然而报错的话,可以参考以下步骤调试。

1,首先查看 Nginx 监听端口是否可以访问,非 Docker 部署,可能需要防火墙添加端口放行。

2,其次验证 Nginx 配置 HTTP 接口能否正确转发服务接口。

3,另外注意,修改 Nginx 配置后,需要重载配置文件或重启。

4,实在找不到问题,尝试使用 Nginx 默认配置文件,加上 HTTPS 配置项,看能否访问 Nginx 欢迎页。

还是再次提醒一下, Let's Encrypt 证书三个月需要重新申请一下~

参考

  1. https://github.com/acmesh-official/acme.sh/wiki/%E8%AF%B4%E6%98%8E
  2. https://shirmy.me/article/12