- 正向代理:将本地机器的端口流量转发到远程 SSH 服务器,再由远程服务器访问目标资源,主要用于绕过防火墙/访问内网。
- 反向代理:将远程服务器上的端口流量转发到本地机器,主要用于将内网服务暴露到公网,例如从家里访问公司内网的 Web 服务。
正向代理 - 访问受限资源
这种场景非常常见,

- 你在公司或学校,网络限制了某些网站或服务的访问。
- 你想通过一台可以访问外网的中间服务器(跳板机/Bastion Host)来访问内网资源。
工作原理: 你的本地机器 -> (加密) -> SSH 代理服务器 -> (解密并转发) -> 目标服务器/互联网
示例:通过跳板机访问内网 Web 服务器
假设我们有以下网络环境:
- 你的本地机器 (Local Machine):
your_local_ip(例如家里的电脑) - 跳板机/SSH 代理服务器 (Bastion Host):
bastion_ip(一台可以公网访问的 Linux 服务器) - 内网目标 Web 服务器 (Target Server):
target_server_ip(公司内网的一台机器,无法从公网直接访问)
目标: 在你的本地浏览器上访问 http://target_server_ip。

方法 A:使用 ssh -L (本地端口转发)
这种方法是在你的本地机器上发起连接,将本地的一个端口绑定到跳板机,再通过跳板机访问目标服务器。
-
在本地机器上执行命令:
ssh -L 8080:target_server_ip:80 your_user@bastion_ip
-L 8080:target_server_ip:80: 这是关键参数。8080: 你本地机器上的一个空闲端口。target_server_ip:80: 你最终想访问的目标服务器的地址和端口。
your_user@bastion_ip: 你登录跳板机的用户名和地址。
-
工作流程:
- 这个命令会建立一个从你的本地机器到
bastion_ip的 SSH 连接。 - 当你本地访问
http://localhost:8080时,数据会被发送到 SSH 连道中。 - SSH 客户端会将这些数据通过加密隧道发送到跳板机。
- 跳板机上的 SSH 服务器会收到数据,并将其解密,然后作为本地请求去访问
target_server_ip的 80 端口。 - 目标服务器的响应会原路返回。
- 这个命令会建立一个从你的本地机器到
-
访问:
(图片来源网络,侵删)- 保持上面的 SSH 会话开启。
- 在你的本地浏览器中打开
http://localhost:8080,你就能看到内网 Web 服务器的页面了。
方法 B:使用 ssh -R (远程端口转发) - 更灵活的代理
这种方法是在跳板机上执行命令,将跳板机上的一个端口绑定到你的本地机器,实现一个反向的代理,这更符合“代理服务器”的概念,因为跳板机主动暴露了一个端口。
-
前提: 你需要能够登录到跳板机,并且有权限在跳板机上执行命令。
-
在跳板机上执行命令:
ssh -R 8888:localhost:80 your_user@bastion_ip
- 这个命令需要在你本地机器上运行,但它建立的是一个反向隧道。
-R 8888:localhost:80: 关键参数。8888: 跳板机上要监听的端口。localhost:80: 你的本地机器上的地址和端口(注意,这里的localhost是指跳板机自己,但我们想让它指向你的本地机器,所以需要更复杂的配置,或者我们换个更清晰的例子)。
让我们用一个更清晰的例子来解释反向代理:
- 目标: 将跳板机上的
8888端口,映射到你本地的22端口。 - 命令:
ssh -R 8888:localhost:22 your_user@bastion_ip - 效果: 任何人(包括你自己)如果连接到跳板机的
8888端口,这个连接实际上会被转发到你本地机器的22端口,这相当于你为你的 SSH 服务创建了一个公网入口。
反向代理 - 将内网服务暴露到公网
这种场景主要用于安全地将内网的服务(如个人项目、数据库管理界面)暴露给外网访问,而无需在路由器上做复杂的端口映射(NAT)。
工作原理: 内网服务器 -> (主动连接) -> SSH 代理服务器 -> (转发) -> 公网访问
示例:从家里访问公司内网的 Jira 服务
假设我们有以下网络环境:
- 你的本地机器 (Local Machine):
your_local_ip(公司内网的一台电脑) - 内网 Jira 服务器:
jira_server_ip(内网地址,端口8080) - SSH 代理服务器 (Bastion Host):
bastion_ip(一台可以公网访问的 Linux 服务器)
目标: 在你的家里电脑上访问 http://bastion_ip:8888,并看到公司内网的 Jira 页面。
方法:使用 ssh -R (远程端口转发)
这是 ssh -R 的典型应用场景。
-
在内网服务器上执行命令: 你需要在可以访问 Jira 服务器的内网机器(Jira 服务器本身,或任何一台能访问它的机器)上执行以下命令:
ssh -N -R 8888:localhost:8080 your_user@bastion_ip
-N: 表示不执行远程命令,仅用于端口转发。-R 8888:localhost:8080: 这是核心。8888: 代理服务器(bastion_ip)上要监听的端口。localhost:8080: 内网 Jira 服务器的地址和端口(这里的localhost是指执行这条命令的机器,Jira 在另一台机器上,就写成jira_server_ip:8080)。
your_user@bastion_ip: 登录代理服务器的用户名和地址。
-
工作流程:
- 这个命令会在内网服务器和代理服务器之间建立一个持久的 SSH 连接。
- 代理服务器上的 SSH 守护进程会监听
8888端口。 - 当有人(比如你在家)访问
http://bastion_ip:8888时,代理服务器会接收这个请求。 - 由于我们使用了
-R,代理服务器知道这个请求需要通过已建立的 SSH 隧道,转发到内网服务器的8080端口。 - 内网服务器处理请求,并将响应通过隧道返回。
-
访问:
- 保持在内网服务器上的 SSH 会话开启。
- 在任何能访问
bastion_ip的设备上(包括你的手机、家里的电脑),打开浏览器访问http://bastion_ip:8888,你就能看到公司的 Jira 页面了。
高级配置与持久化
默认情况下,SSH 会话是交互式的,一旦关闭终端,连接就会断开,要实现一个稳定、持久的服务,你需要使用一些高级技巧。
使用 autossh 自动重连
autossh 是一个专门用来监控 SSH 连接并在其断开时自动重连的工具。
安装:
# Debian/Ubuntu sudo apt-get install autossh # CentOS/RHEL/Fedora sudo yum install autossh
使用示例(反向代理):
autossh -M 20000 -N -R 8888:localhost:8080 your_user@bastion_ip
-M 20000:autossh会使用20000和20001这两个端口来监控连接状态,确保这些端口是空闲的。
使用 systemd 服务(推荐)
这是最稳定、最专业的方式,可以让 SSH 隧道作为系统服务在后台运行,并随系统启动。
步骤:
-
创建一个 systemd 服务文件,
/etc/systemd/system/ssh-tunnel.service:[Unit] Description=Persistent SSH Tunnel to Bastion Host After=network.target [Service] User=your_user # 执行隧道的用户 ExecStart=/usr/bin/ssh -N -R 8888:localhost:8080 your_user@bastion_ip Restart=always # 总是尝试重启 RestartSec=10 # 每次重启间隔10秒 [Install] WantedBy=multi-user.target
-
启动并启用服务:
# 重新加载 systemd 配置 sudo systemctl daemon-reload # 启动服务 sudo systemctl start ssh-tunnel.service # 设置服务开机自启 sudo systemctl enable ssh-tunnel.service # 查看服务状态 sudo systemctl status ssh-tunnel.service
安全注意事项
- 使用密钥认证:永远不要使用密码进行自动化连接,请务必为 SSH 设置基于密钥的认证,并禁用密码登录。
- 在本地机器生成密钥:
ssh-keygen -t rsa -b 4096 - 将公钥复制到代理服务器:
ssh-copy-id your_user@bastion_ip
- 在本地机器生成密钥:
- 限制用户权限:用于建立隧道的用户应该是一个权限受限的用户,最好只允许执行
ssh命令,可以使用rbash(restricted bash) 或配置authorized_keys文件中的command选项来限制。 - 防火墙:确保代理服务器的防火墙规则只允许必要的端口(如 22)和转发端口(如 8888)被访问。
- 关闭不必要的功能:在
sshd_config中,可以禁用X11Forwarding,TcpForwarding等不需要的功能以提高安全性。
| 功能 | 命令 | 主要用途 | 流向 |
|---|---|---|---|
| 正向代理 | ssh -L |
从本地安全访问远程/内网资源 | 本地 -> SSH服务器 -> 目标 |
| 反向代理 | ssh -R |
将内网服务安全暴露到公网 | 内网 -> SSH服务器 -> 公网 |
选择哪种方式取决于你的具体需求,为了实现稳定、自动化的代理服务器,ssh -R 配合 systemd 服务是生产环境中的最佳实践。
