- 后端
- 密码学
【免费下载链接】upspin
Upspin: A framework for naming everyone's everything.
Upspin 是一个开源实验性项目,它既不是传统文件系统,也不是某个云盘应用,而是一套"为所有人命名一切"的框架:通过一组协议与参考实现,把分散在个人设备、家庭服务器与商业云服务中的数据统一进一个全球命名空间。本文以项目官方主页 doc/index.md 为主线,结合仓库内源码与配套文档,系统讲解 Upspin 的动机、命名模型、三大服务器架构、端到端加密、访问控制、配置文件与注册上手流程,帮助你理解其设计并具备动手实践的基础。
项目定位:解决"下载-上传"时代的碎片化问题
官方主页 doc/index.md 用四个直击痛点的问题开篇:
- 你是否曾为了上传到另一台设备而先下载一个文件?
- 你是否曾为了从某个 Web 服务传到另一个服务而先下载再上传?
- 你是否曾仅仅为了把文件分享给一个人,就把它设成"公开"?
- 你是否曾不小心让某些内容被错误的人看到?
Upspin 正是对这些问题的回应。其配套的 Upspin 总览 进一步分析了根源:随着信息从个人电脑迁移到网络服务器,数据与使用者逐渐分离,用户对数据失去了控制权。照片上传到社交平台后由平台托管;数据是否可用取决于当前使用哪台设备;分享手段要么是"公开/私有"的二选一,要么依赖上传、下载、邮件附件这类临时机制;同时服务提供商通常能直接看到信息本身。
Upspin 的解决思路是:如果每一个数据项都有唯一的名字,并且每个人、每台服务器、每台 PC 或手机都能对该名字求值并访问对应数据,再加上端到端安全与一致的分享模型,那么下载/上传、未授权访问、数据孤岛乃至邮件附件都可能成为历史。正如 README.md 所述,Upspin 是"命名与安全分享文件及其他数据的框架",统一性与安全性是首要目标,性能不是。
两个核心设计要素:协议与参考实现
doc/index.md 明确指出,Upspin 由两大设计要素构成:
- 一组协议:基于全局命名系统实现安全、联邦化的共享;
- 参考实现:演示这些能力的一组工具与服务。
换句话说,Upspin 提供的是一层基础设施——其他软件和服务可以构建在这套接口、协议与组件之上,以获得安全访问与分享能力。它不要求所有参与者使用同一个服务商,而是一个联邦:任何实现了标准接口的服务都能加入生态系统。
从源码结构看,这套"协议"的核心定义集中在 upspin/upspin.go:其中声明了三大服务器接口KeyServer、DirServer、StoreServer,以及面向应用的高层Client接口。注释明确写道:"任何实现了名为KeyServer、DirServer或StoreServer的服务器接口的服务,都可以参与 Upspin 生态系统"。仓库内对应的参考实现包括:
- 键服务器:cmd/keyserver/main.go 与进程内实现 key/inprocess/key.go;
- 目录服务器:cmd/dirserver/main.go 与 dir/server/server.go;
- 存储服务器:cmd/storeserver/main.go 与 store/server/server.go;
- 目录与存储二合一服务器:
upspinserver,见 cmd/upspinserver/main.go; - 磁盘存储后端:cloud/storage/disk/disk.go;
- 客户端库:client/client.go。
配合这一套组件的还有命令行工具upspin、FUSE 文件系统upspinfs(cmd/upspinfs)、缓存服务器cacheserver(cmd/cacheserver)以及存储审计工具upspin-audit(cmd/upspin-audit)。
全局命名空间:如何"命名一切"
主页声称 Upspin 提供了一个"全球命名空间"(global name space),其命名模型在 upspin/upspin.go 和 Upspin 总览 中有完整定义。
用户就是电子邮件地址
在 Upspin 中,用户用一个电子邮件地址来标识,称为用户名(User Name)。注册时该地址用于验证身份,之后仅作为标识符使用,例如ann@example.com。upspin/upspin.go 将其定义为独立类型UserName,注释特意说明"用户部分可以在加号后带一个可选后缀",示例包括gopher@google.com、me+you@forever.com。
全限定路径名
每个 Upspin 文件名都有统一结构:以用户名开头,后接斜杠分隔的类 Unix 路径:
ann@example.com/dir/file其中ann@example.com是该文件的所有者(owner),而ann@example.com/称为该用户的用户根(user root),类似于 Unix 的$HOME。Upspin没有本地路径名的概念——所有路径名都是全限定的,永远以用户名开头。upspin/upspin.go 将PathName定义为独立类型,示例即gopher@google.com/burrow/hoard。
带后缀的用户名:一台设备一个身份
某些邮箱服务允许在@前用加号添加后缀。Upspin 用这一技巧让一个用户拥有多个 Upspin 服务身份,例如ann+camera@example.com可以是ann@example.com名下的一台联网摄像头。后缀用户的属性:
- 属于其主用户(无后缀的那个),主用户可以在键服务器上修改带后缀名字的键与存储/目录端点,反之则不行;
- 只能由所有者创建,不需要真实可用的邮箱,通过
upspin命令创建:
$ upspin createsuffixeduser ann+testing@example.com对应的子命令实现位于 cmd/upspin/createsuffixeduser.go。
链接与动态内容
Upspin 名字通常指向静态文件与目录,但命名方案本身不保证内容类型——某些服务器可能提供动态内容。此外还存在链接(link),类似 Unix 符号链接:一个树中的名字可以指向命名空间中任意位置的项目,甚至指向其他用户的树,从而让单个用户把感兴趣的全部名字组织进自己的树中。链接求值的最大跳数在 upspin/upspin.go 中限定为MaxLinkHops = 20。
系统架构:键服务器、目录服务器与存储服务器
Upspin 由三个核心部分构成,每个都是一个提供简单 RPC 接口的网络服务器。官方架构页 doc/arch.md 给出了整体架构图:
三大服务器职责
键服务器(Key Server):存放系统中所有用户的公钥(不是私钥),以及每个用户目录服务器的网络地址。全局生态中由运行在
key.upspin.io的服务器提供服务。所有用户都可以在此保存公钥,也可以查询其他任何用户的公钥。接口定义见 upspin/upspin.go 的KeyServer(Lookup与Put两个方法),用户记录结构User包含Name、Dirs、Stores与PublicKey字段。存储服务器(Store Server):存放系统中的实际数据,按引用(reference)而非名字存取;默认实现中引用是由数据内容计算出的哈希。存储服务器接口
StoreServer(upspin/upspin.go)只有Get、Put、Delete三个方法,对数据不做任何解释。目录服务器(Dir Server):代表用户给存储服务器中的数据命名。目录服务器通常只承载单个用户或单个家庭的树;存储与命名的分离意味着,即使引用了大量大文件,单个用户的目录结构也只是很小的数据量。
以读取ann@example.com/file为例,Upspin 总览 给出的完整操作序列是:
- 从路径名开头提取所有者用户名
ann@example.com; - 到
key.upspin.io的键服务器查询该用户的目录服务器地址; - 联系目录服务器求值完整路径名,返回持有内容的存储服务器地址与引用列表;
- 联系存储服务器取回数据。
这套序列被封装进客户端(client)库中,也可以通过命令行工具或 Unix 上的 FUSE 插件upspinfs使用。存储与目录服务器可以运行在任何地方,但预计多数会作为云服务部署以便可用性、可扩展性与维护。此外接口设计使得在客户端与服务器之间插入缓存层(cacheserver)很容易,以缓解远程网络访问的开销。
端到端加密与密钥管理
主页提到 Upspin 提供"端到端加密以保证隐私",细节在 Upspin 安全文档 中展开。
Packing:数据打包方式
Upspin 将"如何把键指向的数据变成用户数据"的技术称为packing(打包方式),可能涉及校验和验证、解密、签名验证,或者什么都不做。upspin/upspin.go 定义了如下取值:
| 常量 | 值 | 含义 |
|---|---|---|
UnassignedPack | 0 | 未指定打包方式,仅建目录时允许 |
PlainPack | 1 | 不加密、无完整性保护,字节原样拷贝,但SignedName等字段仍签名 |
EEPack | 20 | 椭圆曲线端到端机密性 + 完整性保护(默认),AES 加密数据,附带 ECDSA 签名与 ECDH 包装的密钥 |
EEIntegrityPack | 22 | 与 EE 类似但不提供机密性,仅提供端到端完整性,适合"read: all"场景 |
EE packing 支持按用户密钥曲线选择参数:p256(AES-256、SHA-256、曲线 P256,强度 128)、p384(AES-256、SHA-512、曲线 P384,强度 192)、p521(AES-256、SHA-512、曲线 P521,强度 256)。
双层加密机制
默认的ee加密过程是双层的:
- 写入文件时,客户端随机生成一个文件密钥(dkey),用 AES-CTR 加密文件内容,密文送往存储服务器;
- 对每个有读取权限的读者,用其公钥通过 ECDH 把 dkey 包装(wrap)起来,与数字签名一起存放在目录条目(DirEntry)中;
- 读取时,读者在目录条目中找到用自己公钥包装的 dkey,解密恢复 dkey,再用 dkey 解密数据。
加密、签名与密钥包装全部发生在客户端机器上,而不是任何服务器上——目录服务器与存储服务器、乃至网络嗅探者都看不到明文内容。文档特别指出:目录服务器存储的元数据(明文路径名、读者公钥列表)只受目录服务器内的访问控制保护,因此对元数据高度敏感的用户可以自行运行目录服务器。
密钥管理
用户加入系统时向中心键服务器发布公钥。键服务器通过发布完整、增量哈希的事务日志(key.upspin.io/log)使篡改可被检测:用户被鼓励比对日志哈希、留意自己密钥的任何非本人发起的变化。
本地密钥的存放约定(doc/security.md):
- 公钥:
$HOME/.ssh/下的public.upspinkey,可安全交给任何人,是注册到键服务器的材料; - 私钥:同目录下的
secret.upspinkey,仅靠普通文件权限保护,无额外口令; - 旧密钥对:存放在
secret2.upspinkey,用于解密历史内容。
keygen会打印一个以 proquint 形式表达的 128 位"秘密种子"(secret seed)作为人工可读备份。密钥轮换是一个多步流程,doc/security.md 给出了完整的操作时序表:
| upspin 命令操作 | public,secret.upspinkey | secret2.upspinkey | 键服务器 | 签名 | 包装 |
|---|---|---|---|---|---|
| 初始密钥 | k1 | - | k1 | k1, - | k1 |
| 生成新密钥(keygen) | k2 | k1 | k1 | k1, - | k1 |
| countersign | k2 | k1 | k1 | k2, k1 | k1 |
| rotate | k2 | k1 | k2 | k2, k1 | k1 |
| share -fix | k2 | k1 | k2 | k2, k1 | k2 |
对应的子命令实现见 cmd/upspin/keygen.go、cmd/upspin/countersign.go、cmd/upspin/rotate.go、cmd/upspin/share.go。系统没有任何密码,也无意引入密码;私钥相关操作被集中到factotum包(factotum/factotum.go),为将来类似 qubes-split-gpg 或 ssh-agent 的隔离实现预留了接口——Factotum接口定义见 upspin/upspin.go。
访问控制:Access 文件与 Group
Upspin 的访问控制模型在 doc/access_control.md 中有完整描述,主页将其概括为"易于使用的文件夹分享模型"。
默认完全私有
默认情况下,什么都不会被共享:用户加入 Upspin 后创建的所有数据对其他人不可见。共享的单位是目录——用户在该目录中放一个名为Access的文本文件,用简单文本格式描述授予的权利与用户。
例如Access文件包含:
read: joe@here.com, moe@there.com就允许joe@here.com和moe@there.com读取该目录及其所有子目录中的文件。若某个子目录含有自己的Access文件,则从该子目录向下,其权利完全取代父目录Access文件授予的权利。所有者(路径名开头的用户)始终拥有读取自己树中所有文件、以及更新其中任何Access文件的权限。
五种权利
与 Unix 不同,Upspin 没有 execute 权限,只有两类对象的权利:
| 对象 | 权利 | 说明 |
|---|---|---|
| 文件 | Read | 查看文件内容(发现绑定到名字的存储引用) |
| 文件 | Write | 替换文件内容(Upspin 的 I/O 语义决定这是整体替换) |
| 目录 | Create | 在目录中新增条目(Access与Group文件除外,永远仅限所有者) |
| 目录 | List | 查看目录内容:条目名、大小等公开属性与可访问者列表 |
| 目录 | Delete | 从目录删除条目;作为特别预防,目录必须先清空才能被删除 |
权利的拼写大小写不敏感,可缩写为第一个字符,也可用逗号分组,例如:
r: family, bob@gmail.com w,c,list: family通配符与 Group
Access与Group文件中,*表示"所有权利",即*: family等价于同时授予 read/write/list/create/delete。用户all(忽略大小写)表示"任何已认证的 Upspin 用户",*@example.com表示任何属于example.com域的已认证用户。all有两个限制:必须是一行中唯一提到的用户,且不允许出现在Group文件中,以防误把数据公开给全世界。
组(Group)由所有者用户根下Group子目录中的文件定义,文件路径即组的全局名。例如ann@machine.com创建文件ann@machine.com/Group/family,内容为:
bob@gmail.com ricardo@example.com grandma@example.com则组ann@machine.com/Group/family包含上述用户加上所有者本人。在自己的Access文件中,所有者可省略前缀写family作为简写。
隐私导向的错误语义
为让用户难以在未授权的情况下探测有效名字,操作失败时优先返回"为隐私原因隐藏信息"类错误,而不是"权限被拒绝";若用户已有部分权利但不满足所需权利,才返回"权限被拒绝"。Glob(目录搜索)操作在无权限时会直接从结果列表中省略对应条目。
配置文件与命令行工具
主页的"开始"指向注册流程,而注册后的一切交互都依赖配置文件,其完整说明见 Upspin 配置文档。
配置文件格式
配置文件默认位于$HOME/upspin/config,是纯文本 YAML 格式,每行为空白、注释或key: value:
username: ann@example.com dirserver: dir.example.com storeserver: store.example.com cache: localhost:8888 cmdflags: cacheserver: cachedir: /usr/augie/tmp cachesize: 5000000000各设置的含义:
| 设置项 | 说明 | 默认/要求 |
|---|---|---|
username | 用户的电子邮件地址 | 必须存在 |
packing | 写入时用于加密/保护数据的算法 | 默认ee |
keyserver | 用于发现其他用户公钥的键服务器 | 默认key.upspin.io |
dirserver | 存放用户目录树的服务器 | 必须设置 |
storeserver | 写入新数据的存储服务器 | 必须设置 |
cache | 本地缓存服务器地址(y/n或具体地址) | 未设置则不使用 |
secrets | 存放公钥/私钥的目录 | 默认$HOME/.ssh |
tlscerts | 存放 TLS 根证书的目录 | 默认使用系统根证书集 |
实际使用中通常只需username、dirserver、storeserver与cache四项。服务器地址的一般格式为remote,dir.example.com:443——传输方式(transport)默认remote,端口默认 443(HTTPS/TLS),因此通常可简写为dir.example.com;另两种传输inprocess(进程内服务,常用于调试)与unassigned(不存在的服务器)仅在专家场景出现。
配置文件还可为各命令指定默认 flag 值(cmdflags段),cacheserver与upspinfs命令会读取这些设置,命令行显式指定的值会覆盖之。
upspin 命令行工具
upspin命令用于创建和管理 Upspin 文件、用户与服务器。cmd/upspin/main.go 的说明指出:数据通常通过upspinfs以宿主文件系统方式访问,但upspin命令仍不可替代,例如修改用户密钥(user)、更新访问权限变更后的密钥包装(share)、查看文件全部信息(info)。
注册的子命令包括:countersign、cp、config、createsuffixeduser、deletestorage、get、getref、info、keygen、link、ls、mkdir、put、repack、rotate、setupdomain、setupserver、setupwriters、share、signup、snapshot、tar、user、watch、whichaccess,另有独立的setupstorage与交互式shell。用法为:
upspin [globalflags] <command> [flags] <path>全局 flag 包括-config(配置文件路径,默认$HOME/upspin/config)与-log(日志级别)。路径以@开头表示当前用户的根(ann@example.com),@+suffix则带上后缀。
快速开始:注册新用户
主页明确要求"开始使用请走注册流程",完整步骤见 注册新用户文档。
安装工具
需要先安装 Go,然后构建工具:
$ go install upspin.io/cmd/{upspin,cacheserver,upspin-audit,upspinfs}@latest工具会安装到$GOPATH/bin,包括:命令行工具upspin、图形界面upspin-ui、缓存守护进程cacheserver、存储审计工具upspin-audit,以及 macOS/Linux 上的 FUSE 文件系统upspinfs。
注册流程
- 选择用户名(一个你拥有的电子邮件地址),注意用户名会出现在键服务器日志及你分享的任何路径名中;
- 启动
upspin-ui开始注册:第一步生成密钥对,公钥发布到键服务器,私钥只保存在本机;此时务必抄写并妥善保存 "secret seed"——丢失密钥与种子将永久失去该身份及全部数据,系统没有任何恢复机制; - 第二步:键服务器向邮箱发送确认邮件,点击确认链接以证明你控制该地址;此后 Upspin 永远不会再把该地址当真实邮箱使用,即使邮箱账户日后被劫持也无法影响你的 Upspin 身份;
- 若打算加入已有的目录/存储服务器,先请管理员把你的用户名加入服务器的
Writers组。
指定服务器并创建用户根
注册完成后,upspin-ui提供三个选项:使用现有 Upspin 服务器;部署到 Google Cloud Platform;暂时跳过服务器配置、以只读模式使用。若选择前两者并正确注册,程序会尝试在指定的目录服务器中创建你的用户根。验证成功的经典方式是upspin cp:
$ upspin cp ./hello.jpg you@gmail.com/ $ upspin cp you@gmail.com/hello.jpg ./ciao.jpg $ sum hello.jpg ciao.jpg 1600 21 hello.jpg 1600 21 ciao.jpg用 upspinfs 挂载命名空间
在 Linux/macOS 上可以像挂载本地文件系统一样访问 Upspin 命名空间:
$ mkdir $HOME/up $ upspinfs $HOME/up $ ls $HOME/up/you@gmail.com若第二次运行upspinfs报Transport endpoint is not connected之类的 fuse 错误,卸载后重挂即可。
文档地图:从首页出发的系统化学习路径
doc/index.md 的 Documentation 一节指向 文档总览页,后者按主题给出了完整的注释式链接,构成系统的学习路径:
- 入门:高层次的 Upspin 总览(动机与总体设计)、FAQ;
- 用户指南:注册新用户、访问控制、配置;
- 工具:
upspin命令、upspin-ui、cacheserver、upspinfs、upspin-audit; - 架构:架构页(多幅图示)、访问控制、安全模型;
- 系统设置与管理:部署
upspinserver; - 编程:核心接口定义 upspin/upspin.go、RPC 线协议(rpc)、客户端接口(client)。
此外,首页还列出了社区资源(GitHub 仓库、问题跟踪器、官方讨论邮件列表、贡献指南等),详见仓库根目录的 README.md、CONTRIBUTING.md 与 CONDUCT.md。项目的吉祥物 Augie 由 Renee French 设计,介绍与使用规则见 doc/mascot.md。
现状与注意事项
需要明确两点,以免误导读者:
- 中心基础设施已于 2025 年关停:根据 README.md 顶部的公告,Upspin 团队决定逐步关闭中心基础设施(如键服务器):2025 年 3 月 4 日起键服务器关闭一周,5 月 6 日起永久关闭。因此,本仓库中的代码与文档更适合作为架构研究、源码学习与自托管部署的基础,公共的
key.upspin.io服务不再可用。 - 项目定位是实验性的:README 明确说明 Upspin 尚有不少粗糙之处,不适合非技术用户;它不是 Google 官方产品;性能不是首要目标,统一性与安全性才是。其目标用户是个人、家庭或朋友群体,而非企业信息系统——尽管可用于企业场景,但细粒度分享模型与个人密钥的使用在企业中会显得笨拙。
从源码结构看,Upspin 的全部能力都建立在 upspin/upspin.go 定义的那组简单接口之上:无论键服务器、目录服务器还是存储服务器,任何人都可以实现并接入这一命名空间。这正是主页所强调的愿景——Upspin 只是一种访问方式,"数据是什么、数据在哪里,由你自己决定"。
- 后端
- 密码学
【免费下载链接】upspin
Upspin: A framework for naming everyone's everything.
相关推荐
产品管理工作流实战指南:Product-Management 插件把 Claude 变成你的专属产品经理
产品管理工作流实战指南:Product Management 插件把 Claude 变成你的专属产品经理 从一个周五下午开始 周五下午,你要同时交出一份工程在等
后端密码学Hydra 1.2 升级指南:hydra.job.chdir 与任务运行时工作目录行为的变更解析
Hydra 1.2 升级指南:hydra.job.chdir 与任务运行时工作目录行为的变更解析 在 Hydra 1.2 之前, @hydra.main 装饰的
后端密码学Apollo命名空间深度解析:公共配置共享与覆盖
Apollo命名空间深度解析:公共配置共享与覆盖 在分布式系统中,配置管理往往面临两大核心挑战:如何高效共享通用配置,以及如何灵活处理不同环境的配置差异。Apo
配置中心后端微服务
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考