ego008
ego008
7592 8 0

用简洁可靠的方式为网站配置免费https

Let’s Encrypt 停用 tls-sni 后,对其依赖的 golang.org/x/crypto/acme/autocert 挂掉了,去看看其它的方法,转了一圈,觉得 acme-tiny 简洁可靠,一个 198 行的py 文件就搞定,不过需要 openssl 工具配合。下面是照官方文档按部就班,一次顺利配置成功,贴出来共享。

这里是用nginx 配合,如果想再简单点请参考 https://www.youbbs.org/t/2170

建立一个目录,如 /root/ssl

创建一个 RSA 私钥用于 Let's Encrypt 识别你的身份的帐号:

openssl genrsa 4096 > account.key

创建域名私钥

openssl genrsa 4096 > domain.key

生成 CSR 文件,在 CSR 中推荐至少把域名带 www 和不带 www 的两种情况都加进去,下面是通过 openssl.cnf 模版生成,只需改为你的域名

单域名:

openssl req -new -sha256 -key domain.key -subj "/CN=www.yourdomain.com" > domain.csr

多域名:

openssl req -new -sha256 -key domain.key -subj "/" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:yourdomain.com,DNS:www.yourdomain.com")) > domain.csr

如果提示 /etc/ssl/openssl.cnf 不存在,就搜索 openssl.cnf 看看它在哪儿,改上面命令行里 openssl.cnf 的路径。如果没有就输入下面命令按照提示输入:

openssl req -new -sha256 -key domain.key -out domain.csr

配置验证服务,Let's Encrypt 是在你的服务器上生成一个随机验证文件,再通过创建 CSR 时指定的域名访问,如果可以访问则表明你对这个域名有控制权。接下来要做的是使下面网址可访问

http://yourdomain.com/.well-known/acme-challenge/test.txt

首先创建一个文件夹,如 /srv/www/yoursite 作为网站目录
然后创建一个文件 test.txt

echo 'test' > /srv/www/yoursite/test.txt

下面是 nginx 的配置

server {
    server_name www.yourdomain.com yourdomain.com;

    location ^~ /.well-known/acme-challenge/ {
        alias /srv/www/yoursite/;
        try_files $uri =404;
    }
}

重启 nginx ,访问

curl http://yourdomain.com/.well-known/acme-challenge/test.txt

确保看到上面写入 test.txt 文件的内容 test ,

开始获取网站证书

把 acme-tiny 脚本保存到之前的 /root/ssl 目录

wget https://raw.githubusercontent.com/diafygi/acme-tiny/master/acme_tiny.py

指定账户私钥、CSR 以及网站目录,执行脚本:

python acme_tiny.py --account-key ./account.key --csr ./domain.csr --acme-dir /srv/www/yoursite/ > ./signed.crt

如果一切正常,当前目录下就会看到下面提示并生成一个 signed.crt,这就是申请好的证书文件。

Parsing account key...
Parsing CSR...
Registering account...
Registered!
Verifying www.yourdomain.com...
www.yourdomain.com verified!
Verifying yourdomain.com...
yourdomain.com verified!
Signing certificate...
Certificate signed!

拿到网站证书后,还要下载 Let's Encrypt 的中间证书,需要把中间证书和网站证书合在一起:

wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > intermediate.pem
cat signed.crt intermediate.pem > chained.pem

到这里,只要修改 Nginx 中有关证书的配置并 reload 服务即可:

ssl_certificate     /root/ssl/chained.pem;
ssl_certificate_key /root/ssl/domain.key;

下面是一份可用配置

server {
   listen 443;
   server_name www.yourdomain.com yourdomain.com;

   root html;
   index index.html index.htm;

   ssl on;
   ssl_certificate /root/ssl/chained.pem;
   ssl_certificate_key /root/ssl/domain.key;

   ssl_session_timeout 5m;

   ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
   ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA;
   ssl_prefer_server_ciphers on;

   location / {
       alias /srv/www/yoursite/;
       try_files $uri =404;
   }
}

server {
    listen 80;
    server_name www.yourdomain.com yourdomain.com;

    location ^~ /.well-known/acme-challenge/ {
        alias /srv/www/yoursite/;
        try_files $uri =404;
    }

    location / {
        rewrite ^/(.*) https://yourdomain.com/$1 permanent; 
    }
}

配置自动更新

touch renew_cert.sh
chmod a+x renew_cert.sh
vi renew_cert.sh

写入下面内容

#!/bin/bash

cd /root/ssl
python acme_tiny.py --account-key account.key --csr domain.csr --acme-dir /srv/www/yoursite/ > signed.crt || exit
wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > intermediate.pem
cat signed.crt intermediate.pem > chained.pem
service nginx reload

添加定时任务,crontab -e 加入以下内容:

0 0 1 * * /root/ssl/renew_cert.sh >/dev/null 2>&1

大功告成

acme-tiny https://github.com/diafygi/acme-tiny

0

See Also

Nearby


Discussion (8)

在树上1993
在树上1993 2018-01-12 03:56

问下站长,教程中是 nginx 的配置,repo 中的 youbbs 不是使用nginx吧,改怎么办呢?

0
ego008
ego008 2018-01-12 04:24

@在树上1993 进退都可以
教程中使用nginx 是为了方便说明,如果服务器部署是youbbs + nginx,就利用nginx 做反向代理到youbbs 的端口;
也可以利用上面的方式生成的 crt 和 key 直接扔给youbbs 调用,这样适合一个vps 单独部署youbbs,可以避免nginx 做反向代理损失约6%的性能。
周末有时间我再改一下youbbs,适配这个场景。

0
Chanmeim
Chanmeim 2018-01-12 05:01

@ego008 谢谢!期待周末的更新。

0
Chanmeim
Chanmeim 2018-01-12 15:17

@ego008 core.go 和 main.go 的修改,我在服务器网站目录里没看到对应的文件,怎么改?

//system/core.go
        CookieSecure   bool
  	CookieHttpOnly bool
  	OldSiteDomain  string
 +	TLSCrtFile     string
 +	TLSKeyFile     string
  }
  
  type SiteConf struct { 

https://github.com/ego008/goyoubbs/commit/98d1ce09453ae66d36fe7311c6a9e85a0f4d2211#diff-5467de60ded0da2fb4a582d6bfa29bdd

0
在树上1993
在树上1993 2018-01-13 00:05

@Chanmeim 网站的程序是编译后的,而 github 上是源码。

0
ego008
ego008 2018-01-13 00:36

@Chanmeim
上面的过程得到两个文件后

/root/ssl/chained.pem;
/root/ssl/domain.key;

把路径填到网站配置文件 config/config.yaml

Main:
    HttpPort: 80
    HttpsOn: true
    Domain: "youbbs.org"
    ...
    TLSCrtFile: "/root/ssl/chained.pem"
    TLSKeyFile: "/root/ssl/domain.key"
0
冒烟的蘑菇
冒烟的蘑菇 2018-05-25 16:35

golang 有个 crontab的库,可以拿来用,进一步简化部署者的心智负担~

0
z拽
z拽 2018-09-23 06:26

或者,let's encrypt 推出新版了,v2,通配符证书·

0
Login Topics