给youBBS 配置免费https
goYouBBS 以前使用golang 官方的 golang.org/x/crypto/acme/autocert 库,配置很方便,自动注册、验证、更新,但Let’s Encrypt 停用 tls-sni 后,该库就废了。再去看看其它 ACME 的客户端,发现caddy 配置最方便,但必须用它做反向代理,这样性能损失约16%(nginx 约6%, 个人测试数据)。我只需要crt 和key 文件,让go 应用独占80、433 端口裸跑, acme-tiny 正适合我的需求。
如果用nginx 做反向代理请移步 https://www.youbbs.org/t/2169 47
下面是以 ubuntu/debian 64位系统为例说明整个过程
假设:网站路径 /srv/www/youbbs , 域名 youbbs.org、www.youbbs.org (已解析到该服务器)
下载最新的youbbs 程序包并解压
mkdir -p /srv/www/youbbs
cd /srv/www/youbbs
wget https://github.com/ego008/goyoubbs/releases/download/master/goyoubbs-linux-amd64.zip
wget https://github.com/ego008/goyoubbs/releases/download/master/site.zip
unzip goyoubbs-linux-amd64.zip
unzip site.zip
打开配置文件 config/config.yaml ,修改 端口为80 ,其它保留默认
HttpPort: 80
保存退出后运行
./goyoubbs &
确认在浏览器能打开网站网址
接下来需要用 openssl 来生成相关文件,所有相关的都放在 /root/ssl 下
mkdir -p /root/ssl
cd /root/ssl
openssl genrsa 4096 > account.key
openssl genrsa 4096 > domain.key
openssl req -new -sha256 -key domain.key -subj "/" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:youbbs.org,DNS:www.youbbs.org")) > domain.csr
最后一行命令如果提示 /etc/ssl/openssl.cnf 不存在,就搜索 openssl.cnf 看看它在哪儿,改上面命令行里 openssl.cnf 的路径。如果没有就输入下面命令按照提示输入:
openssl req -new -sha256 -key domain.key -out domain.csr
如果是单域名就使用下面一行
openssl req -new -sha256 -key domain.key -subj "/CN=yoursite.com" > domain.csr
建立一个文本文件test.txt 作路由测试
echo 'test' > /srv/www/youbbs/static/test.txt
打开网址
http://youbbs.org/.well-known/acme-challenge/test.txt
确保看到 test 才能继续往下 ......................... 让小主角 acme_tiny 登场,它的任务就一个
wget https://raw.githubusercontent.com/diafygi/acme-tiny/master/acme_tiny.py
python acme_tiny.py --account-key ./account.key --csr ./domain.csr --acme-dir /srv/www/youbbs/static/ > ./signed.crt
第一行是下载,第二行是acme_tiny.py 要干的活,注意:参数 acme-dir 的值是网站目录下的 static 文件夹
/srv/www/youbbs/static/
如果正常,就会看到下面提示,并在当前目录下成一个 signed.crt 文件,这就是申请好的证书文件。
Parsing account key...
Parsing CSR...
Registering account...
Registered!
Verifying www.youbbs.org...
www.youbbs.org verified!
Verifying youbbs.org...
youbbs.org verified!
Signing certificate...
Certificate signed!
拿到网站证书后,还要下载 Let's Encrypt 的中间证书,需要把中间证书和网站证书合在一起,否则一些在线SSL 安全检测会从A 降到B 级:
wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > intermediate.pem
cat signed.crt intermediate.pem > chained.pem
到这里,就得到了我们需要的两个文件:
/root/ssl/chained.pem
/root/ssl/domain.key
修改网站配置文件 vi /srv/www/youbbs/config/config.yaml 下面只列出修改的部分:
Main:
HttpPort: 80
HttpsOn: true
Domain: "youbbs.org"
...
TLSCrtFile: "/root/ssl/chained.pem"
TLSKeyFile: "/root/ssl/domain.key"
保存,退出
查找原来的进程,kill 掉后重新启动网站进程
# top | grep youbbs
8789 root 20 0 29236 8808 5576 S 0.0 6.7 0:03.95 goyoubbs
# kill 8789
# cd /srv/www/youbbs
# ./goyoubbs &
到这里在浏览器打开你的网站,就会自动转向 https
接下来配置自动更新
cd /root/ssl
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/youbbs/static/ > signed.crt || exit
wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > intermediate.pem
cat signed.crt intermediate.pem > chained.pem
supervisorctl restart youbbs
最后一行是重启网站进程的方式,我这里是用 supervisor 控制进程
添加定时任务,crontab -e 加入以下内容:
0 0 1 * * /root/ssl/renew_cert.sh >/dev/null 2>&1
顺便手动运行定时更新的脚本看看
/root/ssl/renew_cert.sh
执行 python acme_tiny.py --account-key ./account.key --csr ./domain.csr --acme-dir /srv/www/youbbs/static/ > ./signed.crt
出现下面的错误。网站目录是正确的。
在目录 static 下面创建 test.txt 文本之后,我访问第一个网址有 test 显示。但是第二个是404.http://bbs.lirencollege.xyz/static/test.txt
http://bbs.lirencollege.xyz/./well-known/acme-challenge/test.txt
@ego008 域名是直接指定到服务器 ip 的。bbs.lirencollege.xyz 是二级域名,而且只针对这一个。应该用哪个
openssl req -new -sha256 -key domain.key -subj "/CN=bbs.lirencollege.xyz" > domain.csr
openssl req -new -sha256 -key domain.key -subj "/" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:lirencollege.xyz,DNS:bbs.lirencollege.xyz")) > domain.csr
获取 CSR 时信息填写有什么需要注意吗?
@ego008 不能下载 .well-known/acme-challenge/ 目录下的一个文件。测试 test 显示的链接是可以打开的。```root@vultr:~/ssl# python acme_tiny.py --account-key ./account.key --csr ./domain.csr --acme-dir /srv/www/youbbs/static/ > ./signed.crt Parsing account key... Parsing CSR... Registering account... Registered! Verifying bbs.lirencollege.xyz... Traceback (most recent call last): File "acme_tiny.py", line 198, in
main(sys.argv[1:])
File "acme_tiny.py", line 194, in main
signed_crt = get_crt(args.account_key, args.csr, args.acme_dir, log=LOGGER, CA=args.ca)
File "acme_tiny.py", line 123, in get_crt
wellknown_path, wellknown_url))
ValueError: Wrote file to /srv/www/youbbs/static/m9SMPqtMtaXX0ItwW4w7QXZupjiGdvVMxY1lxkGwks0, but couldn't download http://bbs.lirencollege.xyz/.well-known/acme-challenge/m9SMPqtMtaXX0ItwW4w7QXZupjiGdvVMxY1lxkGwks0 ```
@ego008 遇到一个问题,请教一下。论坛 https://bbs.lirencollege.xyz 1 更换了域名 https://2049bbs.xyz 2 ,用 url forwarding redirect 方式转发到新的域名,但是似乎因为旧域名没有了证书,转发失败。 更换域名后,给新域名生成证书是会覆盖原来的吗?