ego008 avatar

给youBBS 配置免费https

🕐 by ego008

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

下面是以 ubuntu/debian 64位系统为例说明整个过程

假设:网站路径 /srv/www/youbbs , 域名 youbbs.org、www.youbbs.org (已解析到该服务器)

下载最新的youbbs 程序包并解压

1
2
3
4
5
6
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 ,其它保留默认

1
HttpPort: 80

保存退出后运行

1
./goyoubbs &

确认在浏览器能打开网站网址

接下来需要用 openssl 来生成相关文件,所有相关的都放在 /root/ssl 下

1
2
3
4
5
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 的路径。如果没有就输入下面命令按照提示输入:

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

如果是单域名就使用下面一行

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

建立一个文本文件test.txt 作路由测试

1
echo 'test' > /srv/www/youbbs/static/test.txt

打开网址

1
http://youbbs.org/.well-known/acme-challenge/test.txt

确保看到 test 才能继续往下 ......................... 让小主角 acme_tiny 登场,它的任务就一个

1
2
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 文件夹

1
/srv/www/youbbs/static/

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

1
2
3
4
5
6
7
8
9
10
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 级:

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

到这里,就得到了我们需要的两个文件:

1
2
/root/ssl/chained.pem
/root/ssl/domain.key

修改网站配置文件 vi /srv/www/youbbs/config/config.yaml 下面只列出修改的部分:

1
2
3
4
5
6
7
Main:
    HttpPort: 80
    HttpsOn: true
    Domain: "youbbs.org"
    ...
    TLSCrtFile: "/root/ssl/chained.pem"
    TLSKeyFile: "/root/ssl/domain.key"

保存,退出

查找原来的进程,kill 掉后重新启动网站进程

1
2
3
4
5
# 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

接下来配置自动更新

1
2
3
4
cd /root/ssl
touch renew_cert.sh
chmod a+x renew_cert.sh
vi renew_cert.sh

写入下面内容

Bash:
1
2
3
4
5
6
7
#!/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 加入以下内容:

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

顺便手动运行定时更新的脚本看看

1
/root/ssl/renew_cert.sh

💘 相关文章

评论

共28条关于"给youBBS 配置免费https"的评论

Chanmeim avatar
#1 Chanmeim 回复

执行 python acme_tiny.py --account-key ./account.key --csr ./domain.csr --acme-dir /srv/www/youbbs/static/ > ./signed.crt 出现下面的错误。网站目录是正确的。

Chanmeim avatar
#2 Chanmeim 回复

在目录 static 下面创建 test.txt 文本之后,我访问第一个网址有 test 显示。但是第二个是404.http://bbs.lirencollege.xyz/static/test.txt http://bbs.lirencollege.xyz/./well-known/acme-challenge/test.txt

ego008 avatar
#3 ego008 回复

@Chanmeim

1
http://yourdomain.com/.well-known/acme-challenge/test.txt
确认这个能访问

Chanmeim avatar
#4 Chanmeim 回复

@ego008 那我应该是在网页目录下创建 ./well-known/acme-challenge/ 目录,并放入 test.txt ,而不是放在 static 目录下?

ego008 avatar
#5 ego008 回复

@Chanmeim 看你的主程序包不是最新的 827bd84513d100e2b6c4637139618b9e ./goyoubbs-linux-amd64.zip

Chanmeim avatar
#6 Chanmeim 回复

@ego008 嗯嗯,更新 goyoubbs-linux-amd64.zip 之后可以访问 test.txt 了。 Thanks

Chanmeim avatar
#7 Chanmeim 回复

@ego008 #1 1楼的错误还是有。是因为域名 DNS 没有指向服务器的 DNS 吗?

ego008 avatar
#9 ego008 回复

域名直接 a 到服务器IP 试试

Chanmeim avatar
#10 Chanmeim 回复

@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 avatar
#12 ego008 回复

@Chanmeim

1
openssl req -new -sha256 -key domain.key -subj "/" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:bbs.lirencollege.xyz")) > domain.csr

Chanmeim avatar
#13 Chanmeim 回复

@ego008 openssl req -new -sha256 -key domain.key -out domain.csr 执行这个输入信息时,common name(server FQDN or YOUR name) 是填写正在申请证书的域名吗?(我填 bbs.lirencollege.xyz ?)

Chanmeim avatar
#15 Chanmeim 回复

@ego008 不能下载 .well-known/acme-challenge/ 目录下的一个文件。测试 test 显示的链接是可以打开的。

: python acme_tiny.py --account-key ./account.key --csr ./domain.csr --acme-dir /srv/www/youbbs/static/ > ./signed.crt
1
2
3
4
5
6
7
8
9
10
11
12
13
Parsing account key...
Parsing CSR...
Registering account...
Registered!
Verifying bbs.lirencollege.xyz...
Traceback (most recent call last):
  File "acme_tiny.py", line 198, in <module>
    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

youbbs avatar
#23 youbbs 回复

@Chanmeim

会覆盖,下面的命令可以试试

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

Chanmeim avatar
#24 Chanmeim 回复

@youbbs openssl req -new -sha256 -key domain.key -out domain.csr Common Name 也是都填两个域名吗?

coder avatar
#27 coder 回复

正在看大佬你的youbbs go的源码,想从头到尾捋一遍,才发现,写的代码量还是挺多的

写一条评论

Based on Golang + fastHTTP + sdb | go1.16.5 Processed in 2ms