Conversation
只能经代理上网的机器此前无法上报。新增 --proxy / MONITOR_PROXY,agent 向代理发 CONNECT,其上的 TLS、WebSocket 升级与所有帧都在隧道里跑:TLS 握手的 SNI 与证书 校验仍然是对 hub 的,代理只看得到 CONNECT 那一行。hub 的域名由代理解析,本机没有 可用 DNS 也能连上。 配了代理之后唯一的直连对象就是代理本身——hub 下发的 ping 探测同样走隧道,否则这类 机器上每个目标都读成 -1,什么也说明不了。代价是延迟量的是「本机 → 代理 → 目标」 整条路,比直连多一跳且含代理解析域名的时间,与直连节点的读数不可横向比较,这点写进 了 README。探测的隧道另给 3 秒上限:把 HANDSHAKE_DEADLINE 压在 1 秒内的理由是内核 的 SYN 重传计时器,那条理由在隧道上不成立。 探测目标由 hub 下发又要进 CONNECT 请求行,带 CR/LF 的目标在写出任何字节前就拒掉, 否则 hub 能往代理请求里塞自己的头;代理在 200 之后抢先发来的字节判错而不是丢弃, 否则隧道里每个字节都会错位。 不配代理时每条路径都退回原状:session 走原来的 dial,NAT 时优先 v4 的逻辑不变, 探测走原来的解析加握手。MONITOR_PROXY 留空等同于不配,安装脚本可以无条件写这个变量。 未引入新依赖,Basic 凭据的 base64 就地实现。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #4
内网机器只能经代理访问外网时,agent 连不上 hub。这个 PR 让出站走 HTTP
CONNECT隧道。做法
新增
--proxy/MONITOR_PROXY,agent 先连代理并发CONNECT hub:443,其上的 TLS、WebSocket升级和所有帧都在隧道里跑。TLS 握手的 SNI 与证书校验仍然是对 hub 的,代理是管道不是对端,只看得到
CONNECT那一行。hub 的域名由代理解析,本机没有可用 DNS 也能连上。http://host:port、host:porthttp://user:pass@host:port@按最后一个@切http://[fd00::1]:3128https://、socks5://端口必须写全:
http://10.0.0.8直接报错退出,不会悄悄去连 80。取舍
探测也走隧道。 配了代理之后 agent 唯一的直连对象就是代理本身,hub 下发的 ping 探测同样经
CONNECT。留成直连的话,这类机器上每个目标都读成 -1,什么也说明不了。代价是延迟量的是「本机 → 代理 → 目标」整条路,比直连多一跳且含代理解析域名的时间,和直连节点的读数不可横向
比较——这点写进了 README。-1 的含义不变:目标不答、代理拒绝、代理不通,从这台机器看是同一件事。
隧道探测另给 3 秒上限。把
HANDSHAKE_DEADLINE压在 1 秒内的理由是内核的 SYN 重传计时器,那条理由在隧道上不成立——这里量的是代理解析目标并与之握手,再按 900ms 算的话,代理邻近范围之外的
目标全会读成 down。3 秒仍远在探测间隔 5 秒的下限之内。
两处安全考虑
CONNECT请求行。带 CR/LF 的目标在写出任何字节前就拒掉,否则hub 能往代理请求里塞自己的头,甚至跟一整个请求。既有注释已把「hub 可能被攻陷或只是有 bug」
算在威胁模型内,这里同样按不可信处理。
--insecure下的升级请求),这些字节不可能是合法的,丢掉会让其后每个字节都错位。兼容性
不配代理时每条路径都退回原状:session 走原来的
dial,NAT 时优先 v4 的逻辑不变,探测走原来的解析加握手,
Proxy::parse根本不会被调用。MONITOR_PROXY留空等同于不配,安装脚本可以无条件写这个变量。未引入新依赖,
Cargo.toml/Cargo.lock没动,Basic 凭据的 base64 就地实现(16 行,只为这一个头)。
版本号没动,按仓库惯例留给发版时的 chore 提交。
测试
新增 9 个单测(代理地址解析各形态、base64、隧道握手与请求行、IPv6 目标的方括号、407 原样带进
错误、200 后抢跑的字节、CRLF 注入、代理不答、探测经隧道且不做本机解析),
cargo fmt --check与
cargo clippy --all-targets -- -D warnings干净。在 Linux 容器里用假 hub(会说 WebSocket、下发 ping 任务)加需要认证的假 CONNECT 代理端到端跑过:
不配代理时同一场景的日志与改动前逐字相同(A/B 对比过改动前后的二进制)。musl 静态产物已在实际
服务器上部署验证通过。