itfetter.文章合集归档关于我联系 ↗
其他 · · · 阅读 0

通过 SSH 隧道访问在云服务部署的项目

Linux 项目部署后,如何通过 SSH 隧道在本地访问?

跳到评论 ↓

Linux 项目部署后,如何通过 SSH 隧道在本地访问?

项目已经部署到 Linux 云服务器上,但还没有配置域名,或者暂时不想将应用端口开放到公网,怎么在自己的电脑上查看?

可以使用 SSH 本地端口转发。它在本机建立一个入口,通过 SSH 加密连接,把浏览器请求转发到服务器上的应用。程序和数据库仍在云服务器运行,不需要把项目下载到本机。

本文以 Windows 电脑访问 Linux 上的 Docker 网站为例。macOS、Linux 客户端的 SSH 命令基本相同。

一、先理解访问路径

image.png

127.0.0.1 指当前设备自身。本机浏览器中的 127.0.0.1 指你的电脑;服务器终端中的同一个地址指云服务器。它们不是同一个网络入口。

因此,云服务器部署好项目后,在电脑打开 http://127.0.0.1:3100,并不会自动访问云端。必须先让本机有程序接收请求,再将请求转发出去。SSH 的 -L 参数就是用来建立这条路径的。

本文示例采用不同端口,帮助区分三个层次:

位置 地址或端口 用途
本机 127.0.0.1:13100 浏览器访问入口
云服务器 127.0.0.1:3100 宿主机发布的应用端口
容器 0.0.0.0:3000 应用实际监听端口
云服务器 SSH 22 建立加密连接

本机与远端端口也可以都用 3100,只要本机端口没有被占用。

二、准备条件与项目端口

需要有一台能通过 SSH 登录的 Linux 服务器、对应账号,以及已经启动的应用。示例服务器地址为 203.0.113.10、账号为 deploy。这是文档示例地址,操作时必须替换为自己的实际信息。

本机先检查是否已有 SSH:

ssh -V

能输出版本即可使用,无需为建立隧道安装项目依赖、数据库或 Docker。若找不到命令,再按系统的 OpenSSH 客户端安装方式处理。

如果项目通过 Docker Compose 运行,端口配置可能如下:

services:
  blog:
    image: ghcr.io/your-account/your-project:your-version
    restart: unless-stopped
    ports:
      - "127.0.0.1:3100:3000"

这是已有项目的配置示意,不是可以独立部署所有网站的完整文件。镜像、数据卷和环境变量应采用项目自己的配置。

映射的含义是:服务器回环地址的 3100 转入容器的 3000。容器内应用通常应监听 0.0.0.0:3000,而宿主机发布入口限定为 127.0.0.1:3100。二者作用不同。

通过隧道预览通常只需要允许 SSH 连接,不必额外在安全组中向公网开放应用的 3100 端口。

三、先在服务器验证应用

在本机终端中登录服务器:

ssh deploy@203.0.113.10

若 SSH 端口是 2222:

ssh -p 2222 deploy@203.0.113.10

首次连接时核对服务器指纹;密码认证输入时通常没有字符和星号回显,这是正常现象。这里输入的是服务器登录密码,不是网站后台密码。

登录后,在 Linux 服务器中执行:

curl -I http://127.0.0.1:3100/

如果应用不支持 HEAD 请求,改用:

curl -sS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3100/

200 或符合预期的登录跳转说明已有 HTTP 响应。若连接失败,先检查应用,不要急着建立隧道。

Docker 项目可以查看:

docker ps
docker logs --tail 100 你的容器名称

重点看容器是否运行、端口映射是否为预期值、日志是否有启动错误。ss -lntp 可辅助检查监听,但 Docker 也可能通过网络转发规则发布端口,不能仅凭这一条命令判断映射是否成功。

验证成功后执行 exit,返回本机终端。

四、在本机开启隧道

下面这条命令在自己的电脑上运行,不是在服务器里运行:

ssh -N -T -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 -o ServerAliveCountMax=3 -L 127.0.0.1:13100:127.0.0.1:3100 deploy@203.0.113.10

认证成功后通常没有新输出,窗口会一直停在那里。保持窗口打开,再在浏览器访问:

http://127.0.0.1:13100

参数解释:

参数 含义
-N 不执行远程命令,连接专门用于转发
-T 不分配远程伪终端
-L 创建本地转发
第一个 127.0.0.1:13100 本机监听入口
第二个 127.0.0.1:3100 从 SSH 服务器角度连接的目标
ExitOnForwardFailure=yes 转发入口无法建立时退出,例如本地端口被占用
ServerAliveInterval=30 空闲时每隔约 30 秒探测 SSH 服务端
ServerAliveCountMax=3 连续探测无响应达到设定次数后断开

保活不是自动重连。网络断开后仍可能需要重新执行命令。转发入口建立成功,也不保证目标网站正常运行。

如果 SSH 使用 2222,增加 -p 2222:

ssh -p 2222 -N -T -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 -o ServerAliveCountMax=3 -L 127.0.0.1:13100:127.0.0.1:3100 deploy@203.0.113.10

想让本机也使用 3100,则将 -L 改为:

-L 127.0.0.1:3100:127.0.0.1:3100

浏览器也相应改为 http://127.0.0.1:3100。

五、判断隧道是否开启

另开一个 PowerShell 窗口,分层检查。

1. 检查本机端口

Test-NetConnection 127.0.0.1 -Port 13100 -InformationLevel Quiet

True 说明本机端口能建立 TCP 连接;False 说明不能连接,应检查隧道是否退出、端口是否填错。

端口能连接也可能是其他程序在监听。进一步查看:

Get-NetTCPConnection -LocalPort 13100 -State Listen |
    Select-Object LocalAddress, LocalPort, OwningProcess

根据输出的进程编号查询,例如编号为 12345:

Get-Process -Id 12345

请替换为实际编号,不要直接照抄。

2. 检查网站响应

curl.exe --noproxy "*" -I http://127.0.0.1:13100/

显式使用 curl.exe,避免部分 PowerShell 环境把 curl 解释为其他命令;--noproxy "*" 让这次请求直接访问本机。

3. 检查完整页面

用浏览器检查文章、图片、登录和接口。首页能显示不代表所有请求正常,尤其需要留意接口是否写死旧域名或另一个端口。

六、关闭隧道与重新连接

前台运行时,在 SSH 窗口按 Ctrl+C 即可关闭。

关闭隧道只会断开本机访问入口,不会停止服务器上的应用或容器。

如果由工具在后台启动,先根据监听端口找到进程,并确认确实属于目标 SSH 隧道,再结束对应进程。例如:

Stop-Process -Id 12345

不要结束所有 SSH 进程,以免中断其他会话。

电脑休眠、重启、网络切换、VPN 切换或 SSH 服务重启都可能造成断线。此时浏览器刷新不会重建隧道,需要重新执行连接命令。

如果日志显示 Connection reset,说明连接被重置,单凭这一行还无法判定是本机网络、链路设备还是远端造成的。

七、保存配置,减少重复输入

Windows 的配置文件通常为 C:\Users\你的用户名\.ssh\config;macOS、Linux 通常为 ~/.ssh/config。如果已有配置,请在文件中追加,不要覆盖其他连接。

Host blog-preview
    HostName 203.0.113.10
    User deploy
    Port 22
    LocalForward 127.0.0.1:13100 127.0.0.1:3100
    ExitOnForwardFailure yes
    ServerAliveInterval 30
    ServerAliveCountMax 3

以后运行:

ssh -N -T blog-preview

使用私钥认证时,可以在该配置段增加实际私钥路径:

    IdentityFile ~/.ssh/id_ed25519

配置文件不用保存明文密码。运行后仍应保持会话,直到不再需要预览。

八、常见故障排查

image.png

浏览器提示 ERR_CONNECTION_REFUSED

先检查本机监听端口。没有监听时,通常是隧道关闭或地址填错,不要直接判断为云端网站故障。

提示 Address already in use

本机端口已被占用。核对占用进程;如果已有可用隧道,直接使用,否则换一个本机端口。远端 3100 不需要跟着改。

提示 channel open failed: connect failed: Connection refused

通常说明 SSH 已连接,但服务器无法连接转发目标。登录 Linux,用 curl 检查 127.0.0.1:3100,核对应用状态和端口映射。

SSH 连接超时

核对公网 IP、SSH 端口、安全组、系统防火墙、SSH 服务以及本机网络。此时优先排查 SSH 链路,而不是开放网站端口。

提示 administratively prohibited

SSH 服务端可能限制了转发。应让服务器管理员核对 AllowTcpForwarding、DisableForwarding、PermitOpen 或账号密钥限制。不要为了排障直接放开所有 SSH 权限。

页面能打开,但文章一直加载

在浏览器开发者工具的 Network 面板检查失败请求:是否访问旧域名、是否跨域、是否遇到登录 Cookie/HTTPS 限制、后端接口是否返回错误。

SSH 只负责转发连接,不会改写前端接口地址、重定向或应用登录策略。

需要更多诊断信息

命令增加 -v:

ssh -v -N -T -L 127.0.0.1:13100:127.0.0.1:3100 deploy@203.0.113.10

分享日志前遮挡不想公开的账号、地址和路径,不要分享密码或私钥。

九、手机访问与正式域名访问

手机中的 127.0.0.1 指手机自己,不能用它直接访问电脑上的隧道。检查手机排版可以先用浏览器窄屏模拟;真机测试应使用另行配置的受控入口或 HTTPS 测试域名。

SSH 隧道适合个人预览、维护内部页面。面向读者的正式网站一般采用:

读者浏览器 → 域名与 HTTPS → Nginx 等反向代理
                              ↓
                     服务器 127.0.0.1:3100
                              ↓
                           网站应用

这样读者不需要 SSH 账号,你的电脑也无需一直在线。隧道可以保留为维护工具,但不承担正式网站的公共访问入口。

官方参考

本文配图为原创 SVG 示意图。Markdown 与 images 文件夹放在一起即可保留相对图片链接;发布到博客时需将图片上传到博客媒体库,再替换图片地址。

感谢读到这里。有想法?和我聊聊 ↗
LET’S TALK

评论与讨论

加入这场讨论

你的问题、补充和不同视角,都很欢迎。

0 / 3000

提交后公开显示 · 昵称由访客自填 · 请勿填写私密信息

全部讨论

最新主评论在前

正在加载讨论…