作者朋友发送了一个需手动用socat
和 k8s 集群中的nginx ingress controller
设置的隧道链接,这引发了作者的思考,此文是作者整晚钻研自己的隧道解决方案的成果。
- Criteria(标准):希望在自己的基础设施上运行,隧道在自己的域名下创建,避免自动泄露新隧道链接以免被自动扫描。
Solutions Considered(考虑的解决方案):
- Ngrok:使用方便,免费版可保留一个静态域名,但需使用$10/mo 或$96/yr 的“Personal”计划,且不满足在本地终止 TLS 的要求。
- Tailscale Funnel:易于设置,可通过 Wireguard 网络连接手机和家庭服务,能处理 TLS 终止,但会将尾网地址显示在证书透明度日志中,可能导致服务被扫描,且不能创建特定名称的隧道。
- VS Code Developer Tunnels:由微软提供,使用方便,默认安全,但依赖微软,不能控制使用的域名。
Roll Your Own Tunnel(自己创建隧道):
- Wildcard Domains(通配符域名):在 DNS 区域创建通配符 A 记录和 TLS 证书,修改 nginx 配置,可实现任意子域名的隧道,且不会泄露至证书透明度日志。
- Enabling Multiple Simultaneous Tunnels(启用多个同时的隧道):利用 ssh 反向隧道可代理到 unix 域套接字的特性,结合 nginx 配置,可根据客户端指定的隧道名称将流量传递到相应的套接字,但存在 Linux 权限问题。
- The world’s sketchiest automation(世界上最粗略的自动化):通过
~/.ssh/rc
文件在建立新的 ssh 连接时自动运行命令,给 nginx 赋予读写套接字的权限,并通过SendEnv
传递隧道域信息,还可添加清理套接字的功能,但存在清理套接字不彻底的问题。 - Streamlining the Client Experience(简化客户端体验):编写一个简单的 bash 脚本
grok
,简化创建隧道的命令,可指定端口和可选的隧道名称,还可生成随机的 12 位十六进制隧道名称,并禁用ControlPath
。
- Limitations(限制):如果套接字留在远程主机上,下次隧道将失败,需手动清理;当前实现保持交互式会话一直打开;不能处理任意的 TCP 隧道;HTTP 日志无法区分客户端。
- Putting It All Together(整合所有内容):提供了远程和本地的配置文件,包括 nginx 配置、
~/.ssh/rc
、~/.bash_logout
和grok
脚本。 - Conclusion(结论):使用该方案存在一些 quirks,但无需在服务器上运行新应用和担心新凭证,可快速发送定制的开发隧道链接。还提到了改进套接字清理和关于将用户输入传递到文件系统路径的安全性的讨论。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。