我正在使用 nginx 在现有 TCP 服务器(Redis)上通过代理添加 TLS 功能(在说“Redis 具有内置 TLS 支持”之前请继续阅读):
stream {
server {
listen 6379 ssl;
ssl_certificate /etc/ssl/private/tls.crt;
ssl_certificate_key /etc/ssl/private/tls.key;
ssl_client_certificate /etc/ssl/private/ca.crt;
ssl_verify_client on;
proxy_pass redis:679;
}
}
然而这将接受全部已由指定 CA 签名的客户端证书。我希望仅接受具有特定 CN 的客户端证书:cn=api
。代理 HTTP 时,我可以使用if
类似这样的语句
if ($ssl_client_s_dn != "CN=api") {
return 403;
}
但是,流服务器似乎if
不允许使用这样的语句。作为一种解决方法,我使用了一个map
语句将与 CN 不匹配的请求路由到不存在的上游,如下所示:
stream {
upstream redis_backend {
server redis:6379;
}
map $ssl_client_s_dn $backend_svr {
"CN=api" redis_backend;
default null;
}
server {
...
proxy_pass $backend_svr;
}
}
然而,我不禁觉得一定有更好的方法来拒绝因客户端证书不匹配而产生的连接。