端口转发与SSH隧道实战:Nginx stream、iptables DNAT与内网穿透


一、端口转发与隧道:内网穿透的两把钥匙

现实里常遇到:数据库、后台管理页、开发服务只监听内网,想从公网/家里访问;或想通过一台公网服务器把流量转发到内网某服务。这就是端口转发与 SSH 隧道。端口转发在"Nginx/iptables 层"做目标地址/端口改写;SSH 隧道则通过加密的 SSH 连接建立安全的"管道",分本地转发、远程转发、动态转发三种。下面分别讲透,并给出常见落地场景。

二、Nginx 端口转发(stream 模块)

非 HTTP 的 TCP 流量(如 MySQL 3306、MongoDB)用 Nginx 的 stream 层转发最方便:

# /etc/nginx/nginx.conf 主配置顶部(stream 块与 http 平级)
stream {
    upstream mysql_backend {
        server 10.0.0.5:3306;
    }
    server {
        listen 3306;
        proxy_pass mysql_backend;
        proxy_connect_timeout 5s;
    }
}
sudo nginx -t && sudo systemctl reload nginx

这样外部访问该机的 3306 即被转到内网 10.0.0.5:3306。配 stream 要注意:stream 块和多的是 separate,不能用 http 的 location;同时转发 MySQL 这类敏感服务务必限制来源 IP + 结合防火墙与 fail2ban。它适合"跳板机帮内网服务对外暴露"的场景。

三、iptables DNAT 端口转发

更"底层"的是 iptables 的 NAT 转发,把公网端口映射到内网主机(需开启内核转发):

echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.conf && sudo sysctl -p

# 把本机公网 2080 转发到内网 10.0.0.5:80
sudo iptables -t nat -A PREROUTING -p tcp --dport 2080 \
     -j DNAT --to-destination 10.0.0.5:80
sudo iptables -t nat -A POSTROUTING -p tcp -d 10.0.0.5 --dport 80 \
     -j MASQUERADE
# 放行并持久化(RHEL 系 service iptables save)
sudo iptables -L -t nat -n

关键点:PREROUTING 做 DNAT(改目标),POSTROUTING 做 MASQUERADE(改源,保证回包能回来)。iptables 转换针对"路由转发"场景,和 Nginx stream 思路不同——前者是内核网络层,后者是用户态代理。二选一依据你的管理习惯与拓扑。

四、SSH 本地转发:把远程服务"拉到本地"

手机/笔记本在外网想访问家里/办公网的某端口,可用 SSH 本地转发:

# 把远程服务器上的 3306(数据库)映射到本地 13306
ssh -L 13306:127.0.0.1:3306 user@server_ip
# 之后本地 127.0.0.1:13306 即通向 server 的 3306

# 挂在后台且不死(-f 后台 -N 不执行命令 -n 禁 stdin)
ssh -f -N -L 13306:127.0.0.1:3306 user@server_ip

图上示意:本机 13306 ←→ 隧道 ←→ server 的 3306。它用加密 SSH 把"远端网络"完整连到本机,适合安全访问开发库而不用把端口暴露公网。

五、SSH 远程转发与跳板

反向场景:把"位于防火墙后面、无法被连入"的内网机器,通过一台公网服务器反向暴露:

# 在内网机器上执行:让公网 Nginx/端口 转发到本机 80
ssh -R 8080:localhost:80 user@publicserver
# 访问 publicserver:8080 即到达内网机原 80 服务

# 动态转发:把 SSH 客户端所在机器作为 SOCKS 代理
ssh -D 1080 user@server_ip
# 之后浏览器 HTTP 代理指向 127.0.0.1:1080 即可借该服务器上网

远程转发(-R)常在"家/内网主机主动连向公网"场景用于内网穿透;动态转发(-D)则把该连接变成 SOCKS 代理,是临时科学上网、调试内网的利器。三者本质都一样:建立加密隧道,区别只在于"数据从哪端进入隧道"。性能上 SSH 隧道有加解密开销,高吞吐场景可考虑 WireGuard(见前文)更专业。

六、安全与防呆建议

  • 最小暴露:只转发业务需要的端口,敏感服务锁来源 IP。
  • 结构清晰:用注释标明每条约道的用途,别堆积一堆说不清规则的转发。
  • SSH 密钥:隧道自动连接用密钥免密,别挂明文密码到脚本。
  • 防火墙配合:转发的目标端口用 firewalld/iptables 限制,结合 fail2ban 防爆破。
  • 端口冲突:先 `ss -tlnp | grep :端口` 确认没被占。
  • 生命周期:隧道断开会自动退出,监控脚本可建议 `ServerAliveInterval` 保持连接。

写在最后

端口转发与 SSH 隧道是运维里"把不在手边的服务接到手上"的核心技能。总结:对外提供服务选 Nginx stream 或 iptables DNAT;安全访问内部服务选 SSH 本地转发;内网方向选 SSH 远程转发;代理上网选动态转发。实践上从"本地转发访问一个开发库"起步,逐步扩展到跳板和转发链路。记住"最小暴露 + 加密 + 防火墙收紧"三条原则,你就能安全地把内网、公网、多台服务器灵活地串起来。


手机扫码阅读

微信或手机浏览器扫一扫,随时随地随心阅读与分享

Linux RAID 软阵列实战:mdadm 创建、故障替换与数据重建

Redis缓存实战:安装配置、PHP接入与持久化调优

评 论
更换验证码