PKI、证书与OpenSSL详解
客户端连接与证书验证问题
在进行OpenVPN客户端连接时,我们需要配置客户端文件。示例配置如下:
remote-cert-tls server
tls-auth /etc/openvpn/cookbook/ta.key 1
ca /etc/openvpn/cookbook/ca.crt
cert /etc/openvpn/cookbook/client4.crt
key /etc/openvpn/cookbook/client4.key
将上述内容保存为
example4-6-client.conf
文件,然后启动客户端:
[root@client]# openvpn --config example4-6-client.conf
此时,客户端无法连接,服务器日志文件会显示如下错误信息:
[...] TLS_ERROR: BIO read tls_read_plaintext error: error:140890B2:SSL
routines:SSL3_GET_CLIENT_CERTIFICATE:no certificate returned
[...] TLS Error: TLS object -> incoming plaintext read error
[...] TLS Error: TLS handshake failed
这表明客户端因证书无效而不被允许连接。其工作原理是,每次客户端连接到OpenVPN服务器时,服务器会检查证书吊销列表(CRL),查看客户端证书是否在列表中。若在列表中,服务器将拒绝接受客户端证书,连接无法建立。
需要注意的是,生成CRL和保持其更新是两个不同的问题。为确保CRL保持最新,最好设置一个cron作业在夜间更新服务器的CRL文件。不过,OpenVPN在CRL更新方面存在一个问题:每次客户端连接时,服务器都会尝试访问CRL文件。若文件不存在或无法访问,服务器进程将报错终止,而不是暂时拒绝客户端访问。
检查过期/吊销的证书
此部分旨在深入了解OpenSSL CA命令的内部机制,展示如何将证书状态从“有效”更改为“吊销”或“过期”。
准备工作
使用之前的方法设置客户端和服务器证书,该过程可在CentOS 6 Linux、Windows或Mac OS上运行。
操作步骤
- 设置环境变量:
$ cd /etc/openvpn/cookbook
$ . ./vars
$ export KEY_NAME=
$ export OPENSSL_CONF=/etc/openvpn/cookbook/openssl-1.0.0.cnf
- 查询证书状态:
$ cd keys
$ openssl x509 -serial -noout -in server.crt
serial=01
$ openssl ca -status 01
Using configuration from /etc/openvpn/cookbook/openssl-1.0.0.cnf
01=Valid (V)
这表明OpenVPN服务器证书仍然有效。
3. 查看已吊销证书的状态:
$ openssl x509 -serial -noout -in client4.crt
serial=06
$ openssl ca -status 06
Using configuration from /etc/openvpn/cookbook/openssl-1.0.0.cnf
08=Revoked (R)
-
查看
/etc/openvpn/cookbook/keys目录下的index.txt文件:
V 181013174924Z 01 unknown .../CN=openvpnserver
R 190117155337Z 160422155408Z 06 unknown .../CN=client4
-
修改
index.txt文件,将R替换为E,并清空第三字段:
E 190117155337Z 08 unknown .../CN=client4
- 再次检查证书状态:
$ openssl ca -status 06
Using configuration from /etc/openvpn/cookbook/openssl-1.0.0.cnf
08=Expired (E)
- 重新生成CRL:
$ openssl ca -gencrl -out crl.pem
$ openssl crl -text -noout -in crl.pem | head -8
Certificate Revocation List (CRL):
Version 1 (0x0)
Signature Algorithm: sha256WithRSAEncryption
Issuer: /C=US/O=Cookbook 2.4/CN=Cookbook 2.4
CA/emailAddress=openvpn@example.com
Last Update: Apr 26 15:02:01 2016 GMT
Next Update: May 26 15:02:01 2016 GMT
No Revoked Certificates.
Signature Algorithm: sha256WithRSAEncryption
这表明证书已被“取消吊销”。其工作原理是,OpenSSL的
ca
命令通过查看
index.txt
文件生成CRL,每行以
R
开头的条目会被添加到CRL中,然后使用CA私钥对CRL进行加密签名。通过将吊销证书的状态更改为
E
甚至
V
,可以取消吊销证书。
中间CA的设置
中间CA(Intermediate CA)的优势在于可以更严格地保护顶级CA(根CA),并可将中间CA分发给负责生成服务器和客户端证书的人员。
准备工作
同样使用之前的方法设置客户端和服务器证书,可在CentOS 6 Linux、Windows或Mac OS上运行。
操作步骤
- 创建中间CA证书:
$ cd /etc/openvpn/cookbook/
$ . ./vars
$ ./build-inter IntermediateCA
- 验证该证书是否可作为证书颁发机构:
$ openssl x509 -text -noout -in keys/IntermediateCA.crt \
| grep -C 1 CA
X509v3 Basic Constraints:
CA:TRUE
Signature Algorithm: sha1WithRSAEncryption
-
为中间CA创建新的
keys目录:
$ mkdir -m 700 -p IntermediateCA/keys
$ cp [a-z]* IntermediateCA
$ cd IntermediateCA
-
编辑新目录中的
vars文件,修改EASY_RSA行:
export EASY_RSA=/etc/openvpn/cookbook/IntermediateCA
-
加载新的
vars文件并设置keys目录:
$ . ./vars
$ ./clean-all
$ cp ../keys/IntermediateCA.crt keys/ca.crt
$ cp ../keys/IntermediateCA.key keys/ca.key
- 创建第一个中间证书:
$ ./build-key IntermediateClient
- 验证证书的颁发者是否为新的中间CA:
$ openssl x509 -subject -issuer -noout -in keys/IntermediateClient.crt
subject= /C=US/O=Cookbook 2.4/CN=IntermediateClient
issuer= /C=US/O=Cookbook 2.4/CN=subCA/emailAddress=...
- 验证证书的有效性:
$ cd /etc/openvpn/cookbook
$ cat keys/ca.crt IntermediateCA/keys/ca.crt > ca+subca.pem
$ cp IntermediateCA/keys/IntermediateClient.{crt,key} .
$ openssl verify -CAfile ca+subca.pem IntermediateClient.crt
IntermediateClient.crt: OK
其工作原理是,中间CA证书有权作为证书颁发机构,可自行签署新证书。中间CA需要一个与根CA目录结构相似的目录结构,设置好目录结构并复制必要文件后,创建客户端证书并验证其有效性。为进行验证,需要将根CA公钥证书和中间CA公钥证书合并到一个文件中,用于整个证书链的验证。
多CA设置 - 堆叠与使用
capath
指令
此设置的目标是创建一个OpenVPN环境,其中客户端证书由“仅客户端”CA签名,服务器证书由不同的“仅服务器”CA签名,以提供额外的操作安全性,防止中间人攻击。
准备工作
使用之前的方法设置服务器证书,使用上一个示例中的客户端证书和中间CA证书。服务器运行CentOS 6 Linux和OpenVPN 2.3.10,客户端运行Fedora 22 Linux和OpenVPN 2.3.10。
操作步骤
-
创建服务器配置文件
example4-9-server.conf:
tls-server
proto udp
port 1194
dev tun
server 192.168.200.0 255.255.255.0
ca /etc/openvpn/cookbook/ca+subca.pem
cert /etc/openvpn/cookbook/server.crt
key /etc/openvpn/cookbook/server.key
dh /etc/openvpn/cookbook/dh1024.pem
tls-auth /etc/openvpn/cookbook/ta.key 0
persist-key
persist-tun
keepalive 10 60
user nobody
group nobody
daemon
log-append /var/log/openvpn.log
- 启动服务器:
[root@server]# openvpn --config example4-9-server.conf
-
创建客户端配置文件
example4-9-client.conf:
client
proto udp
remote openvpnserver.example.com
port 1194
dev tun
nobind
tls-auth /etc/openvpn/cookbook/ta.key 1
ca /etc/openvpn/cookbook/ca.crt
cert /etc/openvpn/cookbook/IntermediateClient.crt
key /etc/openvpn/cookbook/IntermediateClient.key
- 启动客户端:
[root@client]# openvpn --config example4-9-client.conf
- 查看服务器日志,可看到客户端使用中间CA创建的证书进行连接:
... openvpnclient:49283 [IntermediateClient] Peer Connection
Initiated with openvpnclient:49283
其工作原理是,客户端连接服务器时,会将客户端公钥证书发送给服务器进行验证,服务器需要访问完整的证书链,因此将根CA证书和中间CA证书堆叠在一起,以便客户端能够连接到服务器。反之,客户端连接时,服务器公钥证书也会发送给客户端,由于服务器证书最初由根CA签名,因此客户端无需指定完整的证书堆栈。若忘记在OpenVPN服务器配置文件中指定
ca+subca.pem
文件,将收到错误信息。
使用
–capath
指令
另一种在OpenVPN服务器配置中包含多个CA和CRL的方法是使用
capath
指令:
capath /etc/openvpn/cookbook/ca-dir
该目录需要包含所有CA证书和CRL,并使用特殊的命名约定:
- 所有CA证书的名称必须等于CA证书的哈希值,并以
.0
结尾。
- 所有CRL的名称必须等于CA证书的哈希值,并以
.r0
结尾。
对于根CA和中间CA,可以使用以下命令实现:
$ cd /etc/openvpn/cookbook
$ mkdir ca-dir
$ openssl x509 -hash -noout -in keys/ca.crt
bcd54da9
$ cp keys/ca.crt ca-dir/bcd54da9.0
$ cp keys/crl.pem ca-dir/bcd54da9.r0
$ openssl x509 -hash -noout -in IntermediateCA/keys/ca.crt
1f5e4734
$ cp IntermediateCA/keys/ca.crt ca-dir/1f5e4734.0
$ cp IntermediateCA/keys/crl.pem ca-dir/1f5e4734.r0
当使用多个不同的CA证书和相应的CRL时,这种方法比“堆叠”文件更容易管理。
确定使用的加密库
从OpenVPN 2.3开始,可以使用OpenSSL加密库或PolarSSL库(现称为“mbedTLS”)构建OpenVPN。此部分将展示如何确定使用的加密库及其运行时版本号。
准备工作
使用之前的方法设置服务器证书,使用上一个示例中的客户端证书和中间CA证书。计算机运行Fedora 22 Linux和OpenVPN 2.3.10,同时支持OpenSSL和PolarSSL构建。保留之前的服务器配置文件
basic-udp-server.conf
。
操作步骤
- 使用标准配置文件启动常规版本的OpenVPN:
[root@server]# openvpn --config basic-udp-server.conf
- 检查服务器日志文件的前几行:
OpenVPN 2.3.10 x86_64-redhat-linux-gnu [SSL (OpenSSL)] [LZO]
[EPOLL] [PKCS11] [MH] [IPv6] built on Jan 4 2016
library versions: OpenSSL 1.0.1e-fips 11 Feb 2013, LZO 2.08
- 停止服务器:
[root@server]# kill <openvpn进程ID>
-
修改系统的
LD_LIBRARY_PATH指向更新版本的OpenSSL:
[root@server]# export LD_LIBRARY_PATH=..../openssl-1.0.1s
[root@server]# openvpn --config basic-udp-server.conf
- 再次检查服务器日志文件的前几行:
OpenVPN 2.3.10 x86_64-redhat-linux-gnu [SSL (OpenSSL)] [LZO]
[EPOLL] [PKCS11] [MH] [IPv6] built on Jan 4 2016
library versions: OpenSSL 1.0.1s 1 Mar 2016, LZO 2.08
- 再次停止服务器:
[root@server]# kill <openvpn进程ID>
- 切换到PolarSSL构建的OpenVPN版本并启动服务器:
[root@server]# .../openvpn-2.3.10polarssl/openvpn --config basic-udp-server.conf
- 检查服务器日志文件的前几行:
OpenVPN 2.3.10 x86_64-unknown-linux-gnu [SSL (PolarSSL)] [LZO]
[EPOLL] [MH] [IPv6] built on Apr 27 2016
library versions: PolarSSL 1.3.16, LZO 2.08
其工作原理是,OpenVPN启动时会加载并初始化加密库,此时会获取并打印库的版本字符串。通过使用不同的加密库构建版本,我们可以看到服务器日志文件的前几行发生了变化。加密库的类型和构建版本决定了OpenVPN的一些高级功能,库版本字符串为调试非工作设置提供了重要信息。
OpenSSL和PolarSSL的加密特性
从OpenVPN 2.3开始,可以使用OpenSSL或PolarSSL库构建OpenVPN。此部分将展示这两个加密库的一些关键差异。
准备工作
使用之前的方法设置服务器证书,使用上一个示例中的客户端证书和中间CA证书。计算机运行Fedora 22 Linux和OpenVPN 2.3.10,同时支持OpenSSL和PolarSSL构建。
操作步骤
-
使用
--show-ciphers选项启动常规版本的OpenVPN:
[root@server]# openvpn --show-ciphers
OpenVPN将列出所有可用的加密算法,对于OpenSSL 1.0+,加密算法数量可能超过50种。常见的加密算法如下表所示:
| 加密算法 | 密钥位数 | 说明 |
| ---- | ---- | ---- |
| BF-CBC | 128位 | 默认密钥(可变) |
| BF-CFB | 128位 | 默认密钥(可变)(TLS客户端/服务器…) |
| BF-OFB | 128位 | 默认密钥(可变)(TLS客户端/服务器…) |
| AES-128-CBC | 128位 | 默认密钥(固定) |
| AES-128-OFB | 128位 | 默认密钥(固定)(TLS客户端…) |
| AES-128-CFB | 128位 | 默认密钥(固定)(TLS客户端…) |
| AES-256-CBC | 256位 | 默认密钥(固定) |
| AES-256-OFB | 256位 | 默认密钥(固定)(TLS客户端…) |
| AES-256-CFB | 256位 | 默认密钥(固定)(TLS客户端…) |
| AES-128-CFB1 | 128位 | 默认密钥(固定)(TLS客户端…) |
| AES-192-CFB1 | 192位 | 默认密钥(固定)(TLS客户端…) |
| AES-256-CFB1 | 256位 | 默认密钥(固定)(TLS客户端…) |
| AES-128-CFB8 | 128位 | 默认密钥(固定)(TLS客户端…) |
| AES-192-CFB8 | 192位 | 默认密钥(固定)(TLS客户端…) |
| AES-256-CFB8 | 256位 | 默认密钥(固定)(TLS客户端…) |
- 切换到PolarSSL构建的OpenVPN版本并重新运行相同的命令:
[root@server]# .../openvpn-2.3.10polarssl/openvpn --show-ciphers
此时列出的加密算法如下表所示:
| 加密算法 | 密钥位数 |
| ---- | ---- |
| AES-128-CBC | 128位 |
| AES-192-CBC | 192位 |
| AES-256-CBC | 256位 |
| BF-CBC | 128位 |
| CAMELLIA-128-CBC | 128位 |
| CAMELLIA-192-CBC | 192位 |
| CAMELLIA-256-CBC | 256位 |
| DES-CBC | 64位 |
| DES-EDE-CBC | 128位 |
| DES-EDE3-CBC | 192位 |
-
使用
--show-digests选项启动常规版本的OpenVPN:
[root@server]# openvpn --show-digests
OpenVPN将列出所有可用的HMAC算法,可使用
--auth
选项指定。此列表可能超过25个条目,以下是最常用的算法:
| 算法 | 摘要大小 |
| ---- | ---- |
| MD5 | 128位 |
| SHA | 160位 |
| RIPEMD160 | 160位 |
| ecdsa-with-SHA1 | 160位 |
| SHA224 | 224位 |
| SHA256 | 256位 |
| SHA384 | 384位 |
| SHA512 | 512位 |
- 切换到PolarSSL构建的OpenVPN版本并重新运行相同的命令:
[root@server]# .../openvpn-2.3.10polarssl/openvpn --show-digests
此时列出的HMAC算法如下表所示:
| 算法 | 密钥位数 |
| ---- | ---- |
| SHA512 | 512位 |
| SHA384 | 384位 |
| SHA256 | 256位 |
通过上述操作,我们可以清楚地看到OpenSSL和PolarSSL在加密算法和HMAC算法支持上的差异。在实际应用中,可以根据具体需求选择合适的加密库。同时,了解这些差异有助于在配置OpenVPN时做出更合适的决策,确保网络通信的安全性和性能。例如,如果需要更多的加密算法选择,OpenSSL可能是更好的选择;而如果对某些特定的加密算法有需求,PolarSSL可能更适合。此外,在调试OpenVPN配置时,这些信息也能帮助我们快速定位问题。总之,深入了解OpenSSL和PolarSSL的加密特性对于构建安全可靠的OpenVPN网络至关重要。
PKI、证书与OpenSSL详解(续)
加密特性差异总结与应用建议
通过前面的操作,我们已经详细了解了OpenSSL和PolarSSL在加密算法和HMAC算法上的差异。下面通过一个表格来更直观地对比两者:
| 特性 | OpenSSL | PolarSSL |
| ---- | ---- | ---- |
| 可用加密算法数量 | 超过50种(OpenSSL 1.0+) | 相对较少 |
| 常见加密算法 | BF - CBC、BF - CFB、BF - OFB、AES多种模式等 | AES - 128 - CBC、AES - 192 - CBC等部分算法 |
| 可用HMAC算法数量 | 超过25种 | 3种(SHA512、SHA384、SHA256) |
| 常见HMAC算法 | MD5、SHA、RIPEMD160等 | SHA512、SHA384、SHA256 |
根据这些差异,我们可以给出以下应用建议:
-
需要丰富加密选项
:如果你的应用场景需要更多的加密算法和HMAC算法选择,以满足不同的安全需求或兼容性要求,那么OpenSSL是更好的选择。例如,在一个复杂的企业网络环境中,可能需要支持多种不同的客户端设备和协议,OpenSSL的丰富选项可以提供更多的灵活性。
-
特定加密需求
:如果你的应用对某些特定的加密算法有要求,并且PolarSSL支持这些算法,那么可以考虑使用PolarSSL。比如,只需要使用AES - 128 - CBC、SHA512等算法,PolarSSL可以提供简洁的解决方案。
-
资源受限环境
:PolarSSL相对OpenSSL可能在资源占用上更有优势,在资源受限的设备或环境中,PolarSSL可能是更合适的选择。
不同场景下的配置选择
在实际应用中,我们需要根据不同的场景来选择合适的配置。下面通过一个mermaid流程图来展示配置选择的决策过程:
graph TD;
A[确定应用场景] --> B{是否需要丰富加密选项};
B -- 是 --> C[选择OpenSSL];
B -- 否 --> D{是否有特定加密需求};
D -- 是 --> E{PolarSSL是否支持};
E -- 是 --> F[选择PolarSSL];
E -- 否 --> C;
D -- 否 --> G{是否资源受限};
G -- 是 --> F;
G -- 否 --> C;
证书管理的最佳实践
在整个PKI和证书管理过程中,有一些最佳实践可以帮助我们更好地保障系统的安全性和稳定性。
-
定期更新CRL
:如前面所述,CRL的更新非常重要。为了确保CRL保持最新,建议设置一个cron作业在夜间更新服务器的CRL文件。示例cron作业配置如下:
0 2 * * * root openssl ca -gencrl -out /etc/openvpn/cookbook/crl.pem
这个cron作业会在每天凌晨2点更新CRL文件。
-
备份证书和密钥
:定期备份所有的证书和密钥文件,以防数据丢失或损坏。可以使用以下命令将证书和密钥备份到指定目录:
mkdir /backup/openvpn_certs
cp /etc/openvpn/cookbook/*.{crt,key,pem} /backup/openvpn_certs
- 监控证书状态 :定期检查证书的状态,确保没有过期或被吊销的证书影响系统的正常运行。可以编写一个脚本,定期执行证书状态检查:
#!/bin/bash
cd /etc/openvpn/cookbook/keys
for cert in *.crt; do
serial=$(openssl x509 -serial -noout -in $cert)
status=$(openssl ca -status ${serial#serial=})
echo "$cert: $status"
done
将上述脚本保存为
check_certs.sh
,并添加执行权限:
chmod +x check_certs.sh
然后可以设置一个cron作业每天执行该脚本:
0 3 * * * root /path/to/check_certs.sh > /var/log/cert_status.log
总结
通过对PKI、证书和OpenSSL的详细介绍,我们了解了客户端连接与证书验证、中间CA的设置、多CA配置、加密库的选择以及证书管理等方面的知识。在实际应用中,我们需要根据具体的需求和场景,选择合适的配置和管理方法。
- 客户端连接时,要确保证书的有效性,避免因证书问题导致连接失败。
- 中间CA的设置可以提高系统的安全性和管理效率,合理分配证书颁发权限。
- 多CA配置可以提供额外的操作安全性,防止中间人攻击。
- 选择合适的加密库可以满足不同的加密需求和资源限制。
- 良好的证书管理实践可以保障系统的稳定性和安全性。
希望这些知识能够帮助你更好地构建和管理基于OpenVPN的安全网络。在实际操作过程中,要不断总结经验,根据实际情况进行调整和优化,以确保网络的安全稳定运行。

9万+

被折叠的 条评论
为什么被折叠?



