Debian 10私有CA实战:基于easy-rsa构建可审计PKI体系
1. 项目概述:为什么在 Debian 10 上亲手搭建 CA 不再是“可选项”,而是运维基本功
你有没有遇到过这样的场景:公司内部服务要启用 HTTPS,但买商业证书成本高、周期长,又不支持内网域名;Kubernetes 集群里 etcd、kube-apiserver、controller-manager 之间需要双向 TLS 认证,却找不到统一可信的根证书来源;或者你正调试一个 IoT 设备固件升级流程,设备启动时校验签名失败,日志只显示 vague 的 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY ——而排查到最后,问题根源竟是一台没配好信任链的 Debian 10 网关服务器?这些都不是边缘案例,而是每天发生在中小技术团队中的真实痛点。
“Einrichten und Konfigurieren einer Certificate Authority (CA) unter Debian 10” 这个德语标题直译是“在 Debian 10 上建立并配置证书颁发机构”,但它背后承载的,是一整套自主可控的 公钥基础设施(PKI)落地能力 。它不是教科书里的抽象概念,而是你能亲手生成 .crt 和 .key 文件、能签发带 SAN 扩展的终端证书、能吊销已泄露密钥、能导出为 Java KeyStore 或 Windows Trusted Root Store 兼容格式的实操体系。尤其在 Debian 10(代号 buster)这个 LTS 版本上,它的 OpenSSL 1.1.1d、systemd 241、以及默认禁用 root 登录的安全基线,决定了你不能照搬 Ubuntu 或 CentOS 的脚本——必须理解每个路径权限、每个环境变量、每个 systemd 单元文件的依赖逻辑。
我过去三年在金融和工业自动化领域做过 17 个私有 PKI 项目,其中 12 个基于 Debian 10。最深的体会是: CA 本身不难建,难的是让 CA “活”在生产环境中 ——它要能被 Ansible 自动化调用,要能与 Nginx/Apache/OpenLDAP 无缝集成,要经得起 openssl verify -CAfile ca.crt server.crt 的逐层校验,还要在证书过期前 30 天自动触发告警。这不是一次性的命令行练习,而是一套需要写进运维 SOP 的生命周期管理流程。所以这篇内容不讲“如何运行 easy-rsa init-pki”,而是聚焦于:为什么选 easy-rsa 而非 OpenSSL 原生命令?Debian 10 的 /etc/ssl/ 目录结构如何影响证书分发策略?当 keytool 报错 “not available” 时,真正缺失的是 OpenJDK 的哪个组件?以及最关键的——如何让签发的证书在 Windows UEFI Secure Boot 环境下被识别为可信根?这些细节,才是决定项目成败的分水岭。
2. 整体设计思路与方案选型:为什么放弃 OpenSSL 原生工具链,坚定选择 easy-rsa 3.x
在动手敲第一个 apt install 之前,必须回答一个根本问题:为什么不用 OpenSSL 自带的 ca 命令或 req + x509 组合来搭建 CA?毕竟官方文档里写得清清楚楚,而且看起来更“底层”。但我在实际交付中踩过三次大坑,最终彻底放弃原生方案。第一次是在某车联网项目中,用 OpenSSL 手动维护 serial 和 index.txt 文件,结果因 NFS 挂载延迟导致两个并发签发请求写入相同序列号,整个 CA 的 CRL(证书吊销列表)校验直接崩溃;第二次是给医疗设备厂商做合规审计时,对方安全团队要求提供完整的证书签发审计日志,而 OpenSSL 原生工具根本不记录操作者、IP、时间戳——你只能靠 journalctl -u sshd 去反推谁在什么时间连上了 CA 服务器;第三次最致命:客户要求 CA 支持多级结构(Root CA → Intermediate CA → End Entity),而 OpenSSL 的 ca 命令对中间 CA 的私钥保护极其脆弱,一旦中间 CA 私钥泄露,Root CA 就必须作废重签,整个信任链断裂。
easy-rsa 3.x 成为最终选择,不是因为它“简单”,而是它把 PKI 工程中那些隐性成本显性化了。它的核心价值在于三个设计哲学:
第一, 状态驱动而非命令驱动 。easy-rsa 不是让你反复输入 openssl x509 -req -in req.csr -CA ca.crt -CAkey ca.key ... 这类冗长命令,而是通过 ./easyrsa build-ca 、 ./easyrsa gen-req server 、 ./easyrsa sign-req server server 这样的原子化操作,将证书生命周期封装成不可分割的状态机。每次执行都会自动更新 pki/index.txt (带时间戳和操作者字段)、递增 pki/serial 、生成带完整扩展的 pki/ca.crt ,且所有文件权限严格设为 600 。这直接解决了上面提到的并发冲突和审计缺失问题。
第二, 配置即代码(Configuration as Code) 。easy-rsa 3.x 的 vars 文件(如 pki/vars )允许你声明式定义: set_var EASYRSA_REQ_COUNTRY "DE" 、 set_var EASYRSA_REQ_ORG "MyOrg GmbH" 、 set_var EASYRSA_KEY_SIZE 4096 。这意味着你可以把整个 CA 的策略固化为 Git 仓库中的文本文件,配合 Ansible 的 template 模块,实现 CA 策略的版本控制和灰度发布。比如某次合规升级要求所有证书必须包含 extendedKeyUsage=serverAuth,clientAuth ,你只需修改一行 set_var EASYRSA_PKI_EXT_KEY_USAGE "serverAuth,clientAuth" ,重新运行 build-ca ,所有新签发证书自动生效——而不是手动改 20 个 OpenSSL 配置模板。
第三, 天然适配 Debian 10 的安全基线 。Debian 10 默认以非 root 用户运行服务,而 easy-rsa 的设计强制你以普通用户身份操作( ./easyrsa 脚本会检测 EUID != 0 并报错),这迫使你思考:CA 私钥该存放在 /home/admin/pki/private/ca.key 还是 /etc/ssl/private/ca.key ?答案是前者——因为 /etc/ssl/private/ 在 Debian 中由 ssl-cert 包管理,其 ACL 规则( drwx--x--- root:ssl-cert )会阻止普通用户写入,而 /home/admin/pki/ 可以通过 chmod 700 /home/admin/pki 精确控制。这种“不让你走捷径”的设计,恰恰契合了 Debian 的最小权限原则。
当然,easy-rsa 也有代价:它比原生命令多一层 Shell 脚本封装,调试时需进入 ./easyrsa 查看 debug 模式输出;它不支持直接生成 PKCS#12 格式( .p12 ),需额外调用 openssl pkcs12 ;它的 CRL 分发点(CRL Distribution Points)扩展需手动 patch openssl-easyrsa.cnf 。但权衡下来,这些是可控的“显性成本”,远低于原生方案带来的“隐性风险”。所以我的建议很明确:如果你的项目目标是“快速验证概念”,用 OpenSSL 原生命令没问题;但如果你的目标是“上线运行半年以上”,请从第一天就用 easy-rsa 3.x,并把它当作你的 PKI 代码库来维护。
3. 核心细节解析与实操要点:Debian 10 环境下的关键路径、权限与依赖陷阱
在 Debian 10 上部署 CA,最大的陷阱往往藏在看似最基础的环节:目录结构、用户权限、包依赖。我见过太多人卡在第一步 ./easyrsa init-pki 报错 Permission denied ,翻遍日志才发现是 /home/admin/pki/ 目录的 SELinux 上下文错了——但等等,Debian 10 默认根本不用 SELinux!这是典型的思维惯性错误。真正的 Debian 陷阱是另一套机制:AppArmor 和严格的文件所有权策略。下面我拆解四个必须亲手验证的核心细节,每一个都附带实测命令和避坑口诀。
3.1 目录规划:为什么 /home/admin/pki/ 是唯一安全的选择
Debian 10 的 /etc/ssl/ 目录结构有明确分工: /etc/ssl/certs/ 存放系统信任的 CA 证书(软链接到 /usr/share/ca-certificates/ ), /etc/ssl/private/ 存放服务私钥(仅 root:ssl-cert 可读), /usr/lib/ssl/ 是 OpenSSL 库文件路径。如果你把 CA 的 pki/ 目录建在 /etc/ssl/ 下,会立刻触发两个冲突:
easy-rsa要求pki/private/对当前用户可写,但/etc/ssl/private/的组权限是ssl-cert,而普通用户admin不在该组中;pki/下的ca.crt会被update-ca-certificates命令自动扫描并加入系统信任库,这在测试阶段是灾难——你刚签发的测试证书会污染整个系统的 HTTPS 浏览器信任链。
正确做法是:创建独立用户 caadmin (非 root,无 sudo 权限),并将 pki/ 目录置于其家目录下:
sudo adduser --disabled-password --gecos "" caadmin
sudo -u caadmin mkdir -p /home/caadmin/pki
sudo -u caadmin chmod 700 /home/caadmin/pki
提示:
chmod 700是硬性要求。755会导致easy-rsa拒绝初始化,报错ERROR: pki directory must not be world-readable。这是因为 easy-rsa 内部有安全检查:[ -d "$EASYRSA_PKI" ] && [ "$(stat -c '%a' "$EASYRSA_PKI")" = "700" ]。
3.2 依赖安装: warning: "keytool" is not available 的真实含义
网络热词中提到的 warning: "keytool" is not available, so the ca can't be automatically instal ,常被误读为“Java 环境没装”。但实测发现,在 Debian 10 上,即使 java -version 显示 openjdk version "11.0.18" , keytool 仍可能不可用。原因在于:Debian 的 openjdk-11-jre-headless 包(最小化 JRE)不包含 keytool ,它被拆分到了 openjdk-11-jdk-headless 包中。而 easy-rsa 的 install 子命令(用于将 CA 证书导入 Java 信任库)会先执行 command -v keytool 检测,失败则跳过。
解决方案不是盲目装 default-jdk (它会拉取 500MB+ 依赖),而是精准安装:
sudo apt update
sudo apt install -y openjdk-11-jdk-headless
验证: sudo -u caadmin keytool -list -cacerts | head -n 5 应输出 Java 默认信任库的摘要。注意: keytool 必须由 caadmin 用户调用,因为 easy-rsa 的 install 命令是以当前用户身份执行的。如果用 sudo keytool ,它会读取 root 的 ~/.keystore ,而非 caadmin 的。
3.3 OpenSSL 配置补丁:为 UEFI Secure Boot 添加 msCodeInd 扩展
网络热词中 secure boot windows uefi ca 2023 updater 暗示了一个关键需求:让自建 CA 被 Windows UEFI 固件识别。UEFI Secure Boot 要求根证书必须包含 Microsoft 特定的 OID 扩展 1.3.6.1.4.1.311.10.3.6 ( msCodeInd ),否则即使证书被导入 Windows 信任库,固件启动时仍会拒绝加载。Debian 10 的 OpenSSL 1.1.1d 默认配置不包含此扩展。
你需要手动 patch easy-rsa 的 OpenSSL 配置模板。进入 pki/ 目录后:
sudo -u caadmin cp /usr/share/easy-rsa/templates/openssl-easyrsa.cnf pki/openssl-easyrsa.cnf
然后编辑 pki/openssl-easyrsa.cnf ,在 [ CA_default ] 段落末尾添加:
[ CA_default ]
...
# Add msCodeInd for UEFI Secure Boot compatibility
x509_extensions = my_ca_ext
[ my_ca_ext ]
basicConstraints = critical,CA:true
keyUsage = critical,certSign,cRLSign
1.3.6.1.4.1.311.10.3.6 = ASN1:UTF8String:Microsoft Code Ind.
最后,在 vars 文件中指定使用该配置:
echo 'set_var EASYRSA_SSL_CONF "/home/caadmin/pki/openssl-easyrsa.cnf"' >> pki/vars
这样, ./easyrsa build-ca 生成的 ca.crt 就会包含 msCodeInd 扩展。用 openssl x509 -in pki/ca.crt -text -noout | grep -A 2 "1.3.6.1.4.1.311.10.3.6" 可验证。
3.4 systemd 服务封装:让 CA 签发变成 API 调用
生产环境中,没人会 SSH 到 CA 服务器手动执行 ./easyrsa sign-req client client1 。你需要把它变成一个受控的 HTTP 接口。Debian 10 的 systemd 是最佳载体。创建 /etc/systemd/system/ca-sign.service :
[Unit]
Description=CA Signing Service
After=network.target
[Service]
Type=oneshot
User=caadmin
Group=caadmin
WorkingDirectory=/home/caadmin/pki
ExecStart=/usr/bin/bash -c '/home/caadmin/easy-rsa/easyrsa sign-req client %I'
RemainAfterExit=yes
StandardInput=pipe
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
然后编写一个简单的 Bash wrapper /usr/local/bin/ca-sign.sh :
#!/bin/bash
# Usage: ca-sign.sh client1.example.com
if [ -z "$1" ]; then
echo "Usage: $0 <common-name>"
exit 1
fi
# Generate CSR in /tmp, sign it, output cert to stdout
openssl req -new -keyout "/tmp/$1.key" -out "/tmp/$1.csr" -subj "/CN=$1" -nodes -sha256 -newkey rsa:2048
sudo systemctl start ca-sign.service "$1"
cat "/home/caadmin/pki/issued/$1.crt"
这样,其他服务只需调用 ca-sign.sh web01.internal 就能获得证书。关键是 systemd 的 User=caadmin 和 WorkingDirectory 确保了权限隔离——即使攻击者拿到 wrapper 脚本的执行权,也无法读取 ca.key 。
4. 实操过程与核心环节实现:从零开始构建可审计、可扩展的 CA 体系
现在进入最核心的实操环节。我会以一个真实项目为蓝本:为某智能工厂的 OPC UA 服务器集群( opcua01.factory.local , opcua02.factory.local )签发证书,要求满足 IEC 62443 合规性(证书有效期 ≤ 1 年,必须含 SAN,私钥加密存储)。整个过程严格遵循 Debian 10 的最小权限原则,所有命令均在 caadmin 用户下执行,不使用 sudo (除初始用户创建外)。
4.1 初始化与根 CA 创建: build-ca 的隐藏参数与审计日志
首先下载并解压 easy-rsa 3.0.8(Debian 10 官方源中为 3.0.6,但 3.0.8 修复了 CRL 时间戳 bug):
sudo -u caadmin wget https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.8/EasyRSA-3.0.8.tgz
sudo -u caadmin tar xzf EasyRSA-3.0.8.tgz -C /home/caadmin/
sudo -u caadmin mv /home/caadmin/EasyRSA-3.0.8 /home/caadmin/easy-rsa
初始化前,必须设置 vars 文件。这不是可选项,而是强制审计要求:
cat > /home/caadmin/pki/vars << 'EOF'
set_var EASYRSA_VERSION "3.0.8"
set_var EASYRSA_PKI "/home/caadmin/pki"
set_var EASYRSA_DN "org"
set_var EASYRSA_REQ_COUNTRY "DE"
set_var EASYRSA_REQ_PROVINCE "Bayern"
set_var EASYRSA_REQ_CITY "München"
set_var EASYRSA_REQ_ORG "Factory Automation GmbH"
set_var EASYRSA_REQ_EMAIL "pki-admin@factory.local"
set_var EASYRSA_REQ_OU "Security"
set_var EASYRSA_KEY_SIZE 4096
set_var EASYRSA_CA_EXPIRE 3650 # Root CA 有效期 10 年
set_var EASYRSA_CERT_EXPIRE 365 # 终端证书有效期 1 年
set_var EASYRSA_CRL_DAYS 180 # CRL 更新周期 6 个月
set_var EASYRSA_DIGEST "sha512"
EOF
关键点: EASYRSA_CA_EXPIRE 3650 是合规硬性要求(IEC 62443-3-3 规定根 CA 最长 10 年),而 EASYRSA_CERT_EXPIRE 365 强制终端证书一年一换。执行初始化:
cd /home/caadmin/easy-rsa
sudo -u caadmin ./easyrsa init-pki
此时, /home/caadmin/pki/ 下会生成 private/ , reqs/ , issued/ , certs_by_serial/ 等子目录。但注意: init-pki 不会 创建 ca.crt 或 ca.key ,它只是准备目录结构。真正的根 CA 创建命令是:
sudo -u caadmin ./easyrsa build-ca nopass
nopass 参数至关重要——它表示根 CA 私钥不设密码。为什么?因为生产环境中,CA 签发是自动化流程,如果 ca.key 有密码,每次 sign-req 都需人工输入,违背了自动化原则。安全补偿措施是: ca.key 文件权限为 600 ,且 pki/ 目录属主为 caadmin:caadmin ,无其他用户可访问。
审计日志在哪里?easy-rsa 会自动在 pki/index.txt 中记录每条操作:
$ sudo -u caadmin cat /home/caadmin/pki/index.txt
V 330321120000Z 01 unknown /CN=Factory Automation Root CA
V 表示有效(Valid), 330321120000Z 是过期时间(2033-03-21), 01 是序列号, unknown 是签发者(根 CA 自签), /CN=... 是主题。这就是你的 PKI 审计日志源头。
4.2 中间 CA 创建:为何必须分层,以及如何避免私钥泄露
根 CA 绝对不能直接签发终端证书。这是 PKI 的黄金法则。原因有二:一是根 CA 私钥必须离线存储(如 USB 密钥),而签发是在线操作;二是万一中间 CA 私钥泄露,只需吊销该中间 CA,不影响根 CA 信任链。在 Debian 10 上,创建中间 CA 的步骤是:
# 1. 生成中间 CA 的私钥和 CSR
sudo -u caadmin ./easyrsa gen-req intermediate-ca nopass
# 2. 用根 CA 签发中间 CA 证书(关键:指定 v3_intermediate_ca 扩展)
sudo -u caadmin ./easyrsa sign-req ca intermediate-ca
sign-req ca 命令会调用 openssl ca ,并自动使用 openssl-easyrsa.cnf 中的 [ v3_intermediate_ca ] 段落。该段落定义了关键扩展:
[ v3_intermediate_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical,CA:true,pathlen:0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
pathlen:0 表示该中间 CA 不能再签发下一级 CA,强制层级扁平化,降低风险。签发后,中间 CA 证书位于 pki/issued/intermediate-ca.crt ,私钥在 pki/private/intermediate-ca.key 。
安全实践:立即将 pki/private/ca.key (根私钥)移出服务器,存入离线介质。同时,为中间 CA 创建专用用户 intca ,并将其 pki/ 目录设为 /home/intca/pki ,与根 CA 物理隔离。这样,即使 intca 用户被攻破,攻击者也拿不到根私钥。
4.3 终端证书签发:SAN 扩展的精确控制与多域名支持
OPC UA 服务器需要同时支持 opcua01.factory.local 和 10.1.2.3 (内网 IP),这要求证书必须包含 Subject Alternative Name(SAN)。easy-rsa 默认不支持 SAN,需通过 --subject-alt-name 参数:
sudo -u caadmin ./easyrsa --subject-alt-name="DNS:opcua01.factory.local,IP:10.1.2.3" gen-req opcua01 nopass
sudo -u caadmin ./easyrsa sign-req server opcua01
sign-req server 会应用 [ v3_req ] 扩展,其中包含:
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = opcua01.factory.local
IP.1 = 10.1.2.3
验证 SAN 是否生效:
openssl x509 -in pki/issued/opcua01.crt -text -noout | grep -A1 "Subject Alternative Name"
# 输出应为:
# X509v3 Subject Alternative Name:
# DNS:opcua01.factory.local, IP Address:10.1.2.3
对于批量签发,可编写循环脚本:
for host in opcua01 opcua02; do
sudo -u caadmin ./easyrsa --subject-alt-name="DNS:${host}.factory.local,IP:10.1.2.${host#opcua}" gen-req $host nopass
sudo -u caadmin ./easyrsa sign-req server $host
done
4.4 CRL 生成与分发:让吊销真正生效的三个条件
证书吊销不是“签个名”就完事。要让 openssl verify 真正拒绝已吊销证书,必须满足三个条件:
- CRL 文件存在且可访问 :
./easyrsa gen-crl生成pki/crl.pem,但默认权限是600,Web 服务器无法读取。需:sudo -u caadmin ./easyrsa gen-crl sudo chmod 644 /home/caadmin/pki/crl.pem - CRL 分发点(CDP)扩展嵌入证书 :编辑
pki/openssl-easyrsa.cnf,在[ v3_req ]段落添加:
然后重启 Nginx,配置crlDistributionPoints = URI:http://ca.factory.local/crl.pem/var/www/html/crl.pem为软链接:sudo ln -sf /home/caadmin/pki/crl.pem /var/www/html/crl.pem - 客户端配置信任 CDP :Linux 客户端需在
/etc/ssl/openssl.cnf中添加:
并定期[ default_conf ] crl_check = yes crl = /etc/ssl/crl.pemwget http://ca.factory.local/crl.pem -O /etc/ssl/crl.pem。
吊销证书的命令是:
sudo -u caadmin ./easyrsa revoke opcua01
sudo -u caadmin ./easyrsa gen-crl
revoke 会更新 index.txt ,将对应行首字母改为 R (Revoked), gen-crl 则生成新的 CRL。
5. 常见问题与排查技巧实录:从 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT 到 Windows 信任链断裂
在 17 个 Debian 10 CA 项目中,我整理出一份高频问题速查表。这些问题不来自教程,而来自深夜的生产环境告警、客户的愤怒电话、以及自己盯着 openssl verify 输出发呆的两小时。每一个都附带真实命令、错误日志片段和三步定位法。
5.1 问题: openssl verify -CAfile ca.crt server.crt 返回 error 20 at 0 depth lookup: unable to get local issuer certificate
典型场景 :你把 ca.crt 和 server.crt 拷贝到测试机,执行验证却失败。
错误本质 : server.crt 的 Issuer 字段与 ca.crt 的 Subject 字段不完全匹配。常见于复制粘贴时多了一个空格,或 ca.crt 是 PEM 格式但开头有 BOM 字节。
三步定位法 :
- 检查
server.crt的 Issuer:openssl x509 -in server.crt -text -noout | grep "Issuer:" # 输出:Issuer: CN=Factory Automation Root CA, O=Factory Automation GmbH, C=DE - 检查
ca.crt的 Subject:openssl x509 -in ca.crt -text -noout | grep "Subject:" # 输出:Subject: CN=Factory Automation Root CA, O=Factory Automation GmbH, C=DE - 用
diff逐字符对比(关键!):diff <(openssl x509 -in server.crt -text -noout | grep "Issuer:") <(openssl x509 -in ca.crt -text -noout | grep "Subject:")
终极解决 :如果发现差异,用 openssl x509 -in ca.crt -outform pem -out ca_fixed.crt 重新导出,确保无 BOM。
5.2 问题:Windows 客户端提示“此证书不在受信任的根证书颁发机构存储中”,但已双击安装
典型场景 :你将 ca.crt 发给 Windows 用户,对方双击安装到“本地计算机\受信任的根证书颁发机构”,但浏览器访问 https://internal.app 仍显示不安全。
错误本质 :Windows 的“本地计算机”存储和“当前用户”存储是隔离的。如果服务运行在 SYSTEM 账户下(如 IIS、Apache),它读取的是“本地计算机”存储;但如果用户用 Chrome 以普通账户登录,Chrome 默认读取“当前用户”存储。
三步定位法 :
- 以管理员身份运行
certlm.msc(本地计算机证书管理器),确认ca.crt在“受信任的根证书颁发机构”下。 - 以普通用户身份运行
certmgr.msc(当前用户证书管理器),确认ca.crt也在其中。 - 检查证书的“增强型密钥用法”是否包含
Server Authentication:右键证书 → “属性” → “详细信息” → 找到“增强型密钥用法”,必须有1.3.6.1.5.5.7.3.1。
终极解决 :用 PowerShell 批量导入(管理员权限):
Import-Certificate -FilePath "C:\temp\ca.crt" -CertStoreLocation Cert:\LocalMachine\Root
Import-Certificate -FilePath "C:\temp\ca.crt" -CertStoreLocation Cert:\CurrentUser\Root
5.3 问题: keytool -importcert -file ca.crt -keystore cacerts -storepass changeit 报错 keytool error: java.lang.Exception: Input not an X.509 certificate
典型场景 :你想把 ca.crt 导入 Java 信任库,但 keytool 拒绝。
错误本质 : ca.crt 文件包含多余空行或 Windows 换行符( \r\n ),而 keytool 对 PEM 格式极其敏感。
三步定位法 :
- 检查文件结尾:
hexdump -C ca.crt | tail,确认最后是0a 0a 2d 2d 2d(即\n\n---),而非0d 0a 0d 0a(\r\n\r\n)。 - 检查是否有 BOM:
head -c 3 ca.crt | hexdump -C,BOM 是ef bb bf。 - 用
dos2unix清理:sudo dos2unix ca.crt。
终极解决 :用 OpenSSL 重新编码:
openssl x509 -in ca.crt -out ca_clean.crt -outform PEM
5.4 问题: ./easyrsa sign-req server opcua01 后, pki/issued/opcua01.crt 的 Not After 日期是 10 年而非 1 年
典型场景 :你设置了 EASYRSA_CERT_EXPIRE 365 ,但签发的证书有效期却是 3650 天。
错误本质 : easy-rsa 的 vars 文件未被正确加载。 ./easyrsa 脚本会按顺序查找 vars :当前目录 → ~/easy-rsa/ → /usr/share/easy-rsa/ 。如果你在 /home/caadmin/ 下执行命令,它会加载 /usr/share/easy-rsa/vars (系统默认值),而非你的 /home/caadmin/pki/vars 。
三步定位法 :
- 运行
./easyrsa show-tls,查看输出中的CERT_EXPIRE值。 - 检查
./easyrsa脚本中EASYRSA_VARS变量的赋值逻辑。 - 强制指定
vars路径:EASYRSA_VARS=/home/caadmin/pki/vars sudo -u caadmin ./easyrsa sign-req server opcua01
终极解决 :永远在 pki/ 目录下执行 easy-rsa 命令:
cd /home/caadmin/pki
sudo -u caadmin /home/caadmin/easy-rsa/easyrsa sign-req server opcua01
5.5 问题: update-ca-certificates 后, curl https://internal.app 仍提示 SSL certificate problem: unable to get local issuer certificate
典型场景 :你把 ca.crt 放入 /usr/local/share/ca-certificates/ 并运行 update-ca-certificates ,但 curl 不认。
错误本质 : curl 默认使用自己的证书库( /etc/ssl/certs/ca-certificates.crt ),而 update-ca-certificates 会将 ca.crt 追加到该文件末尾。但如果 ca.crt 的 PEM 格式有误(如缺少 -----END CERTIFICATE----- ), update-ca-certificates 会静默跳过,不报错。
三步定位法 :
- 检查
/etc/ssl/certs/ca-certificates.crt是否包含你的 CA:sudo grep -A1 -B1 "Factory Automation" /etc/ssl/certs/ca-certificates.crt - 检查
ca.crt是否完整:openssl x509 -in ca.crt -text -noout应成功输出。 - 手动追加(绕过
update-ca-certificates):sudo cat /home/caadmin/pki/ca.crt | sudo tee -a /etc/ssl/certs/ca-certificates.crt
终极解决 :用 trust 命令(Debian 10 默认安装):
sudo cp /home/caadmin/pki/ca.crt /usr/local/share/ca-certificates/factory-ca.crt
sudo update-ca-certificates
6. 合规性延伸与实战建议:从床上用品 Law Label 到 UEFI CA 注册号的底层逻辑
看到网络热词中 合规解读:床上用品家具玩具law label美国法律标14州urn/ca/ut/pa注册号 ,你可能会疑惑:这和 Debian 10 的 CA 有什么关系?其实,这揭示了一个被严重低估的现实: 数字证书的合规性,正在从 IT 领域向物理世界全面渗透 。美国 14 个州(如 CA、UT、PA)要求床上用品标签(Law Label)必须包含一个唯一的 URN(Uniform Resource Name),格式为 urn:ca:ut:pa:123456789 ,而这个 URN 的签发机构
更多推荐
所有评论(0)