v2rayN 的节点可以设置出口为Socks 方便使用落地节点 套别的隧道 实现链式代理

需求

上一篇讲了怎么手动修改配置文件sockopt, 实现出口为Socks, 这样可以套别的隧道, 实现链式代理.

为了方便使用, 我们修改v2rayN, 实现这个功能.

比如, 一个 vless + websocket + tls 节点, 设置出口为Socks, 而不是自由的出去.


方案

在 outbounds出站列表 里面 增加一个 Socks 的 outbound出站, tag 设置为 tunnel

在原本的 outbound出站 的 streamSettings 里面 增加一个 sockopt, 里面设置一个属性 dialerProxy, 值为 tunnel (和上面那个outbound出站的tag一致)

出站配置里vless节点的dialerProxy指向tunnel,socks出站端口10086

界面设计

参数设置 窗口 增加一页 "出口设置"

解决方案资源管理器里面找到 参数设置 窗口.

选择中间这个面积最大的 TabControl 控件.

在空白处右键菜单, 添加TabItem.

在参数设置窗口的设计器里右键,选添加TabItem

点击这个新增的 TabItem, 设置 宽 高 属性为 Auto, 设置 Header 属性为 "Core出口设置"

新标签页的宽高设为Auto,Header填Core出口设置

拖动控件, 添加 2个 Label, 2个 TextBox

拖进两个Label和两个TextBox,分别标Socks5出口的IP和端口

设置 Label 的 Content 属性, 设置为 "Socks5出口的接收方IP", "Socks5出口的接收方端口"

Label的Content设为Socks5出口的接收方IP

设置 TextBox 的 名称 为: txtSocksOutboundIP, txtSocksOutboundPort

两个TextBox分别命名为txtSocksOutboundIP和txtSocksOutboundPort

编译, 运行一下, 看看界面显示效果是否正常.


绑写数据

给窗口 OptionSettingWindow 添加两个数据属性. socksOutboundIP, socksOutboundPort.

OptionSettingViewModel里新增socksOutboundIP和socksOutboundPort两个属性

把新增的这两个文本框与窗口的数据属性绑定.

把两个文本框绑定到这两个属性

按窗口的 确认 按钮之后, 调用的函数是 OptionSettingViewModel.SaveSetting 

进里面打个断点. 运行起来, 点击 确认 按钮, 监视 面板里面检查一下数据绑定没问题, 获取到了文本框的内容.

点确认后断点里看到IP是127.0.0.1、端口是10086

参数的保存和读取

参考一下现有代码写法, 要修改一些数据结构, 添加相关的属性.

添加一个数据结构 class SocksOutbound

新增SocksOutbound类,包含socksOutboundIP和socksOutboundPort

class Config 添加数据成员

Config类里加上socksOutbound数据成员

OptionSettingViewModel.SaveSetting 函数里面 把参数保存.

在SaveSetting里把界面上的IP和端口存进配置

检查 保存界面参数的 json 文件, 没问题.

guiNConfig.json里socksOutbound已保存为127.0.0.1和10086

在 OptionSettingViewModel 参数设置 窗口的构造函数中, 添加加载数据的语句

在参数设置窗口的构造函数里加上加载这两个参数的语句

编译, 运行, 检查各种操作下, 这两个参数的设置和加载没有问题.


生成config.json配置文件

阅读代码, 找到生成配置文件的逻辑.

找到 CoreConfigV2ray.outbound 函数. 根据代码的逻辑, 本来要在这个函数里新增一个Socks 的 outbound, 调试的时候发现, 这时候 v2rayConfig.outbounds 数组里面已经有好几个outbound了, 除了要设置参数的, 还有1条 direct 的 freedom 和1条 block 的 blackhole.

调试时outbounds有三项:vmess、freedom和blackhole

那我要看看是哪里构造的. 

经过调试发现, 原来在这一步已经读入了一个默认配置文件, 里面就已经有了 direct 和 black的 outbound. 那我们不是在这里把 tunnel 加进去就行了?

断点停在GetEmbedText读取默认配置的那一行

找了一找, 发现默认配置文件放在这里

默认配置文件是Sample目录下的SampleClientConfig

修改这个默认配置文件, 增加一个 outbound, 如下

在默认配置里加一个socks出站,地址127.0.0.1、端口10086、标签tunnel

outbound 中新增的 Socks5 tunnel 已经添加好了. 


接下来是 streamSettings 里面 增加一个 sockopt, 里面设置一个属性 dialerProxy, 值为 tunnel

还是修改默认配置文件, 在现有的 outbound里面, streamSettings 结构里面增加一个 sockopt

streamSettings的sockopt里dialerProxy设为tunnel

为了支持这个新增的部分, class StreamSettings4Ray 的数据结构也需要相应的同步修改

StreamSettings4Ray里同步加上sockopt属性

相应地, 也要新增一个 class SockoptObject 的数据结构, 包含一个 dialerProxy 属性

新增SockoptObject类,包含dialerProxy属性

到目前为止, 可以编译运行一下, 调试确认把我们新设置的默认配置文件都加载到内存的数据结构中去了.

调试确认新加的socks出站已加载,端口10086、标签tunnel

出站首项的dialerProxy已是tunnel


有了这些以后, 我们不能老是跑写死的  127.0.0.1 : 10086 是吧?  所以还差一步, 把界面上输入的Socks的IP和端口赋值给当前配置.

在函数 CoreConfigV2ray.GenerateClientConfigContent 中, 增加一步处理 socksOut

在GenerateClientConfig里调用socksOut

然后再简单的实现具体步骤.

把程序的总配置参数中的 socksOut的 IP 和 端口 设置到准备生成配置文件的数据结构中.

socksOut把界面上填的IP和端口写进出站配置

好了, 编译运行, 测试一下功能.


========

完

Github源码 https://github.com/crazypeace/v2rayN/tree/outboundSocks


如果你觉得这个功能有用, 就来官方 PR 涨人气! 目前官方还没有合入主线, 作者还在考虑.

评论