[ server ] [ xray ] - 完成Xray Json的生成功能 - 基本完成

This commit is contained in:
zeaslity
2023-02-10 18:03:57 +08:00
parent a7caec8853
commit caa13293eb
8 changed files with 171 additions and 45 deletions

View File

@@ -1,8 +1,11 @@
package io.wdd.func.xray.beans.config; package io.wdd.func.xray.beans.config;
import io.wdd.func.xray.beans.xray.protocol.outbound.VMESS; import io.wdd.func.xray.beans.xray.protocol.outbound.*;
import io.wdd.func.xray.beans.xray.transport.*; import io.wdd.func.xray.beans.xray.transport.*;
import java.util.ArrayList;
import java.util.List;
import static io.wdd.func.xray.beans.config.TcpHttpHeaderTemplate.HttpRequestTemplate; import static io.wdd.func.xray.beans.config.TcpHttpHeaderTemplate.HttpRequestTemplate;
@@ -29,18 +32,26 @@ public class OutboundVmessHTTPTemplateClass {
streamSettingsObject.setTcpSettings(tcpObject); streamSettingsObject.setTcpSettings(tcpObject);
OutboundVmessHTTPTemplate.setStreamSettings(streamSettingsObject); OutboundVmessHTTPTemplate.setStreamSettings(streamSettingsObject);
// 需要初始化这个
VmessOutSettings vmessOutSettings = new VmessOutSettings();
OutboundConfigurationObject.ServerObject serverObject = new OutboundConfigurationObject.ServerObject();
vmessOutSettings.setVnext(
new ArrayList<>(
List.of(serverObject)
)
);
OutboundVmessHTTPTemplate.setSettings(vmessOutSettings);
MuxObject muxObject = new MuxObject(); MuxObject muxObject = new MuxObject();
muxObject.setConcurrency(-1); muxObject.setConcurrency(-1);
muxObject.setEnabled(Boolean.FALSE); muxObject.setEnabled(Boolean.FALSE);
OutboundVmessHTTPTemplate.setMux(muxObject); OutboundVmessHTTPTemplate.setMux(muxObject);
OutboundFree = new Freedom();
OutboundFree = new OutboundObject(); OutboundBlackHole = new Blackhole();
OutboundFree.setProtocol("free");
OutboundBlackHole = new OutboundObject();
OutboundBlackHole.setProtocol("blackhole");
OutboundBlackHole.setTag("block"); OutboundBlackHole.setTag("block");
} }

View File

@@ -23,7 +23,7 @@ public class ProxyNodeSet {
.num(0) .num(0)
.publicIPv4("43.136.177.228") .publicIPv4("43.136.177.228")
.proxyNodeType(ProxyNodeType.INTERFACE) .proxyNodeType(ProxyNodeType.INTERFACE)
.name("chengdu-agent") .name("cd-agent")
.agentTopicName("Chengdu-amd-01") .agentTopicName("Chengdu-amd-01")
.build(); .build();
@@ -34,7 +34,7 @@ public class ProxyNodeSet {
.num(1) .num(1)
.publicIPv4("42.192.52.227") .publicIPv4("42.192.52.227")
.proxyNodeType(ProxyNodeType.RELAY) .proxyNodeType(ProxyNodeType.RELAY)
.name("tencent-shanghai") .name("tc-sh")
.agentTopicName("Shanghai-amd64-01") .agentTopicName("Shanghai-amd64-01")
.build(); .build();
@@ -44,7 +44,7 @@ public class ProxyNodeSet {
.num(2) .num(2)
.publicIPv4("43.154.83.213") .publicIPv4("43.154.83.213")
.proxyNodeType(ProxyNodeType.EXTERNAL) .proxyNodeType(ProxyNodeType.EXTERNAL)
.name("tencent-hongkong") .name("tc-hk")
.agentTopicName("Hongkong-amd64-01") .agentTopicName("Hongkong-amd64-01")
.build(); .build();
@@ -55,7 +55,7 @@ public class ProxyNodeSet {
.num(3) .num(3)
.publicIPv4("140.238.30.110") .publicIPv4("140.238.30.110")
.proxyNodeType(ProxyNodeType.EXTERNAL) .proxyNodeType(ProxyNodeType.EXTERNAL)
.name("oracle-seoul-2") .name("seoul-2")
.agentTopicName("Seoul-amd64-02") .agentTopicName("Seoul-amd64-02")
.build(); .build();
@@ -66,7 +66,7 @@ public class ProxyNodeSet {
.num(4) .num(4)
.publicIPv4("140.238.52.228") .publicIPv4("140.238.52.228")
.proxyNodeType(ProxyNodeType.EXTERNAL) .proxyNodeType(ProxyNodeType.EXTERNAL)
.name("oracle-tokyo-2") .name("tokyo-2")
.agentTopicName("Tokyo-amd64-02") .agentTopicName("Tokyo-amd64-02")
.build(); .build();
@@ -76,7 +76,7 @@ public class ProxyNodeSet {
.num(5) .num(5)
.publicIPv4("129.146.171.163") .publicIPv4("129.146.171.163")
.proxyNodeType(ProxyNodeType.EXTERNAL) .proxyNodeType(ProxyNodeType.EXTERNAL)
.name("oracle-phoenix-2") .name("phoenix-2")
.agentTopicName("Phoenix-amd64-02") .agentTopicName("Phoenix-amd64-02")
.build(); .build();
@@ -86,7 +86,7 @@ public class ProxyNodeSet {
.num(6) .num(6)
.publicIPv4("141.147.106.62") .publicIPv4("141.147.106.62")
.proxyNodeType(ProxyNodeType.EXTERNAL) .proxyNodeType(ProxyNodeType.EXTERNAL)
.name("oracle-london-2") .name("london-2")
.agentTopicName("London-amd64-02") .agentTopicName("London-amd64-02")
.build(); .build();

View File

@@ -1,9 +1,10 @@
package io.wdd.func.xray.beans.xray.protocol.outbound; package io.wdd.func.xray.beans.xray.protocol.outbound;
import io.wdd.func.xray.beans.xray.transport.OutboundObject;
import lombok.Data; import lombok.Data;
@Data @Data
public class Blackhole extends OutboundConfigurationObject{ public class Blackhole extends OutboundObject {
private ResponseObject response; private ResponseObject response;

View File

@@ -1,9 +1,10 @@
package io.wdd.func.xray.beans.xray.protocol.outbound; package io.wdd.func.xray.beans.xray.protocol.outbound;
import io.wdd.func.xray.beans.xray.transport.OutboundObject;
import lombok.Data; import lombok.Data;
@Data @Data
public class Freedom extends OutboundConfigurationObject{ public class Freedom extends OutboundObject {
private String domainStrategy; private String domainStrategy;
private String redirect; private String redirect;

View File

@@ -0,0 +1,7 @@
package io.wdd.func.xray.beans.xray.protocol.outbound;
import lombok.Data;
@Data
public class VmessOutSettings extends OutboundConfigurationObject{
}

View File

@@ -3,9 +3,7 @@ package io.wdd.func.xray.beans.xray.transport;
import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeInfo;
; ;
import io.wdd.func.xray.beans.xray.protocol.outbound.OutboundConfigurationObject; import io.wdd.func.xray.beans.xray.protocol.outbound.*;
import io.wdd.func.xray.beans.xray.protocol.outbound.VLESS;
import io.wdd.func.xray.beans.xray.protocol.outbound.VMESS;
import lombok.Data; import lombok.Data;
@Data @Data
@@ -13,8 +11,10 @@ import lombok.Data;
@JsonSubTypes(value = { @JsonSubTypes(value = {
@JsonSubTypes.Type(value = VLESS.class, name = "vless"), @JsonSubTypes.Type(value = VLESS.class, name = "vless"),
@JsonSubTypes.Type(value = VMESS.class, name = "vmess"), @JsonSubTypes.Type(value = VMESS.class, name = "vmess"),
@JsonSubTypes.Type(value = Freedom.class, name = "freedom"),
@JsonSubTypes.Type(value = Blackhole.class, name = "blackhole"),
}) })
public class OutboundObject { public abstract class OutboundObject {
private String sendThrough; private String sendThrough;
private String protocol; private String protocol;

View File

@@ -1,5 +1,8 @@
package io.wdd.func.xray.service; 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.func.xray.beans.node.ProxyNode; import io.wdd.func.xray.beans.node.ProxyNode;
import io.wdd.func.xray.beans.xray.RoutingObject; import io.wdd.func.xray.beans.xray.RoutingObject;
import io.wdd.func.xray.beans.xray.RuleObject; import io.wdd.func.xray.beans.xray.RuleObject;
@@ -7,12 +10,14 @@ import io.wdd.func.xray.beans.xray.XrayConfig;
import io.wdd.func.xray.beans.xray.protocol.inbound.vmess.ClientObject; import io.wdd.func.xray.beans.xray.protocol.inbound.vmess.ClientObject;
import io.wdd.func.xray.beans.xray.protocol.inbound.vmess.InboundConfigurationObject; import io.wdd.func.xray.beans.xray.protocol.inbound.vmess.InboundConfigurationObject;
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.OutboundConfigurationObject; import io.wdd.func.xray.beans.xray.protocol.outbound.OutboundConfigurationObject;
import io.wdd.func.xray.beans.xray.transport.OutboundObject; import io.wdd.func.xray.beans.xray.transport.OutboundObject;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.beanutils.BeanUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.util.*; import java.util.*;
@@ -26,6 +31,9 @@ import static io.wdd.func.xray.beans.node.ProxyNodeSet.*;
@Slf4j @Slf4j
public class XrayCoreServiceImpl implements XrayCoreService { public class XrayCoreServiceImpl implements XrayCoreService {
@Resource
ObjectMapper objectMapper;
@Override @Override
public void generateXrayJsonFromNodeList(ArrayList<ArrayList<ProxyNode>> allNetworkPathList) { public void generateXrayJsonFromNodeList(ArrayList<ArrayList<ProxyNode>> allNetworkPathList) {
@@ -42,7 +50,7 @@ public class XrayCoreServiceImpl implements XrayCoreService {
) )
); );
ArrayList<ProxyNode> pathB = new ArrayList<>( /*ArrayList<ProxyNode> pathB = new ArrayList<>(
Arrays.asList( Arrays.asList(
shanghai, shanghai,
seoul2, seoul2,
@@ -55,11 +63,11 @@ public class XrayCoreServiceImpl implements XrayCoreService {
seoul2, seoul2,
phoenix2 phoenix2
) )
); );*/
allNetworkPathList.add(pathA); allNetworkPathList.add(pathA);
allNetworkPathList.add(pathB); // allNetworkPathList.add(pathB);
allNetworkPathList.add(pathC); // allNetworkPathList.add(pathC);
// 需要根据所有的交叉链路进行计算 // 需要根据所有的交叉链路进行计算
@@ -105,6 +113,11 @@ public class XrayCoreServiceImpl implements XrayCoreService {
return; return;
} }
// 忽略掉 null的字段
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
ArrayList<XrayConfig> tmpXrayConfigList = new ArrayList<>(); ArrayList<XrayConfig> tmpXrayConfigList = new ArrayList<>();
// 采用 VMESS + websocket的形式形成 链状代理 // 采用 VMESS + websocket的形式形成 链状代理
@@ -124,25 +137,51 @@ public class XrayCoreServiceImpl implements XrayCoreService {
.email(tag + "@octopus.io") .email(tag + "@octopus.io")
.build(); .build();
Integer port = 19999;
for (int pos = 0; pos < pathLength; pos++) { for (int pos = 0; pos < pathLength; pos++) {
XrayConfig xrayConfig = new XrayConfig(); XrayConfig xrayConfig = new XrayConfig();
if (pos == pathLength - 1) { if (pos == pathLength - 1) {
// 最后一个节点,形式不一样
buildInbound(xrayConfig, clientObject); // 最后一个节点,形式不一样
buildInbound(
xrayConfig,
clientObject,
port,
tag
);
// 设置FreeOut // 设置FreeOut
buildOutboundFree(xrayConfig, tag); buildOutboundFree(
xrayConfig,
tag
);
// 设置 路由信息 // 设置 路由信息
buildRouting(xrayConfig, tag); buildRouting(
xrayConfig,
tag
);
// 添加到临时缓存中 // 添加到临时缓存中
tmpXrayConfigList.add(xrayConfig); tmpXrayConfigList.add(xrayConfig);
// 调试
try {
String s = objectMapper
.writerWithDefaultPrettyPrinter()
.writeValueAsString(xrayConfig);
System.out.println(s);
System.out.println("-----------------------------------");
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
return; return;
} }
@@ -151,27 +190,52 @@ public class XrayCoreServiceImpl implements XrayCoreService {
xrayConfig.setLog(LogTemplate); xrayConfig.setLog(LogTemplate);
// 初始化 InBound // 初始化 InBound
buildInbound(xrayConfig, clientObject); buildInbound(
xrayConfig,
clientObject,
port,
tag
);
// 设置 outbounds的信息 // 设置 outbounds的信息
buildOutbound(xrayConfig, networkPathList, pos, clientObject); buildOutbound(
xrayConfig,
networkPathList,
pos,
clientObject,
tag,
port
);
// 设置 路由信息 // 设置 路由信息
buildRouting(xrayConfig, tag); buildRouting(
xrayConfig,
tag
);
// 添加到临时缓存中 // 添加到临时缓存中
tmpXrayConfigList.add(xrayConfig); tmpXrayConfigList.add(xrayConfig);
// 调试 // 调试
System.out.println("xrayConfig = " + xrayConfig); try {
String s = objectMapper
.writerWithDefaultPrettyPrinter()
.writeValueAsString(xrayConfig);
System.out.println(s);
System.out.println("-----------------------------------");
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
} }
} }
private void buildOutboundFree(XrayConfig xrayConfig, String tag) { private void buildOutboundFree(XrayConfig xrayConfig, String tag) {
OutboundObject freeOut = new OutboundObject(); OutboundObject freeOut = new Freedom();
freeOut.setProtocol("freedom");
freeOut.setTag(tag); freeOut.setTag(tag);
xrayConfig.setOutbounds(new ArrayList<>( xrayConfig.setOutbounds(new ArrayList<>(
@@ -201,11 +265,12 @@ public class XrayCoreServiceImpl implements XrayCoreService {
xrayConfig.setRouting(routingObject); xrayConfig.setRouting(routingObject);
} }
private void buildOutbound(XrayConfig xrayConfig, ArrayList<ProxyNode> networkPathList, int pos, ClientObject clientObject) { private void buildOutbound(XrayConfig xrayConfig, ArrayList<ProxyNode> networkPathList, int pos, ClientObject clientObject, String tag, Integer port) {
OutboundObject outboundObject = new OutboundObject(); io.wdd.func.xray.beans.xray.protocol.outbound.VMESS vmessOutbound = new io.wdd.func.xray.beans.xray.protocol.outbound.VMESS();
try { try {
BeanUtils.copyProperties(outboundObject, BeanUtils.copyProperties(
OutboundVmessHTTPTemplate vmessOutbound,
OutboundVmessHTTPTemplate
); );
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
@@ -213,13 +278,23 @@ public class XrayCoreServiceImpl implements XrayCoreService {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
// 设置Tag信息
vmessOutbound.setTag(tag);
// 设置出口信息 // 设置出口信息
OutboundConfigurationObject.ServerObject serverObject = outboundObject OutboundConfigurationObject.ServerObject serverObject = vmessOutbound
.getSettings() .getSettings()
.getVnext() .getVnext()
.get(0); .get(0);
// 出口的IP应该为下一节点 // 出口的IP应该为下一节点
serverObject.setAddress(networkPathList.get(pos+1).getPublicIPv4()); serverObject.setAddress(networkPathList
.get(pos + 1)
.getPublicIPv4());
// 端口
serverObject.setPort(port);
serverObject.setUsers( serverObject.setUsers(
List.of(clientObject) List.of(clientObject)
); );
@@ -227,7 +302,7 @@ public class XrayCoreServiceImpl implements XrayCoreService {
xrayConfig.setOutbounds( xrayConfig.setOutbounds(
new ArrayList<>( new ArrayList<>(
List.of( List.of(
outboundObject, vmessOutbound,
OutboundFree, OutboundFree,
OutboundBlackHole OutboundBlackHole
) )
@@ -235,18 +310,22 @@ public class XrayCoreServiceImpl implements XrayCoreService {
); );
} }
private void buildInbound(XrayConfig xrayConfig, ClientObject clientObject) { private void buildInbound(XrayConfig xrayConfig, ClientObject clientObject, Integer port, String tag) {
VMESS inboundObject = new VMESS(); VMESS inboundObject = new VMESS();
try { try {
BeanUtils.copyProperties(inboundObject, BeanUtils.copyProperties(
InboundVmessHTTPTemplate inboundObject,
InboundVmessHTTPTemplate
); );
} catch (IllegalAccessException | InvocationTargetException e) { } catch (IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
inboundObject.setTag(tag);
// todo port怎么办 // todo port怎么办
inboundObject.setPort(19999); inboundObject.setPort(port);
// 设置 listen地址 // 设置 listen地址
inboundObject.setListen(ListenAddress); inboundObject.setListen(ListenAddress);
@@ -285,7 +364,13 @@ public class XrayCoreServiceImpl implements XrayCoreService {
} }
); );
return sb.toString(); // 去掉末尾的 ->
String s = sb.toString();
return s.substring(
0,
s.length() - 2
);
} }
} }

View File

@@ -0,0 +1,21 @@
package io.wdd.server;
import io.wdd.func.xray.service.XrayCoreService;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
@SpringBootTest
public class XrayGenerateTest {
@Resource
XrayCoreService xrayCoreService;
@Test
public void go(){
xrayCoreService.generateXrayJsonFromNodeList(null);
}
}