凌峰创科服务平台

linux ssh 代理服务器

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

正向代理 - 访问受限资源

这种场景非常常见,

linux ssh 代理服务器-图1
(图片来源网络,侵删)
  • 你在公司或学校,网络限制了某些网站或服务的访问。
  • 你想通过一台可以访问外网的中间服务器(跳板机/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

linux ssh 代理服务器-图2
(图片来源网络,侵删)

方法 A:使用 ssh -L (本地端口转发)

这种方法是在你的本地机器上发起连接,将本地的一个端口绑定到跳板机,再通过跳板机访问目标服务器。

  1. 在本地机器上执行命令:

    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: 你登录跳板机的用户名和地址。
  2. 工作流程:

    • 这个命令会建立一个从你的本地机器到 bastion_ip 的 SSH 连接。
    • 当你本地访问 http://localhost:8080 时,数据会被发送到 SSH 连道中。
    • SSH 客户端会将这些数据通过加密隧道发送到跳板机。
    • 跳板机上的 SSH 服务器会收到数据,并将其解密,然后作为本地请求去访问 target_server_ip 的 80 端口。
    • 目标服务器的响应会原路返回。
  3. 访问:

    linux ssh 代理服务器-图3
    (图片来源网络,侵删)
    • 保持上面的 SSH 会话开启。
    • 在你的本地浏览器中打开 http://localhost:8080,你就能看到内网 Web 服务器的页面了。

方法 B:使用 ssh -R (远程端口转发) - 更灵活的代理

这种方法是在跳板机上执行命令,将跳板机上的一个端口绑定到你的本地机器,实现一个反向的代理,这更符合“代理服务器”的概念,因为跳板机主动暴露了一个端口。

  1. 前提: 你需要能够登录到跳板机,并且有权限在跳板机上执行命令。

  2. 在跳板机上执行命令:

    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 的典型应用场景。

  1. 在内网服务器上执行命令: 你需要在可以访问 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: 登录代理服务器的用户名和地址。
  2. 工作流程:

    • 这个命令会在内网服务器和代理服务器之间建立一个持久的 SSH 连接。
    • 代理服务器上的 SSH 守护进程会监听 8888 端口。
    • 当有人(比如你在家)访问 http://bastion_ip:8888 时,代理服务器会接收这个请求。
    • 由于我们使用了 -R,代理服务器知道这个请求需要通过已建立的 SSH 隧道,转发到内网服务器的 8080 端口。
    • 内网服务器处理请求,并将响应通过隧道返回。
  3. 访问:

    • 保持在内网服务器上的 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 会使用 2000020001 这两个端口来监控连接状态,确保这些端口是空闲的。

使用 systemd 服务(推荐)

这是最稳定、最专业的方式,可以让 SSH 隧道作为系统服务在后台运行,并随系统启动。

步骤:

  1. 创建一个 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
  2. 启动并启用服务:

    # 重新加载 systemd 配置
    sudo systemctl daemon-reload
    # 启动服务
    sudo systemctl start ssh-tunnel.service
    # 设置服务开机自启
    sudo systemctl enable ssh-tunnel.service
    # 查看服务状态
    sudo systemctl status ssh-tunnel.service

安全注意事项

  1. 使用密钥认证:永远不要使用密码进行自动化连接,请务必为 SSH 设置基于密钥的认证,并禁用密码登录。
    • 在本地机器生成密钥:ssh-keygen -t rsa -b 4096
    • 将公钥复制到代理服务器:ssh-copy-id your_user@bastion_ip
  2. 限制用户权限:用于建立隧道的用户应该是一个权限受限的用户,最好只允许执行 ssh 命令,可以使用 rbash (restricted bash) 或配置 authorized_keys 文件中的 command 选项来限制。
  3. 防火墙:确保代理服务器的防火墙规则只允许必要的端口(如 22)和转发端口(如 8888)被访问。
  4. 关闭不必要的功能:在 sshd_config 中,可以禁用 X11Forwarding, TcpForwarding 等不需要的功能以提高安全性。
功能 命令 主要用途 流向
正向代理 ssh -L 从本地安全访问远程/内网资源 本地 -> SSH服务器 -> 目标
反向代理 ssh -R 将内网服务安全暴露到公网 内网 -> SSH服务器 -> 公网

选择哪种方式取决于你的具体需求,为了实现稳定、自动化的代理服务器,ssh -R 配合 systemd 服务是生产环境中的最佳实践。

分享:
扫描分享到社交APP
上一篇
下一篇