前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Nginx - 四层代理TCP配置SSL加密访问

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

作者头像
小小工匠
发布2024-05-26 13:50:31
1390
发布2024-05-26 13:50:31
举报
文章被收录于专栏:小工匠聊架构小工匠聊架构

指北

要在Nginx上配置SSL加密的四层代理TCP连接,你需要进行如下步骤:

1. 准备SSL证书和密钥

确保你拥有SSL证书(.crt文件)和对应的私钥(.key文件)。

2. 配置Nginx

创建一个Nginx配置文件,例如nginx.conf,并添加以下内容:

代码语言:javascript
复制
stream {
    server {
        listen 443 ssl;

        # SSL证书和密钥路径
        ssl_certificate /path/to/your/certificate.crt;
        ssl_certificate_key /path/to/your/private.key;

        # 允许的SSL协议版本
        ssl_protocols TLSv1.2 TLSv1.3;

        # 配置SSL密码套件
        ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';

        # 配置SSL会话缓存
        ssl_session_cache shared:SSL:10m;
        ssl_session_timeout 10m;

        # 代理到后端服务器的地址和端口
        proxy_pass your_backend_server:your_backend_port;
    }
}

替换以下部分:

  • /path/to/your/certificate.crt:SSL证书的路径。
  • /path/to/your/private.key:SSL私钥的路径。
  • your_backend_server:后端服务器的地址。
  • your_backend_port:后端服务器的端口。

3. 启动Nginx

启动Nginx服务,确保配置生效。

4. 验证配置

使用SSL客户端与Nginx建立连接,确认SSL连接是否正常工作。可以使用openssl命令或其他SSL客户端工具来进行验证。

注意事项

  • 确保SSL证书和私钥的权限设置正确,Nginx能够读取它们。
  • 配置中的SSL密码套件和协议版本可以根据需求进行调整。
  • 确保防火墙和网络配置允许连接到Nginx服务器的443端口。

以上配置将Nginx配置为监听SSL连接并将其代理到后端服务器。这样,客户端与Nginx之间的通信将通过SSL加密进行,而Nginx与后端服务器之间的通信则可以是加密或非加密的,具体取决于后端服务器的配置。


实操

编译参数

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

代码语言:javascript
复制
--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 主配置文件

代码语言:javascript
复制
user nginx;  # 设置运行 Nginx 的用户

error_log  logs/nginx_error.log;  # 错误日志路径

worker_processes  1;  # Nginx worker 进程数

events {
    worker_connections  4096;  # 每个 worker 进程的最大连接数
}

include /opt/nginx-1.24.0/conf/conf.d/tcp.conf;  # 包含 TCP 配置文件

http {
    include       mime.types;  # 包含 MIME 类型配置文件
    default_type  application/octet-stream;  # 默认 MIME 类型

    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;  # 开启 sendfile
    charset utf-8;  # 字符编码
    keepalive_timeout  65;  # 客户端连接保持超时时间
    large_client_header_buffers 8 128k;  # 客户端请求头部缓冲区大小
    server_tokens off;  # 关闭服务器版本号显示
    proxy_buffering on;  # 开启代理缓冲
    proxy_hide_header X-Powered-By;  # 隐藏响应头 X-Powered-By
    proxy_hide_header Server;  # 隐藏响应头 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;  # 客户端请求最大 body 大小
    client_body_buffer_size 100M;  # 客户端请求 body 缓冲区大小
    client_header_buffer_size 128k;  # 客户端请求头缓冲区大小
    fastcgi_connect_timeout 600;  # FastCGI 连接超时时间
    fastcgi_send_timeout 600;  # FastCGI 发送超时时间
    fastcgi_read_timeout 600;  # FastCGI 读取超时时间
    fastcgi_buffer_size 128k;  # FastCGI 缓冲区大小
    fastcgi_buffers 4 128k;  # FastCGI 缓冲区设置
    fastcgi_busy_buffers_size 256k;  # FastCGI 繁忙缓冲区大小
    fastcgi_temp_file_write_size 256k;  # FastCGI 临时文件写入大小
    gzip on;  # 开启 Gzip 压缩
    gzip_min_length 1000;  # 最小压缩文件大小
    gzip_buffers 16 8k;  # Gzip 缓冲区大小
    gzip_comp_level 8;  # Gzip 压缩级别
    gzip_proxied any;  # Gzip 压缩代理设置
    gzip_disable "MSIE [1-6]\.";  # 禁用 Gzip 的用户代理
    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;  # Gzip 压缩类型
    tcp_nopush      on;  # 开启 TCP nopush
    tcp_nodelay     on;  # 开启 TCP nodelay
    server_names_hash_bucket_size 128;  # 服务器名称散列桶大小
    add_header Nginx-Server "";  # 添加自定义响应头
    max_ranges 1;  # 最大 ranges 数
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;  # 设置使用的 SSL 协议版本
    include /opt/nginx-1.24.0/conf/conf.d/*.conf;  # 包含所有 .conf 文件
}

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


子配置文件定义TCP配置信息

代码语言:javascript
复制
```nginx
stream {
    upstream redis {
        server 127.0.0.1:6379;  # 定义 upstream,指向 Redis 服务
    }

    # 日志配置
    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;  # 监听 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 证书路径
        ssl_certificate_key    /opt/nginx-1.22.1/conf/cert/server.key;  # SSL 证书私钥路径
        ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;  # 设置 SSL 协议版本
        proxy_ssl_session_reuse on;  # 启用 SSL 会话重用
        ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;  # SSL 加密算法
        ssl_session_cache shared:SSL:10m;  # SSL 会话缓存
        ssl_session_timeout 10m;  # SSL 会话超时时间
        proxy_pass redis;  # 代理到 Redis 服务
    }

    # 模拟客户端解密,对外暴露
    server {
        listen 8104;  # 监听 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 服务
        ssl_verify_client on;  # 启用客户端证书验证
        ssl_client_certificate /opt/nginx-1.22.1/conf/cert/ca.crt;  # 客户端证书路径
        proxy_ssl   on;  # 开启 SSL
        ssl_certificate   /opt/nginx-1.24.0/conf/cert/server.crt;  # SSL 证书路径
        ssl_certificate_key    /opt/nginx-1.24.0/conf/cert/server.key;  # SSL 证书私钥路径
        ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;  # 设置 SSL 协议版本
    }
}

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

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

日志如下

代码语言:javascript
复制
==> tcp-ssl-access.log <==
127.0.0.1 [18/May/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 [18/May/2024:02:37:57 +0000] TCP 200 7490 250 22.959 "127.0.0.1:8100" "250" "7490" "0.003"   将时间替换成今天
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-05-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 指北
    • 1. 准备SSL证书和密钥
      • 2. 配置Nginx
        • 3. 启动Nginx
          • 4. 验证配置
            • 注意事项
            • 实操
              • 编译参数
                • 准备工作
                  • 配置参数详解
                    • Nginx 主配置文件
                      • 子配置文件定义TCP配置信息
                      相关产品与服务
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档