4、TLS/SSL加密通信:证书生成与管理、HTTPS强制配置、双向TLS认证
说到TLS/SSL,我估计在座的各位都不陌生。但说实话,很多人在配置Commissioner的时候,对证书这块就是“能用就行”的态度。嗯,我早年也这么干过,直到有一次在生产环境里,因为证书链不完整导致客户端握手失败,被运维同事追着骂了三天。
今天咱们就把这块彻底捋清楚。从证书生成,到HTTPS强制跳转,再到双向认证,一步到位。
4.1 证书体系:你得先搞明白谁是谁
先看一张图,把整个证书信任链串起来。你想想看,如果没有这张图,后面配置的时候很容易搞混。
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
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
| 特性 | 单向TLS | 双向TLS (mTLS) |
|---|---|---|
| 服务器验证客户端 | 否(仅验证服务器) | 是(双方互验) |
| 客户端需要证书 | 不需要 | 必须 |
| 安全性等级 | 中(防窃听) | 高(防窃听+防冒充) |
| 配置复杂度 | 低 | 中高 |
| 适用场景 | 公网Web服务 | 内部服务间通信、IoT设备管理 |
4.5 证书管理最佳实践
证书不是配完就完事了,后续管理才是大头。我整理了几条血泪教训换来的经验:
- 证书监控:部署证书过期监控脚本,提前30天告警。我见过太多因为证书过期导致服务中断的事故。
- 私钥保护:私钥文件权限设为600,定期审计谁有权限访问。最好用HSM或密钥管理服务。
- 证书吊销:维护一个CRL(证书吊销列表)或OCSP响应器。一旦有设备被攻破,立即吊销其证书。
- 自动化轮换:能用ACME协议自动续签就别手动。手动操作迟早会漏,相信我。
好了,这一章的内容就这些。证书这块看似琐碎,但它是整个通信安全的基石。你想想看,如果连加密通道都不可信,那后面的认证和授权全是空中楼阁。配置的时候多花点心思,后面能省很多麻烦。