4、TLS/SSL加密通信:证书生成与管理、HTTPS强制配置、双向TLS认证

说到TLS/SSL,我估计在座的各位都不陌生。但说实话,很多人在配置Commissioner的时候,对证书这块就是“能用就行”的态度。嗯,我早年也这么干过,直到有一次在生产环境里,因为证书链不完整导致客户端握手失败,被运维同事追着骂了三天。

今天咱们就把这块彻底捋清楚。从证书生成,到HTTPS强制跳转,再到双向认证,一步到位。

4.1 证书体系:你得先搞明白谁是谁

先看一张图,把整个证书信任链串起来。你想想看,如果没有这张图,后面配置的时候很容易搞混。

TLS/SSL证书信任链与通信流程 TLS/SSL 证书信任链与通信流程 根CA证书(自签名) 中间CA证书 服务器证书(Commissioner) 客户端证书(Agent) 说明: • 根CA证书是信任锚点,必须预埋在客户端信任库中。 • 双向认证时,客户端和服务器都需要出示证书并验证对方。 • 橙色虚线表示双向TLS认证中的相互验证过程。
我的习惯:生产环境一定要用中间CA,别直接用根CA签发服务器证书。一旦根CA私钥泄露,整个信任链都得重建。我在一个金融项目里吃过这个亏,后来重建了300多台设备的证书,那叫一个酸爽。

4.2 证书生成与管理:自己动手,丰衣足食

Commissioner支持多种证书来源。我个人最推荐的是用OpenSSL自建CA体系,灵活且可控。

4.2.1 生成根CA证书

这是整个信任链的基石。私钥一定要保管好,建议加密存储。

# 生成根CA私钥(带加密)
openssl genrsa -aes256 -out ca-key.pem 4096

# 生成根CA证书(自签名,有效期10年)
openssl req -x509 -new -nodes -key ca-key.pem \
  -sha256 -days 3650 -out ca-cert.pem \
  -subj "/C=CN/ST=Beijing/L=Beijing/O=MyOrg/CN=MyRootCA"

4.2.2 生成服务器证书(Commissioner)

这里要注意,Common Name (CN) 必须填Commissioner所在服务器的域名或IP,否则客户端会报证书名不匹配。

# 生成服务器私钥
openssl genrsa -out server-key.pem 2048

# 生成证书签名请求 (CSR)
openssl req -new -key server-key.pem -out server.csr \
  -subj "/C=CN/ST=Beijing/L=Beijing/O=MyOrg/CN=commissioner.example.com"

# 使用根CA签发服务器证书(有效期2年)
openssl x509 -req -in server.csr -CA ca-cert.pem -CAkey ca-key.pem \
  -CAcreateserial -out server-cert.pem -days 730 -sha256

4.2.3 生成客户端证书(用于双向认证)

步骤和服务器证书类似,但CN一般填客户端标识,比如设备ID或用户名。

# 生成客户端私钥
openssl genrsa -out client-key.pem 2048

# 生成CSR
openssl req -new -key client-key.pem -out client.csr \
  -subj "/C=CN/ST=Beijing/L=Beijing/O=MyOrg/CN=device-001"

# 签发客户端证书
openssl x509 -req -in client.csr -CA ca-cert.pem -CAkey ca-key.pem \
  -CAcreateserial -out client-cert.pem -days 365 -sha256
我曾经踩过的坑:证书有效期设得太长(比如10年),结果发现私钥泄露了,不得不紧急吊销。现在我的标准是:根CA 5-10年,中间CA 3-5年,服务器和客户端证书最多2年。定期轮换才是王道。

4.3 HTTPS强制配置:别让明文流量裸奔

Commissioner默认可能同时监听HTTP和HTTPS。但生产环境里,我建议直接关掉HTTP,或者把所有HTTP请求301重定向到HTTPS。

4.3.1 在Commissioner配置文件中启用HTTPS

找到 commissioner.conf 或 config.yaml,修改以下关键项:

# 示例配置片段
tls:
  enabled: true
  cert_file: "/etc/commissioner/certs/server-cert.pem"
  key_file: "/etc/commissioner/certs/server-key.pem"
  ca_file: "/etc/commissioner/certs/ca-cert.pem"   # 用于验证客户端证书
  min_version: "1.2"                                # 禁止TLS 1.0/1.1
  cipher_suites:                                    # 只允许强加密套件
    - "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
    - "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"

http:
  enabled: false                                    # 关掉明文HTTP
  # 或者保留但强制跳转
  redirect_to_https: true

4.3.2 验证HTTPS配置

配置完重启服务,用curl测试一下:

# 测试HTTPS是否正常
curl -v --cacert ca-cert.pem https://commissioner.example.com:8443/health

# 测试HTTP是否被重定向
curl -v http://commissioner.example.com:8080/health
# 应该返回 301 Moved Permanently
小技巧:用 --tlsv1.2 参数强制指定TLS版本,可以确认服务端没有降级攻击的风险。我每次上线前都会跑一遍这个检查。

4.4 双向TLS认证:你验证我,我也验证你

单向TLS只验证服务器身份,客户端是匿名的。但在Commissioner的场景里,Agent连接Server时,Server也需要确认Agent是不是合法的。说白了,就是双方都出示证书,互相验明正身。

4.4.1 配置双向认证

在Commissioner端,开启客户端证书验证:

tls:
  client_auth: "require"          # 可选值: none, optional, require
  # require 表示强制客户端提供证书,否则拒绝连接

在Agent端,配置时带上客户端证书和私钥:

# Agent连接配置示例
commissioner:
  url: "https://commissioner.example.com:8443"
  tls:
    ca_file: "/etc/agent/certs/ca-cert.pem"
    cert_file: "/etc/agent/certs/client-cert.pem"
    key_file: "/etc/agent/certs/client-key.pem"

4.4.2 验证双向认证

用curl模拟客户端证书认证:

# 不带客户端证书,应该被拒绝
curl -v --cacert ca-cert.pem https://commissioner.example.com:8443/health
# 预期结果: 400 Bad Request / TLS handshake error

# 带上客户端证书,应该成功
curl -v --cacert ca-cert.pem \
  --cert client-cert.pem --key client-key.pem \
  https://commissioner.example.com:8443/health
# 预期结果: 200 OK
关键对比:单向 vs 双向TLS
特性 单向TLS 双向TLS (mTLS)
服务器验证客户端 否(仅验证服务器) 是(双方互验)
客户端需要证书 不需要 必须
安全性等级 中(防窃听) 高(防窃听+防冒充)
配置复杂度 低 中高
适用场景 公网Web服务 内部服务间通信、IoT设备管理
注意:开启双向认证后,所有未携带合法证书的客户端都会被拒绝。我曾经在测试环境忘了给Agent配证书,结果排查了半天才发现是证书没下发。建议先在staging环境验证完整流程,再推生产。

4.5 证书管理最佳实践

证书不是配完就完事了,后续管理才是大头。我整理了几条血泪教训换来的经验:

  • 证书监控:部署证书过期监控脚本,提前30天告警。我见过太多因为证书过期导致服务中断的事故。
  • 私钥保护:私钥文件权限设为600,定期审计谁有权限访问。最好用HSM或密钥管理服务。
  • 证书吊销:维护一个CRL(证书吊销列表)或OCSP响应器。一旦有设备被攻破,立即吊销其证书。
  • 自动化轮换:能用ACME协议自动续签就别手动。手动操作迟早会漏,相信我。

好了,这一章的内容就这些。证书这块看似琐碎,但它是整个通信安全的基石。你想想看,如果连加密通道都不可信,那后面的认证和授权全是空中楼阁。配置的时候多花点心思,后面能省很多麻烦。