Skip to content
YLing2024Public

About

把文本、文件或一段密钥用一次性链接交给别人,取一次即销毁;反向也能开一个带输入框的收件口。Go 单二进制,无中间件。

Topics

Resources

Contributing

Stars

0 stars

Watchers

1 watching

Forks

Repository files navigation

drop

把一段文本、一个文件或一段密钥串,用一次性链接交给别人;取一次即销毁。反向也行:开一个带输入框的收件口,让对方把内容投递进来,你取走后即销毁。

它解决的是"私密数据只交接一次"这个场景:不想把凭据留在聊天记录里,也不想开一个需要注册登录的共享空间。链接本身就是凭据,拿到链接即可取件,无需账号。

特性

  • 一次性:取件即销毁。状态迁移在 bbolt 写事务内完成,并发下恰好一个成功。
  • 路径即凭据:token 由 32 字节 CSPRNG 生成,base62 编码为 43 字符,不可枚举。
  • AES-256-GCM 静态加密:内容加密后落盘,密钥文件 <data>/key 权限 0600。磁盘被拿走也读不出内容。
  • 库内只存 token 哈希:数据库里只有 sha256(token),不存明文 token。
  • 到期自动清理:内置 sweeper 默认每 60s 把过期链接置为 expired 并删除内容。
  • 审计只记元数据:ts、link_id、event、kind、name、size、ip_hash、result;不含内容与 token。
  • 单二进制、无中间件:Go 标准库 net/http + 纯 Go 的 bbolt,无 web 框架、无外部依赖服务。

快速开始

源码运行

需要 Go 1.24 及以上。

# 终端 A:启动服务。DROP_API_KEY 是引导用的 API Key,会被登记入库,CLI 侧也用它鉴权。
DROP_API_KEY=dev-secret-key go run ./cmd/drop serve
# 终端 B:创建一条一次性文本链接,stdout 打印链接。
DROP_API_KEY=dev-secret-key go run ./cmd/drop put --text "hello" --ttl 1h

服务默认监听 127.0.0.1:18960,数据目录 ./data。首次启动会生成管理员账号 admin 与随机口令并打印一次(如不想随机,可先设 DROP_ADMIN_PASSWORD)。

Docker

docker compose up -d

仓库根目录的 docker-compose.yml 会把本机 ./data 挂到容器的 /data,并监听 127.0.0.1:18960。镜像可用 make docker 或 docker build -t drop:latest . 单独构建。

CLI 用法

除 serve 外,所有子命令都通过 REST 直连 DROP_SERVER(默认 http://127.0.0.1:18960)。需要鉴权的子命令从 --key-file、DROP_API_KEY 或 DROP_API_KEY_FILE 读取 API Key;明文 Key 不要写进命令行参数。

# 创建出站链接:文件、stdin 或直接文本
drop put ./report.pdf --ttl 2h --name 报告
drop put - --ttl 30m < secret.txt
drop put --text "一次性口令" --ttl 1h

# 创建入站投递链接(带输入框的收件口)
drop req --ttl 1h --name 回执

# 取件:默认输出到 stdout,也可落盘(文件权限 0600)
drop get https://drop.example.com/d/<token> --stdout
drop get <token> -o report.pdf

# 查看链接元数据
drop ls --limit 20
drop ls --json

# 撤销链接(置 revoked 并删除内容)
drop rm <id>

# 查看审计(只含元数据)
drop audit --limit 50

# API Key 管理;明文 Key 只在创建时打印一次
drop key create ci
drop key list
drop key revoke ci

# 重置内置管理员口令(新口令只打印一次)
drop admin reset-password --user admin

# 版本
drop version

drop ls 输出示例(列:ID / 类型 / 状态 / 名称 / 大小 / 到期):

ID                          类型   状态      名称  大小  到期
01M4TP7J16F1QJV98DPDHCFSPB  out  active  自检  11  2026-10-13T21:16:34+08:00

drop audit 输出示例(列:时间 / 事件 / 链接 / 类型 / 结果):

时间                                   事件       链接                          类型   结果
2026-10-13T21:11:34.469617029+08:00  created  01M4TP7JA5VXXHNDTEX19NWP7W  in   ok

配置

环境变量提供初值,serve 的命令行 flag 覆盖同名配置。所有项都有默认值。

环境变量 flag 默认值 说明
DROP_ADDR -addr 127.0.0.1:18960 监听地址
DROP_DATA_DIR -data ./data 数据目录
DROP_BASE_URL -base-url http://127.0.0.1:18960 生成链接用的外部地址(生产填 https 域名)
DROP_AUTH_MODE -auth-mode builtin builtin 或 sso
DROP_MAX_SIZE -max-size 25m 单次提交/上传上限
DROP_DEFAULT_TTL -default-ttl 1h 默认有效期,上限 7d
DROP_SWEEP_INTERVAL -sweep-interval 60s 过期清理间隔
DROP_TRUST_PROXY -trust-proxy 0 置 1 才信任 X-Forwarded-For
DROP_WEBHOOK_URL -webhook-url 空 非空才发事件回调(只含元数据)
DROP_LOG_LEVEL -log-level info debug / info / warn / error
DROP_KEY_FILE -key-file <data>/key 内容加密密钥文件路径
DROP_ADMIN_USER 无 admin 内置管理员用户名
DROP_ADMIN_PASSWORD 无 空 首启预置管理员口令,空则随机生成并打印一次
DROP_SERVER 无 http://127.0.0.1:18960 CLI 直连的服务地址
DROP_API_KEY 无 空 CLI / serve 引导用的 API Key
DROP_API_KEY_FILE 无 空 API Key 文件路径(CLI 侧)

体积支持 512k / 25m / 1g(二进制单位,1m = 1 MiB);有效期支持 30m / 2h / 7d,上限 7d。

数据目录内容:

<data>/drop.db        bbolt 数据库(0600)
<data>/key            内容加密密钥(0600)
<data>/admin.json     内置账号(bcrypt 摘要,0600)
<data>/blobs/<id>     加密后的内容文件

key 丢失后已加密内容无法恢复,备份时请一并保留。

部署

deploy/ 下有可直接改用的样例:

  • deploy/drop.service:systemd 单元。ExecStart 为 /opt/drop/drop serve -addr 127.0.0.1:18960 -data /var/lib/drop,Restart=always、NoNewPrivileges=yes、PrivateTmp=yes、LimitNOFILE=65535,并从 -/etc/drop/drop.env 读取环境变量。
  • deploy/nginx.conf.example:反向代理样例。对外只暴露 HTTPS,回源到 127.0.0.1:18960。

反向代理要点:

  • 只让应用监听回环,由反代终结 TLS 并对外。
  • 生产把 DROP_BASE_URL 设为对外 https 地址,否则打印出来的链接指向 127.0.0.1。
  • 反代日志必须对 /d/<token>、/r/<token> 做脱敏,样例里 log_format 已把这两类路径统一记为 /d/(redacted)、/r/(redacted)。
  • /healthz 只对回环与内网放行。
  • 确实位于可信反代之后时才设 DROP_TRUST_PROXY=1,否则按 socket 对端 IP 限流。

示例统一使用 drop.example.com / 127.0.0.1,部署时替换成自己的域名即可。

认证

默认 AUTH_MODE=builtin:自带账号密码,首次启动生成管理员账号。设 DROP_AUTH_MODE=sso 即关掉自带入口,身份与未授权时的跳转、401 由服务前面的认证层决定。

安全说明

  • 取件动作是 POST,不是 GET。邮件/IM 网关、浏览器链接预览与安全扫描会预取 GET;页面先 GET(无副作用),点按钮再 POST 取件,避免链接被"用掉"。
  • 无效链接统一 404。未知、过期、已用、已撤销返回同一状态码与逐字节相同的响应体,不泄露"这条链接曾经存在过"。
  • 日志不记 token 与内容。访问日志里 /d/<token>、/r/<token> 统一记成 /d/<redacted>、/r/<redacted>,不打印 query 与请求体;debug 级别也不打 token 与内容。
  • 静态加密。内容用 AES-256-GCM 加密后落盘,取件成功后立即删除内容文件。
  • 响应头。Cache-Control: no-store、Referrer-Policy: no-referrer、X-Robots-Tag: noindex、X-Content-Type-Options: nosniff 与严格 CSP;取件页不引任何第三方资源。

许可证

MIT,见 LICENSE。

About

把文本、文件或一段密钥用一次性链接交给别人,取一次即销毁;反向也能开一个带输入框的收件口。Go 单二进制,无中间件。

Topics

Resources

Contributing

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages