Nginx 四层代理TCP配置SSL加密访问

释放双眼,带上耳机,听听看~!
🤖 由 ChatGPT 生成的文章摘要

Nginx配置四层代理使用到stream模块,需要在编译时指定--with-stream。本地演示环境还需要添加--with-stream_ssl_module模块; ngx_stream_ssl_module 提供了基于 SSL/TLS 协议的 TCP 连接监听

编译参数如下

root@abcdocker:/opt/nginx-1.24.0# ./sbin/nginx -V
nginx version: nginx/1.24.0
built by gcc 11.4.0 (Ubuntu 11.4.0-1ubuntu1~22.04)
built with OpenSSL 1.1.1t  7 Feb 2023
TLS SNI support enabled
configure arguments: --prefix=/opt/nginx-1.24.0 --with-openssl=/usr/local/src/openssl-1.1.1t --with-pcre=/usr/local/src/pcre-8.45 --with-zlib=/usr/local/src/zlib-1.2.13 --with-http_ssl_module --with-http_stub_status_module --with-stream --with-http_stub_status_module --with-http_gzip_static_module --with-stream_ssl_module

准备工作

  • CA证书(key、crt、ca.crt)证书使用openssl或者使用域名证书都可以,可不可信都可以
  • Nginx 1.19版本以上+
  • 代理后端(我这里tcp后端使用Redis模拟)

配置参数详解

指令名称 指令值格式 默认值 指令说明
ssl_protocols [SSLv2][SSLv3][TLSv1][TLSv1.1][TLSv1.2][TLSv1.3] TLSv1 TLSv1.1 TLSv1.2 设置使用的 SSL 协议版本
ssl_certificate file -- PEM 格式的 SSL 证书文件,可自建或由 CA 机构颁发
ssl_certificate_key file -- PEM 格式的 SSL 证书私钥文件,可自建或由 CA 机构颁发
ssl_password_file file -- 存放 SSL 证书私钥文件的密码文件,一个密码一行。有多个密码时,Nginx 会依次尝试
ssl_ciphers ciphers HIGH:!aNULL:!MD5 设置 SSL TCP 建立连接时用于协商使用的加密算法组合,也称为密码套件。指令值内容为 openssl 的密码套件名称,多个套件名称由“:”分隔
ssl_prefer_server_ciphers on 或 off off 是否启用 SSLv3 和 TLSv1 协议在 SSL TCP 连接时优先使用服务端设置的密码套件
ssl_dhparam file -- DH 密钥交换的 Diffie-Hellman 参数文件
ssl_ecdh_curve curve auto 配置 SSL 加密时使用椭圆曲线 DH 密钥交换的曲线参数,多个参数使用“:”分隔。ecdh 是 Elliptic-Curve 和 Diffie-Hellman 的缩写,指令值为 auto 时,配置的曲线参数是 prime256v1
ssl_session_cache off 或 none 或[builtin[:size]][shared:name:size] none SSL TCP 会话缓存设置
ssl_session_tickets on 或 off on 是否启用 SSL TCP 会话缓存 session ticket 机制,指令值为 off 时,使用 session ID 会话缓存机制
ssl_session_ticket_key file -- 指定会话凭证密钥文件,用以多台 Nginx 间实现 session ticket 共享,否则 Nginx 会随机生成一个会话凭证密钥
ssl_session_timeout time 5m 设置客户端可用会话缓存的超时时间
ssl_verify_client on 或 off 或optional或optional_no_ca off 设置是否启用对客户端证书验证功能,指令值为 on 时,启用验证;指令值为 optional 时,如果接收到客户端证书则启用验证;指令值为 optional_no_ca 时,若接收到客户端证书,则启用客户端证书验证,但不进行证书链校验。验证结果将存储在 $ssl_client_verity 变量中
ssl_crl file -- 证书吊销列表文件,用以验证客户端 SSL 证书有效性的 PEM 格式文件
ssl_client_certificate file -- 指定一个 PEM 格式的 CA 证书(根或中间证书)文件,该证书用作客户端的证书验证。该证书列表会被发送给客户端
ssl_trusted_certificate file -- 指定一个 PEM 格式的 CA 证书(根或中间证书)文件,该证书用作客户端的证书验证。该证书列表不会被发送给客户端
ssl_verify _depth number 1 设置客户端证书链验证深度

Nginx 主配置文件

include /opt/nginx-1.24.0/conf/conf.d/tcp.conf引用TCP配置文件不可以在http标签下,需要和http标签同级,否则会提示stream语法错误

user nginx;
error_log  logs/nginx_error.log;
worker_processes  1;
events {
    worker_connections  4096;
}
    include /opt/nginx-1.24.0/conf/conf.d/tcp.conf;
http {
    include       mime.types;
    default_type  application/octet-stream;
    log_format  main  ' $remote_addr | $remote_user | $time_local | $request | $http_host |'
                      ' $status | $upstream_status | $body_bytes_sent | $http_referer '
                      ' $http_user_agent | $upstream_addr | $request_time | $upstream_response_time';
    sendfile        on;
    charset utf-8;
    keepalive_timeout  65;
    large_client_header_buffers 8 128k;
    server_tokens off;
    proxy_buffering on;
    proxy_hide_header X-Powered-By;
    proxy_hide_header Server;
    proxy_buffer_size 1024k;
    proxy_buffers 32 1024k;
    proxy_busy_buffers_size 2048k;
    proxy_temp_file_write_size 2048k;
    proxy_connect_timeout 300s;
    proxy_read_timeout 300s;
    proxy_send_timeout 300s;
    proxy_ignore_headers Set-Cookie; # 忽略缓存cookie
    client_header_timeout 120s;
    client_max_body_size 100M;
    client_body_buffer_size 100M;
    client_header_buffer_size 128k;
    fastcgi_connect_timeout 600;
    fastcgi_send_timeout 600;
    fastcgi_read_timeout 600;
    fastcgi_buffer_size 128k;
    fastcgi_buffers 4 128k;
    fastcgi_busy_buffers_size 256k;
    fastcgi_temp_file_write_size 256k;
    gzip on;
    gzip_min_length 1000;
    gzip_buffers 16 8k;
    gzip_comp_level 8;
    gzip_proxied any;
    gzip_disable "MSIE [1-6]\.";
    gzip_types  text/plain   text/css application/javascript application/x-javascript text/xml application/json application/xml application/xml+rss text/javascript image/jpg image/jpeg image/png image/gif;
    tcp_nopush      on;
    tcp_nodelay     on;
    server_names_hash_bucket_size 128;
    add_header Nginx-Server "";
    max_ranges 1;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    include /opt/nginx-1.24.0/conf/conf.d/*.conf;
}

Nginx 子配置文件

上面住配置文件定义全局的配置变量,下面子配置文件定义TCP配置信息

  • 6379为Redis端口号
  • 8100为SSL TCP协议,加密传输
  • 8104为模拟客户端操作(也可以直接Client-->Nginx SSL TCP-->后端服务)
  • 所有配置文件在上面均有参数解释
stream {
  upstream redis{
      server 127.0.0.1:6379;
  }

# logs conf
    log_format proxy '$remote_addr [$time_local] '
                 '$protocol $status $bytes_sent $bytes_received '
                 '$session_time "$upstream_addr" '
                 '"$upstream_bytes_sent" "$upstream_bytes_received" "$upstream_connect_time"';

#SSL代理本地服务器
    server {
        listen 8100 ssl;
    access_log /opt/nginx-1.22.1/logs/tcp-ssl-access.log proxy;
        ssl_certificate   /opt/nginx-1.22.1/conf/cert/server.crt;
        ssl_certificate_key    /opt/nginx-1.22.1/conf/cert/server.key;
        ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
        proxy_ssl_session_reuse on;
        ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
        ssl_session_cache shared:SSL:10m;
        ssl_session_timeout 10m;
        proxy_pass redis;
}

#模拟客户端解密,对外暴露

server {
    listen 8104;
    access_log /opt/nginx-1.22.1/logs/tcp-access.log proxy;
    proxy_connect_timeout 60s;
    proxy_timeout 60s;
    proxy_pass 127.0.0.1:8100;
    ssl_verify_client on;
    ssl_client_certificate /opt/nginx-1.22.1/conf/cert/ca.crt;
    proxy_ssl   on;
    ssl_certificate   /opt/nginx-1.24.0/conf/cert/server.crt;
    ssl_certificate_key    /opt/nginx-1.24.0/conf/cert/server.key;
    ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
   }

}

访问逻辑

访问架构图如下

Nginx 四层代理TCP配置SSL加密访问

访问截图

使用Redis Client访问Nginx 对外8104端口

Nginx 四层代理TCP配置SSL加密访问

Nginx 四层代理TCP配置SSL加密访问

Nginx TCP访问日志如下

==> tcp-ssl-access.log <==

127.0.0.1 [20/Mar/2024:02:37:57 +0000] TCP 200 7490 250 22.958 "127.0.0.1:6379" "250" "7490" "0.000"

==> tcp-access.log <==
111.111.222.10 [20/Mar/2024:02:37:57 +0000] TCP 200 7490 250 22.959 "127.0.0.1:8100" "250" "7490" "0.003"

在Nginx服务器上,我们也可以发现直接redis-cli访问8100是会提示连接失败,虽然端口通讯,但是没有携带证书,Nginx会拒绝连接,使用8104端口,就可以正常通信

给TA打赏
共{{data.count}}人
人已打赏
NGINX

Nginx 获取真实IP配置_Nginx 透传IP

2023-12-15 11:15:15

NGINX

Nginx TCP Stream配置日志记录

2024-3-20 11:12:40

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索