stunnel 双向证书认证:防止没授权的客户端连接stunnel服务器,防止客户端连接假的服务器。
stunnel官方的说明是:(客户端)检查服务器端证书是为了防止中间人攻击;(服务器端)检查客户端证书是为了严格控制客户端的访问。
- Server authentication prevents Man-In-The-Middle (MITM) attacks on the encryption protocol.
- Client authentication allows for restricting access for individual clients (access control).
stunnel安全说明
stunnel有四种证书检查配置,用verify
选项控制。
- Do not Verify Certificates 不检查证书,默认值
If no verify argument is given, then stunnel will ignore any certificates offered and will allow all connections. - verify = 1 如果证书存在则检查证书
Verify the certificate, if present. - verify = 2 每个SSL连接要求检查证书
Require and verify certificates
Stunnel will require and verify certificates for every SSL connection. If no certificate or an invalid certificate is presented, then it will drop the connection. - verify = 3 依据本地安装的证书检查证书
Require and verify certificates against locally installed certificates. - verify = 4 忽略CA chain,只验证peer certificate
ignore CA chain and only verify peer certificate
当verify
配置2 3 4的时候,都会开启双向证书认证,自行选择。这里选择verify = 3
。
stunnel服务端的防盗连安全机制是:在服务器CAfile
里配置客户端的证书,并设置verify = 3
,服务器端检查客户端证书,证书不在CAfile
列表的客户端则会被断开连接。
同样,为了避免客户端连接到假的服务端,则需要配置verify = 3
,并把服务端的公钥证书放在客户端侧的CAfile
里。
第一步 生成证书
生成两个证书,一个服务端的stunnel_s.pem
,一个客户端的stunnel_c.pem
,有效期设置长一点,10000天,时间可以自行调整。
$openssl req -new -x509 -days 10000 -nodes -out stunnel_c.pem -keyout stunnel_c.pem
$openssl req -new -x509 -days 10000 -nodes -out stunnel_s.pem -keyout stunnel_s.pem
第二步 服务器端stunnel.conf
将证书拷贝到/etc/stunnel目录,设置权限400(文件拥有者只读,其他人不可查看).
$sudo cp stunnel_s.pem /etc/stunnel/
$sudo cp stunnel_c.pem /etc/stunnel/
$sudo chmod 400 /etc/stunnel/*.pem
创建stunnel.conf
文件,内容如下,拷贝到/etc/stunnel/
目录。对外端口是8445,加密的是cow HTTP proxy的7777端口连接,根据情况自行修改。如果要调试打开output
选项。cow是个HTTP代理,智能分流值得推荐。
;fips=no
client = no
sslVersion=all
chroot = /var/lib/stunnel4/
setuid = root
setgid = root
pid = /stunnel4.open.pid
;output = /stunnel.open.log
cert = /etc/stunnel/stunnel_s.pem
key = /etc/stunnel/stunnel_s.pem
[open]
accept = 8445
connect = 7777
verify = 3
CAfile = /etc/stunnel/stunnel_c.pem
重启stunnel服务器
$sudo service stunnel4 restart
第三步 客户端stunnel.conf
我的客户端运行在windows系统,所以下面的配置是windows上stunnel验证的。其他系统配置类似,自行配置验证。
将stunnel_c.pem
和stunnel_s.pem
(存放在客户端的stunnel_s.pem最好删除证书里BEGIN PRIVATE KEY私钥部分,只保留BEGIN CERTIFICATE公钥部分)拷贝到stunnel
安装目录,修改stunnel.conf
文件,配置如下。stunnel_ip
是服务器端stunnel的IP,端口是8084,浏览器配置127.0.0.1:8084 HTTP代理。如果要换其他端口自行修改。
fips=no
client = yes
sslVersion = all
socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1
socket = l:SO_LINGER=1:1
socket = r:SO_LINGER=1:1
[fastssl]
accept = 127.0.0.1:8084
connect = stunnel_ip:8445
verify = 3
CAfile = stunnel_s.pem
cert = stunnel_c.pem
key = stunnel_c.pem
如果客户端连接stunnel
服务器端需要HTTP代理(公司网络),fastssl
部分这样配置
[fastssl]
accept = 127.0.0.1:8084
connect = proxy.company.com:80
protocol = connect
protocolHost = stunnel_ip:8445
pem证书安全存放说明
pem证书是文本文件,里面BEGIN PRIVATE KEY
和END PRIVATE KEY
是私钥部分,BEGIN CERTIFICATE
和END CERTIFICATE
是公钥部分。cert
和key
配置完整的pem,而CAfile
里只包含对方的公钥部分即可,即服务端CAfile
是客户端的公钥,客户端CAfile
是服务端的公钥。遵循这样原则,客户端的私钥只放客户端,服务端的私钥只放服务端,而公钥是可以多处存放的。
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCo9WC13gg9WCRX
...
kPpWg2PAANRi5Bmr9ScvBISSYQ==
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIID6TCCAtGgAwIBAgIJANBMqvP0YuV4MA0GCSqGSIb3DQEBBQUAMIGKMQswCQYD
...
o5tKoL9GcMhyjDoD9GCMfP6fY5DwPqhhqFTsPd47DzEdQ8amxPMn5kR/w/xk
-----END CERTIFICATE-----
多个公钥证书保存在一个CAfile
里,这样排列存放。官方说明Where do I put all these certificates?。
-----BEGIN CERTIFICATE-----
certificate #1 data here
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
certificate #2 data here
-----END CERTIFICATE-----
参考博客
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。