Nginx ssl_preread传递客户端IP

ssl_preread是基于L4的反代方案,TLS SNI握手时客户端会提供域名,所以可以让Nginx在无需完成TLS握手的情况下,就根据域名进行后端服务器的选择。简单来讲,你只需要给后端服务器配置一个SSL证书,而提供反代功能的Nginx则无需配置。文档见此:http://nginx.org/en/docs/stream/ngx_stream_ssl_preread_module.html

因为这是L4反代,所以通过“proxy_set_header”传递客户端IP的方法是行不通的。其实传递客户端IP的解决办法跟上一篇文章类似:L4(传输层)IP透明反向代理的实现(传递客户端真实IP),nginx也是实现了IP_TRANSPARENT的:https://www.nginx.com/blog/ip-transparency-direct-server-return-nginx-plus-transparent-proxy#ip-transparency,所以,在server里面加上下面一行:

然后按前一篇文章的思路,对路由表进行配置即可。

提醒一下,ssl_preread是配置在stream block下的,放在别的地方,会提示:

所以正确的nginx.conf结构应该如下:

另外,如果在stream中listen了443,http中就无法listen 443了,启动nginx会提示:

可以让http中的server listen loopback地址的另一个端口,让stream中的server proxy_pass这个loopback地址的端口,例如127.0.2.1:8443,然后通过127.0.2.1做策略路由:

然后配置策略路由:

 

libvirtd: virNetTLSContextValidCertificate:994 : Unable to verify TLS peer: No certificate was found.

使用TLS连接libvirtd时,默认需要验证客户端是否拥有由CA签名的证书,详见libvirtd配置文件(/etc/libvirt/libvirtd.conf):

 

取消此行的注释即可关闭此验证(当然你得启用其它身份认证途径):

 

也可选择以让CA给客户端签发证书:

完成上面的操作后,把整个${PKI_PREFIX}目录打包到客户端服务器上,在libvirt connection uri上加上参数pkipath=${PKI_PREFIX}即可:

当然如果CA证书,客户端私钥以及证书都放在默认位置,可以不使用pkipath参数,详见References [1]。

 

References:

[1] https://libvirt.org/remote.html#Remote_URI_reference