croc 网页客户端深度指南:croc-web 统一服务器、WASM 安全协议与 WebSocket 中继桥接

croc 网页客户端深度指南:croc-web 统一服务器、WASM 安全协议与 WebSocket 中继桥接 croc 网页客户端深度指南croc-web 统一服务器、WASM 安全协议与 WebSocket 中继桥接【免费下载链接】crocEasily and securely send things from one computer to another :crocodile: :package:项目地址: https://gitcode.com/GitHub_Trending/cr/croccroc 的网页客户端web client是一个 React/Vite 应用可与普通crocCLI 对端完成文件收发和短文本消息直传其生产构建与 WebAssembly 运行时被嵌入独立的croc-web二进制由这一个 HTTP 地址同时承载网站、运行时配置、健康检查和 WebSocket-to-TCP 中继桥。本文基于 web/README.md 与对应源码展开帮你掌握croc-web的本地开发、自托管中继池配置、生产拓扑与存储模式stored mode的完整运维细节以及安全敏感协议操作如何被编译进 WASM 供浏览器执行。一、croc web 客户端定位浏览器与 CLI 对端之间保持加密croc-web的客户端能力包括与普通crocCLI 对端发送和接收文件以及短的直接文本消息文件元数据与内容在浏览器和另一 croc 客户端之间保持加密生产构建与 WebAssembly 运行时嵌入croc-web二进制部署后的二进制不需要任何外部静态文件。启动时如果带上--store-dirUI 会额外提供一个显式的 stored 模式由发送方选择一个有限的生存期。该模式在浏览器内加密文件名、元数据和 4 MiB 分块只上传密文并同时产出一个浏览器链接和一个 CLI 令牌传输会在“已验证下载次数额度”或“所选生存期”中先到者触发时被删除。常规直传direct模式仍是默认模式。两种发送模式都可以为浏览器接收地址显示 QR 码直传模式的二维码打开接收页并自动填好 croc 码开始连接stored 模式的二维码包含完整的加密分享链接。直传模式还提供与croc send --text兼容的次级文本编辑器文本在显示前被审查、在内存中校验从不落盘到临时存储且文本载荷限制为 1 MiB 的 UTF-8 内容。进度方面活跃的发送与接收会显示总量与单文件进度、实测字节/秒速率以及用arrival-time库计算的 ETA见 web/package.json 中的arrival-time依赖。二、安全敏感操作编译进 WASM同一份 Go 协议代码跑在浏览器里这是 croc web 最核心的设计安全敏感的协议操作不是用 JavaScript 重写而是直接由本仓库的 Go 包编译为 WebAssembly从而与原生客户端共享同一份密码学实现。文档列出的 WASM 能力包括croc PAKE用于中继relay握手与对端peer握手与身份和会话绑定的 HKDF加对端通道的相互确认mutual confirmation用于兼容旧版本的中继单跳legacy-compatible relay hop的 PBKDF2以及 AES-GCM 加密原始 DEFLATE 压缩xxhash 校验EFF 三词码生成与兼容性解析与原生客户端共享的 SHA-256 码到中继路由。从源码看WASM 入口在 web/wasm/main.go它通过syscall/js把一组函数挂到全局crocWasm对象上与上述文档条目一一对应pakeInit/pakeInitWithIdentities/pakeUpdate分别基于pake库和仓库内 src/pakekey/pakekey.go 的带身份 PAKEpakeUpdate完成握手并返回会话密钥derivePeerKeys/confirmPeerKey通过pakekey.Derive用目的、房间、曲线、发起方/响应方身份与盐派生加密密钥和两个确认标签再校验对端确认实现通道密钥与身份、会话的绑定deriveKey调用 src/crypt/crypt.go 的crypt.NewPBKDF2派生中继跳密钥encrypt/decryptAES-GCM 加解密cipherInit/cipherRelease/encodeChunk/decodeChunk维护 AEAD 句柄并按分块加密可选先压缩compress/decompress调用 src/compress/compress.go解压时要求显式字节上限hashInit/hashUpdate/hashFinal流式 xxhashcodeComponents/relayIndex基于 src/codephrase/codephrase.go 解析 croc 码并计算码对应的中继索引SHA-256 路由与原生客户端共享逻辑sha256Init等SHA-256 摘要storeGenerateKey/storeRedeemCapability/storeSealManifest/storeOpenManifest/storeSealChunk/storeOpenChunkstored 模式在浏览器内完成密钥生成、能力赎回、清单与 4 MiB 分块的密封/开启底层是 src/storecrypto/storecrypto.go。每个暴露函数都走safeCall包装recover panic 后返回{ok:false,error}字节数据通过js.CopyBytesToGo/js.CopyBytesToJS以Uint8Array传递。构建脚本为 web/scripts/build-wasm.mjsnpm run wasm这解释了“浏览器端只上传密文”的可信边界加密路径不经过 JavaScript 生态的第三方依赖。三、本地开发一条命令跑起完整客户端 croc-web在 web 目录下npm install npm run dev:stack该流程会先构建并嵌入完整客户端然后运行croc-web localhost:5173这个本地快捷方式会直接把服务绑定到localhost:5173网站和 WebSocket 中继都在同一地址可用。这一行为由 src/webcli/webcli.go 中resolveServeAddress实现当显式给出带端口的回环地址如localhost:5173且未显式提供--bind时bind直接沿用该公网地址。需要前端热重载时运行npm run dev:hotdev:hot会先执行embed再用concurrently并行跑 Vite dev server 与croc-web --bind 127.0.0.1:9014 localhost:5173见 web/package.json 的 scripts 定义。常用检查命令npm test # vitest 单元测试 npm run test:e2e # Playwright 端到端先 embed npm run typecheck # tsc -b npm run build npm run embed make build-web go test ./...npm run embed构建 WASM 与 Vite 客户端并把产物复制到被 git 忽略的src/webassets/dist目录Go 的 embed 包只在croc-web中打包它生成文件不提交仓库。部署后的croc-web二进制既不需要该目录也不需要任何外部静态文件。从源码看src/webassets/assets.go 使用//go:embed all:distFiles()返回dist子树web/scripts/embed-dist.mjs 把web/dist拷入src/webassets/dist同时把 CLI 安装脚本 src/install/default.txt 拷为default.txt——这正是/路径下 curl/wget 收到的安装脚本。Playwright 套件npm run test:e2e会构建真实的croc与croc-web二进制在临时端口上启动隔离的本地 croc 中继与统一嵌入式服务器然后逐字节验证 CLI → Web、Web → CLI、Web → Web、CLI stored → Web、Web stored → CLI 五类传输见 web/e2e/transfers.spec.ts。浏览器安装一次即可npx playwright install chromium。测试进程使用隔离的CROC_CONFIG_DIR与存储目录不读取也不改动你已记住的 croc 配置。四、自托管中继池croc-web 作为受约束的 WebSocket 到 TCP 桥服务器端固定一个有序的上游主机列表并放行所有 TCP 端口使/ws不可能被当成任意网络代理使用。单主机自托管池示例croc-web --pass YOUR_RELAY_PASSWORD \ --bind 127.0.0.1:9014 \ --relays relay.example.com \ --ports 9009,9010,9011,9012,9013,9014,9015,9016,9017 \ files.example.comfiles.example.com是作为位置参数传入的公网网站地址UsageText 为croc-web [OPTIONS] [public-host[:port]]。服务器通过/config.js把权威有序中继地址与密码作为浏览器默认值注入window.__CROC_RUNTIME_CONFIG__ {gatewayURL:/ws,relayAddresses:[...],relayPassword:...,store:{...}};对应实现在 src/webrelay/webrelay.go 的confighandler带Cache-Control: no-store与X-Content-Type-Options: nosniff。公共客户端使用1.getcroc.com,2.getcroc.com,3.getcroc.com,4.getcroc.com即 src/publicrelay/publicrelay.go 中固定的四台 9009 端口池也是--relays的默认值运维可以用--relays提供另一个逗号分隔的顺序。关于“最佳中继”记忆直传生成的发送会把胜出中继地址存进功能性 cookiecroc-best-relay有效期 30 天之后的发送直接复用该精确地址不做探测也不延长 cookie 有效期无效池条目会被自动替换中继连接失败会清除 cookie让下一次发送重新竞速整个配置的池手动清除站点 cookie 等价于强制同样的刷新。/ws端点的约束在源码中非常明确src/webrelay/webrelay.go 的websockethandler 只接受relay零基索引port放行端口两个参数索引必须落在配置的主机列表内、端口必须落在放行集合内否则返回 403连接建立后只是用 64 KiB 缓冲做双向io.CopyBuffer的透明字节流转发不参与 croc 协议本身。croc-web的完整命令行参数默认值取自 src/webcli/webcli.go参数默认值说明--bind127.0.0.1:9014本地 HTTP 绑定地址--relays/--relay1.getcroc.com:9009,...公共池有序逗号分隔的上游 croc 中继主机--ports9009,...,9017放行的上游中继端口--passmodels.DEFAULT_PASSPHRASE中继密码支持环境变量CROC_PASS若值是可读文件路径则读取文件内容--debugfalse开启 debug 日志--store-dir空不启用在此目录启用加密临时存储--store-max-transfer1GiB单个 stored 传输的最大明文字节--store-quota5GiB所有受管 stored 传输的总字节上限--store-min-free512MiB磁盘需保留的空闲空间--store-max-files100单个 stored 传输的最大文件数--store-downloads1每个 stored 传输的最大已验证下载次数CROC_STORE_DOWNLOADS--store-max-expiration0不限最长 stored 生存期单位 m/h/d/wCROC_STORE_MAX_EXPIRATION--store-create-rate5每客户端 IP 每小时最多创建的 stored 传输数--store-active-uploads2每客户端 IP 的并发上传数--store-trusted-proxy空可重复信任的反向代理 CIDR用于客户端 IP 转发注意--pass的determinePass逻辑如果该值恰好是一个可读文件的路径会读取文件内容作为实际密码适合把密码放在磁盘文件里而非命令行。五、统一服务器暴露的端点从Handler的路由注册src/webrelay/webrelay.go看croc-web一个进程提供GET /与内嵌静态客户端资源User-Agent 为curl/或wget/时返回安装脚本default.txt浏览器则收到 Web 客户端响应带Vary: User-AgentGET /config.js运行时配置注入见上一节GET /healthz返回okGET /ws?relay零基索引port放行端口升级为二进制 WebSocket两个值都必须命中配置的白名单单条 WebSocket 消息上限 65 MiB当设置--store-dir时额外注册/api/v1/store/transfers及其子路径由store.Service处理。静态文件缓存策略也值得注意assets/前缀资源是public, max-age31536000, immutableHTML 页面no-cacheService Worker 文件no-cache。六、生产拓扑HTTPS 反向代理 存储模式生产环境把croc-web放在 HTTPS 反向代理之后croc-web --bind 127.0.0.1:9014 getcroc.com完整回源包括 WebSocket 升级都指向127.0.0.1:9014并保留原始Host头。服务器在/返回站点、在/ws返回 WebSocket 桥因此无需拆分路由或外部静态文件部署TLS 证书留在反向代理。可选的 Umami 分析只有在两个运行时变量都设置时才启用UMAMI_URLhttps://umami.schollz.com \ UMAMI_WEBSITE_IDwebsite-uuid \ croc-web --bind 127.0.0.1:9014 getcroc.com成功的浏览器传输会发出send-direct、send-with-storage、receive自定义事件。未配置 Umami 时事件追踪关闭、传输行为完全一致已配置时服务器把 Umami 的 defer 脚本直接注入每个页面的head见injectUmamiScript要求 URL 必须为 HTTPS。Umami 记录常规页面浏览自定义传输事件上报的 URL 会去掉查询串与 fragment。服务器在成功向 curlGET /交付安装脚本后还会发出installer-curl事件wget 下载与 HEAD 请求不计入该服务端事件只上报站点主机名、/路径、事件名和 croc 版本。临时存储在未显式配置目录前保持关闭croc-web \ --bind 127.0.0.1:9014 \ --store-dir /var/lib/croc/store \ --store-max-transfer 1GiB \ --store-quota 5GiB \ --store-min-free 512MiB \ --store-max-expiration 2w \ getcroc.com运维要求存储目录被锁给单个服务器进程应是持久、私有、仅 croc 服务账号可写的目录并排除出备份。若可信反向代理提供X-Forwarded-For用可重复的--store-trusted-proxy CIDR标识其网络不受信任的转发头会被忽略。全部限制与运维细节见 src/docs/STORED_TRANSFERS.md。--bind默认为127.0.0.1:9014当显式使用带端口的回环网站地址如localhost:5173时本地快捷方式会绑定到该地址除非显式提供--bind。七、当前边界与限制文档明确列出的当前能力边界适用于本仓库版本一次一个对端、一次一个传输文本消息仅限直传模式stored 模式只接受常规文件可以一次发送多个选中的文件发送文件夹与 ZIP 打包未实现CLI 发送的嵌套文件夹与空文件夹在浏览器支持目录访问时可以接收逐文件下载的兜底方案会把文件名压平并在冲突时追加数字后缀本地组播multicast、浏览器到浏览器直传、非 xxhash 的实时传输未实现stored 上传仅接受常规文件。CLI 端 stored 下载可续传已完成分块浏览器 stored 下载在受支持时以流式方式工作标签页关闭后不续传目标是当前主流常青evergreen桌面浏览器。参考入口文档主体web/README.md服务器与 WS 桥src/webrelay/webrelay.go命令行与默认参数src/webcli/webcli.goWASM 桥接web/wasm/main.go嵌入与拷贝src/webassets/assets.go、web/scripts/embed-dist.mjs公共中继池与竞速选择src/publicrelay/publicrelay.gostored 模式运维文档src/docs/STORED_TRANSFERS.md端到端传输验证web/e2e/transfers.spec.ts【免费下载链接】crocEasily and securely send things from one computer to another :crocodile: :package:项目地址: https://gitcode.com/GitHub_Trending/cr/croc创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考