[server][ xray]- 优化Xray配置部分的代码

This commit is contained in:
zeaslity
2023-03-01 10:58:33 +08:00
parent 0959aebf67
commit 295e3ea024
6 changed files with 190 additions and 79 deletions

View File

@@ -61,8 +61,15 @@ public class XrayController {
)
);
ArrayList<ProxyNode> pathE = new ArrayList<>(
Collections.singletonList(
seoul5
)
);
// allNetworkPathList.add(pathA);
allNetworkPathList.add(pathD);
// allNetworkPathList.add(pathD);
allNetworkPathList.add(pathE);
// allNetworkPathList.add(pathB);
// allNetworkPathList.add(pathC);
@@ -72,7 +79,7 @@ public class XrayController {
xrayConfigDistribute.buildXrayUpdateResult(allNetworkPathList.get(0));
System.out.println("结束!");
System.out.println("Xray controller test() 结束!");
}
}

View File

@@ -17,6 +17,7 @@ public class ProxyNodeSet {
// 开发使用
public static ProxyNode chengduAgent;
public static ProxyNode tokyoDev;
public static ProxyNode seoul5;
static {
@@ -117,15 +118,58 @@ public class ProxyNodeSet {
.agentTopicName("Chengdu-amd64-77-remote")
.build();
ProxyNodeMap.put(chengdu.getNum(), chengdu);
ProxyNodeMap.put(hongkong.getNum(), hongkong);
ProxyNodeMap.put(shanghai.getNum(), shanghai);
ProxyNodeMap.put(seoul2.getNum(), seoul2);
ProxyNodeMap.put(tokyo2.getNum(), tokyo2);
ProxyNodeMap.put(phoenix2.getNum(), phoenix2);
ProxyNodeMap.put(london2.getNum(), london2);
ProxyNodeMap.put(chengduAgent.getNum(), chengduAgent);
ProxyNodeMap.put(tokyoDev.getNum(), tokyoDev);
seoul5 = ProxyNode
.builder()
.location("Seoul")
.num(97)
.publicIPv4("146.56.159.175")
.proxyNodeType(ProxyNodeType.EXTERNAL)
.name("oracle-seoul5")
.agentName("Seoul-arm64-02")
.agentTopicName("Seoul-arm64-02-oracle")
.build();
ProxyNodeMap.put(
chengdu.getNum(),
chengdu
);
ProxyNodeMap.put(
hongkong.getNum(),
hongkong
);
ProxyNodeMap.put(
shanghai.getNum(),
shanghai
);
ProxyNodeMap.put(
seoul2.getNum(),
seoul2
);
ProxyNodeMap.put(
tokyo2.getNum(),
tokyo2
);
ProxyNodeMap.put(
phoenix2.getNum(),
phoenix2
);
ProxyNodeMap.put(
london2.getNum(),
london2
);
ProxyNodeMap.put(
chengduAgent.getNum(),
chengduAgent
);
ProxyNodeMap.put(
tokyoDev.getNum(),
tokyoDev
);
ProxyNodeMap.put(
seoul5.getNum(),
seoul5
);
}

View File

@@ -6,6 +6,9 @@ import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* https://xtls.github.io/config/inbounds/vmess.html#clientobject
*/
@Data
@NoArgsConstructor
@AllArgsConstructor

View File

@@ -1,7 +1,17 @@
package io.wdd.func.xray.service;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.util.DefaultIndenter;
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import io.wdd.common.handler.MyRuntimeException;
import io.wdd.common.utils.TimeUtils;
import io.wdd.func.xray.beans.node.ProxyNode;
import io.wdd.func.xray.beans.node.XrayConfigInfo;
import io.wdd.func.xray.beans.xray.XrayConfig;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.core.io.ClassPathResource;
@@ -15,22 +25,79 @@ import java.util.concurrent.atomic.AtomicInteger;
/**
* 获取rerouces目录 https://blog.csdn.net/pengpengpeng85/article/details/84785575
*
* <p>
* 写入文件的教程 https://cloud.tencent.com/developer/article/1895274
*/
@Slf4j
@Service
public class XrayConfigPersistor {
private static String XrayResultPath = "xrayResult/";
// 参考 https://github.com/FasterXML/jackson-databind/issues/585
private static final ObjectWriter objectWriter = new ObjectMapper()
// 忽略掉 null的字段
.setSerializationInclusion(JsonInclude.Include.NON_NULL)
// 写的文件必须是unix类型的分隔符号
.writer(
new DefaultPrettyPrinter()
.withObjectIndenter(
new DefaultIndenter()
.withLinefeed("\n")
));
private static final String XrayResultPath = "xrayResult/";
public static AtomicInteger cleanVersion = new AtomicInteger(0);
/**
* 执行Xray生成配置文件的持久化工作,沈成伟临时文件保存至当前目录中
*
* @param xrayConfig
* @param currentVersion
* @param proxyNode
* @return
*/
public XrayConfigInfo persist(XrayConfig xrayConfig, int currentVersion, ProxyNode proxyNode) {
try {
// 将生成的xrayConfig直接写为字符串
String resultContent = objectWriter
.writeValueAsString(xrayConfig);
public File write(String fileName , String content, int currentVersion) {
// 获得到文件名称
String timeString = TimeUtils.currentFormatTimeString();
String fileName = buildXrayConfigFileName(
proxyNode,
timeString
);
System.out.println("currentVersion = " + currentVersion);
// 文件持久化!
File xrayConfigFile = write(
fileName,
resultContent,
currentVersion
);
// 文件写入完成,保存文件信息
XrayConfigInfo xrayConfigInfo = new XrayConfigInfo();
xrayConfigInfo.setXrayConfigFile(xrayConfigFile);
xrayConfigInfo.setXrayConfigFileName(fileName);
return xrayConfigInfo;
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
private String buildXrayConfigFileName(ProxyNode proxyNode, String timeString) {
return proxyNode.getNum() + "-" + proxyNode.getAgentName() + "-" + timeString + ".json";
}
private File write(String fileName, String content, int currentVersion) {
log.debug(
"currentVersion = {}",
currentVersion
);
if (cleanVersion.get() == currentVersion) {
// 清除旧的内容
@@ -41,29 +108,51 @@ public class XrayConfigPersistor {
// 构造对象开始写入, 生成文件
File resultFile = getResultFile(fileName);
try {
log.debug("开始写入XrayConfig进入文件中文件名为 => {}",fileName);
FileWriter fileWriter = new FileWriter(
FileWriter fileWriter = null;
BufferedWriter bufferedWriter = null;
try {
log.debug(
"开始写入XrayConfig进入文件中文件名为 => {}",
fileName
);
fileWriter = new FileWriter(
resultFile
);
BufferedWriter bufferedWriter = new BufferedWriter(
bufferedWriter = new BufferedWriter(
fileWriter
);
log.debug("文件内容为 => {}", content);
log.debug(
"文件内容为 => {}",
content
);
bufferedWriter.write(content);
// must close
bufferedWriter.close();
fileWriter.close();
return resultFile;
} catch (IOException e) {
log.error("打开文件失败写入tmp文件失败 文件为 => {}", resultFile.getName());
log.error(
"打开文件失败写入tmp文件失败 文件为 => {}",
resultFile.getName()
);
throw new MyRuntimeException(e);
} finally {
try {
// must close
bufferedWriter.close();
fileWriter.close();
} catch (IOException e) {
log.error(
"关闭文件写入流失败!, 请检查 文件为 => [ {} ], 内容为 => {}",
fileName,
content
);
throw new MyRuntimeException(e);
}
}
}
@@ -82,11 +171,12 @@ public class XrayConfigPersistor {
}
/**
* 根据文件名,需要创建一个文件
* 根据文件名,需要创建一个文件
*
* @param fileName 文件名,如 xxx.json
* @return
*/
private File getResultFile(String fileName ){
private File getResultFile(String fileName) {
ClassPathResource classPathResource = new ClassPathResource(XrayResultPath);
@@ -99,7 +189,10 @@ public class XrayConfigPersistor {
);
} catch (IOException e) {
log.error("获取文件失败请检查! fileName is => {}", fileName);
log.error(
"获取文件失败请检查! fileName is => {}",
fileName
);
throw new MyRuntimeException(e);
}

View File

@@ -1,9 +1,5 @@
package io.wdd.func.xray.service;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.wdd.common.utils.TimeUtils;
import io.wdd.func.xray.beans.node.ProxyNode;
import io.wdd.func.xray.beans.node.XrayConfigInfo;
import io.wdd.func.xray.beans.xray.RoutingObject;
@@ -20,7 +16,6 @@ import org.apache.commons.beanutils.BeanUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
@@ -36,13 +31,9 @@ import static io.wdd.func.xray.service.XrayConfigPersistor.cleanVersion;
@Slf4j
public class XrayCoreServiceImpl implements XrayCoreService {
@Resource
ObjectMapper objectMapper;
@Resource
XrayConfigPersistor xrayConfigPersistor;
@Override
public void generateXrayJsonFromNodeList(ArrayList<ArrayList<ProxyNode>> allNetworkPathList) {
@@ -81,9 +72,6 @@ public class XrayCoreServiceImpl implements XrayCoreService {
private void generateXrayJsonSinglePath(ArrayList<ProxyNode> networkPathList) {
int pathLength = networkPathList.size();
// 忽略掉 null的字段
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
// 采用 VMESS + websocket的形式形成 链状代理
// 由于 Vlss+XTLS的形式形成 链状结构
String tag = generatePathTag(networkPathList);
@@ -97,7 +85,8 @@ public class XrayCoreServiceImpl implements XrayCoreService {
.builder()
.id(uuid)
.level(0)
.alterId(23)
// 为了进一步防止被探测,一个用户可以在主 ID 的基础上,再额外生成多个 ID。这里只需要指定额外的 ID 的数量,推荐值为 0 代表启用 VMessAEAD
.alterId(0)
.email(tag + "@octopus.io")
.build();
@@ -123,46 +112,19 @@ public class XrayCoreServiceImpl implements XrayCoreService {
pos
);
// 持久化
try {
String resultContent = objectMapper
.writerWithDefaultPrettyPrinter()
.writeValueAsString(xrayConfig);
// 持久化 Xray生成的文件信息
XrayConfigInfo xrayConfigInfo = xrayConfigPersistor.persist(
xrayConfig,
currentVersion,
proxyNode
);
// 获得到文件名称
String timeString = TimeUtils.currentFormatTimeString();
String fileName = buildXrayConfigFileName(
proxyNode,
timeString
);
// 文件持久化!
File xrayConfigFile = xrayConfigPersistor.write(
fileName,
resultContent,
currentVersion
);
// 文件写入完成,保存文件信息
XrayConfigInfo xrayConfigInfo = new XrayConfigInfo();
xrayConfigInfo.setXrayConfigFile(xrayConfigFile);
xrayConfigInfo.setXrayConfigFileName(fileName);
proxyNode.setXrayConfigInfo(xrayConfigInfo);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
proxyNode.setXrayConfigInfo(xrayConfigInfo);
}
}
private String buildXrayConfigFileName(ProxyNode proxyNode, String timeString) {
return proxyNode.getNum() + "-" + proxyNode.getAgentName() + "-" + timeString + ".json";
}
private XrayConfig doBuildXrayConfig(boolean isOutBoundFree, String tag, ClientObject clientObject, int port, ArrayList<ProxyNode> networkPathList, int pos) {