Skip to content
LithivmPublic

About

Windows 内网透明代理:按目标网段在内核层接管 TCP,经你自己的 SOCKS5/HTTP 上游转发。Proxifier 式规则 + Wails 界面

Topics

Resources

Stars

3 stars

Watchers

1 watching

Forks

Repository files navigation

NetHub

给指定网段装一条隐形代理:目标落在你配的网段里的 TCP 连接会被内核层(WinDivert)接管, 经你自己的 SOCKS5 / HTTP 上游转发出去。替代「Proxifier + gost 脚本」。

界面截图

功能

  • 应用零改动 —— 浏览器、数据库客户端、任何按 hosts 解析的程序都不用配代理
  • 规则对齐 Proxifier —— 一条规则 = 名字 + 一组目标 +(可选)一组端口 + 走哪个链;自上而下匹配、命中即止; 目标写法沿用 Proxifier:198.51.100.99、198.51.100.0/24、IP 区间 198.51.100.1-198.51.100.255(保存时展开成网段)、 IP 通配 198.51.100.*、域名 main.example.com 与通配域名 *.example.com; 动作还可以是「直连」(不走代理)或「阻断」,用来放行本机网段 / 局域网邻居(打印机、共享盘)或拉黑某些地址
  • 一条链可填多个上游 —— 故障转移 / 轮询 / 随机 / 粘性(同一台客户端固定走同一条),自带健康探测,坏了自动换、好了自动回
  • 快 —— 预热连接池(把 TCP+TLS+握手提前做好,业务连接来了只发一条 CONNECT)、TLS 会话复用、 「第一条超过 150ms 未连上就并发试其他上游」(实测某条链要 620ms、另一条只要 75ms,竞速直接把业务拉到快链路)
  • 看得见 —— 顶栏有实时流量图(60 秒滚动,上行/下行两条线 + 此刻速率,一眼看出隧道在不在传); 「连接」页实时显示动作/链/时长/收发字节;同目标、同进程的并行连接会合并成一行 (×N),点开看每条的本地端口 / 命中规则 / 错误全文(一个页面就会对同一 origin 开 6 条 TCP); 「连接」页下半部分的「统计」卡回答“这段时间谁在占通道” —— 累计的连接数 / 失败数 / 收发字节, 按目标与应用两个维度排(默认按流量倒序,点表头换列序),域名能认出来就并到域名那一行; 「复制」一下就拿走整张表(制表符分隔,能直接贴进表格)、 「清零」从头再数; 「诊断」页的「接管状态」卡一眼看全 内核面(拦截与过滤器)/ 域名面(通配与 DNS 接管)/ 连接面(连接与进程名解析), 带异常判据——它是仪表盘,不是日志(只有当前值,没有时间戳流水); 业务目标定时巡检(默认关,设置里一键开);疑似环路检测(被别的代理绕回来时告警)
  • 运维友好 —— 配置自动备份(留 3 份)可回滚、配置体检、规则重叠检查、 配置一键导出/导入(一个文件就够)、按需抓包(导出 pcap,Wireshark 直接打开)
  • 自带代理客户端(不需要装 gost / v2ray)—— 协议:socks5 / socks4 / socks4a / http(s) / ss(shadowsocks,AEAD) / trojan / vless / vmess; 传输层可叠加 +tls / +ws / +wss(如 socks5+wss://host:8443?path=/ws); 旧 gost 的 .bat 可以在界面里直接导入(只取其中的上游地址); xray 分享链接直接粘(vmess://<base64>、vless://uuid@host?type=ws&security=tls…); 客户端证书用 ?cert=&key=(要求双向认证的上游); 不支持的写法会当场报错并说清该怎么写,不会静默降级(详见下面「上游协议能填到哪一步」)
  • 口令是明文(和 gost 脚本一样)—— config.yaml 里直接写账号口令,不加密; 发配置给别人看用「导出配置(抹掉口令)」。不要把 config.yaml 提交进 git 或发到群里
  • 界面(Wails + WebView2)—— 实时日志、链路自检、与 Clash 共存检测、跟随系统的深/浅主题(可手动锁定)、托盘常驻 (图标可选「实时流量图」:最近 16 秒的面积 + 上沿线,可选显示总量/上行/下行, 配色跟随 Windows 任务栏明暗 —— 收起窗口后一眼看出还在不在干活)
  • 该出声时出声 —— 「内网域名可能被别的代理接管」这类不看界面就无从得知的风险, 会发一条 Windows 系统通知(只在 GUI 形态有效:服务形态跑在 Session 0,通知到不了用户桌面)
  • 不抢设置 —— 不改系统代理、不动路由表,和 Clash / v2rayN 这类工具共存
  • 改完不用重启 —— 规则 / 链路 / 上游/ 拨号参数保存即生效(不断已有连接); CLI 用 nethub.exe -apply 改完能等到“运行实例真的吃进去了”才返回
  • QUIC 不再漏出去 —— 本该走链的目标上的 HTTP/3(UDP 443)会被拦下并记一行日志, 而不是默默地直连出去;浏览器随即回落 TCP,那条路仍由我们接管

安装

到 Releases 下载 NetHub.zip,解压到任意目录:

  1. 先让安全软件放行驱动 —— 火绒 / 360 / 腾讯管家默认会拦 WinDivert64.sys,两个文件要分别放行:

    • nethub.exe → 杀软的信任区(免得主程序被当木马删掉)
    • WinDivert64.sys → 火绒 6.0:系统防护 → 漏洞驱动拦截 → 例外驱动; 360 / 腾讯管家:驱动(内核)防护白名单
    • 只加信任区不够:火绒把 WinDivert 当“漏洞驱动”在内核层直接拒加载, 这时程序报的是 1450「系统资源不足,无法完成请求的服务」 —— 字面像内存不够,其实不是。
    • 加完重启安全软件:例外/白名单是它启动时读进内存的,不重启不生效。

    漏了这步的表现:开机自启时驱动加载失败(没人盯着界面,最容易被拦), 日志里反复出现 WinDivert 打开失败(第 N/6 次),程序起不来。

  2. 双击 nethub.exe(会请求一次管理员权限)

  3. 在界面里配置:到「隧道链路」页填上你的上游地址 → 到「路由规则」页加一条规则(网段 → 走哪条链) → 回顶部点「启动服务」。配置也可以直接改程序目录里的 config.yaml(模板见 config.yaml.example),两者等价 (别忘了给本机网段加一条「直连」规则,规则页有「填本机网段」按钮)

需要 Windows 10 / 11 x64 + 管理员权限。

命令行 / 无界面

同一个 nethub.exe 也能完全不靠界面用(脚本、自动化、远程运维、让 agent 配网络):

nethub.exe -check                # 只校验配置文件,逐条列出错误(不启动、不改任何东西,不需管理员)
nethub.exe -status               # 打印机器可读的 JSON 现状:版本/服务状态/链路/规则/开关/运行实例(含它在用哪份配置)
nethub.exe -apply <新配置.yaml>   # 校验 → 落盘 → 让正在运行的实例热生效(不重启、不断已有连接)
nethub.exe -headless             # 无界面只跑引擎(自动化用)
nethub.exe -service-install      # 装成 Windows 服务(**只是备着**:不自己启动、也不随开机启动)
nethub.exe -service-autostart on  # 启用服务形态:随开机启动、无人登录也跑(装 ≠ 启用)
nethub.exe -service-autostart off # 停用:不再随开机(注册保留,随时能再打开)
nethub.exe -service-uninstall    # 卸载服务
nethub.exe -service-state        # 打印服务状态(含「开机自启开没开」)
nethub.exe -quit                 # 让正在运行的实例优雅退出
nethub.exe -autostart            # 装成计划任务开机自启(GUI 形态用,登录后延迟启动)
nethub.exe -clash-check          # 只检测系统代理会不会把内网送进代理
nethub.exe -test-upstream        # 直接实测上游链路(不经 gost)
nethub.exe -import-bats <目录>    # 从 gost 的 .bat 目录导入链路配置
nethub.exe -rollback             # 回滚到上一版本(一键更新出问题时用)
nethub.exe -version              # 打印版本号

一种形态只装一种自启,别混装(2026-10-15 现场踩到):

  • 有人在用的机器 → GUI 形态:双击 nethub.exe + -autostart(计划任务,登录后延迟启动, 有托盘、有系统通知)。登录后延迟默认 20 秒,改成别的值在界面「设置」里(autostart_delay)。
  • 服务器 / 无人登录 → 服务形态:-service-install 装好 + 界面「服务模式」卡片里拨开 「开机自启用服务形态」(或 -service-autostart on)。安装 ≠ 启用:只装不启用 = 「留着备用」,开机不会跑(同 Clash 装了虚拟网卡但没开 TUN)。服务形态没有托盘和系统通知。

两个自启都开着的后果:服务在开机时先拿到引擎,登录后才起来的计划任务界面版 只能当「只读失败者」——没托盘、没通知、还会刷一串权限报错(看着像 bug,其实是都开了)。 两种形态都装着没问题(装只是备着);冲突的是两条自启。 纠正:桌面机 → -service-autostart off(注册留着)+ -autostart; 服务器 → -service-autostart on + 去掉计划任务(界面里关掉开机自启即可)。 界面里拨「开机自启用服务形态」时会自动关掉计划任务那条自启,不用两边手动对着改。

服务形态会自己从崩溃/被杀里恢复(无人值守的机器靠这个):装了服务之后, 进程被外部结束或崩掉时 Windows 会在 5 秒、30 秒各拉一次,本窗口(一天)内最多两次 ——再不行就停在停止状态等人工(防止配置写坏了一个劲儿重启、把客户网络反复搞断)。 自己按「停止」-quit / sc stop 或界面里停不算失败,不会被拉回来。 每次真被拉起时日志里会写一行“上次未正常退出(runtime.json 还在:pid=……)”+ 一条托盘通知, 所以现场“隐道为什么重启了”有答案。

GUI(计划任务)形态没有这个能力 —— 系统层面没给(计划任务的“失败重试”实测对 进程被外部结束不生效)。“被杀了要有人再点一下”对有人在的桌面机可接受; 无人值守就该装服务形态而不是计划任务。

改动配置的标准流程(人、脚本、agent 都一样):

改 config.yaml(或界面里改)→ nethub.exe -check → nethub.exe -status 确认生效

规则、链路、上游的改动是即时生效的(界面里保存就生效,外部改文件后 2 秒内自动生效), 不用重启进程、也不会断掉正在用的连接。只有三项要重启:本机中转端口、DNS 接管(假 IP)、 system hosts 条目 —— -status 的 runtime.restartNeeded 会明说是哪一项。 脚本/agent 改配置建议用 nethub.exe -apply 新配置.yaml:它会校验、落盘,并等运行实例真的 吃进去才返回(返回 0 = 已生效;3 = 写进去了但实例没应用,原因在日志里)。

-status / -check 的输出是 UTF-8。PowerShell 里读它的 JSON 要先声明编码,否则管道会按 控制台代码页解码、还可能把引号吃掉,ConvertFrom-Json 会报“JSON 解析失败”:

[Console]::OutputEncoding = [Text.Encoding]::UTF8
$st = (nethub.exe -status | ConvertFrom-Json)
$st.runtime            # 运行实例:pid / running / configMatchesFile / restartNeeded
$st.tuning.quicBlock   # QUIC 阻断开着没有

config.yaml 是唯一配置来源,命令行与界面等价;配置文件就在 nethub.exe 同目录。

日志

  • 写在 nethub.exe 同目录的 logs/nethub.log(8 MB 轮转、保留 5 份,界面「运行日志」页看实时)。
  • 一条连接两行,格式照 Proxifier 的 open/close(谁 → 哪 → 哪条链):
    open : chrome.exe (8804) → main.example.com(192.0.2.217):80 via etyy
    close: chrome.exe (8804) → main.example.com(192.0.2.217):80 via etyy ↑76 B ↓279 B 884ms/997ms
    
    —— 名字学到的就带上名字(运维认名字不认 IP);末尾两个时间是「连上游(含域名解析)」与 「从发起到收尾」。命中哪条规则不在这两行里(那是 verbose 的 route.match), 这样 normal 才能像 Proxifier 那样“一眼读完”。
  • 日志三档(运行日志页右上的滑块 normal | verbose | debug,默认 normal,即时生效、不用重启)。 屏幕与文件是两个档(照 Proxifier 的 Screen Log / File Log):日志页那个滑块只管界面显示, 设置 › 文件与日志 里的「文件详细程度」管 logs/nethub.log(跟随界面 / normal / verbose / debug,默认跟随)。 现场最常用的组合是屏幕 normal + 文件 verbose:看着清爽,事后把日志发出去又有判定面。 (它放在设置里而不是日志页,因为它是“改一次就一直有效”的偏好,与“现在想看多详细”不是一回事。)
    • normal —— 现场面(对齐 Proxifier:errors + 连接 open/close):连接开/关、 直连/阻断、启停、配置变更热生效、上游可用/不可用翻转、本机网络变化、错误。
    • verbose —— 判定面:多出每条连接为什么这么走(route.match:命中了第几条规则、 走哪条链 / 直连 / 阻断 / 没命中)、DNS 请求与应答(dns.query / dns.answer)、名字学习、 DNS 接管、内置直连逐目标、周期统计快照(stats);以及三条排查用的量: upstream.pick(这条连接实际用了哪个上游、第几条、rtt、是现拨还是预热会话)、 conn.stage(域名解析 / 连上游 / 目标首个字节 / 全程,分段耗时)、 direct.done(直连/阻断连接的收尾:多少字节、活了多久)。 排查“某个目标为什么没走隧道 / 为什么慢”就切它。
    • debug —— 内部面:多出引擎内部状态与装配(包循环分片、内置直连开关、DNS 接管启动、 假 IP 段并表、名字表 / 假 IP 池的维护、内核层开关、进程表查询失败、规则表编译、过滤器原文)。 行数可能很多。
    • 三档的语义照抄 Proxifier 的 Normal / Verbose / Debug(见 logbus.Level 的注释)。
    • 连接页右上角有个「详细日志」按钮(对齐 Proxifier 连接面板上的 enable verbose output): 看到一条可疑连接时不用跳页拨滑块,点一下就是 verbose(再点一下回 normal,与日志页滑块同一设置)。
    • 档位会记住:存在 ui.log_level(屏幕)与 ui.log_level_file(文件,空 = 跟随屏幕), 重启后仍是上次选的;-apply / 导入配置 / 回滚备份 / 无人值守部署都不会把它们改掉 (算“本机偏好”,不是要派发的配置内容)。 启动时日志里有一行 日志档位:屏幕 normal / 文件 verbose(来自 config.yaml), -status 的 logLevel / logLevelFile 也是它。
    • 切到 debug 会立刻转储一份当前内部状态(规则表、过滤器原文、名字表、假 IP 池、 连接表、内核层句柄)—— 否则那些内容只在启动那一刻写,错过就只能重启(而重启会断业务连接)。
  • 被去重的重复项一定会补出行数(suppressed: key=… count=37 window=1m), 所以“只出现一次”就是真的只发生了一次。
  • 要交给别人排查时:把 logs 目录下最新那份 nethub.log 发出去(切到 debug 那段 自带过滤器原文等现场材料)。

换一台机器:一个文件就够

程序装好后,在「设置 → 配置:导出与导入」里:

  • 导出配置(含凭据) —— 一份完整 config.yaml,拷到新机器上点「导入配置」选它即可开箱即用 (⚠ 含明文口令,请私发)
  • 导出配置(无凭据) —— 同样能导入,只是上游口令被剔除(导入后补上),适合发给人看或存进仓库
  • 从地址导入 —— 也可以填一个 http(s) 地址,从那里拉配置(团队统一下发的轻量做法)
  • 导入都是先校验 → 自动备份 → 再生效,校验不过什么都不改;回滚就是导入 backups/ 里的旧文件

上游协议能填到哪一步

上游地址写在配置的 chains[].forward(界面里就是「链路」页的上游框),一行一个,可多个(故障转移)。

协议 写法 备注
SOCKS5 socks5://user:pass@host:1080 · socks5+tls://… 也支持 ?auth=<base64(user:pass)>(gost 的写法)
SOCKS4 socks4://user@host:1080 · socks4a://… 4a 会把域名交给上游解析;4 只能本机解析
HTTP 代理 http://user:pass@host:8080 · https://… 走 CONNECT,能代任意 TCP
shadowsocks ss://aes-256-gcm:口令@host:8388 传统:aes-128/192/256-gcm、chacha20-ietf-poly1305;2022:2022-blake3-aes-128/256-gcm、2022-blake3-chacha20-poly1305(口令位置填 base64 的 PSK);也认 ss://base64(方式:口令)@…
trojan trojan://口令@host:443 天生 TLS;服务端成功时不回话,所以「连上了」不等于认证通过
VLESS vless://uuid@host:443?security=tls&sni=… 或 vless://uuid@host:443?type=ws&path=/ws
VMess vmess://<base64(json)>(分享链接) 或 vmess://uuid@host:443?security=tls
传输后缀 +tls +ws +wss 只认两段:socks5+wss 对,socks5+ws+tls 错(gost 也会把它默默丢掉)
公共参数 ?path= ?host=(ws)· ?sni= ?secure=true · ?cert= ?key=(客户端证书) xray 分享链接里的 type= security= sni= allowInsecure= 也认

从聊天工具里粘来的链接往往没做 URL 编码(凭据里带 + / = ? #,或者中文口令)—— 这种我们自己补上编码再解析,你不用先去转义一遍;PSK 长度不对、把口令当 PSK 写这类错 会在保存配置时就报,并告诉你应该是什么样(不用等到连不上才猜)。

明确不做(写了会报错并告诉你怎么改,不会静默降级):

  • VLESS 的 flow / Vision(xtls-rprx-vision):服务端账号一旦配了 Vision,客户端不声明会被直接拒连 (不是降级)。请让上游把这个账号的 flow 去掉。
  • REALITY / XTLS(要 uTLS 指纹伪装 + X25519,不是打开一个开关);grpc / kcp / quic / h2 传输; VMess 的 alterId ≠ 0(xray 已删 LEGACY,AEAD 下它没有意义); shadowsocks 的老式流密码(aes-*-cfb / rc4 / bf-cfb)与 none / dummy 加密(不安全,上游也基本停用)。
  • shadowsocks 2022 的多用户写法(一个服务端多个 PSK,要 EIH 报头);UDP(2022 的 UDP 与 TCP 是两套东西); 2022 的 PSK 长度不合法、把服务端口令当 PSK 写这类错,保存时就会报错并告诉你该是多长。

关于「连接成功」的语义:shadowsocks / trojan / VLESS / VMess 都没有“认证成功”的应答 (口令或 UUID 不对时服务端是静默断开)。所以日志里出现“已连上”并不意味着凭据对 —— 诊断页的「链路自检」会真正跑一次业务目标往返,以它为准。

已知边界(先说清楚,省得现场试)

  • UDP 不中继,只拦下。本该走链的目标上的 UDP(主要是 443 的 QUIC)会被拦下并记一行 quic.block,应用随即回落 TCP(那条路仍归我们管);单条规则可勾「不拦 QUIC」放行。

    只有 UDP 的业务做不到 —— 这一条不是“还没做”,是上游不支持:实测 4 条上游的 SOCKS5 UDP ASSOCIATE 都回“成功”(还会回一个绑定端口,说明它确实建了 UDP socket), 但真发一个包过去4/4 收不到回包;其中一条回的绑定地址是上游自己内网里的 Docker 地址 (172.17.0.2),客户端根本路由不到 —— 这是结构性不可达。

    同行也一样:Proxifier 用的是 Windows 官方网络框架(WFP),它对 UDP 也只有“忽略”与“丢弃”两档,从不转发。 诊断页「UDP(QUIC)能力探测」可以随时自己验一遍(点那个「i」有完整说明)。

  • 只做 IPv4。DNS 层会把 AAAA 查询答成“没有这条记录”,免得应用拿到 IPv6 地址绕过我们(内网业务全是 IPv4)。

  • 看不见加密 DNS。DoH / ECH 下拿不到明文域名,通配域名规则(*.example.com)对那种名字不生效 —— 不静默,日志与界面会说;写具体域名的规则不受影响。

  • 统计不落盘。「连接」页里的统计卡,数字只在内存里,程序退出就没了(口径是累计:本程序启动以来, 与链页/顶栏同一个起点,引擎重启不清零;要重新起算点「清零」)。 长期的账看日志里每 5 分钟一行的流量概览;另:按应用/按目标各只留最近活跃的 512 项 (超出的按最久没活动淘汰,挤掉几个会写在页上)。

  • 直连的流量要先打开开关才看得到。「连接」页里「也统计直连流量」默认是关的(零开销: 直连的包不进内核过滤器),所以统计卡也就看不到那部分 —— 要看先把它打开。

常见问题

现象 原因 / 处理
报错 1450 或驱动装不上 安全软件拦了 WinDivert64.sys。只加信任区不够:火绒要把它加进「系统防护 → 漏洞驱动拦截 → 例外驱动」,加完重启安全软件(见上面「安装」第 1 条)
某个内网地址连不上 规则页「检查重叠」看是不是被前面的规则抢了;诊断页「链路自检」看链通不通
内网域名打不开(页面报解析失败 / 一直转圈) 日志里看到 交给上游解析失败: host unreachable 就是它:这个域名必须在「设置 → 系统 hosts 接管」里写成 <内网IP> 域名。光写成规则目标(按域名)不够 —— 本机解析不了的名字交给上游解析同样解析不了(上游那边也没有这条内网 DNS),但写成 hosts 后应用直接连的就是那个内网 IP(它本来就落在接管网段里),完全不需要任何人解析域名
内网特别慢、日志里同一目标疯狂重连 「与 Clash 共存」卡里的环路检测会告警:多半是别的代理把流量绕回来了
某个协议的报文完全不按代理走(最常见的只有 UDP 的程序) 我们只中继 TCP,UDP 只拦不转 —— 见上面「已知边界」;上游也转不了 UDP(实测 4/4 收不到回包)
想确认某个 IP 到底走哪条链 规则页把清单糊进「模拟」框,一次看完(支持网段抽样)
与 Clash 共存 Clash 的「绕过地址」要把内网段排掉(诊断页会给出该填的内容),否则内网会被 Clash 抢走
关窗口后程序还在跑 这是设计:点 X 是收进托盘。要真退出:托盘右键 → 退出,或 nethub.exe -quit
托盘图标变成一条小曲线 设置 › 外观 › 「托盘图标显示实时流量」开着(默认关)。空载时只剩一条底线;
「显示内容」可选总量 / 只上行 / 只下行

界面设计规范见 DESIGN.md;改代码、架构与踩坑见 AGENTS.md。 MIT 许可,第三方组件(WinDivert 等)见 LICENSE。

About

Windows 内网透明代理:按目标网段在内核层接管 TCP,经你自己的 SOCKS5/HTTP 上游转发。Proxifier 式规则 + Wails 界面

Topics

Resources

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages