找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

1431

积分

0

好友

208

主题
发表于 7 小时前 | 查看: 1| 回复: 0

在Sealos平台上,每个DevBox都是一个独立的开发环境容器。我们梳理用户反馈时发现一个普遍困扰:用户需要为每个DevBox的SSH连接端口支付额外费用,并在“节省成本”与“使用便利”之间被迫做出选择。

这让我们意识到,我们给用户出了一道不应该存在的选择题。

问题的根源:端口即成本

为什么会有这个问题?这源于旧有的技术架构。

在旧架构中,每个DevBox都被分配一个独立的Kubernetes NodePort(如30123、30124)以供SSH连接。但在云环境中,独占端口会产生持续成本

  • 基础费用:¥0.007/小时/端口(无论是否使用)
  • 流量费用:¥0.000781/MB(实际传输的数据)

这意味着,即使DevBox关机,只要端口保留,费用就在持续产生。单个端口每月基础费用约为¥5.04。

我们最初的解决方案是提供两种关机模式,但这将技术实现的复杂性转嫁给了用户。用户不应关心端口分配或NodePort的细节。

我们需要一个更优的方案。

深入SSH协议:寻找突破口

在一次技术讨论中,我们提出了一个关键问题:“为什么我们需要为每个DevBox分配独立端口?SSH协议本身不就支持在单个端口上服务多个目标吗?”

这促使我们重新审视SSH协议。要理解新方案,需要先了解SSH的分层架构。

图片

传输层:建立安全通道

传输层负责建立安全的通信通道。当用户执行 ssh user@host 时,首先进行传输层握手,服务器会发送自己的公钥(Host Key)供客户端验证。

这对我们设计Gateway有一个重要启示:需要确保所有Gateway副本使用相同的Host Key,使用户只需信任一次。我们通过确定性的密钥生成算法来实现这一点。

认证层:身份验证的核心

传输层建立后,客户端需向服务器证明身份。最常用的公钥认证流程如下:

  1. 客户端发送认证请求,包含用户名、公钥及一个用该公钥对应的私钥签名的随机数据。
  2. 服务器检查公钥是否在目标用户的~/.ssh/authorized_keys中。
  3. 服务器使用存储的公钥验证签名。
  4. 验证成功则建立认证。

整个过程私钥从不离开客户端,确保了安全性。

连接层:通道多路复用

认证成功后,连接层开始工作,其核心是通道多路复用。SSH能在单个TCP连接上创建多个独立通道(如用于交互式shell的session通道),每个通道有独立的流控机制。

理解了SSH的三层架构,我们的解决方案切入点变得清晰:在认证层确定目标,在连接层代理通道。

新架构:SSH Gateway的诞生

基于对SSH协议的深入理解,我们设计了SSH Gateway架构。

核心思路

传统的SSH服务器是“终点”,而SSH Gateway是“中转站”。客户端连接到Gateway,Gateway再代理连接到目标DevBox。

图片

对比旧架构,最关键的优化是:Gateway只需要一个NodePort(例如2233)。这意味着用户不再需要为多个SSH端口付费。

图片

随之而来的关键问题是:当所有连接都进入同一端口,Gateway如何知道用户想连接哪个DevBox?我们针对不同场景设计了两种模式。

模式一:公钥映射 - 最简方案

这是我们主推的最简单、最安全的模式。每个DevBox创建时,系统会自动生成一对Ed25519密钥。

工作原理

Gateway维护一张映射表:公钥指纹 → DevBox信息(命名空间、名称、IP、私钥)。当用户使用DevBox的私钥发起连接时,Gateway通过客户端提供的公钥在映射表中找到目标,并用对应的私钥建立到DevBox的连接。

图片

用户体验

这种模式对用户来说几乎零学习成本:

# 首次连接,私钥会自动下载
$ sealos devbox ssh myworkspace
# 后续连接可直接使用
$ ssh myworkspace

无论DevBox关机、重启或冷关机,用户的SSH配置都无需修改。这得益于SSH公钥认证的特性:公钥的唯一性使其可作为身份标识,且Gateway能在认证阶段获取并匹配公钥。

模式二:用户名编码 + Agent Forwarding - 支持自定义密钥

许多用户倾向于使用自己的SSH密钥。为此,我们设计了第二种模式。

用户名编码:在用户名中嵌入路由信息

我们设计了一种特殊的用户名格式:username@namespace-devboxname(例如:ubuntu@myteam-workspace)。Gateway会解析此格式,提取命名空间和DevBox名称作为目标信息。

图片

私钥困境与SSH Agent Forwarding解决方案

一个技术难题出现了:Gateway要连接到DevBox,必须使用用户的私钥进行认证,但我们绝不能要求用户上传私钥。这似乎是个死局。

我们通过SSH Agent Forwarding优雅地解决了这个问题,这是SSH协议为跳板机场景设计的精妙特性。

SSH Agent是一个运行在用户本地的程序,用于安全存储私钥并响应签名请求。当用户启用Agent Forwarding连接至Gateway时,会发生以下关键步骤:

  1. 客户端与Gateway建立连接并完成认证。
  2. 客户端请求在连接上启用Agent Forwarding。
  3. Gateway主动向客户端请求打开一个“反向”的Agent通道。
  4. 当Gateway需要连接到目标DevBox时,它通过这个Agent通道,将认证请求转发给客户端的本地Agent进行签名,再将签名结果返回,全程私钥永不离开用户客户端

图片

这个方案的优势在于:完全符合SSH标准、支持硬件密钥、用户无需安装特殊客户端。

用户只需配置一次SSH config即可:

# ~/.ssh/config
Host myworkspace
    HostName gateway.sealos.io
    Port 2233
    User ubuntu@myteam-workspace  # 使用编码后的用户名
    IdentityFile ~/.ssh/id_rsa
    ForwardAgent yes  # 启用Agent Forwarding

结语

好的技术产品不应该把技术复杂性转嫁给用户。 SSH Gateway架构不仅显著降低了端口成本,更重要的是,它让开发者能够专注于开发本身,而无需被基础设施的细节所困扰。这正是云原生理念所倡导的,通过抽象和自动化来提升效率与体验。

这一优化也深刻体现了对网络协议(如SSH)底层原理的深入理解如何驱动上层架构的创新。

如果大家对SSH Gateway的实现细节感兴趣,可以查看我们的开源代码:
https://github.com/labring/sealos/tree/main/service/sshgate




上一篇:PDM多集群管理实战:统一三地Proxmox虚拟化平台,节省50%运维人力
下一篇:Claude Code AskUserQuestion工具深度解析:多问题交互在Agent智能体设计中的应用
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2025-12-24 19:00 , Processed in 0.239973 second(s), 38 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表