跳转至

07 四层代理透传证书给后端服务认证

nginx 做四层代理不在网关层校验证书

背景

  • 代理Kubernetes 的ingress 到集群外时, 会涉及到多个域名, 如果在nginx 层就校验证书会存放许多的证书信息

处理方案

1、 启用 ssl_preread 功能可以完美解决此问题;

在 Nginx 中,ssl_preread 是一个配置指令,用于启用 SSL/TLS 握手的预读功能。它使得 Nginx 能够解析客户端发起的 SSL/TLS 握手,而无需完全建立 SSL/TLS 连接。

ssl_preread 指令设置为 on 时,Nginx 会尝试读取客户端发送的 SSL/TLS 握手数据,通常是 ClientHello 消息。这样,Nginx 可以在建立完整的 SSL/TLS 连接之前,根据握手数据中的信息进行一些处理或决策。

ssl_preread 的主要应用场景是在代理服务器层面根据客户端请求的内容进行路由或负载均衡。通过读取握手数据,Nginx 可以获取到请求的主机名、协议版本、加密套件等信息,然后基于这些信息决定将请求转发到哪个后端服务器。

以下是 ssl_preread 的基本用法示例:

复制

stream {
    server {
        listen 443;
        ssl_preread on;

        # 在此处根据握手数据进行路由或负载均衡配置
        # ...
    }
}

在上述配置中,Nginx 监听 443 端口,并启用了 ssl_preread 功能。您可以根据实际需求在 ssl_preread 指令下方添加其他配置,例如使用 proxy_pass 指令将请求转发到不同的后端服务器。

需要注意的是,ssl_preread 功能只能在 Nginx 的 stream 模块中使用,而不能在 http 模块中使用。另外,为了使 ssl_preread 生效,Nginx 必须构建时启用了 SSL/TLS 功能。

通过使用 ssl_preread,您可以在代理服务器层面根据 SSL/TLS 握手数据做出决策,以实现更灵活和智能的流量管理。

示例代码

实现转发test.cn wiki.test.cn resume.test.cn 的域名

stream {
    log_format stream-main '$remote_addr [$time_local] '
        '$protocol $status $bytes_sent $bytes_received '
        '$session_time "$ssl_preread_server_name"';
    map $ssl_preread_server_name $backend_server_name {
        test.cn test_backend;
        wiki.test.cn test_backend;
        resume.test.cn test_backend;
    }
    upstream test_backend {
        server 127.0.0.1:10443;

    }
    server {
        listen     443  reuseport;
        proxy_pass $backend_server_name;
        ssl_preread on;
    }

}