仓库服务
cipherfs serve 持有仓库租约并运行 HTTP 服务库;独立 cipherfs-web 可执行程序已删除。本机客户端使用私有 Unix socket 或 Windows 命名管道与文件中的归属凭据,服务不要求挂载驱动。
# 现有仓库;通过通常的交互提示或 CIPHERFS_PASSWORD 取得密码。
cipherfs serve --vault ~/vault
# HTTP/JSON 监听,初始密封,通过 API 解封。
cipherfs serve --vault ~/vault --listen-address 127.0.0.1:3000
# 非回环监听强制使用 PEM 证书链与私钥文件。
cipherfs serve --vault ~/vault --listen-address 0.0.0.0:3443 \
--tls-certificate /etc/cipherfs/server.pem --tls-private-key /etc/cipherfs/server-key.pem
TCP 使用可撤销 Bearer JWT 会话,无权调用私有本机挂载、导出或凭据操作。只有回环地址允许明文 HTTP;IPv4/IPv6 通配地址及其他地址强制 TLS,握手限时十秒。命令参数与配置只放 TLS 文件路径、解锁来源引用,不放密码或密钥值。
配置
cipherfs serve --config /etc/cipherfs/serve.json 使用有界 JSON,拒绝未知字段、重复别名/路径与不合法监听策略。路径必须绝对;最多 128 个仓库、16 个监听,端口零表示由系统分配。
{
"vaults": [
{"name": "personal", "vault_path": "/srv/cipherfs/personal", "unlock_source_ref": "env:PERSONAL_PASSWORD"},
{"name": "work", "vault_path": "/srv/cipherfs/work", "unlock_source_ref": "env:WORK_PASSWORD"}
],
"listeners": [{"listen_address": "127.0.0.1:3000"}]
}
所有现有仓库先以密封状态取得租约并发布私有端点;没有来源时也可仅用本机 CLI 解封。env:NAME 每次读取密码,secret_sources 与 auto_unseal 支持文件、systemd、原生钥匙串和 HTTPS 来源,见凭据与密封。来源失败保持 sealed 并按 1–30 秒退避重试;仓库无法取得或配置非法才排空已取得归属并报错。TLS 监听增加 "tls": {"certificate_path": "/etc/cipherfs/server.pem", "private_key_path": "/etc/cipherfs/server-key.pem"}。
每个仓库独立拥有租约、会话、同步与挂载服务。API 前缀为 /vaults/personal/api/v1、/vaults/work/api/v1,会话不能跨仓库。单仓库同时开放 /api/v1。服务只提供 API;桌面界面由 cipherfs-app 提供。
S3 前门
CLI 构建启用 --features s3(协议适配器要求 Rust 1.96 以上),在同一个配置中增加 s3_gateway。它使用独立监听器和同一批仓库归属,不需要另开数据库、挂载或对象存放点;HTTP/JSON 和私有本机 API 继续并存。
{
"vaults": [{"name": "personal", "vault_path": "/srv/cipherfs/personal"}],
"secret_sources": {"applications": {"kind": "files", "directory_path": "/etc/cipherfs/application-secrets"}},
"s3_gateway": {
"allowed_hosts": ["127.0.0.1:9000"],
"buckets": {"personal-files": {"vault": "personal"}},
"applications": [{
"application_id": "backup",
"access_key_id": "backup-application",
"credential_ref": {"source": "applications", "name": "backup"},
"buckets": ["personal-files"],
"read_only": false
}]
}
}
应用秘密单独放在仓库之外的私有凭据文件中,16–256 个可见 ASCII 字符,不带行尾换行。每次验签重新读取命名来源,来源失败拒绝访问。此例不自动解封:通过本机 CLI 解封,或另配独立 auto_unseal 来源。应用 S3 密钥不能解封仓库或调用 JSON/本机管理 API。
默认监听 127.0.0.1:9000,签名 region 为 us-east-1;可以设置 listen_address、region 和 tls。非回环地址强制 TLS,证书路径格式与 HTTP 监听相同。allowed_hosts 是精确 HTTP authority 白名单,包括客户端实际使用的端口;不接受通配、转发 Host 路由或 absolute-form 请求目标。客户端使用 path-style(endpoint/bucket/key)与 SigV4,匿名与 SigV2 均拒绝。应用仅能访问自己配置的桶,read_only 禁止变更;每个桶声明仓库,可另设规范路径 prefix;键、列举和历史都相对此子树。子树之外的版本号不能绕过键映射。
支持桶发现/HEAD/location/versioning、PUT/GET/HEAD/DELETE、ListObjects v1/v2、ListObjectVersions、分片创建/上传/列举/完成/中止、单字节范围与 SigV4 预签名请求。对象列举支持 prefix、delimiter 和分页。共享版本号就是 CipherFS 版本身份,普通历史按原始键读取;并发 head 在文件当前生效的键下列举、读取,也覆盖并发移动。历史仍受仓库保留与退役规则约束。本地专属文件可以读取,写入沿用本地专属规则,不因此获得共享历史;显式仓库目录不作为 S3 对象列出。
默认 etag_policy: "version" 使用包含版本身份的强校验标记,分片完成后也一样,不是明文 MD5。需要明文 MD5 校验标记的客户端可选择 etag_policy: "content_md5";GET、HEAD 和列举会流式读取并认证正文以计算 ETag,因此元数据操作也可能拉取未缓存正文,分片完成返回整体明文的 MD5。分片 ETag 使用 MD5,完成请求必须匹配。发布前检查 Content-MD5、SHA-1、SHA-256、CRC32、CRC32C、CRC64NVME 校验和及已验签的流式 trailer;正文不完整、取消或校验失败不会替换现有对象。GET/HEAD 支持 ETag 条件;日期条件和条件写入返回 NotImplemented。
键精确对应 NFC 仓库文件路径,最多 1,024 UTF-8 字节;空键、首尾斜杠、重复斜杠、点段、反斜杠和控制字符明确拒绝,不归一化成别的对象。不实现桶创建/删除、virtual-host 桶路由、CopyObject、ACL、标签、S3 自定义 metadata、S3 加密选项及永久版本删除;仓库支持的管理和退役能力通过原有 API 使用。共享格式不变。
上传使用有界明文缓冲与加密临时文件;默认最多 128 个分片上传、合计 16 GiB 密文暂存预算,通过 max_uploads、spool_budget_bytes 调整。单次 PUT/分片最多 5 GiB;完成清单最多 10,000 段,除最后一段外至少 5 MiB。上传 ID 绑定应用、桶、键和归属会话,完成只发布一次仓库写入;中止、24 小时过期、密封和退出释放临时状态,重启不恢复未完成上传。下载背压可被密封取消。上游协议库的 debug 事件可能带解码键或签名材料,因此整个协议调用隔离 tracing;访问审计阶段与 tracing 分开实施。
应用服务器控制
认证 JSON 接口另提供准确版本的耐久确认、FileId 读写、单文件固定、有界访问热度预取和可选的毫秒保留期限。路由、回执与取消语义见应用服务器 API。
状态与退出
GET /health 返回进程存活、sealed、vaults_count、sealed_count、recovery_pending_count,不含仓库路径、身份或凭据。全部仓库解锁时 GET /ready 为 200,否则 503。别名下的 /health、/ready 仅反映该仓库。状态接口不代替文件访问认证。
启用同步时,配置式服务的健康/就绪响应另含 directory_delete_attempts_count:本进程全部 Directory 后端 DELETE 调用次数,含失败与目标不存在的调用。计数在进程启动时清零,不是持久删除历史。serve 排空后输出含最终计数的 JSON serve_stopped 事件;核对跨重启期间时须同时记录进程生命周期与退出计数。
SIGINT 与 Unix SIGTERM 停止接受 TCP 连接、撤销会话、卸载并等待挂载退出,排空已接纳操作与同步,释放本机端点和租约;TCP 慢连接的退出等待有界。cipherfs seal / POST /api/v1/seal 撤销会话、停止同步与挂载、排空工作并清钥,但保留租约和私有端点;cipherfs unseal 或 /api/v1/unseal 重新认证,同一归属的旧句柄与会话不复活。锁定/注销只关闭对应仓库;配置守护进程继续服务其他仓库并允许以后解锁。单仓库纯本机命令在仓库关闭后退出。
下载 worker 失败时会记录固定错误分类、OS 错误编号与已入队字节数,不记录明文路径、凭据或提供方错误正文。CLI 若在响应 body 中途断开,会报告已输出字节数并以非零状态退出,不把已读前缀当作完整文件;可结合归属进程日志区分正文不可用、文件系统错误、取消和完整性失败。
归属挂载
cipherfs mount --vault ~/vault --mount-point ~/mounted
cipherfs mount --vault ~/vault --mount-point ~/mounted --unmount
已有可达归属进程时,请它完成挂载/卸载后返回,挂载随归属进程存活;本机 API 只能卸载该归属跟踪的目标。关闭仓库先卸载全部目标,再释放租约。没有归属时 mount 自己成为归属并发布同一本机 API;--background 继续使用既有私有密码/就绪握手。归属构建需包含 fuse(通常默认含 fuse-t);Windows 明确不支持挂载。
继续使用既有空目标、存储不重叠、只读与后端检查;macOS 默认原生 FUSE-T,Linux 使用内核 FUSE。Partial 正文由归属既有后台运行时经已配置存放点/对端取得。