面向 Kindle Voyage + KUAL 的轻量 LocalSend 兼容实现,让旧 Kindle 可以在局域网内与 Windows、macOS、iOS / iPadOS 等 LocalSend 客户端互传文件,而不需要在 Kindle 上运行 Flutter 图形界面。
当前版本:v0.1.18 本次发布包为 Voyage ARMv7 的 v0.1.18 构建;传输核心与外围稳定性、ZIP 安装和结果提示功能均已审计。
- 兼容 LocalSend v2.2 的设备发现、注册、准备上传、上传与取消流程。
- Windows v2.1 固定
Content-Length上传兼容。 - macOS v2.2 流式上传兼容,包括缺少
Content-Length/Transfer-Encoding的特殊 framing。 - 支持 iPhone / iPad 上的 LocalSend 客户端与 Kindle 互传文件。
- 文件直接接收到
/mnt/us/documents。 - 支持从 Kindle 的 Outbox 向已发现设备发送文件。
- KUAL 菜单控制:启动接收、定时接收、停止、发现设备、发送 Outbox、网络诊断。
- 运行时临时开放
wlan0的 53317 端口;停止后自动清理防火墙规则。 - SHA-256 校验、会话/token/IP 校验、路径穿越保护与临时文件原子落盘。
- 单实例保护、崩溃残留清理、日志轮转、存储空间诊断和 peer 状态写入节流。
- 自签名设备身份,用于与 HTTPS LocalSend peer 通信时的 mTLS / fingerprint 校验。
- 安全安装通过 LocalSend 收到的 ZIP 更新包到 Kindle USB 根目录
/mnt/us。
项目主要针对 Kindle Voyage 上的 KUAL 环境。
已完成重点实机验证:
- Windows → Kindle;
- macOS → Kindle;
- Windows/macOS 交叉连续传输。
协议兼容支持:
- iOS / iPhone;
- iPadOS / iPad。
其它 Kindle 型号可能可以运行,但未做同等程度的实机验证。
当前接收服务默认使用:
- 协议:HTTP(局域网兼容模式)
- LocalSend 协议版本:2.2
- 端口:53317
- 网络接口:
wlan0 - 接收目录:
/mnt/us/documents - Outbox:
/mnt/us/LocalSend/Outbox
由于 Kindle 接收端使用 HTTP,请只在可信任的局域网中使用。不要把 53317 端口暴露到公网。
发布包的目录结构:
extensions/
└── localsend/
├── bin/
│ ├── kual.sh
│ └── localsend-kindle
├── config.xml
└── menu.json
安装步骤:
- 如果旧版本正在运行,在 KUAL 中选择
LocalSend → 停止 LocalSend。 - 将发布 ZIP 解压到 Kindle USB 根目录并覆盖扩展文件。
- 断开 USB 后打开 KUAL。
- 选择
LocalSend → 接收 10 分钟、接收 30 分钟或持续接收。 - Windows、macOS、iPhone 或 iPad 与 Kindle 保持在同一局域网,然后在 LocalSend 中选择 Kindle 发送文件。
收到的文件会直接保存到:
/mnt/us/documents
v0.1.18 不会只删除 PID 或修改菜单状态。
停止流程:
- 根据
daemon.pid找到实际localsend-kindle进程; - 校验
/proc/<pid>/cmdline,避免误杀其它进程; - 先发送
SIGTERM并等待正常退出; - 超时后才使用
SIGKILL; - 再次确认原 PID 已经不再是 LocalSend;
- 清理
daemon.pid/daemon.lock; - 删除临时
LSKUAL防火墙规则; - 只有上述停止流程确认完成后,KUAL 才显示“LocalSend 已确认停止”。
如果进程仍然存在或防火墙清理失败,会明确显示停止不完整,而不是报告假成功。
v0.1.18 延续并强化了独立的安全安装器。它没有修改已冻结的 Windows/macOS 传输核心。
这里的“Kindle 根目录”只表示 Kindle USB 用户分区:
/mnt/us
不会解压到 Linux 系统根目录 /,不会修改只读 rootfs。
- 在 Windows、macOS、iPhone 或 iPad 的 LocalSend 中,把更新 ZIP 发送给 Kindle。
- ZIP 会先作为普通文件保存到
/mnt/us/documents。 - 打开 KUAL:
LocalSend
└── 安装 ZIP 到 Kindle 根目录
├── 刷新 ZIP 列表
├── 选择 → 某个更新包.zip
├── 确认安装已选 ZIP
└── 取消待安装 ZIP
- 先点“刷新 ZIP 列表”。
- 选择具体 ZIP 文件。
- 此时不会立刻安装,只会锁定待安装文件并记录 SHA-256。
- 再点“确认安装已选 ZIP”才执行安装。
如果 LocalSend 当时正在运行,安装器会先确认停止 LocalSend;安装结束后再尝试恢复原来的持续接收状态。
安装完成后,原 ZIP 文件不会自动删除。
真正写入 /mnt/us 前,会完整预检整个 ZIP:
- 拒绝绝对路径;
- 拒绝
../路径穿越; - 拒绝反斜杠异常路径;
- 拒绝符号链接、设备文件和其它特殊文件;
- 拒绝重复/大小写冲突目标;
- 拒绝“文件同时又作为目录父级”的异常 ZIP;
- 拒绝 ZIP 覆盖它自己;
- 限制 ZIP 条目数量;
- 计算解压后总大小并检查可用空间;
- 保留额外 32 MiB 安全空间;
- 选择 ZIP 时记录 SHA-256,确认安装时再次计算并比对,防止选中后文件被替换;
- 禁止更新包覆盖 LocalSend 的设备私钥、证书、peer 状态、日志和用户
settings.json。
允许正常覆盖程序代码,例如:
extensions/koreader/...
koreader/...
extensions/localsend/bin/...
因此既可以安装其它 KUAL/KOReader 更新,也可以用于后续 LocalSend-KUAL 自身升级,同时保留 LocalSend 的本地身份和用户配置。
安装时不是直接把 ZIP 内容粗暴写到目标文件:
- 已存在的目标文件先备份到临时事务目录;
- ZIP 中的新文件先写入目标目录旁边的临时文件;
- 写完并
fsync后再rename替换; - ZIP CRC/大小异常会被检测;
- 任意文件安装失败,已应用的文件会按逆序自动恢复;
- 安装成功后自动删除临时备份。
这能避免普通解压工具在中途出错时留下半个损坏文件。
任何设备在“整个多文件升级事务进行到一半时突然断电”都无法做到绝对原子;本安装器已经做到单文件原子替换、事务备份和失败回滚。安装升级包时建议保持 Kindle 电量充足,不要在安装过程中拔 USB 或强制重启。
extension/localsend/config/settings.json 不提交到 Git 仓库。程序首次运行时会自动生成安全默认配置。
运行时会在 Kindle 本地生成:
extension/localsend/config/settings.json
extension/localsend/state/device.crt
extension/localsend/state/device.key
extension/localsend/state/http-fingerprint
extension/localsend/state/peers.json
extension/localsend/state/status.json
extension/localsend/state/daemon.pid
extension/localsend/state/daemon.lock
extension/localsend/state/pending-install.json
extension/localsend/state/install.lock
extension/localsend/logs/localsend.log
这些内容可能包含设备身份、PIN、局域网 peer 信息或运行日志,均不应提交到公开仓库。
需要 Go 1.23 或兼容版本。
运行测试:
go test ./...
go vet ./...构建 Voyage ARMv7 静态二进制:
CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=7 \
go build -trimpath -ldflags='-s -w' \
-o extension/localsend/bin/localsend-kindle \
./cmd/localsend-kindle生成的运行包不需要 Go、动态库或源码。
FROZEN_CORE_SHA256.txt 记录了完成实机双平台验证的核心源码 SHA-256。go test ./... 中的冻结校验会在这些核心文件被意外修改时失败。
冻结范围包括:
- 接收服务;
- macOS framing 兼容;
- Windows 固定长度路径;
- 发送客户端;
- 设备发现;
- 临时防火墙;
- TLS / HTTP 设备身份;
- 协议核心类型。
v0.1.18 的 ZIP 安装器、KUAL 停止复核和菜单功能都位于冻结核心之外。
本项目是面向 Kindle/KUAL 的第三方兼容实现,不是 LocalSend 官方客户端,也不隶属于 Amazon。
LocalSend 官方项目:https://github.com/localsend/localsend
本项目采用 MIT License,详见 LICENSE。
LocalSend 名称、上游项目以及其它第三方内容的权利归各自权利人所有。