服务器免密登录与流量端口转发

概览

实现 SSH 免密登录,并让云服务器流量转发到本地端口,通过代理再返回。

免密登录

打开 ~/.ssh/config,写入:

bash 复制代码
Host <server ip>
    HostName <server ip>
    User root           # 默认为 root 用户
    Port 22             # SSH 默认端口

打开 Cursor 的 Remote Explorer,会看到多了 <server ip> 这个选项。

现在配置免密

  1. 本机生成密钥

    bash 复制代码
    ssh-keygen -t ed25519  # 随便取一个文件名
  2. 公钥写入服务器

    bash 复制代码
    ssh-copy-id ~/.ssh/id_ed25519.pub <user>@<server-ip>
  3. 验证免密登录

打开 Cursor 的 Remote Explorer,直接点击配置的 <server ip>;也可以使用命令行:

bash 复制代码
ssh <user>@<server-ip>

端口转发与代理

原理

建立与云服务器的 SSH 正向隧道后,再搭建一条反向隧道(云服务器 -> 本机)。以下以 "云服务器 1080 端口 ↔ 本机 7897 端口" 为例:

  • 云服务器访问外网时,将流量统一发到 1080 端口。
  • 反向隧道把 1080 端口的流量转发到本机 7897。
  • 本机 7897 端口交给代理软件,按节点分发,再把结果回传给云服务器。

实现

提供三种实现方法,实现方法三选一即可, 但是前置步骤要完成

前置步骤
  1. 在代理软件的端口设置中开启混合端口转发(以 7897 为例)。
  2. 在云服务器中配置环境变量,统一走 1080 端口。编辑 ~/.bashrc
bash 复制代码
# 代理配置
PROXY_SERVER="127.0.0.1"
PROXY_PORT="1080"
PROXY_URL="http://$PROXY_SERVER:$PROXY_PORT"

# 使用 curl 快速检测(1秒超时)
if curl -s -o /dev/null -w "%{http_code}" --max-time 1 -x "$PROXY_URL" https://www.google.com 2>/dev/null | grep -q "200"; then
    export http_proxy="$PROXY_URL"
    export https_proxy="$PROXY_URL"
    export HTTP_PROXY="$PROXY_URL"
    export HTTPS_PROXY="$PROXY_URL"
    echo "✓ 代理可用,已启用"
else
    unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY
    echo "✗ 代理不可用,直连模式"
fi

# .bashrc 中添加函数
proxy_on() {
    export http_proxy="http://127.0.0.1:1080"
    export https_proxy="http://127.0.0.1:1080"
    export HTTP_PROXY="http://127.0.0.1:1080"
    export HTTPS_PROXY="http://127.0.0.1:1080"
    echo "✓ 代理已启用"
}

proxy_off() {
    unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY
    echo "✗ 代理已关闭"
}

proxy_test() {
    echo "测试代理..."
    curl --proxy http://127.0.0.1:1080 -I -s https://www.google.com
}

保存后运行 source ~/.bashrc 使其生效。

  1. 编辑 /etc/ssh/sshd_config,将以下参数取消注释并设为 yes
    • AllowTcpForwarding:允许 SSH 客户端发起本地/远程端口转发。
    • GatewayPorts:远程端口转发可绑定 0.0.0.0/::
    • PermitTunnel:允许基于 SSH 的三层隧道。
三种方法

注: 三种方法在云服务器上绑定的端口都是 1080, 最好用完一个方法就关闭, 而不是一起使用, 否则可能造成端口冲突

  1. 写入本地 SSH 配置
    ~/.ssh/config 中(基于免密配置)写入:
bash 复制代码
Host <server ip>
    HostName <server ip>
    User root
    Port 22
    # 追加下面三条即可
    RemoteForward 1080 localhost:7897
    ServerAliveInterval 30
    ServerAliveCountMax 3

写好后,Cursor 远程连接服务器时会自动启动反向隧道。

  1. 使用脚本与工具保持隧道

    • 普通 SSH,一旦关闭终端会话就会断开:
    bash 复制代码
    ssh -M 0 -f -N -v -o ServerAliveInterval=30 -o ServerAliveCountMax=3 \
        -i ~/.ssh/<key file name> -R 1080:localhost:7897 <user>@<server ip>
    • 使用 autossh 可以保持连接,先通过 Homebrew 安装:
    bash 复制代码
    brew install autossh

    再写脚本方便启动和提示:

bash 复制代码
# 文件名 start_ssh_tunnel.sh
autossh -M 0 -f -N -v -g -o ServerAliveInterval=30 -o ServerAliveCountMax=3 -i ~/.ssh/<key file name> -R 1080:localhost:7897 <user>@<server ip>

if [ $? -eq 0 ]; then
  echo -e "\033[32m✅ 隧道启动成功!\033[0m"
  echo -e "📌 验证方法:"
  echo -e "  1. Mac 端查看进程:ps aux | grep autossh"
  echo -e "  2. 服务器端查看端口:ss -tulnp | grep :1080"
  echo -e "  3. 关闭隧道:pkill autossh"
else
  echo -e "\033[31m❌ 隧道启动失败!\033[0m"
  echo -e "🔍 可能原因:"
  echo -e "  1. autossh 未安装(执行 brew install autossh)"
  echo -e "  2. 密钥路径错误(当前路径:~/.ssh/id_rsa)"
  echo -e "  3. 服务器 1080 端口被占用"
fi

后续操作:

bash 复制代码
# 打开端口转发
./start_ssh_tunnel.sh

# 关闭端口转发
pkill autossh

# 查看 autossh 相关进程(含 grep 本身)
ps aux | grep autossh
  1. Termius 配置端口转发

    在 Termius 左侧 Port Forwarding 中新建规则:

    • Remote host: <server ip>
    • Remote port: 1080
    • Bind address: 127.0.0.1
    • Destination address: 127.0.0.1
    • Destination port: 7897

    没搞懂 Bind address 和 Destination address 的区别 不过确认 Termius 显示 From <server ip>:1080 to 127.0.0.1:7897 即表示已连通,启用后再连接服务器即可完成转发。

测试

测试要使用 curl, 而不能使用 ping 因为 ping 基于 ICMP 协议, 运行在网络层,而我们配置的 SSH 端口转发 + 代理仅支持 TCP/UDP 协议,ICMP 数据包无法通过代理隧道转发

bash 复制代码
# 请求国内网络
curl --proxy http://127.0.0.1:1080 -I -s https://www.baidu.com

# 请求国外网络
curl --proxy http://127.0.0.1:1080 -I -s https://www.google.com
相关推荐
开开心心_Every2 小时前
解决打印机共享难题的实用工具
linux·b树·安全·游戏·随机森林·pdf·计算机外设
江华森4 小时前
操作系统与 Linux 内核实战教程
linux·运维·服务器
齐潇宇4 小时前
Redis数据库基础
linux·数据库·redis·缓存
嵌入式学习和实践4 小时前
Ubuntu 系统 socat 详细介绍与使用教程 - 映射任意两种数据通道
linux·ubuntu·虚拟串口·数据映射·socat
小此方5 小时前
Re:Linux系统篇(二十八)文件篇·一:理解 Linux 文件基础I/O、Linux 文件操作与系统调用机制
linux·运维·服务器
likerhood5 小时前
Linux 服务器基础资源查看:CPU、GPU、内存、磁盘与一键检测脚本
linux·运维·服务器
AOwhisky5 小时前
学习自测与解析:MySQL 系列第三期与第四期
linux·运维·数据库·学习·mysql·云计算
流浪0015 小时前
Linux系统篇(三):Linux 命令行参数 & 环境变量:程序和系统沟通的底层逻辑
linux·运维·服务器
Ameilide5 小时前
Linux 应用软件编程 多任务并发
linux·运维·服务器