我用 Rust 写了一个 SSH 本地端口转发管理器:Via 的实现与取舍
工作中访问内网的数据库、缓存和搜索服务我一直在跳板机后面开 SSH 本地端口转发再用一堆 bash 脚本统一启动这些隧道。脚本越攒越多散在各个目录哪条规则改过、哪个隧道断了全靠记忆和手动重跑。市面上有终端、有 SFTP 工具但没有一个专门用来统一管理和记录 SSH 本地转发的所以我写了 Via——一个 macOS 桌面端的 SSH 本地端口转发管理器。读完这篇文章能判断它适不适合自己的工作流。仓库地址https://github.com/colinrs/viaVia 在解决什么问题SSH 的-L参数能把本机端口经跳板机转发到内网地址Via 做的就是这个只是把它做成了一张可编辑的表格127.0.0.1:3306 → bastion.example.comSSH 会话 → rds.internal:3306一条规则一行本地端口、目标主机、目标端口三个字段加上状态和开关。本机连127.0.0.1:3306就等于连上只有跳板机才够得到的内网服务。规则按会话分组一个跳板机下面挂多条转发数据库、Redis、OpenSearch 各占一行。转发数据链路怎么实现核心逻辑在src-tauri/src/services/forwarder.rs里整个流程只有四步在127.0.0.1:local_port上 bind 一个TcpListener。每 accept 到一个本地连接通过已认证的 SSH 会话open_direct_tcpip打开一条到target_host:target_port的通道。在本端连接和 SSH 通道之间copy_bidirectional双向拷贝字节。字节流就透明地流到了内网服务。关键代码的骨架如下重点看 accept 循环和每个连接的处理方式letlistenerTcpListener::bind((Ipv4Addr::LOCALHOST,rule.local_port)).await?;lettasktokio::spawn(asyncmove{loop{tokio::select!{_task_cancel.cancelled()break,acceptedlistener.accept()matchaccepted{Ok((mutinbound,_)){// 每个本地连接单独开一条 direct-tcpip 通道tokio::spawn(asyncmove{ifletOk(mutoutbound)session.open_direct_tcpip(host,port).await{let_tokio::io::copy_bidirectional(mutinbound,mutoutbound).await;}});}Err(_)break,}}}});这段代码里每个进来的连接都单独 spawn 一个 task各开各的 direct-tcpip 通道互不影响一条规则失败不会影响同一会话里的其他规则。bind 地址固定是Ipv4Addr::LOCALHOST这决定了 Via 的一条安全边界隧道永远只监听回环不会暴露到局域网。bind 失败时把AddrInUse单独映射成ViaError::PortConflict前端就能直接显示「端口被占用」。技术选型前端是 Vue 3 TypeScript Vite配置、加密、SSH、监听、状态和重连这些逻辑都在 RustTauri 2后端。SSH 客户端用 russh本地配置存在单个 SQLite 文件里。对比 Electron选 Tauri 2 是因为后端要长期持有 TCP 监听、SSH 会话和重连调度这些放 Rust 里更直接、内存占用也更低。前端只负责展示和操作所有状态由 Rust 后端通过 Tauri 事件推过来。代码结构里能直接看到这个分工。前端不直接调后端中间隔着createViaStore它把 Tauri 的invoke/listen包成ViaBridge接口测试时换成 mock。前端对后端返回的数据做了防御式校验DTO 字段一变测试会先报错不会把错误状态悄悄塞进界面。凭据怎么存SSH 密码和私钥口令是敏感信息Via 的处理分两层用户设置主密码时用 Argon2 派生包装密钥把数据密钥用 XChaCha20-Poly1305 加密后写进 SQLite。首次初始化生成 10 个恢复码只显示一次忘记主密码时用一个未使用的恢复码重置。用户不设主密码时密码和私钥口令只留在内存不落盘重启后重新输入。导出配置时永远不含密码、私钥口令、私钥内容。导出的 JSON 只有分组、会话的非敏感字段和转发规则可以直接分享给同事导入这是当时最想要的「把配置分享给他人」的能力。主机密钥信任首次连一台跳板机Via 会要求确认主机密钥指纹之后指纹变了就阻断连接。这一步防中间人攻击思路和ssh的known_hosts一样。状态机与自动重连断线重连是最容易出问题的地方。Via 把重连逻辑放在前后两端必须保持同步Rust 后端TunnelManager持有五个 HashMap会话、规则、运行中的 Forwarder、手动停止的规则 id、每条规则的状态。传输层断掉时非手动停止的规则进入reconnecting按2^attempt退避重连退避间隔封顶 60 秒。前端收到reconnecting事件后用同样的退避策略重新调connect_sessionstart_enabled_rules。手动停止被两端都记着后端manually_stopped前端reconnectingSessions所以用户主动停掉的规则不会被自动重连拉起来。pubconstfnreconnect_delay_seconds(attempt:u32)-u64{matchattempt{0..51_u64attempt,// 1, 2, 4, 8, 16, 32 秒_60,}}性能转发数据面用 Criterion 在127.0.0.1回环上测过走的是 Forwarder 的实际数据路径accept 循环 copy_bidirectionalSSH 会话用 mock 实现峰值单向吞吐量 3.08 GiB/s16 MiB 批量中位数数据面往返延迟 32.5 µs1 字节 echo中位数Via 在数据拷贝这一环几乎没有额外开销延迟和吞吐主要受网络和 SSH 限制。benchmark 代码在src-tauri/benches/forwarder.rs跑make bench可以复现。取舍与边界Via 只做 Local Forwarding-RRemote和-DDynamic/SOCKS5都不做终端、SFTP、云端同步、跨平台也都不在 V1 范围。这个取舍的理由是把一个需求做窄才能在统一管理、状态展示和重连这些地方做得够细。V1 先把「管理和记录本地转发」这一件事做好。当前只官方支持 macOSWindows x64 和 Linux x64 会随 CI 构建产物发布但未测试。获取与使用还在用 bash 脚本维护 SSH 转发的可以试试 Via。源码、截图和 benchmark 都在仓库里GitHubhttps://github.com/colinrs/via本地跑起来只要两步makeinstallmakedevmake dev会启动 Vite 开发服务器和 Tauri 桌面窗口。发布产物是 macOS.app本地make package会生成 ad-hoc 签名的包对外分发前再换 Apple Developer ID 重新签名并公证。

相关新闻

快速幂算法:从原理到模板,掌握高效幂运算的核心

快速幂算法:从原理到模板,掌握高效幂运算的核心

1. 项目概述:为什么我们需要“记忆”快速幂模板?在算法竞赛、面试准备或者日常的性能优化工作中,快速幂算法是一个绕不开的高频考点。无论是计算一个超大整数的幂次(比如a^b % mod),还是作为矩阵快速幂、计…

2026/8/23 8:53:41 阅读更多 →
从材料到全电池:硅负极工程化的经典路标—Cho课题组Joule 2017综述九周年深度回望

从材料到全电池:硅负极工程化的经典路标—Cho课题组Joule 2017综述九周年深度回望

关键词:硅负极 体积膨胀 SEI膜 全电池工程 预锂化 干法电极 硅碳复合 能量密度 产业化TL;DRJaephil Cho课题组在Joule曾经发表过一篇硅负极综述,系统性地将研究视角从"材料级"拉升至"全电池工程级",提出四大失效…

2026/8/23 8:53:41 阅读更多 →
嵌入式Linux开发环境搭建:从交叉编译到Qt部署全流程详解

嵌入式Linux开发环境搭建:从交叉编译到Qt部署全流程详解

1. 从零到一:为什么嵌入式Linux开发离不开Qt? 如果你刚接触嵌入式Linux开发,可能会被一堆名词搞晕:交叉编译、根文件系统、FrameBuffer、Wayland…… 然后你发现,要在那块小小的开发板上显示一个带按钮的窗口&#xf…

2026/8/23 8:52:41 阅读更多 →

最新新闻

十分钟搞懂 macFUSE:macOS 免内核代码自建文件系统的免费保姆级攻略

十分钟搞懂 macFUSE:macOS 免内核代码自建文件系统的免费保姆级攻略

十分钟搞懂 macFUSE:macOS 免内核代码自建文件系统的免费保姆级攻略 【免费下载链接】osxfuse macFUSE umbrella repository 项目地址: https://gitcode.com/gh_mirrors/os/osxfuse macFUSE 是 macOS 上的一套用户态文件系统框架:文件系统代码跑在…

2026/8/23 10:57:26 阅读更多 →
UI-TARS 桌面应用:用自然语言指挥电脑,从零部署到跑通第一个任务

UI-TARS 桌面应用:用自然语言指挥电脑,从零部署到跑通第一个任务

UI-TARS 桌面应用:用自然语言指挥电脑,从零部署到跑通第一个任务 【免费下载链接】UI-TARS-desktop The Open-Source Multimodal AI Agent Stack: Connecting Cutting-Edge AI Models and Agent Infra 项目地址: https://gitcode.com/GitHub_Trending/…

2026/8/23 10:57:26 阅读更多 →
多模态智能体在开放3D世界中的端到端任务执行与评测实践

多模态智能体在开放3D世界中的端到端任务执行与评测实践

1. 先搞清楚这个“多模态智能体”到底解决了什么实际问题 如果你看到“多模态智能体”、“开放3D世界”这些词,第一反应可能是“又一个炫酷的AI概念”。但这次不一样,它解决的是一个非常具体且棘手的工程问题: 如何让一个AI智能体&#xff0…

2026/8/23 10:57:26 阅读更多 →
CSP-J/S经典真题解析:队列优化公交换乘模拟算法

CSP-J/S经典真题解析:队列优化公交换乘模拟算法

1. 项目概述:从一道经典真题看算法竞赛中的模拟与优化如果你正在准备CSP-J/S(信息学奥赛入门级/提高级)或者类似的算法竞赛,那么“公交换乘”这道题绝对是一个绕不开的经典。它源自2019年CSP-J(原NOIP普及组&#xff0…

2026/8/23 10:57:26 阅读更多 →
大语言模型面试题库:从理论到实践的50个关键问题

大语言模型面试题库:从理论到实践的50个关键问题

1. 项目背景与核心价值 最近在帮团队面试AI方向候选人时,发现很多同学对大语言模型的理解还停留在表面调用API的阶段。这促使我系统整理了这份覆盖LLM全知识栈的面试题库,包含从基础理论到生产实践的50个关键问题。不同于网上零散的面试题集合&#xff0…

2026/8/23 10:57:26 阅读更多 →
Chat2DB 完整指南:一座「数据库控制塔」,快速连接 40+ 数据库,让 AI 帮你写 SQL

Chat2DB 完整指南:一座「数据库控制塔」,快速连接 40+ 数据库,让 AI 帮你写 SQL

Chat2DB 完整指南:一座「数据库控制塔」,快速连接 40 数据库,让 AI 帮你写 SQL 【免费下载链接】Chat2DB Chat2DB is a free, cross-platform, local-first database client and SQL workspace for developers, DBAs, analysts, and data tea…

2026/8/23 10:56:26 阅读更多 →

日新闻

[光学原理与应用-521]:对光的错误理解与纠偏

[光学原理与应用-521]:对光的错误理解与纠偏

首先光是一种能量的载体和形态,宏观上观察到的光是由无数个微观的光量子组成的,每个光子在产生的瞬间,其在真空的空间中以确定不变的速度沿着一个初始的方向一直向前,在微观层面,每个光量子的运动轨迹是以波函数所展现…

2026/8/23 0:00:50 阅读更多 →
SIP通话转接原理与REFER方法实战解析

SIP通话转接原理与REFER方法实战解析

1. 通话转接不是“挂断再拨号”,而是SIP会话的动态重定向你有没有遇到过这样的场景:客服坐席A正在和客户通电话,突然需要把这通对话无缝转给专家坐席B,客户完全感知不到中间的断连——既没听到忙音,也没被要求重新拨号…

2026/8/23 0:00:50 阅读更多 →
Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

1. 为什么选择Kolla-ansible来部署单节点OpenStack?如果你正在寻找一种能把OpenStack从“概念”快速变成“可用的实验环境”的方法,那么Kolla-ansible几乎是当前最主流、最省心的选择。我见过太多人卡在手动编译依赖、配置服务、处理版本冲突的泥潭里&am…

2026/8/23 0:00:50 阅读更多 →

周新闻

[光学原理与应用-521]:对光的错误理解与纠偏

[光学原理与应用-521]:对光的错误理解与纠偏

首先光是一种能量的载体和形态,宏观上观察到的光是由无数个微观的光量子组成的,每个光子在产生的瞬间,其在真空的空间中以确定不变的速度沿着一个初始的方向一直向前,在微观层面,每个光量子的运动轨迹是以波函数所展现…

2026/8/23 0:00:50 阅读更多 →
SIP通话转接原理与REFER方法实战解析

SIP通话转接原理与REFER方法实战解析

1. 通话转接不是“挂断再拨号”,而是SIP会话的动态重定向你有没有遇到过这样的场景:客服坐席A正在和客户通电话,突然需要把这通对话无缝转给专家坐席B,客户完全感知不到中间的断连——既没听到忙音,也没被要求重新拨号…

2026/8/23 0:00:50 阅读更多 →
Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

1. 为什么选择Kolla-ansible来部署单节点OpenStack?如果你正在寻找一种能把OpenStack从“概念”快速变成“可用的实验环境”的方法,那么Kolla-ansible几乎是当前最主流、最省心的选择。我见过太多人卡在手动编译依赖、配置服务、处理版本冲突的泥潭里&am…

2026/8/23 0:00:50 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/22 18:08:39 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/22 7:31:03 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/22 3:22:48 阅读更多 →