[server][ xray]- 完成代理链配置生成 - 2
This commit is contained in:
@@ -14,6 +14,7 @@ import io.wdd.func.xray.beans.node.XrayConfigInfo;
|
|||||||
import io.wdd.func.xray.beans.xray.XrayConfig;
|
import io.wdd.func.xray.beans.xray.XrayConfig;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
import org.springframework.core.io.ClassPathResource;
|
import org.springframework.core.io.ClassPathResource;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@@ -49,12 +50,21 @@ public class XrayConfigPersistor {
|
|||||||
/**
|
/**
|
||||||
* 执行Xray生成配置文件的持久化工作,沈成伟临时文件保存至当前目录中
|
* 执行Xray生成配置文件的持久化工作,沈成伟临时文件保存至当前目录中
|
||||||
*
|
*
|
||||||
|
* @param isOutBoundFree
|
||||||
* @param xrayConfig
|
* @param xrayConfig
|
||||||
* @param currentVersion
|
* @param currentVersion
|
||||||
* @param proxyNode
|
* @param proxyNode
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public XrayConfigInfo persist(XrayConfig xrayConfig, int currentVersion, ProxyNode proxyNode) {
|
public XrayConfigInfo persist(XrayConfig xrayConfig, int currentVersion, ProxyNode proxyNode) {
|
||||||
|
|
||||||
|
// 从缓存层获取信息
|
||||||
|
XrayConfigInfo xrayConfigInfo = proxyNode.getXrayConfigInfo();
|
||||||
|
if (ObjectUtils.isEmpty(xrayConfigInfo)) {
|
||||||
|
xrayConfigInfo = new XrayConfigInfo();
|
||||||
|
proxyNode.setXrayConfigInfo(xrayConfigInfo);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 将生成的xrayConfig直接写为字符串
|
// 将生成的xrayConfig直接写为字符串
|
||||||
String resultContent = objectWriter
|
String resultContent = objectWriter
|
||||||
@@ -74,10 +84,11 @@ public class XrayConfigPersistor {
|
|||||||
currentVersion
|
currentVersion
|
||||||
);
|
);
|
||||||
|
|
||||||
// 文件写入完成,保存文件信息
|
|
||||||
XrayConfigInfo xrayConfigInfo = new XrayConfigInfo();
|
|
||||||
xrayConfigInfo.setXrayConfigFile(xrayConfigFile);
|
xrayConfigInfo.setXrayConfigFile(xrayConfigFile);
|
||||||
xrayConfigInfo.setXrayConfigFileName(fileName);
|
xrayConfigInfo.setXrayConfigFileName(fileName);
|
||||||
|
|
||||||
|
|
||||||
|
// 文件写入完成,保存文件信息
|
||||||
xrayConfigInfo.setXrayConfig(xrayConfig);
|
xrayConfigInfo.setXrayConfig(xrayConfig);
|
||||||
|
|
||||||
return xrayConfigInfo;
|
return xrayConfigInfo;
|
||||||
|
|||||||
@@ -10,11 +10,14 @@ import io.wdd.func.xray.beans.xray.protocol.inbound.vmess.InboundConfigurationOb
|
|||||||
import io.wdd.func.xray.beans.xray.protocol.inbound.vmess.VMESS;
|
import io.wdd.func.xray.beans.xray.protocol.inbound.vmess.VMESS;
|
||||||
import io.wdd.func.xray.beans.xray.protocol.outbound.Freedom;
|
import io.wdd.func.xray.beans.xray.protocol.outbound.Freedom;
|
||||||
import io.wdd.func.xray.beans.xray.protocol.outbound.OutboundConfigurationObject;
|
import io.wdd.func.xray.beans.xray.protocol.outbound.OutboundConfigurationObject;
|
||||||
|
import io.wdd.func.xray.beans.xray.transport.InboundObject;
|
||||||
import io.wdd.func.xray.beans.xray.transport.OutboundObject;
|
import io.wdd.func.xray.beans.xray.transport.OutboundObject;
|
||||||
import io.wdd.func.xray.persisit.XrayDBOperator;
|
import io.wdd.func.xray.persisit.XrayDBOperator;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.beanutils.BeanUtils;
|
import org.apache.commons.beanutils.BeanUtils;
|
||||||
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
@@ -33,14 +36,12 @@ import static io.wdd.func.xray.service.XrayConfigPersistor.cleanVersion;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class XrayCoreServiceImpl implements XrayCoreService {
|
public class XrayCoreServiceImpl implements XrayCoreService {
|
||||||
|
|
||||||
|
private static final String ProxyChainSplitor = "->";
|
||||||
@Resource
|
@Resource
|
||||||
XrayConfigPersistor xrayConfigPersistor;
|
XrayConfigPersistor xrayConfigPersistor;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
XrayDBOperator xrayDBOperator;
|
XrayDBOperator xrayDBOperator;
|
||||||
|
|
||||||
private static final String ProxyChainSplitor = "->";
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<List<ProxyNode>> transformProxyChainString(List<String> proxyChainList, boolean isTopicName) {
|
public List<List<ProxyNode>> transformProxyChainString(List<String> proxyChainList, boolean isTopicName) {
|
||||||
|
|
||||||
@@ -90,17 +91,21 @@ public class XrayCoreServiceImpl implements XrayCoreService {
|
|||||||
// value => Xray Config Json
|
// value => Xray Config Json
|
||||||
// HashMap<ProxyNode, XrayConfig> resultMap = new HashMap<>();
|
// HashMap<ProxyNode, XrayConfig> resultMap = new HashMap<>();
|
||||||
|
|
||||||
|
// 清除tmp目录时候使用的一个锁
|
||||||
|
|
||||||
|
int currentVersion = cleanVersion.get();
|
||||||
allNetworkPathList
|
allNetworkPathList
|
||||||
.stream()
|
.stream()
|
||||||
.forEach(
|
.forEach(
|
||||||
networkPathList -> {
|
networkPathList -> {
|
||||||
// 每一条每一条的执行,依次添加相应的 in-out 连接
|
|
||||||
generateXrayJsonSinglePath(
|
generateXrayJsonSinglePath(
|
||||||
networkPathList
|
networkPathList,
|
||||||
|
currentVersion
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// 拿到所有的proxyNode
|
// 拿到所有的proxyNode
|
||||||
Set<ProxyNode> proxyNodeSet = allNetworkPathList
|
Set<ProxyNode> proxyNodeSet = allNetworkPathList
|
||||||
.stream()
|
.stream()
|
||||||
@@ -127,7 +132,8 @@ public class XrayCoreServiceImpl implements XrayCoreService {
|
|||||||
return PROXY_NODE_TOPIC_NAME_MAP;
|
return PROXY_NODE_TOPIC_NAME_MAP;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateXrayJsonSinglePath(List<ProxyNode> networkPathList) {
|
private void generateXrayJsonSinglePath(List<ProxyNode> networkPathList, int currentVersion) {
|
||||||
|
|
||||||
int pathLength = networkPathList.size();
|
int pathLength = networkPathList.size();
|
||||||
|
|
||||||
// 采用 VMESS + websocket的形式形成 链状代理
|
// 采用 VMESS + websocket的形式形成 链状代理
|
||||||
@@ -138,7 +144,6 @@ public class XrayCoreServiceImpl implements XrayCoreService {
|
|||||||
String uuid = UUID
|
String uuid = UUID
|
||||||
.randomUUID()
|
.randomUUID()
|
||||||
.toString();
|
.toString();
|
||||||
|
|
||||||
ClientObject clientObject = ClientObject
|
ClientObject clientObject = ClientObject
|
||||||
.builder()
|
.builder()
|
||||||
.id(uuid)
|
.id(uuid)
|
||||||
@@ -150,19 +155,14 @@ public class XrayCoreServiceImpl implements XrayCoreService {
|
|||||||
|
|
||||||
int port = 19999;
|
int port = 19999;
|
||||||
|
|
||||||
// 清楚tmp目录时候使用的一个锁
|
|
||||||
int currentVersion = cleanVersion.get();
|
|
||||||
|
|
||||||
for (int pos = 0; pos < pathLength; pos++) {
|
for (int pos = 0; pos < pathLength; pos++) {
|
||||||
|
|
||||||
ProxyNode proxyNode = networkPathList.get(pos);
|
ProxyNode proxyNode = networkPathList.get(pos);
|
||||||
|
|
||||||
// 最后一个节点需要进行 FreeOutbound的构造
|
|
||||||
boolean isOutBoundFree = pos == pathLength - 1;
|
|
||||||
|
|
||||||
// 构造 xrayConfig
|
// 构造 xrayConfig
|
||||||
XrayConfig xrayConfig = doBuildXrayConfig(
|
XrayConfig xrayConfig = doBuildXrayConfig(
|
||||||
isOutBoundFree,
|
|
||||||
tag,
|
tag,
|
||||||
clientObject,
|
clientObject,
|
||||||
port,
|
port,
|
||||||
@@ -170,22 +170,29 @@ public class XrayCoreServiceImpl implements XrayCoreService {
|
|||||||
pos
|
pos
|
||||||
);
|
);
|
||||||
|
|
||||||
// 持久化 Xray生成的文件信息
|
// 在 缓存层 持久化 Xray生成的文件信息
|
||||||
XrayConfigInfo xrayConfigInfo = xrayConfigPersistor.persist(
|
XrayConfigInfo xrayConfigInfo = xrayConfigPersistor.persist(
|
||||||
xrayConfig,
|
xrayConfig,
|
||||||
currentVersion,
|
currentVersion,
|
||||||
proxyNode
|
proxyNode
|
||||||
);
|
);
|
||||||
|
|
||||||
proxyNode.setXrayConfigInfo(xrayConfigInfo);
|
proxyNode.setXrayConfigInfo(xrayConfigInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private XrayConfig doBuildXrayConfig(boolean isOutBoundFree, String tag, ClientObject clientObject, int port, List<ProxyNode> networkPathList, int pos) {
|
private XrayConfig doBuildXrayConfig(String tag, ClientObject clientObject, int port, List<ProxyNode> networkPathList, int pos) {
|
||||||
|
|
||||||
XrayConfig xrayConfig = new XrayConfig();
|
// 需要从现有的XrayConfig基础上进行生成
|
||||||
|
// 尝试从 缓存层获取
|
||||||
|
XrayConfig xrayConfig = networkPathList
|
||||||
|
.get(pos)
|
||||||
|
.getXrayConfigInfo()
|
||||||
|
.getXrayConfig();
|
||||||
|
if (ObjectUtils.isEmpty(xrayConfig)) {
|
||||||
|
xrayConfig = new XrayConfig();
|
||||||
|
}
|
||||||
|
|
||||||
// 设置Log属性
|
// 设置Log属性
|
||||||
xrayConfig.setLog(LogTemplate);
|
xrayConfig.setLog(LogTemplate);
|
||||||
@@ -198,26 +205,16 @@ public class XrayCoreServiceImpl implements XrayCoreService {
|
|||||||
tag
|
tag
|
||||||
);
|
);
|
||||||
|
|
||||||
if (isOutBoundFree) {
|
// 中间节点,需要有特定的输出
|
||||||
// 最后一个直接出去就行了
|
// 设置 outbounds的信息
|
||||||
// 设置FreeOut
|
buildOutbound(
|
||||||
buildOutboundFree(
|
xrayConfig,
|
||||||
xrayConfig,
|
networkPathList,
|
||||||
tag
|
pos,
|
||||||
);
|
clientObject,
|
||||||
} else {
|
tag,
|
||||||
// 中间节点,需要有特定的输出
|
port
|
||||||
// 设置 outbounds的信息
|
);
|
||||||
buildOutbound(
|
|
||||||
xrayConfig,
|
|
||||||
networkPathList,
|
|
||||||
pos,
|
|
||||||
clientObject,
|
|
||||||
tag,
|
|
||||||
port
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 设置 路由信息
|
// 设置 路由信息
|
||||||
buildRouting(
|
buildRouting(
|
||||||
@@ -241,8 +238,13 @@ public class XrayCoreServiceImpl implements XrayCoreService {
|
|||||||
|
|
||||||
private void buildRouting(XrayConfig xrayConfig, String tag) {
|
private void buildRouting(XrayConfig xrayConfig, String tag) {
|
||||||
|
|
||||||
RoutingObject routingObject = new RoutingObject();
|
// 从缓存中获取
|
||||||
routingObject.setDomainStrategy("IPIfNonMatch");
|
RoutingObject routingObject = xrayConfig.getRouting();
|
||||||
|
if (ObjectUtils.isEmpty(routingObject)) {
|
||||||
|
routingObject = new RoutingObject();
|
||||||
|
routingObject.setDomainStrategy("IPIfNonMatch");
|
||||||
|
xrayConfig.setRouting(routingObject);
|
||||||
|
}
|
||||||
|
|
||||||
RuleObject ruleObject = RuleObject
|
RuleObject ruleObject = RuleObject
|
||||||
.builder()
|
.builder()
|
||||||
@@ -251,16 +253,39 @@ public class XrayCoreServiceImpl implements XrayCoreService {
|
|||||||
.outboundTag(tag)
|
.outboundTag(tag)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
routingObject.setRules(
|
List<RuleObject> ruleObjectList = routingObject.getRules();
|
||||||
new ArrayList<>(
|
if (CollectionUtils.isEmpty(ruleObjectList)) {
|
||||||
List.of(ruleObject)
|
ruleObjectList = new ArrayList<>();
|
||||||
)
|
routingObject.setRules(ruleObjectList);
|
||||||
);
|
}
|
||||||
|
|
||||||
xrayConfig.setRouting(routingObject);
|
ruleObjectList.add(ruleObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void buildOutbound(XrayConfig xrayConfig, List<ProxyNode> networkPathList, int pos, ClientObject clientObject, String tag, Integer port) {
|
private void buildOutbound(XrayConfig xrayConfig, List<ProxyNode> networkPathList, int pos, ClientObject clientObject, String tag, Integer port) {
|
||||||
|
|
||||||
|
// 从缓存中获取
|
||||||
|
List<OutboundObject> outboundObjectList = xrayConfig.getOutbounds();
|
||||||
|
if (CollectionUtils.isEmpty(outboundObjectList)) {
|
||||||
|
outboundObjectList = new ArrayList<>();
|
||||||
|
xrayConfig.setOutbounds(outboundObjectList);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ChainLastPosIndex = networkPathList.size() - 1;
|
||||||
|
|
||||||
|
if (pos == ChainLastPosIndex) {
|
||||||
|
// 代理链的最后一位
|
||||||
|
if (!outboundObjectList.contains(OutboundFree)) {
|
||||||
|
outboundObjectList.add(OutboundFree);
|
||||||
|
}
|
||||||
|
if (!outboundObjectList.contains(OutboundBlackHole)) {
|
||||||
|
outboundObjectList.add(OutboundBlackHole);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 中间节点,需要进行特定的构建
|
||||||
|
|
||||||
io.wdd.func.xray.beans.xray.protocol.outbound.VMESS vmessOutbound = new io.wdd.func.xray.beans.xray.protocol.outbound.VMESS();
|
io.wdd.func.xray.beans.xray.protocol.outbound.VMESS vmessOutbound = new io.wdd.func.xray.beans.xray.protocol.outbound.VMESS();
|
||||||
try {
|
try {
|
||||||
BeanUtils.copyProperties(
|
BeanUtils.copyProperties(
|
||||||
@@ -294,18 +319,18 @@ public class XrayCoreServiceImpl implements XrayCoreService {
|
|||||||
List.of(clientObject)
|
List.of(clientObject)
|
||||||
);
|
);
|
||||||
|
|
||||||
xrayConfig.setOutbounds(
|
outboundObjectList.add(vmessOutbound);
|
||||||
new ArrayList<>(
|
|
||||||
List.of(
|
|
||||||
vmessOutbound,
|
|
||||||
OutboundFree,
|
|
||||||
OutboundBlackHole
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void buildInbound(XrayConfig xrayConfig, ClientObject clientObject, Integer port, String tag) {
|
private void buildInbound(XrayConfig xrayConfig, ClientObject clientObject, Integer port, String tag) {
|
||||||
|
|
||||||
|
// 从缓存中获取
|
||||||
|
List<InboundObject> inboundObjectList = xrayConfig.getInbounds();
|
||||||
|
if (CollectionUtils.isEmpty(inboundObjectList)) {
|
||||||
|
inboundObjectList = new ArrayList<>();
|
||||||
|
xrayConfig.setInbounds(inboundObjectList);
|
||||||
|
}
|
||||||
|
|
||||||
VMESS inboundObject = new VMESS();
|
VMESS inboundObject = new VMESS();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -332,13 +357,8 @@ public class XrayCoreServiceImpl implements XrayCoreService {
|
|||||||
|
|
||||||
inboundObject.setSettings(inboundConfigurationObject);
|
inboundObject.setSettings(inboundConfigurationObject);
|
||||||
|
|
||||||
xrayConfig.setInbounds(
|
// 增加进去
|
||||||
new ArrayList<>(
|
inboundObjectList.add(inboundObject);
|
||||||
List.of(
|
|
||||||
inboundObject
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user