一 . 环境说明
本文详细介绍搭建外网根 CA 服务器的完整步骤,核心实现两大功能:生成根 CA 证书及相关密钥、通过 Nginx 提供 HTTP 服务供外部查询证书吊销列表(CRL)。
二 . 环境说明
- 操作系统:CentOS Stream 9
- 复现平台支持:天枢一体化虚拟仿真靶场平台
- 关键域名:www.testpki.com(根 CA 关联域名,需与 DNS 解析配置一致)
三 . 根 CA 基础环境搭建
3 .1 创建 CA 专用目录结构
实现目标:分离 CA 的证书、私钥、CRL、证书请求(CSR)等文件,确保私钥安全性(仅所有者可访问)。
操作命令如下:
# 创建多级目录:certs(证书)、crl(吊销列表)、newcerts(新签发证书)、private(私钥)、csr(证书请求)
[root@localhost ~]# mkdir -p /root/ca/{certs,crl,newcerts,private,csr}
[root@localhost ~]# cd /root/ca
# 私钥目录设置700权限(仅root可读写,防止泄露)
[root@localhost ca]# chmod 700 private
# 创建CA数据库文件(记录证书签发/吊销状态)
[root@localhost ca]# touch index.txt
3 .2 配置 OpenSSL
实现目标:定义 CA 的核心规则(如证书策略、扩展属性、文件路径等),确保后续证书生成符合 PKI 规范。
配置文件内容及说明 :
[root@localhost ca]# cat > openssl.cnf << 'EOF'
# -------------------------- 全局CA配置 --------------------------
[ ca ]
default_ca = CA_default # 指定默认CA配置段
# -------------------------- CA默认配置 --------------------------
[ CA_default ]
dir = /root/ca # CA根目录
certs = $dir/certs # 已签发证书存储路径
crl_dir = $dir/crl # CRL文件存储路径
new_certs_dir = $dir/newcerts # 新签发证书临时存储路径
database = $dir/index.txt # CA数据库(记录证书状态)
serial = $dir/serial # 证书序列号文件(初始需手动创建,如echo "01" > serial)
RANDFILE = $dir/private/.rand # 随机数文件(增强加密安全性)
private_key = $dir/private/root.ca.key.pem # 根CA私钥路径
certificate = $dir/certs/root.ca.cert.pem # 根CA证书路径
crl = $dir/crl/root.ca.crl.pem # 根CA CRL文件路径
crlnumber = $dir/crlnumber # CRL序列号文件(初始需手动创建,如echo "01" > crlnumber)
default_crl_days = 30 # CRL有效期(30天,到期需重新生成)
default_md = sha256 # 默认哈希算法(SHA-256,比SHA-1更安全)
preserve = no # 不保留证书请求文件
policy = policy_strict # 证书请求验证策略(严格匹配)
# -------------------------- 严格验证策略 --------------------------
[ policy_strict ]
countryName = match # 国家代码必须与根CA一致
# stateOrProvinceName = match # 省/州必须与根CA一致
organizationName = match # 组织名称必须与根CA一致
organizationalUnitName = optional # 部门名称可选
commonName = supplied # 通用名(CN)必须由请求方提供
# -------------------------- 证书请求(CSR)配置 --------------------------
[ req ]
default_bits = 4096 # 默认密钥长度(4096位,抗暴力破解能力更强)
distinguished_name = req_distinguished_name # 证书持有者信息字段定义
string_mask = utf8only # 仅支持UTF-8字符
default_md = sha256 # CSR默认哈希算法
# -------------------------- 证书持有者信息字段 --------------------------
[ req_distinguished_name ]
countryName = Country Name (2 letter code) # 国家代码(如CN)
stateOrProvinceName = State or Province Name # 省/州(如Chongqing)
localityName = Locality Name # 城市(如Chongqing)
organizationName = Organization Name # 组织名称(如DubheLjsec)
organizationalUnitName = Organizational Unit Name # 部门名称(如IT)
commonName = Common Name # 通用名(根CA需填域名www.testpki.com)
# -------------------------- 根CA证书扩展属性 --------------------------
[ v3_ca ]
subjectKeyIdentifier = hash # 证书持有者密钥标识(哈希值)
authorityKeyIdentifier = keyid:always,issuer # 签发者密钥标识(始终包含,关联根CA)
basicConstraints = critical, CA:true # 核心约束:标记为CA(不可省略)
keyUsage = critical, digitalSignature, cRLSign, keyCertSign # 密钥用途:数字签名、CRL签名、证书签名
# -------------------------- 中间CA证书扩展属性(预留) --------------------------
[ v3_intermediate_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0 # 核心约束:允许签发证书,但不能再签发下级CA(pathlen:0)
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
crlDistributionPoints = URI:http://www.testpki.com/crl/root.ca.crl.pem # CRL查询地址(HTTP)
nameConstraints = critical, @permitted_names # 名称约束:仅允许签发.cn域名的证书
# -------------------------- 名称约束规则 --------------------------
[ permitted_names ]
DNS.0 = .cn # 允许的DNS域名后缀(仅.cn)
EOF
关键补充操作:创建证书序列号文件和 CRL 序列号文件(OpenSSL 依赖这两个文件生成证书 / CRL)。
[root@localhost ca]# echo "01" > serial # 证书起始序列号(十六进制,后续递增)
[root@localhost ca]# echo "01" > crlnumber # CRL起始序列号 |
四 . 生成根 CA 核心组件
4 .1 生成根 CA 私钥
实现目标:私钥是根 CA 的核心身份凭证,用于签名证书和 CRL,需加密存储防止泄露。
操作命令及参数解释如下:
[root@localhost ca]# openssl genrsa -aes256 -out private/root.ca.key.pem 4096
Enter PEM pass phrase:dubhe # 私钥加密密码(自定义,需牢记,丢失无法恢复)
Verifying - Enter PEM pass phrase:dubhe
- -aes256:用 AES-256 算法加密私钥(比 DES 更安全)
- -out:指定私钥输出路径
- 4096:私钥长度(推荐 4096 位,兼容主流设备)
权限验证
确保私钥仅所有者可读写:
[root@localhost ca]# ls -l private/root.ca.key.pem
-rw-------. 1 root root 3456 Nov 18 05:40 private/root.ca.key.pem # 权限应为600
4 .2 生成根 CA 自签名证书
实现目标:根 CA 证书是信任链的起点,需自签名(无上级 CA 签发),有效期建议设置较长(如 20 年)。
操作命令及参数解释如下:
[root@localhost ca]# openssl req -config openssl.cnf -key private/root.ca.key.pem -new -x509 -days 7300 -sha256 -extensions v3_ca -out certs/root.ca.cert.pem
Enter pass phrase for private/root.ca.key.pem:dubhe # 输入私钥加密密码
- config:指定 OpenSSL 配置文件
- new:生成新的证书请求(CSR)
- x509:直接生成自签名证书(跳过 CSR 提交步骤,根 CA 专用)
- days 7300:证书有效期(7300 天≈20 年)
- extensions v3_ca:应用根 CA 扩展属性(标记为 CA 身份)
- out:指定证书输出路径
交互信息填写(示例):
You are about to be asked to enter information that will be incorporated into your certificate request.
-----
Country Name (2 letter code) []:CN # 国家代码(固定为CN)
State or Province Name []:Chongqing # 省/州(与配置文件策略匹配)
Locality Name []:Chongqing # 城市(与配置文件策略匹配)
Organization Name []:DubheLjsec # 组织名称(与配置文件策略匹配)
Organizational Unit Name []:IT # 部门名称(可选)
Common Name []:www.testpki.com # 通用名(必须为根CA关联域名)
证书验证:
确认证书是否有效(查看证书详情):
[root@localhost ca]# openssl x509 -in certs/root.ca.cert.pem -text -noout
# 输出应包含“CA:TRUE”(确认CA身份)、有效期、密钥用途等信息
4 .3 生成根 CA 证书吊销列表(CRL)
实现目标:CRL 记录已吊销的证书信息,客户端通过 HTTP 查询 CRL,验证证书是否有效。
操作命令如下:
[root@localhost ca]# openssl ca -config openssl.cnf -gencrl -out crl/root.ca.crl.pem
Using configuration from openssl.cnf
Enter pass phrase for /root/ca/private/root.ca.key.pem:dubhe # 输入私钥加密密码
CRL 验证:
查看 CRL 内容(初始无吊销证书,仅包含 CRL 有效期等信息):
[root@localhost ca]# openssl crl -in crl/root.ca.crl.pem -text -noout
# 输出应包含“Next Update”(下次更新时间,当前+30天)
五 . 部署 Nginx 提供 HTTP CRL 服务
5 .1 安装 Nginx
操作命令如下:
[root@localhost ca]# dnf install nginx -y
- 自动安装依赖包:centos-logos-httpd(HTTP 图标资源)、nginx-core(Nginx 核心组件)、nginx-filesystem(Nginx 目录结构)
5 .2 配置 CRL 文件访问路径
实现目标:将 CRL 文件放到 Nginx 的 Web 根目录,确保客户端可通过www.testpki.com/crl/root.ca…
操作命令如下:
# 创建CRL访问目录
[root@localhost ca]# mkdir -p /usr/share/nginx/html/crl
# 复制CRL文件到Web目录(保持文件权限可读取)
[root@localhost ca]# cp crl/root.ca.crl.pem /usr/share/nginx/html/crl/
# 确保Nginx可读取CRL文件
[root@localhost ca]# chmod 644 /usr/share/nginx/html/crl/root.ca.crl.pem
5 .3 启动 Nginx 并设置开机自启
操作命令如下:
# 启动Nginx服务
[root@localhost ca]# systemctl start nginx
# 设置开机自启(避免服务器重启后服务失效)
[root@localhost ca]# systemctl enable nginx --now
# 验证Nginx状态
[root@localhost ca]# systemctl status nginx
# 输出应包含“active (running)”表示服务正常
5 .4 开放防火墙 HTTP 端口
实现目标:允许外部客户端通过 HTTP(80 端口)访问 Nginx 服务。
操作命令如下:
# 永久开放HTTP服务(80端口)
[root@localhost ca]# firewall-cmd --permanent --add-service=http
# 返回结果:success
# 重新加载防火墙规则(使配置生效)
[root@localhost ca]# firewall-cmd --reload
# 返回结果:success
# 验证防火墙规则
[root@localhost ca]# firewall-cmd --list-services
# 输出应包含“http”
六. 在 pfSense 中配置 DNS 解析
实现目标:将www.testpki.com域名解析到根 CA 服务器的 IP(22.33.44.55),确保客户端能通过域名访问 CRL。
6.1 操作步骤(基于 pfSense 界面)
(1)登录 pfSense 管理界面:
通过天枢一体化虚拟仿真靶场平台Internet区域的WIN 访问pfSense 的 Web 管理地址(如https://3.4.5.1),输入管理员账号密码登录。
(2)进入 DNS 解析器配置:
点击顶部菜单 Services > DNS Resolver > General,确认 “Enable DNS resolver” 已勾选(启用 DNS 解析功能),“Listen Port” 保持默认53。
(3)添加 Host Override(域名映射):
点击 Host Overrides 下方的 Add 按钮,进入 “Edit Host Override” 页面。
填写配置项:
点击 Save 保存配置,再点击页面顶部的 Apply Changes 使配置生效。
七. 验证 CRL HTTP 访问功能
7.1 本地验证(根 CA 服务器上)
# 使用curl访问CRL(验证Nginx配置)
[root@localhost ca]# curl http://localhost/crl/root.ca.crl.pem
# 输出应为CRL文件的PEM格式内容(以“-----BEGIN X509 CRL-----”开头)
7.2 客户端验证(需在 pfSense 管理的网络内)
-
确保客户端已通过 pfSense 获取 DNS(或手动设置 DNS 为 pfSense 的 IP)。
-
在客户端浏览器或终端访问:www.testpki.com/crl/root.ca…
(1)成功:下载或显示 CRL 文件的 PEM 内容。
(2)失败:检查 DNS 解析(ping www.testpki.com是否返回22.33.44.55)、防火墙规则、Nginx 状态。