通过 Tor 隐藏服务进行加密的按键通话语音通信。
TerminalPhone 是一个独立的 Bash 脚本,可在 Tor 网络上实现两方或多方之间的匿名、端到端加密语音和文本通信。它的工作方式类似于对讲机:您录制一条语音消息,然后将其压缩、加密,并以单个单元的形式传输给远程方。您还可以在通话期间发送加密的文本消息。无需服务器基础设施、无需账户、无需电话号码。您的 Tor 隐藏服务 .onion 地址就是您的身份。
T 键输入消息。.onion 地址。远程地址显示在通话标题中。S 键访问设置。可即时更改密码;远程方的显示会自动更新。jq(按需安装)。每次触发后音量会自动恢复。.onion 地址作为永久的、可路由的端点。无需端口转发或公共 IP。.onion 地址显示为可扫描的 QR 码。如果未安装 qrencode,系统会提示您安装。QR 码在备用屏幕缓冲区上渲染,关闭时销毁。有一条注意事项警告某些 QR 扫描器会自动添加 http:// 前缀;拨号时会自动去除此前缀。.tmp 扩展名和随机十六进制标识符。不会向文件系统泄露文件类型或时间元数据。ExcludeNodes 和 StrictNodes。/dev/urandom 中的随机数据覆写。读取文件大小,使用 dd 和 conv=notrunc 将那么多字节的随机数据写入文件,使用 sync 将写入刷新到存储设备,然后使用 rm 删除文件。涵盖所有敏感的运行时文件:原始 PCM 录音、Opus 编码音频、加密负载、解密后的入站音频和聊天、语音效果中间文件、密码和 HMAC 密钥材料、nonce 日志、会话标志、PID 文件、命名管道、轮换时的 Tor 隐藏服务密钥以及中继会话数据。对于目录,内部所有文件都会被递归覆写。内置测试选项会创建一个示例文件,以明文和十六进制显示原始内容,覆写它,并显示覆写后的十六进制,以便用户直观确认数据已被销毁。默认关闭 —— 对于大多数用户来说,标准的 rm 完全足够。TerminalPhone 的临时文件小而短暂,磁盘空间通常会被正常的系统活动快速重用。此功能适用于希望额外增加一层防护以抵御取证恢复的用户。注意:在 SSD 和闪存存储上,磨损均衡意味着覆写可能落在不同的物理 NAND 单元上 —— 全盘加密是闪存介质上唯一可靠的防御手段。在传统 HDD 上,覆写会在相同的物理位置替换数据,对所有基于软件的数据恢复都有效。RELAY:1 握手自动检测中继模式,并显示实时的群组呼叫方数量。一个呼叫方离开不会断开其他人。操作员仪表板显示呼叫方数量、运行时间和数据吞吐量。支持的发行版: Debian/Ubuntu(apt)、Fedora/RHEL(dnf)、Arch(pacman)。``` bash
git clone https://gitlab.com/here_forawhile/terminalphone.git cd terminalphone bash terminalphone.sh
从菜单中选择选项 **7** 即可自动安装所有依赖项。将安装以下软件包:
| 软件包 | 用途 |
|---|---|
| `tor` | 洋葱路由与隐藏服务 |
| `opus-tools` | 语音压缩(Opus 编解码器) |
| `sox` | 音频处理工具 |
| `socat` | 通过 Tor SOCKS 代理的双向 TCP 中继 |
| `openssl` | AES-256-CBC 加密与解密 |
| `alsa-utils` | 音频录制与播放(`arecord`、`aplay`) |
### macOS``` bash
git clone https://gitlab.com/here_forawhile/terminalphone.git
cd terminalphone
bash terminalphone.sh
选择选项 7 即可自动安装所有依赖项。如果尚未安装 Homebrew,脚本会先安装它,然后再安装以下软件包:
注意: macOS 使用 sox 同时进行录制(rec)和播放(play),而非 ALSA。无需额外安装音频软件包。
Apple Silicon(M1/M2/M3+): 如果你的终端恰好以 Rosetta 2 模式运行(即 x86_64 进程),而 Homebrew 安装在原生 ARM 前缀(/opt/homebrew)下,brew install 通常会失败并报错 Cannot install under Rosetta 2 in ARM default prefix。依赖安装器现在会检测到这种情况,并自动在 arch -arm64 下重新运行 Homebrew,因此无论脚本以何种方式启动,选项 7 都能正常工作。
TerminalPhone 通过 Termux 支持 Android 设备。由于 Android 的沙盒音频架构,需要额外安装两个组件。
步骤 1:安装 Termux
从 F-Droid 安装 Termux。请勿使用 Play 商店版本,因为它已过时且不再接收更新。
步骤 2:安装 Termux:API 应用
从 F-Droid 安装 Termux:API。这是一个独立的 Android 应用(并非 Termux 软件包),用于在 Termux 与 Android 系统 API 之间建立桥接。TerminalPhone 需要它来访问设备麦克风和媒体播放功能。
如果设备上未安装 Termux:API 应用,termux-microphone-record 和 termux-media-player 命令将无法正常工作,音频录制和播放会静默失败。
安装 Termux:API 应用后,请在系统提示时授予其麦克风权限。
步骤 3:在 Termux 内安装 Termux:API 软件包```bash pkg install termux-api
这会安装与 Termux:API 应用通信的命令行工具。
**第 4 步:运行 TerminalPhone**```bash
git clone https://gitlab.com/here_forawhile/terminalphone.git
cd terminalphone
bash terminalphone.sh
选择选项 7 以安装所有剩余依赖项。安装程序将首先运行 pkg upgrade 来解决任何软件包链接问题,然后安装 tor、opus-tools、sox、socat、openssl-tool、ffmpeg 和 termux-api。
Termux 特定依赖项:
| 软件包 | 用途 |
|---|---|
termux-api | 用于访问 Android 麦克风和媒体播放器的 CLI 桥接工具 |
ffmpeg | 将 Android 的 M4A 录音转换为用于 Opus 编码的原始 PCM 格式 |
To receive a call: Select option 1 (Listen for calls) To make a call: Select option 2 (Call an onion address)
双方都必须运行 Tor,并在发起通话前配置相同的共享密钥。
---
## 使用方法
### 菜单选项```
1 Listen for calls Wait for an incoming connection
2 Call an onion address Connect to a remote .onion endpoint
3 Show my onion address Display your .onion address (with optional QR code)
4 Set shared secret Configure the pre-shared encryption key
5 Test audio (loopback) Record and play back audio locally
6 Show status Display Tor, secret, and connection status
7 Install dependencies Install all required packages
8 Start Tor Start the Tor process and hidden service
9 Stop Tor Stop the Tor process
10 Restart Tor Stop and restart Tor
11 Rotate onion address Generate a new .onion address (destroys the old one)
12 Settings Configure Opus quality, PTT chime, Snowflake, auto-listen, PTT key, voice changer, security, Tor settings
13 Relay mode Start a zero-knowledge group bridge for N callers
0 Quit Stop Tor and exit
全双工模式(WebSockets):
| 按键 | 操作 |
|---|---|
| M | 静音 / 取消静音麦克风。 |
| T | 发送通话内加密文本消息。 |
| Q | 挂断并返回菜单。 |
按键通话模式(Linux / macOS):
| 按键 | 操作 |
|---|---|
| 按住 SPACE | 录制语音消息。松开时自动发送。 |
| T | 发送加密文本消息。 |
| S | 通话中打开设置(更换密码、调整质量)。 |
| Q | 挂断并返回菜单。 |
按键通话模式(Termux):
Android 的软件键盘在松开时发送按键事件,而非按下时。TerminalPhone 通过在 Termux 上使用切换模式来适应这一点。
| 按键 | 操作 |
|---|---|
| 点击 SPACE | 开始录制。再次点击停止并发送。 |
| T | 发送加密文本消息。 |
| S | 通话中打开设置(更换密码、调整质量)。 |
| Q | 挂断并返回菜单。 |
| 音量减 ×2 |
bash terminalphone.sh install # Install dependencies bash terminalphone.sh test # Audio loopback test bash terminalphone.sh status # Show status bash terminalphone.sh listen # Listen for incoming calls bash terminalphone.sh call ADDRESS # Call a .onion address bash terminalphone.sh relay # Start relay mode (group bridge)
---
## 工作原理
TerminalPhone 采用先录制后发送的模式。当你激活 PTT 时,麦克风会持续录音,直到你松开为止。完整的录音随后会经过以下流程处理:```
SENDER RECEIVER
────── ────────
Microphone Speaker
│ ▲
▼ │
Raw PCM (8kHz, 16-bit, mono) Opus decode
│ ▲
▼ │
Opus encode (16kbps) AES-256-CBC decrypt
│ ▲
▼ │
AES-256-CBC encrypt Base64 decode
│ ▲
▼ │
Base64 encode ──▶ socat ──▶ Tor ──▶ socat ──▶ Receive
线缆协议是基于TCP连接的行式文本:
在Termux上,额外的转换步骤处理Android原生M4A录音格式,使用ffmpeg在Opus编码前转换为原始PCM。
加密: 所有音频在传输前使用用户可配置的密码(默认:AES-256-CBC)进行加密。提供21种精选密码,从最强(256位)到足够(128位)排序。密钥通过PBKDF2从预共享密钥派生,迭代10,000次。加密在应用层应用,独立于Tor的传输加密。密钥通过文件描述符(-pass fd:3)传递给OpenSSL,而非命令行参数,因此绝不会暴露在进程表中。
密码协商: 双方在连接时以及通话中密码变更时交换密码名称。密码名称并非机密(Kerckhoffs原则)。如果本地和远程密码不匹配,双方都会在通话头部看到红色指示器。
传输: 所有数据通过Tor隐藏服务电路路由。任何一方的IP地址都不会暴露。没有明文网络流量。网络观察者无法将连接归因于任何一方。
流量分析抵抗: 先录制后发送模型产生不规则的传输模式(不规则间隔的可变长度消息),比连续流更难进行指纹识别。
认证: 共享密钥作为隐式认证。如果双方没有相同的密钥,解密失败且不播放音频。连接时,双方交换.onion地址用于呼叫方识别。密钥可选地使用口令进行静态加密;启动时,脚本提示输入口令以解锁。
HMAC协议签名(可选): 启用后,每条线缆协议消息——包括HANGUP、PTT_START和PING等控制信号——都使用从共享密钥派生的HMAC-SHA256签名。每条消息包含随机nonce,使相同命令产生唯一签名。每次通话跟踪已见nonce并拒绝重复,防止重放攻击。HMAC设置在通话开始时通过运行时文件冻结,使发送和接收路径始终一致,即使在通话中切换设置(更改在下次通话生效)。在接收端,任何签名无效、缺失或重放的消息都会被静默丢弃。这防止了攻破Tor电路(但没有共享密钥)的攻击者注入或重放命令。双方都必须启用HMAC才能进行通话。与1.1.3之前的版本不兼容。
限制:
中继模式安全: 中继在架构上是零知识的。它从不拥有共享密钥,无法解密任何内容。音频数据通过仅存在于内存中的内核管道缓冲区(FIFO)流动——不会写入磁盘。中继停止时,所有临时文件都会被删除。中继操作员无法确定说了什么、呼叫方是谁,或读取任何消息。中继过滤所有控制信号(HANGUP、ID:、CIPHER:、PTT_START、PTT_STOP),仅转发AUDIO:、MSG:和PING。全局被动对手可以进行流量关联分析,将呼叫方与中继关联,但消息内容仍然不透明。
中继容量: 主要瓶颈是Tor带宽。Tor隐藏服务吞吐量高度可变,取决于电路质量、中继拥塞和地理距离。典型的10秒语音消息约为20KB加密数据,每次传输扇出到N-1个监听者。
| 呼叫方 |
|---|
实际容量为:在手机(Termux)上运行的中继为3--5个呼叫方,或在具有稳定连接的专用Linux机器上为5--10个呼叫方。在移动设备上运行的中继面临额外限制:移动数据在Tor之上增加延迟,Android可能终止后台Termux进程以回收内存,且每个连接的呼叫方都会增加电池消耗。Tor电路带宽根据路径质量可从50KB/s到500KB/s不等,电路可能在会话中途降级或轮换。单跳模式提高吞吐量,但不能消除Tor中继拥塞。这些估计假设PTT模型,即一次只有一人传输——同时传输会进一步降低性能。群组通话中的呼叫方应考虑降低Opus比特率(设置 → Opus编码)以减少消息大小并减轻中继负载。
所有配置存储在脚本位置相对路径下的.terminalphone/中:```
.terminalphone/
tor_data/ Tor data directory and hidden service keys
audio/ Temporary audio files (cleaned on exit)
pids/ Process ID tracking
shared_secret Encrypted shared secret file
torrc Generated Tor configuration
默认音频参数(定义在脚本顶部):
| 参数 | 默认值 | 描述 |
|---|---|---|
| `LISTEN_PORT` | 7777 | 传入连接的 TCP 端口 |
| `TOR_SOCKS_PORT` | 9050 | Tor SOCKS 代理端口 |
| `OPUS_BITRATE` | 16 | Opus 编码比特率(kbps) |
| `CIPHER` | aes-256-cbc | 加密算法(可通过设置配置) |
| `SNOWFLAKE_ENABLED` | 0 | 用于规避审查的 Snowflake 网桥 |
| `AUTO_LISTEN` | 0 | Tor 启动时自动监听来电 |
| `PTT_KEY` | SPACE | 按键通话键(可通过设置配置) |
| `VOL_PTT` | 0 | 音量键双击通话,仅限 Termux(实验性) |
| `EXCLUDE_NODES` | (空) | Tor ExcludeNodes 国家列表(例如 `{US},{GB}`) |
| `HMAC_AUTH` | 0 | 对所有协议消息进行 HMAC 签名(可选,双方必须一致) |
| `OVERWRITE_DELETE` | 0 | 删除前用随机数据覆盖临时文件(默认关闭) |
| `PTT_CHIME` | off | 通话提示音预设(off、tone、double、chirp、ding、click、custom) |
| `SINGLE_HOP` | 0 | 单跳 Tor 模式以降低延迟(禁用服务器匿名性) |
| `SAMPLE_RATE` | 8000 | 音频采样率(Hz) |
| `CHUNK_DURATION` | 1 | 音频测试块持续时间(秒) |
---
## 故障排除
**Tor 引导失败:**
检查位于 `.terminalphone/tor_data/tor.log` 的 Tor 日志。常见原因包括时钟偏差、网络限制阻止 Tor,或另一个 Tor 实例正在使用相同的 SOCKS 端口。
**Termux 上没有音频:**
确认已从 F-Droid 安装 Termux:API 应用(不仅仅是 `termux-api` 软件包)。在 Android 设置中授予 Termux:API 应用麦克风权限。运行音频回环测试(选项 5)进行验证。
**ffmpeg 在 Termux 上安装失败:**
在安装依赖项之前运行 `pkg upgrade`。安装程序会自动执行此操作,但如果您手动安装软件包,过时的共享库可能会导致链接错误。
**音频测试正常但通话无声:**
确认双方使用相同的共享密钥。密钥不匹配会导致解密失败且不显示错误消息——通话会接通但听不到任何音频。
**Snowflake 网桥连接缓慢:**
Snowflake 通过 WebRTC 代理路由流量,这会增加额外的引导时间。启用 Snowflake 后,Tor 需要 30--60 秒(或更长时间)才能达到 100% 是正常现象。脚本会在引导期间显示耐心提示。
**首次 Tor 引导缓慢:**
首次启动时,Tor 必须从头下载完整的网络共识,这可能需要一两分钟。脚本会检测到这一点并显示提示。首次运行时引导超时时间会自动从 120 秒延长至 300 秒。后续启动会使用缓存的共识数据,速度会快得多。
**挂断后无法返回菜单:**
如果按 Q 后脚本卡住,请按 Ctrl+C 强制清理并返回 shell。
**macOS 上出现 `Cannot install under Rosetta 2 in ARM default prefix`:**
当终端在 Rosetta 2 下运行(`x86_64` 进程)但 Homebrew 位于原生 ARM 前缀(`/opt/homebrew`)时,Apple Silicon 上会出现此问题。依赖安装程序(选项 **7**)现在会检测到这一点,并自动在 `arch -arm64` 下重新运行 `brew`。如果您手动安装软件包,请自行添加前缀:`arch -arm64 brew install <pkg>`。或者,使用 `arch -arm64 bash terminalphone.sh` 以原生方式启动脚本。
---
[MIRROR V1.0.0](https://bin.disroot.org/?e1356291b098cb75#FMQ4gxFwgdr3rjR1dpGS2csLmDPzDEkQW16fQ5P2Vt4y)
[MIRROR V1.0.1](https://bin.disroot.org/?d3bc0b8976113f58#AuUm4ev4vfeVmPyrh2KjAdhDP6WN4UX6yKQh9ERGD5Qt)
[MIRROR V1.0.2](https://bin.disroot.org/?6bc5b2fd046de1d7#G7TmnytrMeaM5AZYWth6BjjdqUb9RDf3K9erHUExKcGX)
[MIRROR V1.0.3](https://bin.disroot.org/?c5010f039e4693fd#Brp1w7LRQH9d5Ye5npZDPxNVR855SW9QUAk9cJaUuLYX)
[MIRROR V1.0.4](https://bin.disroot.org/?1831f6b78e349142#7zaAMVPNJL3MfbGJzjtm6cCPcvQftf4ULXupdne5dRKw)
[MIRROR V1.0.5](https://bin.disroot.org/?edfcfc844987ed03#56LuBbqbkfNDXfHpydyaB3VcWYhYenX18dtSvNumERY9)
[MIRROR V1.0.6](https://bin.disroot.org/?6c7b4774108b0c1c#GQPst46zjAYidndmNvytforX7MK2LyHanL4d829vVcv4)
[MIRROR V1.0.7](https://bin.disroot.org/?047003637623b4fa#EwmaysciDpiDkht8xV7ce3QcR9oxFXaxSikh4cLheXBB)
[MIRROR V1.0.8](https://bin.disroot.org/?06e38bd64e6fbdad#88MYs3dmq9rSMkmocpW3NYaaG4YfSdRCc9LJnEEzqGYp)
[MIRROR V1.0.9](https://bin.disroot.org/?950218a9a7c71c66#E7Z94VCGBZozrfXYhGwKyAdMeTxuavg92tA1pn2DbrrB)
[MIRROR V1.1.0](https://bin.disroot.org/?0b0da14f31521b3a#B1c23J8xFoZZKErvGG28PgbtfgtMUcDABWmQEoSZfXgh)
[MIRROR V1.1.1](https://bin.disroot.org/?d8e2d4f0300eb5af#9Y1C8CkcH9jAmv1fh4GZs1yYpJmWCG5xG3SvDYdwnJam)
[MIRROR V1.1.2](https://bin.disroot.org/?b1059616f880925f#8ef2oscZXUkPAsJZwGfWvLPQagVAk5GgW4DyssmLvQpG)
[MIRROR V1.1.3](https://bin.disroot.org/?b02658801518aaa7#JE6CsBLWUwAnTdBqeHgeXL7QF5UExgi9rnygcfyMZjCJ)
[MIRROR V1.1.4](https://bin.disroot.org/?d31248fc44c287a0#HQELFWFEMpM9kfTZSGDXTdGFMVKTejox5CajF9Vm4Www)
[MIRROR V1.1.5](https://bin.disroot.org/?284b723ed6aad15f#8VCrrri6yRpdg3uVDSY94wpx7LYkw5uYhm4Vbhka83sM)
[MIRROR V1.1.5.1](https://bin.disroot.org/?26aaef1eff20c271#4GxQQPSDhrszTu1RmERySNVqD2fZW5GZwm3JeL1parpB)
[MIRROR V1.1.6](https://bin.disroot.org/?ae8270578cd9e081#BbcDLU49XqhecvwviHRcdfrZ4vhKdL2AMeKaT5v9oLV1)
[MIRROR V1.1.7](https://bin.disroot.org/?457e4308abe582d8#B9LJG88rmUwrGHHuCof8WpE8CXGmkc2tyrXXicEiJFWk)
[MIRROR V1.1.8](https://bin.disroot.org/?ef81486d3a5141a1#EN1YuLPqqs2FAEsvXkGbZdiWXt3vxvGTw845C4QsYmSn)
[MIRROR V1.1.9](https://bin.disroot.org/?fbcca457ac58964f#DsUCbJwgBRhnL1FK3a6VpwE5sCRNProXvk86u7RpWQM9)
---
## 许可证
MIT
| 软件包 | 用途 |
|---|
tor | 洋葱路由与隐藏服务 |
opus-tools | 语音压缩(Opus 编解码器) |
sox | 音频录制与播放(rec、play) |
socat | 通过 Tor SOCKS 代理进行双向 TCP 中继 |
openssl | AES-256-CBC 加密与解密 |
| 通过音量键切换录制(需在设置中启用音量 PTT)。 |
| 消息 | 描述 |
|---|
ID:<onion> | 呼叫方ID——发送方的.onion地址 |
CIPHER:<name> | 发送方的加密密码。在连接时及变更时交换。 |
PTT_START | 发送方已开始录音 |
PTT_STOP | 发送方已完成;音频随后发送或已发送 |
AUDIO:<base64> | 完整的加密音频消息 |
MSG:<base64> | 加密的文本消息 |
HANGUP | 发送方正在断开连接 |
PING | 保活信号 |
RELAY:1 | 中继问候——由中继在连接时发送,触发群组模式 |
GROUP:<n> | 群组大小更新——由中继在呼叫方加入或离开时广播 |
| 每条消息出站 |
|---|
| 预期体验 |
|---|
| 2--3 | 20--40KB | 在大多数连接上可靠 |
| 3--5 | 40--80KB | 在稳定电路上良好,移动数据上可能有延迟 |
| 5--10 | 80--180KB | 接近极限,传输间有明显延迟 |
| 10+ | 180KB+ | 不可靠,显著排队和潜在消息丢失 |