统一根证书
前言
之前在开发机(Ubuntu)上安装了Caddy、在 R2S(OpenWrt)上安装了Caddy,每安装一次 Caddy 都会自动生成根证书,客户端设备想访问站点就得导入两个根证书,不如这些 Caddy 都使用相同的根证书,那客户端设备也就只需要导入一个根证书即可。
1. 统一服务器根证书
证书所在目录如下:
# 使用 apt 安装时目录属于 caddy 用户的,需要切换到 root 才能查看
sudo -i
# 根证书路径
cd /var/lib/caddy/.local/share/caddy/pki/authorities/local/
# 站点证书路径
cd /var/lib/caddy/.local/share/caddy/certificates/local/
# 退出 root
exit
# 根证书路径
cd /.local/share/caddy/pki/authorities/local/
# 站点证书路径
cd /.local/share/caddy/certificates/local/
我打算统一为 OpenWrt 上 Caddy 生成的根证书,那么在 Ubuntu 系统的操作如下:
# 停止 Caddy
sudo systemctl stop caddy
# Caddy 根证书
sudo -i
# 删除根证书
sudo rm -rf /var/lib/caddy/.local/share/caddy/pki/authorities/local/*
# 删除站点证书
sudo rm -rf /var/lib/caddy/.local/share/caddy/certificates/local/*
# 复制证书(假设已经把 OpenWrt 上 /.local/share/caddy/pki/authorities/local/* 放在了 Ubuntu 的 ~/crt)
sudo cp -r ~/crt/* /var/lib/caddy/.local/share/caddy/pki/authorities/local/
# 设置权限
sudo chown -R caddy:caddy /var/lib/caddy/.local/share/caddy/pki/authorities/local
# 启动 Caddy
sudo systemctl start caddy
# 退出
exit
注意:当 Caddy 启动时会自动将根证书安装到服务器中,由于 Caddy 用户不是 root 用户,这个操作会失败,使用sudo systemctl status caddy
查看时会看到提示failed to install root certificate
。我们就需要手动安装根证书到系统:
# 手动复制证书
sudo cp /var/lib/caddy/.local/share/caddy/pki/authorities/local/root.crt /usr/local/share/ca-certificates/Caddy_Local_CA.crt
# 更新系统 CA 信任库
sudo update-ca-certificates
2. 统一 Windows 根证书
先把之前导入的证书都删掉,按Win+R
然后输入certmgr.msc
打开证书管理器,找到之前导入的证书,右键删除即可。接着再重新导入根证书。
以前导入到浏览器中的证书,也可以再在浏览器中找到并删除。浏览器不会将系统中的证书导入到浏览器中,它会直接信任系统中的证书。
3. 统一代理软件证书
由于 ios 系统是信任用户导入的证书,因此 ios 上的代理软件通常都会有 MitM(Man-in-the-Middle Attack,中间人攻击) 功能,这就需要导入一个根证书并信任,代理软件就会使用这个根证书签发站点证书,从而实现 MitM。这个根证书一般是由代理软件自动生成,有效期为一年,当然可以手动导入已有的证书,所以我们也可以将前面的根证书导入进来。
支持手动导入证书的代理软件有:Surge、Loon、Shadowrocket、QuantumultX,这里我们以 Surge 为例,其他软件类似。
# 要安装 openssl 命令。 pass:123 表示安装证书时的密码,若不想要密码则留空 pass:
openssl pkcs12 -export -in root.crt -inkey root.key -out root.p12 -name "dev" -passout pass:123
# 需要安装 base64 命令。 将 p12 证书转为 base64 字符串。
base64 -w 0 root.p12 > root.p12.b64
然后将root.p12.b64
中的内容复制到 Surge 配置文件的中的ca-p12
字段值,ca-passphrase
字段值为 123。之后安装证书到系统并信任即可。
虽然我们在上面导出导出 p12 证书时指定了 name 为 dev
,但是安装到手机时会发现证书名并不是 dev,而是Caddy Local Authority - 2025 ECC Root
,这显示的其实时根证书的 Subject,可以通过命令查看openssl x509 -in root.crt -noout -subject
。
如果一定强迫症想要显示指定的名字,只能重新生成根证书:
openssl req -new -x509 -key root.key -out root.crt -days 3650 -subj "/CN=dev"
这里-subj
的值是有格式要求的,/C=国家代码/ST=省份/L=城市/O=组织/OU=部门/CN=主机名或用户名/emailAddress=邮箱
,但不是所有值都必须。
4. 同一代理软件使用自定义证书
生成一个具有自定义标识的证书,然后导入代理软件中使用。
首先在 Surge、Loon、QuantumultX 中自动生成证书并安装,然后对比差异,发现在证书的约束方面各有不同,其中 Surge 的最为宽松,故按照 Surge 的标准来生成一个证书。
首先创建一个证书配置文件rootca.cnf
:
[ req ]
distinguished_name = req_distinguished_name
prompt = no
x509_extensions = v3_ca
default_bits = 2048
[ req_distinguished_name ]
O = Mayee
CN = Mayee Long-term support
[ v3_ca ]
basicConstraints = CA:TRUE
keyUsage = keyCertSign
subjectKeyIdentifier = hash
接着执行如下命令:
# 创建一个私钥(无密)。如果想要私钥加密则: openssl genpkey -algorithm RSA -aes256 -out RootCA.key -pkeyopt rsa_keygen_bits:2048
openssl genpkey -algorithm RSA -out RootCA.key -pkeyopt rsa_keygen_bits:2048
chmod 600 RootCA.key
# 使用私钥签发证书。-days 设置证书有效期(单位:天)。如果使用的加密私钥需输入私钥密码
openssl req -x509 -new -key RootCA.key -sha256 -days 3650 -out RootCA.crt -config rootca.cnf -extensions v3_ca
# 生成 p12 证书,需要设置一个导入密码
openssl pkcs12 -export -in RootCA.crt -inkey RootCA.key -out RootCA.p12 -name "Mayee Long-term support" -passout pass:123
# 将 p12 证书用 base64 编码,方便复制到代理软件中
base64 -w 0 RootCA.p12 > RootCA.p12.txt
在rootca.cnf
中也就[req_distinguished_name]
节下的内容自定义,其他不用动。
将 base64 后的证书及导入密码复制到代理软件中,然后在软件内安装证书会下载描述文件安装。注意,当前只有 Surge 支持自定义的证书安装描述文件,Loon 和 QuantumultX 安装描述文件时会提示错误,这并不是证书有问题,是因为它们只认自己生成的证书来作为描述文件安装。解决方法:证书只需要安装一次即可,如果有 Surge 就用它安装,安装好后其他软件只需要配置好就能用了;如果没有 Surge 就把 p12 文件传到手机中,然后点击文件安装,输入安装密码即可。
版权所有
版权归属:Mayee