欢迎光临本地信息咨询网
详情描述

方案概述

使用 Nginx 的 ngx_stream_proxy_module 模块实现 TCP 级别的 SSH 端口转发,通过 SSL/TLS 加密通道。

配置步骤

1. 安装 Nginx(包含 Stream 模块)

# Ubuntu/Debian
sudo apt update
sudo apt install nginx libnginx-mod-stream

# CentOS/RHEL
sudo yum install nginx nginx-mod-stream

2. 配置 Nginx Stream 模块

编辑 /etc/nginx/nginx.conf,在 http 块同级添加 stream 配置:

# /etc/nginx/nginx.conf
events {
    worker_connections 1024;
}

# SSH 代理配置(TCP 层)
stream {
    # 上游 SSH 服务器组
    upstream ssh_backend {
        server 192.168.1.100:22;  # 目标服务器1
        server 192.168.1.101:22;  # 目标服务器2
        server 192.168.1.102:22;  # 目标服务器3
    }

    # SSH 代理服务器配置
    server {
        listen 8022;  # 代理监听端口
        proxy_pass ssh_backend;
        proxy_connect_timeout 30s;
        proxy_timeout 1h;

        # 可选:SSL/TLS 加密
        # ssl_preread on;
        # ssl_certificate /path/to/cert.pem;
        # ssl_certificate_key /path/to/key.pem;
    }

    # 基于 SNI 的多域名转发
    map $ssl_preread_server_name $backend_name {
        host1.example.com   192.168.1.100:22;
        host2.example.com   192.168.1.101:22;
        default            ssh_backend;
    }

    server {
        listen 8023 ssl;
        ssl_preread on;
        proxy_pass $backend_name;
        ssl_certificate /etc/nginx/ssl/cert.pem;
        ssl_certificate_key /etc/nginx/ssl/key.pem;
    }
}

http {
    # 原有的 HTTP 配置...
}

3. 使用 SSL/TLS 加密(推荐)

# 生成自签名证书
sudo mkdir -p /etc/nginx/ssl
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
    -keyout /etc/nginx/ssl/ssh-proxy.key \
    -out /etc/nginx/ssl/ssh-proxy.crt \
    -subj "/C=CN/ST=Beijing/L=Beijing/O=Company/CN=ssh-proxy.example.com"

4. 客户端连接方式

方式一:直接连接(无 SSL)
# 使用 ProxyCommand
ssh -o ProxyCommand="nc -X connect -x nginx-host:8022 %h %p" user@target-host

# 或配置 ~/.ssh/config
Host jump-host
    HostName nginx-host
    Port 8022
    User your-username
方式二:通过 SSL/TLS 连接
# 使用 sslh 或自定义代理
# 安装 sslh(应用层分流)
sudo apt install sslh

# sslh 配置(将 SSH 和 HTTPS 分流到不同端口)

5. 高级配置:基于认证的转发

stream {
    # 带认证的 SSH 代理
    server {
        listen 8024;

        # 使用 nginx 的 auth 模块或结合 Lua 脚本
        # proxy_pass ssh_backend;

        # 通过变量控制访问
        set $allow_access 0;

        # 这里可以结合 nginx 的 http 认证模块
        # 或使用 nginx-stream-lua-module
    }
}

6. 完整示例:HTTP + SSH 混合配置

# /etc/nginx/nginx.conf
user nginx;
worker_processes auto;

events {
    worker_connections 1024;
}

# SSH 隧道配置
stream {
    # 日志格式
    log_format proxy '$remote_addr [$time_local] '
                     '$protocol $status $bytes_sent $bytes_received '
                     '$session_time "$upstream_addr"';

    access_log /var/log/nginx/ssh-access.log proxy;
    error_log /var/log/nginx/ssh-error.log;

    # 目标服务器映射
    map $ssl_preread_server_name $target_backend {
        web-server     192.168.1.100:22;
        db-server      192.168.1.101:22;
        app-server     192.168.1.102:22;
        default        192.168.1.100:22;
    }

    # SSL 加密的 SSH 代理
    server {
        listen 443 ssl reuseport;
        ssl_preread on;
        proxy_pass $target_backend;
        proxy_connect_timeout 30s;
        proxy_timeout 2h;

        ssl_certificate /etc/nginx/ssl/cert.pem;
        ssl_certificate_key /etc/nginx/ssl/key.pem;
    }

    # 明文 SSH 代理(内网使用)
    server {
        listen 8022 reuseport;
        proxy_pass 192.168.1.100:22;
        proxy_buffer_size 16k;
    }
}

# Web 服务配置
http {
    # ... 原有的 HTTP 配置
    server {
        listen 80;
        server_name jump.example.com;

        # 跳板机管理页面
        location / {
            root /usr/share/nginx/html;
            index index.html;
        }

        # SSH over WebSocket 示例(使用 websockify)
        location /ssh/ {
            proxy_pass http://127.0.0.1:6080;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
        }
    }
}

7. 客户端配置示例

~/.ssh/config 文件配置:

# 通过 Nginx 代理连接
Host *.internal
    ProxyCommand nc -X connect -x nginx-proxy:8022 %h %p
    ServerAliveInterval 60
    TCPKeepAlive yes

# 具体主机配置
Host web-server
    HostName web-server.internal
    User admin
    Port 22

Host db-server
    HostName db-server.internal
    User root
    Port 22

8. 安全加固建议

# 限制访问 IP
server {
    listen 8022;
    allow 10.0.0.0/8;    # 内网 IP 段
    allow 192.168.1.0/24;
    deny all;

    proxy_pass ssh_backend;

    # 连接速率限制
    proxy_upload_rate 512k;
    proxy_download_rate 2m;
}

# 连接数限制
limit_conn_zone $binary_remote_addr zone=ssh_conn:10m;

server {
    listen 8022;
    limit_conn ssh_conn 5;  # 每个 IP 最多 5 个连接
    proxy_pass ssh_backend;
}

9. 启动和测试

# 检查配置
sudo nginx -t

# 重启 Nginx
sudo systemctl restart nginx

# 查看日志
sudo tail -f /var/log/nginx/ssh-access.log

# 测试连接
ssh -p 8022 user@nginx-proxy -t 'ssh user@target-server'

替代方案考虑

如果需求更复杂,可以考虑:

OpenSSH 内置跳板机:使用 SSH 的 ProxyJumpProxyCommand 专业堡垒机:如 Jumpserver、Teleport SSH over HTTPS:使用 SSLH 或 GoTTY

这种 Nginx 方案适合简单的 TCP 端口转发需求,如果需要完整的会话审计、用户管理、权限控制等功能,建议使用专业的堡垒机解决方案。

相关帖子
适合再就业父母的时间管理与工作效率提升方法有哪些?
适合再就业父母的时间管理与工作效率提升方法有哪些?
淄博市救护车长途出租@长途跨省救护车租车服务
淄博市救护车长途出租@长途跨省救护车租车服务
“君子远庖厨”背后:探讨猪油在中国古代社会生产力与家庭分工中的角色。
“君子远庖厨”背后:探讨猪油在中国古代社会生产力与家庭分工中的角色。
淄博市网站搭建服务%网站优化,多年专业建站经验
淄博市网站搭建服务%网站优化,多年专业建站经验
淄博市网站开发服务@erp系统开发,网站制作
淄博市网站开发服务@erp系统开发,网站制作
高温津贴是否需要缴纳个人所得税,具体是如何规定和计算的?
高温津贴是否需要缴纳个人所得税,具体是如何规定和计算的?
北京市120救护车长途转运病人回家@长途跨省救护车租车服务
北京市120救护车长途转运病人回家@长途跨省救护车租车服务
洗完澡后立刻吹头发,对头皮和发质可能会有哪些潜在的影响呢?
洗完澡后立刻吹头发,对头皮和发质可能会有哪些潜在的影响呢?
咸阳市120长途救护车出租设备齐全&120救护车怎么收费
咸阳市120长途救护车出租设备齐全&120救护车怎么收费
哪些类型的房产或哪些特殊情况不能适用“带押过户”这项便利政策?
哪些类型的房产或哪些特殊情况不能适用“带押过户”这项便利政策?
2026年长假调休方案已出,如何才能更科学地拼出超长假期?
2026年长假调休方案已出,如何才能更科学地拼出超长假期?
有哪些适合独居老人的轻度体育锻炼方式,可以在家进行?
有哪些适合独居老人的轻度体育锻炼方式,可以在家进行?
如何区分观点表达、事实陈述与故意误导,从而在讨论中保持清晰理性的认知?
如何区分观点表达、事实陈述与故意误导,从而在讨论中保持清晰理性的认知?
家里有多件旧物想一起处理,“以旧换新”补贴可以叠加或多次享受吗?
家里有多件旧物想一起处理,“以旧换新”补贴可以叠加或多次享受吗?
详解ZABBIX监控ESXI主机的问题
详解ZABBIX监控ESXI主机的问题
邵阳市模版网站开发&安卓系统app开发,多年建站经验
邵阳市模版网站开发&安卓系统app开发,多年建站经验
开封市php开源cms二次开发%精准获客助手,一站式服务
开封市php开源cms二次开发%精准获客助手,一站式服务
在订阅制日益普及的2026年,如何管理才能不让“自动续费”悄悄扣款?
在订阅制日益普及的2026年,如何管理才能不让“自动续费”悄悄扣款?
衡阳市跨省长途救护车出租&长途医疗护送车,全国各地都有车
衡阳市跨省长途救护车出租&长途医疗护送车,全国各地都有车
2026年企业在开发利用公共数据时,需要特别注意哪些法律边界和合规要求?
2026年企业在开发利用公共数据时,需要特别注意哪些法律边界和合规要求?