TLS双向认证场景,Nginx终结SSL后无法继续传递客户端证书subject

客户端和服务器做TLS双向认证
Nginx终结SSL后将请求转到emq的1883端口
emq配置http_auth认证,客户端可以连上,但是http_auth对应的HTTP认证服务器拿不到客户端证书subject。
Nginx配置如下
stream {
upstream mqtt_server {
server 10.8.168.124:1883;
}
server {
listen 8883 so_keepalive=on ssl;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!RC4:!MD5:!aNULL:!eNULL:!NULL:!DH:!EDH:!EXP:+MEDIUM;
ssl_certificate /usr/local/nginx/certs/emqx.pem;
ssl_certificate_key /usr/local/nginx/certs/emqx.key;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 4h;
ssl_prefer_server_ciphers on;
proxy_connect_timeout 6m;

	ssl_client_certificate /usr/local/nginx/certs/ca.pem;
	ssl_trusted_certificate /usr/local/nginx/certs/ca.pem;
	ssl_verify_depth 2;
	ssl_verify_client on;
	proxy_timeout 6m;
	proxy_pass mqtt_server;
}

}

http_auth配置的请求体
{
“certCommonName”: “${cert_common_name}”,
“certSubject”: “${cert_subject}”,
“clientid”: “${clientid}”,
“password”: “${password}”,
“username”: “${username}”
}

HTTP 认证服务收到的请求日志如下
{“@timestamp”:“2023-11-07T08:55:31.813+08:00”,“@version”:“1”,“method”:“POST”,“protocol”:“HTTP/1.1”,“status_code”:404,“requested_url”:“POST /mqtt/v5/auth HTTP/1.1”,“requested_uri”:“/mqtt/v5/auth”,“remote_host”:“10.8.168.124”,“content_length”:124,“elapsed_time”:11,“request_headers”:{“accept”:“application/json”,“cache-control”:“no-cache”,“connection”:“keep-alive”,“content-length”:“106”,“content-type”:“application/json”,“country”:“TH”,“host”:“10.8.168.124:8080”,“keep-alive”:“timeout=30, max=1000”},“requestContent”:“{"username":"hu_sn111","password":"hu_sn111","clientid":"local-9993","certSubject":"","certCommonName":""}”,“serverName”:“gwm-message-push-service”,“logType”:“accesslog”}

需要 nginx 和 emqx 同时开启 Proxy Protocol.

在 emqx 的 1883 端口的配置里面:listeners.tcp.default.proxy_protocol = true

nginx:

stream {
    server {
        listen 12345;
        proxy_pass example.com:12345;
        proxy_protocol on;
    }
}

详见 https://docs.nginx.com/nginx/admin-guide/load-balancer/using-proxy-protocol/

nginx增加了proxy_protocol on;
emq5.3的1883端口在管理后台启用了代理协议
但是mqttx不断的在重连



1699341028825_091E5C24-BB6E-45af-9DC2-3D917027239A

emqx 开启了代理协议的话,你的所有客户端都需要走 nginx 了。
如果通过 nginx 连接不成功,看看 emqx 这边的日志。

mqttx我访问的就是Nginx的9993端口

emq看不到任务的报错日志

要不然你抓包定位一下吧。也可能是报文没有发送到 emqx 那边去。

你好,最终这个问题解决了吗?

未解决

你也遇到了该问题吗

用 nginx 的 9993 端口,而且 EMQX 没有日志。
应该是连接在 nginx 就断了。
不太清楚你的证书是怎么签发的,但先关了 MQTTX 这里的 SSL Secure 尝试下呢?

我已经成功连接emqx的SSL,包括nginx配置SSL和emqx配置SSL,我昨天不成功是因为证书的问题,我从emqx的提供的文章中进行重新生成自签证书,发现已经可以了。文章链接如下:EMQX 启用双向 SSL/TLS 安全连接 | EMQ

应该就是这个官方说的,签发的证书的问题,一开始我使用关闭SSL验证的,发现是没问题的

我们的系统现在也是这么配置的没有问题。
但是我们原计划1 证书双向认证,2 双向认证通过后,继续传递证书信息-自建任务服务器认证证书subject。2这一步始终过不去。

为啥还有2这一步,因为我们担心证书泄漏,所以需要提取证书信息和客户端信息进行二次认证

我觉得你这个第二次验证,不一定要通过证书来实现,现在不是支持了JWT、用户名与密码等方式,暴露出外网的采用证书双向认证处理,等到了emqx的节点上的时候,可以通过JWT、用户名密码等验证方式,这样其实也是安全的

嗯,没有绝对的安全,只能相对的说。
我们这边安全科要求的,要验证证书和客户端的唯一性信息。否则证书泄漏容易被人利用。比如,黑客拿着客户端1的证书和客户端2的用户名密码进行登录。

安全科给的安防防护方案:
TLS双向认证+用户名密码+客户证书subject匹配用户名校验

这个我觉得应该跟nginx有关了,在转发的同时进行把SSL的验证一起传给服务端,试试nginx的 stream模块的 ssl_preread on 配置,不知道是否可行