使用 acmesh 免费开启 https(详细概念介绍与操作步骤记录)

本贴最后更新于 1474 天前,其中的信息可能已经时移世改

前言

记录一次使用 acme.sh 免费开启 https 的过程,前半部分列举一些用到的概念,后半部分记录具体操作步骤。文章已调整好线性阅读顺序,按顺序阅读即可。流程中涉及的概念会尽量进行讲解,以减少阅读此篇文章时,额外检索产生的时间消耗

概念

acme.sh

acme.sh 是 github 上的一个开源项目,实现了 acme 协议, 可以从 letsencrypt 生成免费的证书。

官方文档(官方文档的使用说明很详细,推荐阅读):

英文:https://github.com/acmesh-official/acme.sh

中文:https://github.com/acmesh-official/acme.sh/wiki/说明

acme.sh 有以下特点(摘自官方文档):

  • 一个完全使用用 Shell(Unix shell)语言编写的 ACME 协议的客户端
  • 支持 ACME v1 和 ACME v2 协议
  • 支持 ACME v2 通配符证书
  • 简单,强大且非常易于使用。 您只需 3 分钟即可学习
  • 和 bash,dash, sh 兼容
  • Let's Encrypt 免费证书客户端最简单的 shell 脚本
  • 完全用 Shell 编写,不依赖 python 或官方的 Let's Encrypt 客户端
  • 只需一个脚本即可发布,续期和自动安装证书
  • 不需要 root/sudoer 权限
  • 对 Docker 友好的
  • 支持 IPv6
  • 对证书续期和错误等有 cron job 通知

Let's Encrypt

Let's Encrypt 是一个于 2015 年三季度推出的数字证书认证机构,旨在以自动化流程消除手动创建和安装证书的复杂流程,并推广使万维网服务器的加密连接无所不在,为安全网站提供免费的 SSL/TLS 证书。
-- 摘自 维基百科

网站开启 https 的时候需要证书,证书由 CA 机构(数字证书认证机构)签发,大部分传统 CA 机构签发证书需要收费,这不利于 https 协议的推广。Let's Encrypt 也是一个 CA 机构,但它是免费签发数字证书的,通过它,我们可以免费开启 https

ACME(自动证书管理环境)

ACME 协议最初是由 Internet Security Research Group 为其公共 CA(公共证书颁发机构)——Let's Encrypt 开发的。ACME 协议通过在给定 Web 服务器上安装证书管理代理来运行。组织或域在一开始就经过验证,代理协助域控制验证,一旦完成,代理可以请求,续订和撤销证书。

详情:ACME 协议:它是什么以及如何工作——asiaregister.com

ACME 协议具体的工作流程这里就不细说了,感兴趣的朋友可以去详情即原出处查看。

全站 https,通配符证书

通配符证书是一个可以被多个子域使用的公钥证书,主域名签发的通配符证书可以在所有子域名中使用。在此之前,配置子域名也是需要每个子域名单独的申请证书的。2018 年 3 月 14 日,Let’s Encrypt 对外宣布 ACME v2 已正式支持通配符证书,这意外味着用户可以在 Let’s Encrypt 上免费申请支持通配符的 SSL 证书。

具体操作

官方文档(官方文档的使用说明很详细,推荐阅读):

英文:https://github.com/acmesh-official/acme.sh

中文:https://github.com/acmesh-official/acme.sh/wiki/说明

本文使用的操作系统(Linux 各版本操作步骤基本一致):CentOS 7.3

1. 安装 acme.sh

输入

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

wget -O -  https://get.acme.sh | sh

curl 命令

curl 命令是一个利用 URL 规则在命令行下工作的文件传输工具。它支持文件的上传和下载,所以是综合传输工具。

详情:curl 命令——linuxde.net

wget 命令

wget 命令用来从指定的 URL 下载文件。wget 非常稳定,它在带宽很窄的情况下和不稳定网络中有很强的适应性,如果是由于网络的原因下载失败,wget 会不断的尝试,直到整个文件下载完毕。如果是服务器打断下载过程,它会再次联到服务器上从停止的地方继续下载。这对从那些限定了链接时间的服务器上下载大文件非常有用。

详情:wget 命令——linuxde.net

acmesh 安装内部流程

普通用户和 root 用户都可以安装使用. 安装过程进行了以下几步:

  1. 把 acme.sh 安装到你的 home 目录(即~目录)下:

    ~/.acme.sh/
    

    并创建一个 bash 的 alias, 方便你的使用: alias acme.sh=~/.acme.sh/acme.sh

    (alias:中文释意"别名")

  2. 自动为你创建 cronjob, 每天 0:00 点自动检测所有的证书, 如果快过期了, 需要更新, 则会自动更新证书。

更高级的安装选项请参考: https://github.com/Neilpang/acme.sh/wiki/How-to-install

安装过程不会污染已有的系统任何功能和文件, 所有的修改都限制在安装目录中: ~/.acme.sh/

cron job

工具型软件 cron 是一款类 Unix 操作系统下的基于时间的任务管理系统。用户们可以通过 cron 在固定时间、日期、间隔下,运行定期任务(可以是命令和脚本)。cron 常用于运维和管理,但也可用于其他地方,如:定期下载文件和邮件。cron 该词来源于希腊语 chronos(χρόνος),原意是时间。
——摘自 维基百科

博主最先使用 curl 命令进行安装,但由于网络原因,失败了:

01 使用 curl 安装 acmesh 网络问题失败.png

如果安装成功,~目录下,使用 ls -la 可以查看到有一个.acme.sh 目录。

curl 命令安装失败后,改用 wget 命令,成功安装:

02 使用 wget 安装 acmesh 成功.png

安装信息中有一段醒目的红色警告:

It is recommended to install socat first.We use socat for standalone server if you use standalone mode.If you don't use standalone mode, just ignore this warning.

即:

推荐先安装 socat。如果你使用 standalone mode,那么我们需要为了 standalone server 使用 socat。如果你不使用 standalone mode,那么请忽略这条警告

standalone mode 非开启 https 必须,在官方英文文档中被另一些配置用到(4. Use Standalone server to issue cert 5. Use Standalone ssl server to issue cert),如果感兴趣的话可以去看官方英文文档。

简略介绍一下 socat:

socat

socat 是一个多功能的网络工具,名字来由是“Socket CAT”,可以看作是 netcat 的加强版。它有一些 netcat 所不具备却又很有需求的功能,例如 ssl 连接。socat 是强大的,可以实现任意 socket 的转换。而 netcat 被称为网络工具中的瑞士军刀,体积小巧,但功能强大。netcat 可以在两台设备上面相互交互,即侦听模式/传输模式。

想要安装 socat 的话,可以使用 yum 安装 socat:

yum install socat

2. 生成证书

acme.sh 实现了 acme 协议支持的所有验证协议. 一般有两种方式验证: http 和 dns 验证。

1.http 方式(推荐)

http 方式需要在你的网站根目录下放置一个文件, 来验证你的域名所有权。完成验证, 然后就可以生成证书了。

acme.sh  --issue  -d mydomain.com -d www.mydomain.com  --webroot  /home/wwwroot/mydomain.com/

只需要指定域名, 并指定域名所在的网站根目录。 acme.sh 会全自动的生成验证文件, 并放到网站的根目录, 然后自动完成验证。最后会聪明的删除验证文件,整个过程没有任何副作用。

第二个参数"example.com" 是您要为其颁发证书的主要域。这里至少要填写一个域名。

博主的网站根目录填写的是 tomcat 服务器的 webapps 目录,文章后面有不需要你不需要指定网站根目录的办法。nginx 服务器在 80 端口做转发,转发到 8080 端口的 tomcat 服务器。

03 验证域名所有权 1.png

04 验证域名所有权 2.JPG

如果你用的 apache 服务器, acme.sh 还可以智能的从 apache 的配置中自动完成验证, 你不需要指定网站根目录:

acme.sh --issue  -d mydomain.com   --apache

如果你用的 nginx 服务器, 或者反代, acme.sh 还可以智能的从 nginx 的配置中自动完成验证, 你不需要指定网站根目录:

acme.sh --issue  -d mydomain.com   --nginx

证书每 60 天自动更新一次。

请注意, 无论是 apache 还是 nginx 模式, acme.sh 在完成验证之后, 都会将服务器配置文件恢复到之前的状态, 不会私自更改你本身的配置。 好处是你不用担心配置被搞坏, 也有一个缺点, 你需要自己配置 ssl 的配置。acme.sh 只能成功生成证书, 需要手动配置 ssl,才能访问 https。这样做虽然麻烦,但是为了配置的安全, 你还是自己手动改配置吧。

这里"你需要自己配置 ssl 的配置"的意思是:

为服务器安装 ssl 模块(Apache 默认没有预装,需要自行安装。nginx 默认预装了 ssl 模块,无需再次安装)。然后在服务器的配置文件中,写证书位置(在第 3.步中我们将完成此项操作)。

2.手动 dns 方式(如使用第一种,可忽略第二种方法)

手动在域名上添加一条 txt 解析记录, 验证域名所有权。

这种方式的好处是, 你不需要任何服务器, 不需要任何公网 ip, 只需要 dns 的解析记录即可完成验证。 坏处是,如果不同时配置 Automatic DNS API,使用这种方式 acme.sh 将无法自动更新证书,每次都需要手动重新解析验证域名所有权。

第二种使用方式请见官方文档(文章开头链接),博主使用的 http 方式,手动 dns 方式这里不细说了。

3. copy/安装 证书

前面证书生成以后, 接下来需要把证书 copy 到真正需要用它的地方。

请注意,默认生成的证书都放在安装目录下: ~/.acme.sh/, 请不要直接使用此目录下的文件,例如: 不要直接让 nginx/apache 的配置文件使用这下面的文件。这里面的文件都是 acmesh 工具内部使用, 目录结构在将来可能会变化,进而导致服务器配置文件中填写的证书路径错误的情况。

正确的使用方法是使用 --installcert 命令,并指定目标位置, 然后证书文件会被 copy 到相应的位置, 例如:

Apache example

acme.sh --installcert -d example.com \
--cert-file      /path/to/certfile/in/apache/cert.pem  \
--key-file       /path/to/keyfile/in/apache/key.pem  \
--fullchain-file /path/to/fullchain/certfile/apache/fullchain.pem \
--reloadcmd     "service apache2 force-reload"

Nginx example

acme.sh --installcert -d example.com \
--key-file       /path/to/keyfile/in/nginx/key.pem  \
--fullchain-file /path/to/fullchain/nginx/cert.pem \
--reloadcmd     "service nginx force-reload"

(一个小提醒, 这里用的是 service nginx force-reload, 不是 service nginx reload, 据测试, reload 并不会重新加载证书, 所以用的 force-reload)

Nginx 的配置 ssl_certificate 使用 /etc/nginx/ssl/fullchain.cer ,而非 /etc/nginx/ssl/<domain>.cer ,否则 SSL Labs 的测试会报 Chain issues Incomplete 错误。

--installcert 命令可以携带很多参数, 来指定目标文件。 并且可以指定 reloadcmd, 当证书更新以后, reloadcmd 会被自动调用,让服务器生效。

–reloadcmd “service nginx force-reload” 是为了在让 acmesh 自动更新时候能够重启 nginx 使得证书生效。

值得注意的是, 这里指定的所有参数都会被自动记录下来, 并在将来证书自动更新以后, 被再次自动调用。

首先,我们需要新建一个路径用于存放拷贝的证书(路径可自定义)。习惯是放在/etc/nginx/ssl/目录下。博主新建的路径:

/etc/nginx/ssl/jellyfishmix

执行(nginx 方式)

acme.sh --installcert -d jellyfishmix.com \
--key-file       /etc/nginx/ssl/jellyfishmix/key.pem \
--fullchain-file /etc/nginx/ssl/jellyfishmix/cert.pem \
--reloadcmd     "service nginx force-reload"

--key-file 参数填写:你的自定义路径 + key.pem

--fullchain-file 参数填写:你的自定义路径 + cert.pem

这里的 key.pemcert.pem 并不表示一个已经存在的文件,而是表示拷贝粘贴后的文件将被命名的名字。

05 拷贝 acmesh 生成的证书.png

nginx 相关

nginx 的安装与使用:CentOS 7 下 yum 安装和配置 Nginx

nginx 的端口转发:nginx 反向代理——将 80 端口请求转发到 8080

nginx 的配置文件路径查看:nginx 快速查看配置文件的方法

nginx.conf 配置 ssl

出处:linux nginx 配置 https

想要 https 就要监听 443 端口,nginx.conf 已经预留出了 server,只要我们放开权限,修改即可。

监听 443 端口

server {
        listen 443 ssl;
        server_name www.example.com;
        
        ssl_certificate /etc/nginx/ssl/jellyfishmix/cert.pem;
        ssl_certificate_key /etc/nginx/ssl/jellyfishmix/key.pem;
        ssl_session_timeout  5m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;     #指定SSL服务器端支持的协议版本
        ssl_ciphers  HIGH:!aNULL:!MD5;
        #ssl_ciphers  ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;    #指定加密算法
        ssl_prefer_server_ciphers   on;    #在使用SSLv3和TLS协议时指定服务器的加密算法要优先于客户端的加密算法
}

注:ssl_certificate 和 ssl_certificate_key 的路径就是我们 ssl 证书申请的路径

ssl_certificate 证书其实是个公钥,它会被发送到连接服务器的每个客户端,ssl_certificate_key 私钥是用来解密的,所以它的权限要得到保护但 nginx 的主进程能够读取。当然私钥和证书可以放在一个证书文件中,这种方式也只有公钥证书才发送到 client。

ssl_session_timeout 客户端可以重用会话缓存中 ssl 参数的过期时间,内网系统默认 5 分钟太短了,可以设成 30m 即 30 分钟甚至 4h。

ssl_protocols 指令用于启动特定的加密协议,nginx 在 1.1.13 和 1.0.12 版本后默认是 ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2,TLSv1.1 与 TLSv1.2 要确保 OpenSSL >= 1.0.1 ,SSLv3 现在还有很多地方在用但有不少被攻击的漏洞。

ssl_ciphers 选择加密套件,不同的浏览器所支持的套件(和顺序)可能会不同。这里指定的是 OpenSSL 库能够识别的写法,你可以通过 openssl -v cipher ‘RC4:HIGH:!aNULL:!MD5’(后面是你所指定的套件加密算法) 来看所支持算法。

ssl_prefer_server_ciphers on 设置协商加密算法时,优先使用我们服务端的加密套件,而不是客户端浏览器的加密套件。

监听 80 端口

server {
        listen 80;
        server_name www.example.com;
        rewrite ^(.*) https://$server_name$1 permanent;
}

因为 http 是默认端口,监听 80 端口可以让 http 重定向到 https 端口上。

博主的 nginx.conf(部分,如要复制,请把所有"jellyfishmix.com"字样替换成自己的域名,证书路径替换为自己的路径):

server {
        # listen       80 default_server;
        # listen       [::]:80 default_server;
        # server_name  _;

        listen          443 ssl;
        server_name     www.jellyfishmix.com;
        
        ssl_certificate /etc/nginx/ssl/jellyfishmix/cert.pem;
        ssl_certificate_key     /etc/nginx/ssl/jellyfishmix/key.pem;
        ssl_session_timeout     5m;
        # 指定SSL服务器端支持的协议版本
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        # ssl_ciphers  ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;       指定加密算法
        ssl_ciphers  HIGH:!aNULL:!MD5;
        # 在使用SSLv3和TLS协议时指定服务器的加密算法要优先于客户端的加密算法
        ssl_prefer_server_ciphers   on;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
            proxy_pass http://39.97.254.25:8080;
        }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }

    server {
        listen          80;
        server_name     www.jellyfishmix.com;
        rewrite ^(.*)   https://$server_name$1  permanent;
    }

然后重新加载 nginx:

systemctl reload nginx

此时请访问自己的域名:example.comwww.example.com 正常情况下,此时可以正常访问域名,并且连接所使用的协议为 https。

4. 续期证书

目前证书在 60 天以后会自动续期, 你无需任何操作。今后有可能会缩短这个时间, 不过都是自动的, 你不用关心。

当然了,你可以强制手动续期:

acme.sh --renew -d example.com --force

5. 如何停止证书续期

如果要停止证书续期,你可以执行以下命令将证书从续期列表中移除:

acme.sh --remove -d example.com

cert/key 文件不会从硬盘中被移除。

你可以自行移除隐藏目录(例如::~/.acme.sh/example.com

6. 更新 acme.sh

目前由于 acme 协议和 letsencrypt CA 都在频繁的更新, 因此 acme.sh 也经常更新以保持同步。

升级 acme.sh 到最新版 :

acme.sh --upgrade

如果你不想手动升级, 可以开启自动升级:

acme.sh  --upgrade  --auto-upgrade

之后, acme.sh 就会自动保持更新了。

你也可以随时关闭自动更新:

acme.sh --upgrade  --auto-upgrade  0

-- END

  • HTTPS
    98 引用 • 271 回帖 • 3 关注
  • SSL

    SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。TLS 与 SSL 在传输层对网络连接进行加密。

    69 引用 • 190 回帖 • 494 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...