ssh端口转发.md 8.7 KB

0. 程序,配置

# 在本机(192.168.247.197)上启动
./setup_remote_copilot.sh

远端主机(10.192.72.11)的vscode中配置--远程[SSH:10.192.72.11]

{
    "http.proxyStrictSSL": false,
    "http.systemCertificates": false,
    "Lingma.HttpProxySettings": "manual",
    "Lingma.HttpProxyConfigurationURL": "http://172.16.40.16:7280",
    "http.proxy": "http://localhost:7281",
    "http.proxySupport": "on",
    "github.copilot.enable": {
        "*": true,
        "yaml": true,
        "plaintext": true,
        "markdown": true
    },
    "github.copilot.advanced": {
        "debug.overrideEngine": "codex",
        "debug.useNodeFetcher": true
    },
    "http.proxyAuthorization": null
}

1. 正向端口转发

在mac本机(192.168.247.197)上运行

ssh -L 8082:localhost:8101 10.192.72.11 

就可以在本机(192.168.247.197)通过访问 http://localhost:8082 来访问远程服务了。

2. 双向端口转发

ssh -o "ExitOnForwardFailure=yes"  -o "ServerAliveInterval=60" -o "ServerAliveCountMax=3" -L 8082:localhost:8101 -R 7281:localhost:7890 ubuntu@10.192.72.11

ssh  -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 -o ServerAliveCountMax=3 -L 8082:localhost:8101 -R 7281:localhost:7890 -N ubuntu@10.192.72.11

这个 SSH 命令用于建立隧道连接,让您可以从本地访问远程服务器上的服务,同时为远程服务器提供代理访问。这正好可以解决您 ngrok 连接问题。

让我详细解释这个命令的各个参数:

SSH 隧道命令解析

连接选项 (-o)

  • ExitOnForwardFailure=yes: 如果端口转发失败,立即退出 SSH 连接
  • ServerAliveInterval=60: 每 60 秒发送一次保活信号
  • ServerAliveCountMax=3: 最多发送 3 次保活信号无响应后断开连接

端口转发

  • -L 8082:localhost:8101: 本地端口转发

    • 将本地的 8082 端口转发到远程服务器的 8101 端口
    • 访问 localhost:8082 相当于访问远程服务器的 localhost:8101
  • -R 7281:localhost:7890: 远程端口转发

    • 将远程服务器的 7281 端口转发到本地的 7890 端口
    • 远程服务器访问 localhost:7281 相当于访问您本地的 localhost:7890
  • -R 参数的完整格式

    -R [bind_address:]port:host:hostport
    
    • bind_address: 远程主机上的监听地址(可选), 不指定时默认是localhost
    • port: 远程主机上的监听端口
    • host: 本机的目标地址
    • hostport: 本机的目标端口

      ssh -i /Users/zhch158/.ssh/id_dotsocr_tunnel -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 -o ServerAliveCountMax=3 -L 8082:localhost:8101 -R 7281:localhost:7281 -N ubuntu@10.192.72.11
      

这个 SSH 命令是您安全隧道方案的核心,让我详细解释每个参数的作用:

🔐 SSH 安全隧道命令解析

ssh -i /Users/zhch158/.ssh/id_dotsocr_tunnel \
    -o ExitOnForwardFailure=yes \
    -o ServerAliveInterval=30 \
    -o ServerAliveCountMax=3 \
    -L 8082:localhost:8101 \
    -R 7281:localhost:7281 \
    -N ubuntu@10.192.72.11

📋 参数详解

🔑 身份认证

  • -i /Users/zhch158/.ssh/id_dotsocr_tunnel
    • 使用专用的 SSH 私钥文件
    • 这是您为 DotsOCR 隧道专门生成的密钥,确保独占访问
    • 可以不指定,使用默认的 ~/.ssh/id_rsa 或其他默认密钥

⚙️ 连接选项 (-o)

  • ExitOnForwardFailure=yes

    • 如果任何端口转发失败,立即终止 SSH 连接
    • 确保隧道完整性,避免部分失效的连接
  • ServerAliveInterval=30

    • 每 30 秒发送一次保活信号到服务器
    • 防止长时间无活动导致连接被防火墙断开
  • ServerAliveCountMax=3

    • 最多发送 3 次保活信号无响应后断开
    • 总计 90 秒无响应后自动断开(30秒 × 3次)

🌐 端口转发配置

正向转发 (-L)
-L 8082:localhost:8101
  • 作用: 本地端口转发
  • 含义:
    • 本机的 localhost:8082 → 远程服务器的 localhost:8101
    • 在您的 Mac 上访问 http://localhost:8082 就相当于访问远程服务器的 vLLM 服务
反向转发 (-R)
-R 7281:localhost:7281
  • 作用: 远程端口转发(关键的安全改进)
  • 含义:
    • 远程服务器的 localhost:7281 → 您本机的 localhost:7281
    • 注意:这里转发到 7281 端口,而不是直接的 7890

🚫 执行选项

  • -N

    • 不执行远程命令,只建立端口转发
    • 纯隧道模式,不会打开远程 shell
  • ubuntu@10.192.72.11

    • 连接到远程服务器的用户和地址

🛡️ 安全架构图解

您的 Mac (192.168.247.197)          远程服务器 (10.192.72.11)
┌─────────────────────────┐         ┌─────────────────────────┐
│                         │         │                         │
│  🌐 浏览器              │         │  🤖 vLLM 服务           │
│  localhost:8082 ◄───────┼─────────┼──► localhost:8101       │
│                         │   SSH   │                         │
│  🔒 安全代理服务器      │  隧道   │  其他用户进程           │
│  localhost:7281 ◄───────┼─────────┼──► localhost:7281       │
│         │               │         │         │               │
│         ▼               │         │         ▼               │
│  🎯 本地代理            │         │    ❌ 被拒绝           │
│  localhost:7890         │         │   (安全检查失败)        │
│  (Clash/V2Ray等)        │         │                         │
└─────────────────────────┘         └─────────────────────────┘

SSH非交互式执行的环境隔离

  • 通过 SSH 执行远程脚本时,默认使用最小化的环境
  • 不会加载用户的 shell 配置文件(如 .bashrc, .profile)
  • 系统级的代理环境变量可能不会被继承

🔧 与您的 secure_tunnel.py 的配合

1. 配置文件对应关系

# secure_tunnel.py 中的配置
{
    "local_forward_port": 8082,      # 对应 -L 8082:localhost:8101
    "remote_service_port": 8101,     # 远程 vLLM 服务端口
    "secure_proxy_port": 7281,       # 对应 -R 7281:localhost:7281
    "target_proxy_host": "127.0.0.1",
    "target_proxy_port": 7890        # 最终的代理目标
}

2. 安全流程

  1. 远程服务器上的进程访问 localhost:7281
  2. SSH 隧道将请求转发到您本机的 localhost:7281
  3. 安全代理服务器(secure_tunnel.py)在 7281 端口监听
  4. 进程检查:验证请求是否来自允许的进程(VS Code、Copilot)
  5. 条件转发:只有合法请求才转发到 localhost:7890(您的真实代理)

🚀 使用场景示例

场景 1: 您使用 VS Code + Copilot

# 远程服务器上的 vLLM 进程请求代理
curl http://localhost:7281/some-api

# 流程:
# 1. 请求到达远程服务器的 7281 端口
# 2. SSH 隧道转发到您本机的 7281 端口
# 3. 安全代理检测到 VS Code 进程运行 ✅
# 4. 转发请求到本机的 7890 端口(真实代理)
# 5. 返回响应

场景 2: 其他用户尝试访问

# 其他用户在远程服务器执行
curl http://localhost:7281/some-api

# 流程:
# 1. 请求到达远程服务器的 7281 端口
# 2. SSH 隧道转发到您本机的 7281 端口
# 3. 安全代理检测:没有 VS Code 进程 ❌
# 4. 返回 HTTP 403 Forbidden
# 5. 记录访问日志

🎯 总结

这个命令实现了一个双向安全隧道

  1. 正向隧道:让您在本机访问远程的 vLLM 服务
  2. 反向隧道:为远程服务器提供受控的代理访问
  3. 安全控制:通过中间代理层实现访问权限控制
  4. 进程绑定:只有特定进程才能使用代理服务

🔍 验证监听状态 连接到远程主机后,可以检查端口监听状态:

# 检查监听端口
netstat -tlnp | grep 7281
# 或
ss -tlnp | grep 7281

# 应该看到类似输出:
# tcp 0 0 127.0.0.1:7281 0.0.0.0:* LISTEN  # localhost 监听
# tcp 0 0 0.0.0.0:7281   0.0.0.0:* LISTEN  # 所有接口监听
# tcp 0 0 10.192.72.11:7281 0.0.0.0:* LISTEN  # 特定IP监听

杀死主机上指定用户ubuntu的所有vscode进程

sudo pkill -u ubuntu -f vscode

🛡️ 安全建议 默认使用 localhost:最安全,只有本机用户可访问 避免使用 0.0.0.0:除非确实需要外部访问 使用特定 IP:如果需要内网访问,指定具体的内网 IP 监控访问日志:定期检查谁在使用代理服务