阅读视图

聊聊Nginx 1.25和HTTP/3

距离之前闲聊Nginx,已经过去快3年。而之前在Nginx 1.16时,由Cloudflare为支持HTTP/3推出的quiche项目,也已过去了近4年。

时间过得很快,终于在前几周,5月23日,Nginx出1.25.0,Mainline版本合并QUIC分支,支持HTTP/3。

更新当天就已经更新到最新版本,只是没写文章。通过这里可查看本站HTTP/3支持状态。

原生支持,肯定是比较开心,毕竟不用去维护过多额外的东西。

我使用的是OpenSSL,虽然官方提示会不支持Early Data,但暂时不是很有所谓。

使用BoringSSL肯定是最好的,之前也看过一些测试结果,BoringSSL各方面性能还是比较不错的(可能部分项目不如OpenSSL 1.1)。但是不支持双证书,而且OCSP stapling需要补丁支持,不能说不好吧,但总觉得差点什么。等什么时候,感觉Early Data或者有其他特性更重要,可能会转变吧。

最近Nginx更新到1.25.1后,HTTP/2 Server Push支持被移除了。也因此,我之前做的Patch,取自CF的HTTP2 HPACK Encoding支持不再可用(因为它是以Server Push为基础)。目前对于最新版Nginx,Patch只保留了Dynamic TLS Record支持。

kn007/patchSomething could be public patches
Github1718433

对于此,个人觉得可以接受,因为这个功能我很少用,只在早期用过几次Server Push。主要是觉得不够实用,或者说没这个需求。但基于此而应用的HTTP2 HPACK Encoding支持倒是挺实用,它可以抑制被攻击时的影响,并且减少流量开销。因为HTTP/2 Server Push移除而丢失这一功能支持,稍微有点可惜了。

转载请注明转自:kn007的个人博客的《聊聊Nginx 1.25和HTTP/3

  •  

使用acme.sh和acme-dns申请Google免费泛域名SSL证书

上来,先给传送门,不想看唠叨,想直接进入正题,请点这里

好久不见,甚是想念,上一篇文章发表时间已经过去很久。这段时间确实忙,也有很多私人事,导致一直没更新。

说起来,Let’s Encrypt出来这么多年,我推荐过给很多人,但自己从未使用过,也没有实际操作过任何ACME客户端(想想其实也不是太好)。

恰遇目前域名两年期泛域名证书(所谓野卡)即将过期,赞助商也不再赞助了,所以考虑使用像Let’s Encrypt如此的免费自动化的证书颁发机构颁发的证书。

可能为了安全、防止滥用等各种原因(我猜,没有细究),这些机构颁发的证书大多为90天上限(也有付费给一年期的)。

也就是说一年下来,证书需要不断更新,而非一年一次或两年一次,手动更新证书蛮累的。所以催生基于使用ACME协议的自动签发客户端来获取证书。

这么多年过去了,ACME客户端发展得十分成熟,常见有Certbot、acme.sh等等,感兴趣的也可以通过这里查看其它客户端。

运气不错的是今年3月底Google刚刚推出了公共证书服务,即与Let’s Encrypt类似的自动化公共证书管理服务。目前处于内测阶段,签发服务需使用Google Cloud的API(Public Certificate Authority API),除激活该API外,还需申请资格。

它颁发的证书和Google各项服务使用相同的根证书GTS(Google Trust Services)。其OCSP有国内节点,未受阻断且速度不错。但GTS的ACME Endpoint被阻断,国内服务器正常来说因为访问不了签发服务器而签发不了。

这次我将使用acme.sh来签发其泛域名证书。因为泛域名证书是必须通过域名的TXT记录(也叫ACME Challenge)来验证域名归属的,所以顺便讲解如何使用acme-dns来自动生成验证记录。

也主要是我使用的域名服务商(Google Domain)并未提供REST API,也就是无法通过请求API来自动更新TXT记录(手动更新岂不累死)。所以只能使用acme-dns这个项目,它提供了一个专门用于TXT记录更新的简单API。

其实即便你的域名服务商他们提供API服务的话,我也十分推荐你使用ACME-DNS这个项目,因为这个API,它只有它自身域的TXT控制权限,而非你的域名的所有控制权限。如果你不想配置太多(或者说不在意太多),也可以参考acme.sh的DNSAPI说明来配置,这看个人选择。


啰嗦够多,让我们进入正题。

本文基于CentOS 8 x64和Nginx。Windows Server用户可以88了。

首先让我们申请下Google公共证书授权服务的使用资格。

这一过程,需要你准备一个GCP(Google Cloud Platform)账号,然后通过这里创建项目。

项目名称和项目ID随意,也可以自定义好记的,一会申请API时要用。

创建好了之后,去启用“Public Certificate Authority API”,找不到的可以通过如下地址(记得修改项目ID):

https://console.cloud.google.com/apis/library/publicca.googleapis.com?project=你的项目ID

接着到这里填写申请表申请测试资格。

带星号部分需要填写:

1.“电子邮箱地址”填写可以收到邮件的邮箱,审核通过后会发邮件给你(建议与GCP帐号相同)。

2.“Google Cloud Project ID”填写你刚刚新建好的项目ID(不记得就去GCP仪表盘复制黏贴一下)。

3.“Estimated usage”填写每季度你大概会签发多少张证书(根据你的实际)。

稍等一两个工作日,待你收到来自“Public CA Preview Access”发给你的邮件后,进入GCP,在你创建的项目下,在右上角点击“激活 Cloud Shell”,打开Google Cloud Shell。

在底部出来的Console命令行下,输入:

gcloud beta publicca external-account-keys create

可能会弹出提示让您授权访问权限,授权即可。随后便会得到b64MacKeykeyId,类似如下:

Created an external account key
[b64MacKey: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
keyId: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx]

得到密钥一会在acme.sh配置中使用,该密钥是有有效期的,所以要尽快使用。

接下来,让我们进入第二步,在服务器端,打开Shell界面,安装acme.sh和acme-dns。

yum install ca-certificates curl wget golang socat openssl openssl-libs openssl-devel crontabs -y
wget -O - https://get.acme.sh | sh
ldconfig
export GOPATH=/tmp/acme-dns/.lib
cd /tmp
git clone https://github.com/joohoi/acme-dns.git
cd acme-dns
go build
mkdir -p /etc/acme-dns/
cat acme-dns.service > /usr/lib/systemd/system/acme-dns.service
cp config.cfg /etc/acme-dns/config.cfg
mv acme-dns /usr/local/bin/acme-dns
setcap 'cap_net_bind_service=+ep' /usr/local/bin/acme-dns
useradd --system --user-group -m -d /var/lib/acme-dns acme-dns
systemctl daemon-reload

以上是我根据官方文档重写的脚本,复制黏贴即可。

其实修改acme-dns配置文件我也有自动化脚本,但每个人实际情况不一样,还是希望大家动手配置下。

如果你想懒且域名服务商提供API,那么你可以跳过下面这部分,查看acme.sh的配置。

那么在acme-dns配置文件/etc/acme-dns/config.cfg中,建议修改下面列举的这几项:

1.listen,你可以使用如“你域名对外IP:53”,或者监听全局的“:53”。
2.protocol,建议只选择“udp”。
3.domain和nsname按照实际(如果你会配的话),不会配的话,建议两个都使用“auth.你的域名”。
4.nsadmin填写你的邮箱,也可以保持不变。
5.records,根据第三点填写,如果你按我说的配,那么将本项内容中所有“auth.example.org”替换为“auth.你的域名”;“198.51.100.1”替换为“你域名对外IP:53”。
6.ip可以填写为“127.0.0.1”,如果你只是自用。
7.port不要与你服务器其他服务的端口冲突,你可以使用如“8053”。
8.tls填写为“none”,如果你刚刚第六点填写的ip项是对外ip,那么建议使用“letsencrypt”并设置acme_cache_dir为“/var/lib/acme-dns/cert”。

根据上面的配置后,记得放通你服务器防火墙的53端口流量。

然后,在Shell中,执行(根据上面写的第六、七、八点):

systemctl enable acme-dns
systemctl start acme-dns

export ACMEDNS_BASE_URL="http://127.0.0.1:8053"
curl -s -X POST $ACMEDNS_BASE_URL/register | python2 -m json.tool > /tmp/acme-dns.challenges
export ACMEDNS_USERNAME="$(cat /tmp/acme-dns.challenges | awk -F"\"" '/username/{print $4}')"
export ACMEDNS_PASSWORD="$(cat /tmp/acme-dns.challenges | awk -F"\"" '/password/{print $4}')"
export ACMEDNS_SUBDOMAIN="$(cat /tmp/acme-dns.challenges | awk -F"\"" '/subdomain/{print $4}')"
echo "FULLDOMAIN = $(cat /tmp/acme-dns.challenges | awk -F"\"" '/fulldomain/{print $4}')"

curl -X POST \
  -H "X-Api-User: $ACMEDNS_USERNAME" \
  -H "X-Api-Key: $ACMEDNS_PASSWORD" \
  -d "{\"subdomain\": \"$ACMEDNS_SUBDOMAIN\", \"txt\": \"___validation_token_received_from_the_ca___\"}" \
  $ACMEDNS_BASE_URL/update

看下最后得到的结果是不是:

{"txt": "___validation_token_received_from_the_ca___"}

是的话,说明acme-dns已经正常了。

再然后根据上面写的第五点和刚刚得到的FULLDOMAIN去你的域名服务商添加记录,如:

auth A 你域名对外IP
auth NS auth.你的域名
_acme-challenge.你的域名 CNAME FULLDOMAIN

那么在等DNS生效的期间,让我们来配置acme.sh。

acme.sh --set-default-ca --server google
acme.sh --register-account --server google -m <你的GCP邮箱> --eab-hmac-key <b64MacKey> --eab-kid <keyId>

acme.sh --issue --server google -d '*.你的域名' -d 你的域名 \
 --dns dns_acmedns --keylength ec-256 \
--cert-file /path/to/server.ecc.crt \
--key-file /path/to/server.ecc.key \
--fullchain-file /path/to/bundle.ecc.crt \
--ca-file /path/to/issuer.ecc.crt \
--reloadcmd "systemctl reload nginx"

acme.sh --issue --server google -d '*.你的域名' -d 你的域名 \
--dns dns_acmedns --keylength 2048 \
--cert-file /path/to/server.rsa.crt \
--key-file /path/to/server.rsa.key \
--fullchain-file /path/to/bundle.rsa.crt \
--ca-file /path/to/issuer.rsa.crt \
--reloadcmd "systemctl reload nginx"

这样就获得ECC和RSA双证书,其中/path/to/是你存放证书的路径(参考nginx配置文件)。

如果你刚刚没有配置acme-dns且你域名服务商提供了相应API,你可以参考acme.sh的DNSAPI说明找到你的域名服务商来配置,替换刚刚命令中dns_acmedns为对标的域名服务商API插件名。

至此,acme.sh和acme-dns便配置完了。现在acme.sh会自动每60天为你重新签约证书并重新加载nginx。

如果你需要邮件提醒的话,可以查阅acme.sh的set-notify说明

值得注意的是目前Google的ECC证书不提供完整ECDSA链,仅最终用户证书为ECC(Let's Encrypt是全链ECC)。

它也不支持Punycode编码的域名(类似xn--1.xn--2这种),虽然较其他签发商,它支持了IP地址签注,但仅限IP地址块的所有者进行验证。

还有就是GTS证书本身也使用到GlobalSign的根证书,所以兼容性会比较好。

最后补充一些图片:

来自“Public CA Preview Access”发过来的邮件:

证书路径:


其他备注:

启用“Public Certificate Authority API”,除了使用文中所提链接,也可以通过Cloud Shell执行以下命令启用:

gcloud config set project 你的项目ID
gcloud services enable publicca.googleapis.com

注意,如果你已经在你创建的项目页面下的话,可以不输入第一行。

转载请注明转自:kn007的个人博客的《使用acme.sh和acme-dns申请Google免费泛域名SSL证书

  •  

快来解锁你的年度互动报告

前几天在瓦匠那儿看到了博友的年度报告,再加上年底各种 APP 都在发总结,就想着不如也从评论者的角度做一份试试。前端页面交给 AI 出,我来处理数据获取,折腾了几个晚上,最后就有了这份博友的年度互动报告。数据不复杂,主要图个好玩,欢迎点进来看看。
  •  

阿里云ESA体验及缓存规则配置

阿里云近期也推出了边缘安全加速ESA免费版,我试了试还挺顺手。它操作和EdgeOne差不多,但号称无限流量,对我这种用阿里云服务器的小站也更友好。我照着教程配了缓存规则,把静态图片、CSS这些都缓存起来,登录用户和动态页面不缓存。网站速度明显快了不少。
  •  

让网站对 AI 更友好:一次关于 llms.txt 的探索与插件开发

最近发现了llms.txt这个新东西。它就像是专门给AI看的“网站说明书”。为了给自己的博客配上标准规范的llms.txt,我试了好多WordPress插件都不满意,格式太乱。干脆自己动手写了一个,把页面、文章的分类和摘要都利用起来,让AI能更准确地抓取内容。算是为网站跟上AI潮流做了一点小努力。
  •  

WordPress中使用ip2region实现评论者IP归属地

我将博客的IP归属地查询从纯真IP数据库换成了ip2region。因为纯真dat版已停更,czdb版的IPv6没什么用,而ip2region v3.0+免费、格式规范且支持IPv6。对于博客评论,城市级精度完全足够。本地数据库还有稳定、快速、保护隐私三大优势。现已成功集成,效果不错。
  •  

博客里的星河:评论数据与青春回声

整理过去18年的两万八千多条评论,像在清点一片星空,六成是你们的声音。四千多个独立邮箱里,大多如流星划过,感谢那瞬间的闪耀;另一些则成了长明的星,用上万条评论温暖着这片宇宙。特别想念那10位评论过百的老友,你们的博客或许已熄灯,但字句还带着温度。愿下一个十年,还能看见你们的星光。
  •  
❌