如何对tcp流认证并加密

一个场景:目前越来越多的业务需要远程读写Redis,而Redis 本身不提供 SSL/TLS 的支持,在需要安全访问的环境下。
这时候就需要额外的手段进行加密认证,这里有两种手段:spiped 和 ngx stream proxy
现在服务端起一个监听在127 的 Redis server

1、使用spiped

[root@ ~]# wget http://www.tarsnap.com/spiped/spiped-1.6.0.tgz
[root@ ~]# tar xf spiped-1.6.0.tgz 
[root@ ~]# cd spiped-1.6.0
[root@ ~]# tar xf spiped-1.6.0.tgz  
[root@ ~]# cd spiped-1.6.0
[root@ spiped-1.6.0]# make && make install
[root@ spiped-1.6.0]# /usr/local/bin/spiped -h 
spiped: illegal option -- -h

usage: spiped {-e | -d} -s <source socket> -t <target socket> -k <key file>
    [-DFj] [-f | -g] [-n <max # connections>] [-o <connection timeout>]
    [-p <pidfile>] [-r <rtime> | -R]
       spiped -v

创建key,并将key分发到代理客户端

[root@ ~]# dd if=/dev/urandom bs=32 count=1 of=/var/spiped/redis_proxy.key

启动服务端和客户端代理:

#服务端:
[root@ ~]# /usr/local/bin/spiped -d -s '[0.0.0.0]:6010' -t '[127.0.0.1]:6379' -k /var/spiped/redis_proxy.key  -p /var/spiped/redis_proxy_srv.pid

#客户端代理:
[root@ ~]# /usr/local/bin/spiped -e -s '[127.0.0.1]:6379' -t '[x.x.x.x]:6010' -k /var/spiped/redis_proxy.key  -p /var/spiped/redis_proxy_cli.pid

客户端测试:

[root@ ~]# /usr/local/redis/bin/redis-cli -h 127.0.0.1 -p 6379 -a redis@passwd ping 
PONG

参考:http://www.tarsnap.com/spiped.html

2、使用ngx stream proxy

配置自签证书,略。
证书和key可以同时给服务端代理和客户端代理使用
ngx_stream_ssl_module模块(1.9.0)为流代理服务器提供必要的支持,以使用SSL / TLS协议。 默认情况下不构建此模块,应使用--with-stream_ssl_module配置参数启用它。

编译nginx需要加入--with-stream --with-stream_ssl_module 选项

服务端代理配置:

upstream redis_server{
    server 127.0.0.1:6379 max_fails=3 fail_timeout=10s;
}

server{
    listen 6010 ssl;

    ssl_certificate /data/ssl/stream_proxy/stream_proxy.crt;      #服务端证书
    ssl_certificate_key /data/ssl/stream_proxy/stream_proxy.key;  #服务端key

    ssl_verify_client on;                                             #开启对客户端的认证
    ssl_client_certificate /data/ssl/stream_proxy/cacert.pem;         #用于认证客户端ca证书

    ssl_session_timeout 10m;
    ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers  ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;

    proxy_connect_timeout 5s;
    proxy_timeout 5s;

    proxy_pass redis6001_server;
    error_log /data/logs/redis_sslproxy_srv.log debug;
}

客户端代理配置:

upstream redis_server{
    server x.x.x.x:6010 max_fails=3 fail_timeout=10s;
}

server{
    listen 127.0.0.1:6379;
    proxy_ssl_name stream_proxy;     #与证书中的hostname一致,覆盖用于验证后端的hostname,并通过SNI在与后端建立连接时传递,默认proxy_pass地址的host部分会被使用。 
    proxy_ssl on;
    proxy_ssl_certificate  /data/ssl/stream_proxy/stream_proxy.crt;      #客户端证书
    proxy_ssl_certificate_key  /data/ssl/stream_proxy/stream_proxy.key;  #客户端key

    proxy_ssl_verify  on;                                                   #开启对服务端的认证
    proxy_ssl_trusted_certificate /data/ssl/stream_proxy/cacert.pem;        #用于认证服务端ca证书

    ssl_session_timeout 10m;
    proxy_ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
    proxy_ssl_ciphers  ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;

    proxy_connect_timeout 5s;
    proxy_timeout 5s;

    proxy_pass redis_server;
    error_log /data/logs/redis_sslproxy_cli.log debug;
}

如果仅仅是实现ngx stream proxy加密不认证的话,只需要在服务端代理配置好证书,客户端代理配置proxy_ssl on即可

参考链接:

1、https://blog.lyz810.com/article/2016/06/ngx_stream_proxy_module_doc_zh-cn/

2、https://blog.lyz810.com/article/2016/06/ngx_stream_ssl_module_doc_zh-cn/

3、https://my.oschina.net/foreverich/blog/1517128?utm_medium=referral

原文地址:https://www.cnblogs.com/wshenjin/p/10376614.html