# 一、背景
V8 入口NGINX 配置为HTTPS,采用自签名 Root CA 证书,Java 容器中的 Chromium(JVPuppeteer)访问页面时会出现如下异常:
com.ruiyun.jvppeteer.exception.NavigateException:
net::ERR_CERT_AUTHORITY_INVALID
原因:
- Chromium 不信任服务器证书
- JVM 默认也不信任内部 Root CA
- 需要同时导入 Linux 系统证书库 和 JVM cacerts
研发在代码中其实可以配置类似
skip-verify证书的相关操作,但是目前多数服务并没有进行配置。因此现场还是需要利用一些手段进行绕过。后续是具体如果自签证书并信任证书的一个操作过程。
# 二、生成证书
#!/bin/bash
set -e
mkdir -p certs
cd certs
echo "========== 1. 生成 Root CA 私钥 =========="
openssl genrsa -out rootCA.key 4096
cat > root-ca.cnf <<EOF
[req]
distinguished_name=req_distinguished_name
x509_extensions=v3_ca
prompt=no
[req_distinguished_name]
C=CN
ST=Beijing
L=Beijing
O=Internal
OU=IT
CN=Internal Root CA
[v3_ca]
basicConstraints=critical,CA:true
keyUsage=critical,keyCertSign,cRLSign
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always
EOF
echo "========== 2. 生成 Root CA =========="
openssl req \
-x509 \
-new \
-nodes \
-key rootCA.key \
-sha256 \
-days 3650 \
-config root-ca.cnf \
-out rootCA.crt
echo "========== 3. 生成 Server 私钥 =========="
openssl genrsa -out server.key 2048
cat > server.cnf <<EOF
[req]
distinguished_name=req_distinguished_name
req_extensions=req_ext
prompt=no
[req_distinguished_name]
C=CN
ST=Beijing
L=Beijing
O=Internal
OU=IT
CN=10.12.43.166 # 根据实际情况调整
[req_ext]
subjectAltName=@alt_names
[alt_names]
IP.1=10.12.43.166 # 根据实际情况调整
IP.2=10.12.43.98 # 根据实际情况调整
IP.3=10.12.43.120 # 根据实际情况调整
IP.4=192.168.11.14 # 根据实际情况调整
IP.5=192.168.11.30 # 根据实际情况调整
IP.6=172.18.32.188 # 根据实际情况调整
EOF
echo "========== 4. 生成 CSR =========="
openssl req \
-new \
-key server.key \
-config server.cnf \
-out server.csr
cat > server-ext.cnf <<EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=critical,CA:false
keyUsage=critical,digitalSignature,keyEncipherment
extendedKeyUsage=serverAuth
subjectAltName=@alt_names
[alt_names]
IP.1=10.12.43.166 # 根据实际情况调整
IP.2=10.12.43.98 # 根据实际情况调整
IP.3=10.12.43.120 # 根据实际情况调整
IP.4=192.168.11.14 # 根据实际情况调整
IP.5=192.168.11.30 # 根据实际情况调整
IP.6=172.18.32.188 # 根据实际情况调整
EOF
echo "========== 5. Root CA 签发 Server =========="
openssl x509 \
-req \
-in server.csr \
-CA rootCA.crt \
-CAkey rootCA.key \
-CAcreateserial \
-out server.crt \
-days 3650 \
-sha256 \
-extfile server-ext.cnf
echo
echo "========== 完成 =========="
echo
echo "生成文件:"
echo "rootCA.crt"
echo "rootCA.key"
echo "server.crt"
echo "server.key"
echo
echo "验证 Root CA:"
openssl x509 -in rootCA.crt -text -noout | grep -A4 "Basic Constraints"
echo
echo "验证 Server:"
openssl x509 -in server.crt -text -noout | grep -A10 "X509v3 extensions"
执行生成脚本:
chmod +x gen-certs.sh
./gen-certs.sh
生成如下文件:
rootCA.crt # Root CA 根证书
rootCA.key # Root CA 私钥(请妥善保管)
server.crt # 服务端证书
server.key # 服务端私钥
Nginx(或 synginx)配置:
ssl_certificate server.crt;
ssl_certificate_key server.key;
注意
服务端必须使用
server.crt,不要直接使用rootCA.crt。
# 三、Kubernetes 启动时自动导入 Root CA
在 Deployment 的 command 或 args 中增加如下命令:
# 我是把证书放到了公共桶里,一定要放在java启动命令之前
wget http://<MinioIP>/seeyon-public/rootCA.crt \
-O /etc/pki/ca-trust/source/anchors/rootCA.crt \
&& update-ca-trust extract \
&& keytool \
-importcert \
-noprompt \
-trustcacerts \
-alias internal-root \
-file /etc/pki/ca-trust/source/anchors/rootCA.crt \
-keystore /apps/jdk/jre/lib/security/cacerts \
-storepass changeit
作用:
- 下载 Root CA
- 导入 Linux 系统证书
- 导入 JVM cacerts
# 四、手动导入 Root CA(调试使用)
# 1、导入 Linux 系统证书
复制证书:
cp rootCA.crt /etc/pki/ca-trust/source/anchors/
刷新系统证书:
update-ca-trust extract
# 2、导入 JVM
# Java 8
keytool \
-importcert \
-noprompt \
-trustcacerts \
-alias internal-root \
-file /etc/pki/ca-trust/source/anchors/rootCA.crt \
-keystore /apps/jdk/jre/lib/security/cacerts \
-storepass changeit
# Java 11+
keytool \
-importcert \
-noprompt \
-trustcacerts \
-alias internal-root \
-file /etc/pki/ca-trust/source/anchors/rootCA.crt \
-keystore $JAVA_HOME/lib/security/cacerts \
-storepass changeit
# 五、验证
# 1、验证系统证书
trust list | grep -A3 "Internal Root CA"
应看到:
label: Internal Root CA
trust: anchor
# 2、验证 JVM
keytool -list \
-keystore /apps/jdk/jre/lib/security/cacerts \
-storepass changeit | grep internal-root
应输出:
internal-root
# 3、验证 HTTPS
curl https://10.12.43.166
如果返回页面(例如 302 跳转),说明系统已经信任 Root CA。
# 六、注意事项
rootCA.key为 Root CA 私钥,仅用于签发服务器证书,严禁部署到业务服务器或容器中。- 服务端仅部署
server.crt和server.key。 - 所有客户端(Linux、Java、Windows 等)只需导入
rootCA.crt即可建立信任关系。 - 如果服务端证书续期或重新签发,只要仍由该
Root CA签发,客户端无需重新导入 Root CA。 - 如果业务使用的是 Java + Chromium(JVPuppeteer),建议同时导入 Linux 系统证书 和 JVM cacerts,避免 Java 网络请求与 Chromium 页面访问出现不同的证书信任行为。
编撰人:zhenxy
快速跳转