nproxy :: 使用 Clojure 开发的代理工具。
- 功能特性
- 界面:支持 CLI 和 GUI。
- 协议:支持 websocket、http、socks5、trojan、vmess 协议。
- 订阅:支持 V2rayN 格式的 vmess 节点订阅管理。
- 分流:支持导入 v2ray 社区维护的分流规则。
- 灵活配置:支持任意维度的配置拆分到单独文件。
- 简单扩展:支持自定义协议插件,通过配置激活,无需修改代码。
- 最小化依赖:几乎没有使用第三方库,降低维护风险。
- 性能:基于 java.io 和虚拟线程构建,性能出色。
代理服务本质上是代理请求的接收和处理,配置中主要描述:入口 inbound,出口 outbound。
默认配置:
{:inbound {:type :proxy
:net-opts {:type :tcp :port 1080}
:proxy-opts {:type :socks5}}
:outbound {:type :direct}}inbound- 指定了在本地 1080 端口上接收 socks5 协议的代理请求
outbound- 指定了以直连的方式处理代理请求
最基础的入口类型是 proxy,包含两个选项:net-opts 和 proxy-opts,分别描述网络和代理。
默认配置:
{:type :proxy
:net-opts {:type :tcp :port 1080}
:proxy-opts {:type :socks5}}net-opts- 指定了在本地 1080 端口上接收连接
proxy-opts- 指定了在连接上接收 socks5 协议的代理请求
其它可选的网络配置(net-opts)有:
- tls
{:type :tcp :port 1080 :ssl? true}- ws
{:type :ws :port 1080}- wss
{:type :ws :port 1080 :ssl? true}
其它可选的代理配置(proxy-opts)有:
- http
{:type :http}- trojan
{:type :trojan :password "CHANGEIT"}- vmess
{:type :vmess :uuid "CHANGEIT"}
使用 multi 类型的入口可以同时监听多个端口:
{:type :multi
:inbounds [{:type :proxy
:net-opts {:type :tcp :port 1080}
:proxy-opts {:type :socks5}}
{:type :proxy
:net-opts {:type :tcp :port 1081}
:proxy-opts {:type :http}}]}在本地 1080 端口上接收 socks5 协议的代理请求,在本地 1081 端口上接收 http 协议的代理请求。
有三类最基础的出口类型:direct、block、和 proxy。
direct 表示直连:
{:type :direct}收到代理请求后,会直接连接请求的地址,然后转发之间的流量,即正常代理。
block 表示丢弃请求:
{:type :block}收到代理请求后,会等待一段时间,然后关闭连接。
proxy 表示通过第三方代理转发:
{:type :proxy
:net-opts {:type :tcp :host "foo" :port 1080}
:proxy-opts {:type :socks5}}net-opts- 指定了通过 tcp 连接节点,地址为 foo:1080
proxy-opts- 指定了在连接上通过 socks5 协议发送代理请求
其它可选的网络配置(net-opts)有:
- tls
{:type :tcp :host "foo" :port 443 :ssl? true}- ws
{:type :ws :host "foo" :port 80 :path "/" :headers {"host" "foo"}}- wss
{:type :ws :host "foo" :port 443 :ssl? true :path "/" :headers {"host" "foo"}}
其它可选的代理配置(proxy-opts)有:
- http
{:type :http}- trojan
{:type :trojan :password "CHANGEIT"}- vmess
{:type :vmess :uuid "CHANGEIT"}
还有一些高阶出口类型用来组合多个基础出口类型:rand-dispatch 和 tag-dispatch。
rand-dispatch 表示随机分派(例如负载均衡):
{:type :rand-dispatch
:outbounds [{:type :proxy
:net-opts {:type :tcp :host "foo" :port 1080}
:proxy-opts {:type :socks5}}
{:type :proxy
:net-opts {:type :tcp :host "bar" :port 1080}
:proxy-opts {:type :socks5}}]}把代理请求随机转发到 foo:1080 或 bar:1080 上的 socks5 代理服务。
tag-dispatch 实现了基于分流规则(域名匹配)的分派:
{:type :tag-dispatch
:tags {"baidu.com" :direct "google.com" :proxy "ads.com" :block}
:default-tag :direct
:outbounds {:direct {:type :direct}
:block {:type :block}
:proxy {:type :proxy
:net-opts {:type :tcp :host "foo" :port 1080}
:proxy-opts {:type :socks5}}}}baidu.com 及其所有子域名的 tag 为 direct,当收到这些代理请求时直连;
同理 google.com 通过第三方域名转发,ads.com 直接丢弃。
默认配置下只支持 tcp 网络协议和 socks5 代理协议,其它协议需要在配置中指定插件启用:
{:plugins [clj-nproxy.plugin.ws clj-nproxy.plugin.vmess]
:outbound {:type :proxy
:net-opts {:type :ws :host "foo" :port 80}
:proxy-opts {:type :vmess :uuid "CHANGEIT"}}}加载两个插件:ws 和 vmess,分别提供 ws 和 vmess 协议。
内置的插件有:
clj-nproxy.plugin.ws- 提供 ws 网络协议
clj-nproxy.plugin.http- 提供 http 代理协议
clj-nproxy.plugin.trojan- 提供 trojan 代理协议
clj-nproxy.plugin.vmess- 提供 vmess 代理协议
plugins 是 Clojure 命名空间的序列,使用者也可以用单独的命名空间自定义协议。
网络层的 ssl 使用 javax.net.ssl 实现,可以通过系统属性配置证书。
关键字:keytool、-Djavax.net.ssl.*
所有配置文件放到 .nproxy/ 目录下面,默认从 .nproxy/config.edn 中读取配置:
.nproxy/config.edn
{:plugins [clj-nproxy.plugin.ws clj-nproxy.plugin.vmess]
:inbound {:type :proxy
:net-opts {:type :tcp :port 1080}
:proxy-opts {:type :socks5}}
:outbound {:type :tag-dispatch
:tags {"baidu.com" :direct "google.com" :proxy "ads.com" :block}
:default-tag :direct
:outbounds {:direct {:type :direct}
:block {:type :block}
:proxy {:type :rand-dispatch
:outbounds [{:type :proxy
:net-opts {:type :tcp :host "foo" :port 1080}
:proxy-opts {:type :socks5}}
{:type :proxy
:net-opts {:type :tcp :host "bar" :port 1080}
:proxy-opts {:type :socks5}}]}}}}在读取配置文件时,定义了读取宏 #file 从其它文件读取。
tags 和 proxy 拆分到 tags.edn 和 sub.edn:
.nproxy/config.edn
{:plugins [clj-nproxy.plugin.ws clj-nproxy.plugin.vmess]
:inbound {:type :proxy
:net-opts {:type :tcp :port 1080}
:proxy-opts {:type :socks5}}
:outbound {:type :tag-dispatch
:tags #file "tags.edn"
:default-tag :direct
:outbounds {:direct {:type :direct}
:block {:type :block}
:proxy #file "sub.edn"}}}.nproxy/tags.edn
{"baidu.com" :direct "google.com" :proxy "ads.com" :block}.nproxy/sub.edn
{:type :rand-dispatch
:outbounds [{:type :proxy
:net-opts {:type :tcp :host "foo" :port 1080}
:proxy-opts {:type :socks5}}
{:type :proxy
:net-opts {:type :tcp :host "bar" :port 1080}
:proxy-opts {:type :socks5}}]}tags.edn 和 sub.edn 可以用其它工具管理(vsub 和 dlc)。
clojure -X clj-nproxy.cli/start-server
clojure -X clj-nproxy.gui/start-server从 .nproxy/config.edn 中读取配置,启动服务。后者还会启动 GUI(swing)。
配置文件是可指定的:
clojure -X clj-nproxy.cli/start-server '{:config-name "test.edn"}'从 .nproxy/test.edn 中读取测试配置。
V2rayN 格式的订阅管理工具。
相关链接:https://github.com/2dust/v2rayN/wiki/Description-of-VMess-share-link
订阅链接保存到 .nproxy/sub.url
echo https://example.com > .nproxy/sub.url获取订阅内容保存到 .nproxy/sub.txt
clojure -X clj-nproxy.tool.vsub/fetch列出所有 vmess 节点
clojure -X clj-nproxy.tool.vsub/list生成出口配置保存到 .nproxy/sub.edn
clojure -X clj-nproxy.tool.vsub/gen社区维护的分流规则导入工具。
相关连接:https://github.com/v2fly/domain-list-community
dlc 仓库保存到 .nproxy/domain-list-community/
git clone https://github.com/v2fly/domain-list-community .nproxy/domain-list-community生成 tags 配置保存到 .nproxy/tags.edn
clojure -X clj-nproxy.tool.dlc/gen