Show HN:Ustps(UDP快速传输安全协议)和USSH
摘要
USTPS是一种安全的UDP传输协议,它添加了AEAD加密,优先考虑速度而非拥塞控制,并提供无序可靠传输和选择性重传,目前处于测试阶段。
查看缓存全文
缓存时间: 2026/06/10 17:46
x1colegal/USTP-Secure
来源:https://github.com/x1colegal/USTP-Secure
USTP-Secure (USTPS)
USTPS 即 UDP Speedy Transmission Protocol Secure(UDP 快速传输协议安全版)。USTP-Secure 在 UDP 上保持了 USTP 的特性,并为每个数据包添加了 AEAD 加密/认证。USTPS 不实现拥塞控制。当网络拥塞时,USTPS 不会像 TCP 那样主动减速。从设计上看,它优先追求速度,在这一点上与 UDP 类似。
状态:Beta
USTPS 不再只是一个概念验证,目前已进入 Beta 阶段。USTPS 可用于多种应用和传输场景。不过,本仓库专注于通过 USTPS 进行流式传输。
构建说明
- 使用
Codex基于GPT-5.4 (Low)构建。 - 在
--loss 33参数下验证无卡顿。 - 测试路径:
巴西 -> 加拿大,RTT 约140ms。
安全模型
- 传输层仍为 UDP(无 TCP 隧道)
- AEAD 加密算法:
chacha20(ChaCha20-Poly1305)aes-256-gcmaes-128-gcm
- USTPS 强制使用 AEAD(无明文模式)
- 不使用静态 PSK。
- 每个客户端加入时执行 X25519 密钥交换。
- 每个客户端获得独立的临时 AEAD 会话密钥。
- 服务器支持多个客户端。
- 如果服务器设置了
--cipher,则使用指定的加密算法。 - 如果省略
--cipher或设置为auto,服务器将使用客户端请求的加密算法。 - 客户端拒绝意外的加密算法协商结果。
- 客户端启用 TOFU(首次使用信任),以在首次连接后检测服务器密钥的意外变化。
- 默认情况下,服务器将持久的 X25519 主机密钥保存在
~/.ustps_host_key,以便 TOFU 在重连和重启后保持稳定。 - 正常的服务器重启不会改变主机密钥。
- 仅当您有意轮换主机密钥时,才在服务器上使用
--regen-key。
数据包魔法值
UST1表示UDP Speedy Transmission Protocol版本 1。USS1表示UDP Speedy Secure版本 1。- 在 USTPS 中,
UST1是内部传输数据包格式。 - 在 USTPS 中,
USS1是外部安全的 AEAD 封装格式。 - 因此,解密前通常看到
USS1,解密后的内部负载通常以UST1开头。
传输模型
- USTPS 在 UDP 上提供可靠传输,但设计上是无序的。
- USTPS 不实现拥塞控制。
- 数据包同时携带传输层的
seq和应用层的stream_pos。 seq用于 ACK、丢包检测和重传。stream_pos告诉应用该负载在逻辑字节流中的位置。- 接收方立即接受乱序到达的数据包,而不会因丢失一个数据包而阻塞后续数据的交付。
示例:
- 物理到达顺序:
1 2 3 5 6 - 数据包
4丢失,接收方缓存间隙信息并发送针对4的RETRANSMIT_REQUEST。 - 数据包
5和6仍被立即接受。 - 当
4稍后到达时,应用可以通过stream_pos重建逻辑顺序,而不是依赖到达顺序。
重传模型
- USTPS 使用选择性重传,而非回退 N 步(Go-Back-N)。
- 每个唯一的
DATA数据包单独被 ACK。 - 丢失的数据包仅针对丢失的
seq触发RETRANSMIT_REQUEST。 - 发送方在收到 ACK 之前将已发送的数据包保留在重传缓冲区中。
- RTO(超时重传)也作为后备机制,以防显式重传请求被延迟或丢失。
- 仅重传丢失的数据包。
为何没有队头阻塞(HoL blocking)
- TCP 存在传输层的队头阻塞:如果一个段丢失,同一字节流中后续的数据无法交付给应用。
- USTPS 在传输层不会这样做。
- 丢失一个数据包不会阻止后续数据包被接收、ACK、缓冲或向上传递。
- 这就是为什么 USTPS 可以物理上观察到像
5, 6, 4, 7, 8这样的流,同时仍保留足够的元数据供应用在需要有序输出时重建逻辑顺序。
重要说明:
- 如果您的最终应用输出是一个严格有序的字节流,那么重排序仍需在 USTPS 之上的某个地方进行。
- 在这种情况下,应用层可能会选择在输出字节之前等待,但这种等待是应用行为,而不是 USTPS 内部的传输层队头阻塞。
如何将 USTPS 集成到您的应用中
- 将 USTPS 视为一种带有流位置元数据的可靠无序数据报传输。
- 不要假设数据包到达顺序是真实的流顺序。
- 当您的应用需要字节流时,使用
stream_pos重建有序输出。 - 如果您的应用可以直接消费无序的数据块,您可以立即处理负载,完全避免有序缓冲。
- 如果您的应用需要有序输出,维护一个以
stream_pos为键的重排序缓冲区,仅在所需位置的数据可用时释放数据。 - 不要通过
seq重建顺序;seq仅用于传输层的可靠性逻辑。
TCP 与 QUIC 对比
- TCP:TCP 是可靠且有序的,但这种顺序由传输层本身强制实现。一个段的丢失会阻塞同一流中的后续数据。
- 在 TCP 之上进行多路复用:即使应用在单个 TCP 连接上多路复用多个逻辑通道,底层 TCP 字节流的丢失仍会阻塞间隙后的进展。
- QUIC:QUIC 消除了不同流之间的跨流队头阻塞,这对于多路复用的应用来说比 TCP 有了很大改进。
- QUIC 流行为:在单个 QUIC 流内部,顺序仍然被强制实现。该流中数据的丢失会阻塞同一流的后续字节。
- USTPS:USTPS 在传输层不强制有序交付。它接受后续数据包,无需等待前面的丢失数据包,并依赖
stream_pos元数据供应用在需要时重建有序输出。此外,它不尝试拥塞控制;当网络拥塞时,USTPS 不会像 TCP 那样主动退避。
服务器(启用 AEAD)
python3 server.py \
--peer-port 0 \
--bind-ip 0.0.0.0 \
--bind-port 40001 \
--video "" \
--cipher chacha20
如果您希望自定义 ffmpeg 编码/转码参数(而非默认的复制模式),请使用 --video-parameters。
示例:
python3 server.py \
--peer-port 0 \
--bind-ip 0.0.0.0 \
--bind-port 40001 \
--video "" \
--video-parameters "-c:v libx264 -preset veryfast -b:v 2500k -c:a aac -b:a 128k -mpegts_flags +resend_headers" \
--cipher chacha20
行为:
- 没有
--video-parameters时:使用-c copy -mpegts_flags +resend_headers - 有
--video-parameters时:完全使用您传入的参数,替代默认的复制设置
关于 --loss
--loss模拟服务器端的出站丢包,用于测试恢复行为。- 取值范围:
0到100 - 示例:
python3 server.py \
--peer-port 0 \
--bind-ip 0.0.0.0 \
--bind-port 40001 \
--video "" \
--cipher chacha20 \
--loss 40
--loss 0表示不模拟丢包。--loss 40表示服务器在数据包离开进程之前随机丢弃约 40% 的出站数据包。- 这对于验证以下功能很有用:
- 重传行为
- 间隙检测
- ACK/NACK 处理
- 在可控丢包条件下的播放弹性
- 在正常的实际使用中,请将
--loss保持为0。
客户端(启用 AEAD)
python3 client.py \
--peer-ip <服务器IP> \
--peer-port 40001 \
--bind-ip 0.0.0.0 \
--bind-port 0 \
--output-mode tcp \
--tcp-host 127.0.0.1 \
--tcp-port 1238 \
--cipher chacha20
注意:
- 默认的播放/重排序延迟现在为
350ms。 - 客户端将首次看到的服务器 X25519 公钥存储在
~/.ustps_known_hosts.json中。 - 如果该密钥后续发生变化,客户端会因 TOFU 不匹配错误而中止,而不是静默信任新密钥。
- 如果您有意轮换了服务器主机密钥,请使用
--regen-key运行客户端,以便在交互式确认后替换存储的 TOFU 密钥。 - TOFU 条目按
<ip>:<port>存储,因此不同地址/端口的服务器被视为不同的主机身份。
关于 --udp-unordered-live
--udp-unordered-live是危险的,通常不推荐用于普通媒体播放器。- 在该模式下,负载会立即按照原始到达顺序转发。
- 如果稍后有数据包被重传,通用播放器可能会将该恢复的负载视为全新的帧或数据包,而不是应该属于逻辑流中更早位置的延迟数据。
- 这可能导致可见的损坏、重复播放伪影、解码器混乱或不稳定的播放。
- 为了与普通播放器兼容,请优先使用本地
TCP输出或带有重排序缓冲区的有序 UDP 输出。
VLC:
tcp://127.0.0.1:1238
USTP 与 USTPS
- USTP:可靠的 UDP 传输,默认无加密。
- USTPS:相同的 UDP 传输,加上每个数据包的 AEAD 加密/认证。
- 如果未收到任何有效的加密数据包(服务器离线或握手失败),客户端会退出并显示明确错误。
互联网草案
USTPS互联网草案:https://datatracker.ietf.org/doc/draft-x1co-ustps/
相关项目
USSH:完全基于 USTPS 从头实现的 Shell/远程终端协议:https://github.com/x1colegal/USSH
相似文章
@tobi: UCP(通用商业协议)正变得越来越好
Shopify 在 2026-08 版本中宣布了对通用商业协议(UCP)的改进,详细介绍了跨多个组件的增强功能,如网关、策略论坛和货币兑换器。
Ruby UTCP
Ruby UTCP 是一个开源库,它为 Ruby 应用程序和 AI 代理提供了一种标准方式,通过各种协议发现和调用工具。它支持 12 种传输,并包括流式传输、身份验证和 OpenAPI 发现等功能。
无服务器DTLS
Proxylity为其UDP网关推出了DTLS监听器,为UDP应用添加了类似TLS的加密与身份验证功能,同时保持数据报传输特性,适用于物联网和实时遥测等场景。
Show HN: 我创建了一个基于 BGP 的黑洞系统,几分钟就能搭建好
SATIS Shield 是一个基于 BGP 的黑洞服务(AS23026),让单路由器网络借助共享威胁情报在上游丢弃攻击流量,只需一个私有 ASN 和一条 GRE/WireGuard 隧道即可,价格为每月 59 美元。
HEVN U.S.
HEVN U.S. 是一项服务,允许用户持有美元并通过美国合作银行进行国际支付。