[server][ xray]- 完成代理链配置生成 - 2

This commit is contained in:
zeaslity
2023-03-01 17:41:37 +08:00
parent 55b7f68282
commit bd4af9261d
2 changed files with 94 additions and 63 deletions

View File

@@ -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;

View File

@@ -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,14 +205,6 @@ public class XrayCoreServiceImpl implements XrayCoreService {
tag tag
); );
if (isOutBoundFree) {
// 最后一个直接出去就行了
// 设置FreeOut
buildOutboundFree(
xrayConfig,
tag
);
} else {
// 中间节点,需要有特定的输出 // 中间节点,需要有特定的输出
// 设置 outbounds的信息 // 设置 outbounds的信息
buildOutbound( buildOutbound(
@@ -216,8 +215,6 @@ public class XrayCoreServiceImpl implements XrayCoreService {
tag, tag,
port 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 routingObject = xrayConfig.getRouting();
if (ObjectUtils.isEmpty(routingObject)) {
routingObject = new RoutingObject();
routingObject.setDomainStrategy("IPIfNonMatch"); 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
)
)
);
} }
/** /**