vesvault/snif

GitHub: vesvault/snif

SNIF 通过基于 SNI 的端到端 TLS 转发,让 NAT 后的 IoT 设备无需公网 IP 即可获得公共可信的 HTTPS 主机名并直接终止 TLS。

Stars: 16 | Forks: 1

``` /************************************************************************** * _________ * /````````_\ S N I F ~ e2e TLS trust for IoT * /\ , / O\ ___ * | | | \__|_____/ o\ e2e TLS SNI Forwarder * | | | ``/`````\___/ e2e TLS CA Proxy * | | | . | <"""""""~~ * | \___/ `` \________/ https://snif.host * \ ''' ``` /```````` (C) 2021-2026 VESvault Corp * \_________/ Jim Zubov * * * Apache License, Version 2.0 * You may use, copy, modify, merge, publish, distribute and/or sell copies * of the Software under the terms of the Apache License, Version 2.0, a copy * of which is provided in the COPYING file, or http://www.apache.org/licenses/LICENSE-2.0 * * This software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR * CONDITIONS OF ANY KIND, either express or implied. * **************************************************************************/ ``` # SNIF — 为 NAT 背后的设备提供端到端 TLS 信任 [![build](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/80c6d9fd72123742.svg)](https://github.com/vesvault/snif/actions/workflows/build.yml) [![codeql](https://github.com/vesvault/snif/actions/workflows/codeql.yml/badge.svg)](https://github.com/vesvault/snif/actions/workflows/codeql.yml) [![License: Apache 2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](COPYING) [![IETF draft](https://img.shields.io/badge/IETF-draft--zubov--snif-orange.svg)](https://datatracker.ietf.org/doc/draft-zubov-snif/) **SNIF 赋予任何设备上的任何应用一个公共的、浏览器信任的 HTTPS 主机名 —— 无需公共 IP,无需端口转发,也无需将你的私钥交给任何人。** 设备生成自己的 TLS 私钥,获取由 CA 签发的真实证书 用于 `*.snif.xyz` 主机名,并接受通过公共 SNIF 中继转发的 入站 TLS 连接。中继根据其 SNI 记录转发原始加密 TCP 流—— 它绝不持有私钥,也无法读取或篡改 流量。其结果是一个点对点的、应用层面的 TLS 隧道,没有任何可读的中间人。 ## 它解决的问题 IoT 设备、家庭服务器和移动应用通常位于 NAT 背后,没有 公共 IP 和稳定的 DNS 名称。常见的替代方案都放弃了 端到端信任: - **端口转发 / 动态 DNS** —— 需要路由器访问权限,并且会直接 暴露设备。 - **反向代理隧道** —— 提供商会终止 TLS,因此它可以读取并 修改通过的所有内容。 - **VPN** —— 为每台设备进行配置非常繁琐,并且仍然需要信任一个集中器。 SNIF 将 TLS 终止保持在**设备上**。中继只能看到一个不透明的、 基于 SNI 路由的字节流,任何不当行为都可以通过 CA 证书记录被公开检测到。 ## 工作原理 私钥由 SNIF connector 在本地生成,并且永远不会 离开设备。 connector 向 SNIF 中继上的 CA 代理发送 CSR。代理获取 X.509 证书并将其返回给设备。 有了证书和私钥,connector 就可以终止 TLS。 到达设备主机名的传入连接首先抵达中继,中继读取 SNI 记录以识别目标设备,并通过匹配的 connector 转发 TLS TCP 流。 设备可以将 `snifd` 作为一个独立的 connector 进程运行,将传入的 TLS 转发到本地端口——可以作为由 `snifd` 终止 TLS 的普通 TCP,或者由 监听应用使用共享的证书和密钥来终止 TLS。在 更高级的设置中,connector 直接集成到提供服务的应用程序中。 从客户端的角度来看,到 SNIF 主机名的 TLS 连接的 工作方式与连接到任何受信任的服务器完全一样。 为了避免通过公共 CA 日志暴露唯一的设备主机名,CA 代理 可以为子域签发泛域名证书;实际的主机名则是该子域中 一个特定的、未公开列出的主机。 ### 初始化 TLS 证书 ``` DNS: *.snif.xyz | (no public IP or DNS hostname) v SNIF Relay IoT Device +----------------+ +--------------------------------+ | | | Generate a Private Key | | | | (never leaves the device) | Certificate | snif-cert: | | | Authority | <-----< Request a permanent hostname | +---------+ | >-----> host1.snif.xyz | | | | | | | | CSR <-----< PKCS#10 CSR <-----< PKCS#10 CSR for host1.snif.xyz | | Verify <-----> host1.snif.xyz | | | | Issue >-----> X.509 cert >-----> X.509 cert for host1.snif.xyz | | | | | | | +---------+ +----------------+ +--------------------------------+ ``` ### 接受 TLS 连接 ``` DNS: *.snif.xyz | (no public IP or DNS hostname) v SNIF Relay IoT Device +----------------+ +--------------------------------+ | | | Private Key + | | | | X.509 cert for host1.snif.xyz | | | | v v v v v | | snifd relay: | | snifd connector or app: | | | | | | <-----< open ctl connection | | TLS SNI= | | | | host1.snif.xyz >-----> receive ctl notification | +-------> ============== <-----< launch Server Process | | | e2e TLS tunnel | | | | | | | | | +----------------+ +--------------------------------+ | +-------^------------------+ | https://host1.snif.xyz | | (TLS SNI=host1.snif.xyz) | | | | A web browser, or | | any TLS enabled client, | | anywhere on the Internet | +--------------------------+ ``` ## 快速开始 — 在设备上运行 connector ``` ./configure make sudo make install ``` 检查 `/etc/snif/snif.conf` 并在需要时调整端口映射和其他 变量。该配置默认使用由 VESvault 运营的公共 SNIF 中继 —— 使用条款请参见 https://snif.host。 ``` # 首次运行会打印一个 authorization link —— 打开它以授权 cert issuance snif-conn # 一旦授权,再次运行;它会打印出永久 # 分配给此 connector 的 SNIF hostname snif-conn ``` 然后启用守护进程(当 `/lib/systemd/system` 可用时,会自动安装一个 systemd 单元): ``` systemctl enable snif-conn systemctl start snif-conn ``` 将你的本地 TLS 服务指向 SNIF 证书和密钥 —— `/etc/snif/snif.crt` 和 `/etc/snif/snif.key`。对于非 root 进程,请将 服务的 uid 添加到 `snif` 组中,以授予对这些文件的访问权限。 测试一下:假设 SNIF 端口 443 映射到了设备的 HTTPS 服务器, 从任何地方打开 `https://{snif_host_name}`。 ## 将 connector 嵌入到应用中 要直接集成 SNIF 而不是运行 `snif-conn`: - 使用 [`lib/cert.h`](lib/cert.h) 来分配 SNIF 主机名,生成 私钥,并签发和续订证书。 - 打开一个到 TCP 端口 `snif` (7123) 上的 `{snif_host_name}` 的 SNIF 控制连接。 - 使用 [`lib/conn.h`](lib/conn.h) 通过控制连接发送和接收 SNIF 消息,并管理服务连接。 connector 库编译为 `libsnif`。 ## 运行私有 SNIF 中继 中继是一个独立的部署(connector + 中继 `snifd` 以及 CA 代理)。它不需要嵌入到任何其他内容中。设置说明请参见 [`ca-proxy/README`](ca-proxy/README)。 ## 目录 ``` lib/ SNIF connector libraries (libsnif) source snifd/ SNIF daemon source — relay and connector ca-proxy/ CA proxy scripts and web API ``` ## 环境要求 **Connector (`snifd` + `snif-conn`)** - OpenSSL >= 1.0.1 - cURL **私有中继 (`snifd` + `snif-relay` + `ca-proxy`)** - 带有 `.htaccess` 的 HTTP + HTTPS 服务器(已在 Apache 上测试) - `mod_rewrite` 和 `mod_headers`(针对其他服务器调整 `.htaccess` 文件) - PHP + `mod_php` - Perl + CPAN ## 规范与安全性 SNIF 是一个规范的开源协议,已作为 IETF Internet-Draft 发布 [draft-zubov-snif](https://datatracker.ietf.org/doc/draft-zubov-snif/) ("Deploying Publicly Trusted TLS Servers on IoT Devices Using SNI-based End-to-End TLS Forwarding")。其快照和平实语言的信任模型位于 [`doc/`](doc/): - [doc/security-model.md](doc/security-model.md) — SNIF 保护的内容、信任 假设以及威胁模型。 - [doc/draft-zubov-snif-04.txt](doc/draft-zubov-snif-04.txt) — 内置的规范快照。 要报告漏洞,请参阅 [SECURITY.md](SECURITY.md) —— 请私下披露, 不要通过公开的 issues。 ## 许可证 SNIF 采用 **Apache License, Version 2.0** 授权 —— 详见 [COPYING](COPYING) 和 [NOTICE](NOTICE)。connector 和中继均采用宽松的开源许可证: 您可以将 connector 嵌入到专有应用中,并建立您自己的中继, 而无需承担 copyleft 义务。
标签:SNI转发, TLS/SSL, 内网穿透, 安全合规, 安全测试工具, 客户端加密, 物联网, 网络代理