[ server ] [ xray ] - 完成Xray Json的生成功能 - 1
This commit is contained in:
@@ -6,23 +6,25 @@ import io.wdd.func.xray.beans.xray.transport.StreamSettingsObject;
|
||||
import io.wdd.func.xray.beans.xray.transport.TcpObject;
|
||||
import io.wdd.func.xray.beans.xray.protocol.inbound.vmess.VMESS;
|
||||
|
||||
import static io.wdd.func.xray.beans.config.TcpHttpHeaderTemplate.HttpRequestTemplate;
|
||||
import static io.wdd.func.xray.beans.config.TcpHttpHeaderTemplate.HttpResponseTemplate;
|
||||
|
||||
public class InboundVmessHTTPTemplate {
|
||||
public class InboundVmessHTTPTemplateClass {
|
||||
|
||||
public static InboundObject InboundTemplate;
|
||||
public static InboundObject InboundVmessHTTPTemplate;
|
||||
|
||||
public static final String ListenAddress = "0.0.0.0";
|
||||
|
||||
static {
|
||||
|
||||
InboundTemplate = new VMESS();
|
||||
InboundVmessHTTPTemplate = new VMESS();
|
||||
|
||||
// 构建 settings- vmess-tcp-http的对象
|
||||
TcpObject tcpObject = new TcpObject();
|
||||
|
||||
// 构建RequestHttp属性对象
|
||||
HttpHeaderObject httpHeaderObject = new HttpHeaderObject();
|
||||
httpHeaderObject.setRequest(HttpRequestTemplate);
|
||||
// httpHeaderObject.setRequest(HttpRequestTemplate);
|
||||
// 服务端接收VMESS才是用Response
|
||||
httpHeaderObject.setResponse(HttpResponseTemplate);
|
||||
|
||||
tcpObject.setHeader(httpHeaderObject);
|
||||
@@ -30,7 +32,7 @@ public class InboundVmessHTTPTemplate {
|
||||
// 设置 settings属性
|
||||
StreamSettingsObject streamSettingsObject = new StreamSettingsObject();
|
||||
streamSettingsObject.setTcpSettings(tcpObject);
|
||||
InboundTemplate.setStreamSettings(streamSettingsObject);
|
||||
InboundVmessHTTPTemplate.setStreamSettings(streamSettingsObject);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package io.wdd.func.xray.beans.config;
|
||||
|
||||
import io.wdd.func.xray.beans.xray.LogObject;
|
||||
|
||||
public class LogTemplateClass {
|
||||
|
||||
public static LogObject LogTemplate;
|
||||
|
||||
|
||||
static {
|
||||
|
||||
LogTemplate = new LogObject();
|
||||
|
||||
LogTemplate.setAccess("/var/log/xray/access.log");
|
||||
LogTemplate.setError("/var/log/xray/error.log");
|
||||
LogTemplate.setLoglevel("warning");
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
package io.wdd.func.xray.beans.config;
|
||||
|
||||
import io.wdd.func.xray.beans.xray.protocol.outbound.OutboundConfigurationObject;
|
||||
import io.wdd.func.xray.beans.xray.protocol.outbound.VMESS;
|
||||
import io.wdd.func.xray.beans.xray.transport.HttpHeaderObject;
|
||||
import io.wdd.func.xray.beans.xray.transport.OutboundObject;
|
||||
import io.wdd.func.xray.beans.xray.transport.TcpObject;
|
||||
|
||||
import static io.wdd.func.xray.beans.config.TcpHttpHeaderTemplate.HttpResponseTemplate;
|
||||
|
||||
/**
|
||||
* outbound 不具备此形式
|
||||
*/
|
||||
@Deprecated
|
||||
public class OutboundVmessHTTPTemplate {
|
||||
|
||||
|
||||
static {
|
||||
|
||||
OutboundConfigurationObject OutboundTemplate = new VMESS();
|
||||
|
||||
// 构造TCP
|
||||
TcpObject tcpObject = new TcpObject();
|
||||
|
||||
|
||||
HttpHeaderObject httpHeaderObject = new HttpHeaderObject();
|
||||
httpHeaderObject.setResponse(HttpResponseTemplate);
|
||||
tcpObject.setHeader(httpHeaderObject);
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package io.wdd.func.xray.beans.config;
|
||||
|
||||
import io.wdd.func.xray.beans.xray.protocol.outbound.VMESS;
|
||||
import io.wdd.func.xray.beans.xray.transport.*;
|
||||
|
||||
import static io.wdd.func.xray.beans.config.TcpHttpHeaderTemplate.HttpRequestTemplate;
|
||||
|
||||
|
||||
public class OutboundVmessHTTPTemplateClass {
|
||||
|
||||
public static OutboundObject OutboundVmessHTTPTemplate;
|
||||
public static OutboundObject OutboundFree;
|
||||
public static OutboundObject OutboundBlackHole;
|
||||
|
||||
static {
|
||||
|
||||
OutboundVmessHTTPTemplate = new VMESS();
|
||||
|
||||
// 构造TCP
|
||||
TcpObject tcpObject = new TcpObject();
|
||||
|
||||
|
||||
HttpHeaderObject httpHeaderObject = new HttpHeaderObject();
|
||||
httpHeaderObject.setRequest(HttpRequestTemplate);
|
||||
tcpObject.setHeader(httpHeaderObject);
|
||||
|
||||
|
||||
StreamSettingsObject streamSettingsObject = new StreamSettingsObject();
|
||||
streamSettingsObject.setTcpSettings(tcpObject);
|
||||
OutboundVmessHTTPTemplate.setStreamSettings(streamSettingsObject);
|
||||
|
||||
MuxObject muxObject = new MuxObject();
|
||||
muxObject.setConcurrency(-1);
|
||||
muxObject.setEnabled(Boolean.FALSE);
|
||||
|
||||
OutboundVmessHTTPTemplate.setMux(muxObject);
|
||||
|
||||
|
||||
OutboundFree = new OutboundObject();
|
||||
OutboundFree.setProtocol("free");
|
||||
|
||||
OutboundBlackHole = new OutboundObject();
|
||||
OutboundBlackHole.setProtocol("blackhole");
|
||||
OutboundBlackHole.setTag("block");
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,14 @@
|
||||
package io.wdd.func.xray.beans.xray;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@SuperBuilder(toBuilder = true)
|
||||
public class Client {
|
||||
|
||||
private String id;
|
||||
|
||||
@@ -13,25 +13,6 @@ public class RoutingObject {
|
||||
|
||||
}
|
||||
|
||||
@Data
|
||||
class RuleObject {
|
||||
|
||||
private String type;
|
||||
private List<String> domain;
|
||||
private List<String> ip;
|
||||
private String port;
|
||||
private String sourcePort;
|
||||
private String network;
|
||||
private List<String> source;
|
||||
private List<String> user;
|
||||
private List<String> inboundTag;
|
||||
private String protocol;
|
||||
private String attrs;
|
||||
private String outboundTag;
|
||||
private String balancerTag;
|
||||
|
||||
}
|
||||
|
||||
@Data
|
||||
class BalancerObject {
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package io.wdd.func.xray.beans.xray;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NotNull
|
||||
@SuperBuilder(toBuilder = true)
|
||||
public class RuleObject {
|
||||
|
||||
private String type;
|
||||
private List<String> domain;
|
||||
private List<String> ip;
|
||||
private String port;
|
||||
private String sourcePort;
|
||||
private String network;
|
||||
private List<String> source;
|
||||
private List<String> user;
|
||||
private List<String> inboundTag;
|
||||
private String protocol;
|
||||
private String attrs;
|
||||
private String outboundTag;
|
||||
private String balancerTag;
|
||||
|
||||
}
|
||||
@@ -4,12 +4,20 @@ package io.wdd.func.xray.beans.xray;
|
||||
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.TransportObject;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* https://github.com/LarryZeta/xray-manager/blob/master/src/main/java/cc/larryzeta/manager/entity/XrayConfig.java
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@SuperBuilder(toBuilder = true)
|
||||
public class XrayConfig {
|
||||
|
||||
private LogObject log;
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
package io.wdd.func.xray.beans.xray.protocol.inbound.vmess;
|
||||
|
||||
import io.wdd.func.xray.beans.xray.Client;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@SuperBuilder(toBuilder = true)
|
||||
public class ClientObject extends Client {
|
||||
|
||||
private Integer level;
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package io.wdd.func.xray.beans.xray.protocol.inbound.vmess;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@SuperBuilder(toBuilder = true)
|
||||
public class InboundConfigurationObject {
|
||||
|
||||
private List<ClientObject> clients;
|
||||
private DetourObject detour;
|
||||
|
||||
@JsonProperty("default")
|
||||
private DefaultObject _default;
|
||||
|
||||
/**
|
||||
* 是否禁止客户端使用不安全的加密方式,当客户端指定下列加密方式时,服务器会主动断开连接。默认值为false。
|
||||
*/
|
||||
boolean disableInsecureEncryption;
|
||||
|
||||
}
|
||||
@@ -5,6 +5,6 @@ import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class VMESS extends InboundObject {
|
||||
private VmessConfig settings;
|
||||
private InboundConfigurationObject settings;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
package io.wdd.func.xray.beans.xray.protocol.inbound.vmess;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class VmessConfig {
|
||||
|
||||
private List<ClientObject> clients;
|
||||
private DetourObject detour;
|
||||
@JsonProperty("default")
|
||||
private DefaultObject _default;
|
||||
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package io.wdd.func.xray.beans.xray.protocol.outbound;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.wdd.func.xray.beans.xray.protocol.inbound.vmess.ClientObject;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@@ -21,7 +22,7 @@ public abstract class OutboundConfigurationObject {
|
||||
@JsonProperty("port")
|
||||
private Integer port;
|
||||
@JsonProperty("users")
|
||||
private List<UserObject> users;
|
||||
private List<ClientObject> users;
|
||||
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
|
||||
@@ -4,7 +4,7 @@ import io.wdd.func.xray.beans.xray.transport.OutboundObject;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class VMESS extends OutboundConfigurationObject {
|
||||
public class VMESS extends OutboundObject {
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package io.wdd.func.xray.beans.xray.transport;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public
|
||||
class MuxObject {
|
||||
|
||||
private Boolean enabled;
|
||||
private Integer concurrency;
|
||||
|
||||
}
|
||||
@@ -31,10 +31,3 @@ class ProxySettingsObject {
|
||||
private String tag;
|
||||
}
|
||||
|
||||
@Data
|
||||
class MuxObject {
|
||||
|
||||
private Boolean enabled;
|
||||
private Integer concurrency;
|
||||
|
||||
}
|
||||
@@ -1,14 +1,25 @@
|
||||
package io.wdd.func.xray.service;
|
||||
|
||||
import io.wdd.func.xray.beans.node.ProxyNode;
|
||||
import io.wdd.func.xray.beans.xray.RoutingObject;
|
||||
import io.wdd.func.xray.beans.xray.RuleObject;
|
||||
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.InboundConfigurationObject;
|
||||
import io.wdd.func.xray.beans.xray.protocol.inbound.vmess.VMESS;
|
||||
import io.wdd.func.xray.beans.xray.protocol.outbound.OutboundConfigurationObject;
|
||||
import io.wdd.func.xray.beans.xray.transport.OutboundObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.beanutils.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.*;
|
||||
|
||||
import static io.wdd.func.xray.beans.config.InboundVmessHTTPTemplateClass.InboundVmessHTTPTemplate;
|
||||
import static io.wdd.func.xray.beans.config.InboundVmessHTTPTemplateClass.ListenAddress;
|
||||
import static io.wdd.func.xray.beans.config.LogTemplateClass.LogTemplate;
|
||||
import static io.wdd.func.xray.beans.config.OutboundVmessHTTPTemplateClass.*;
|
||||
import static io.wdd.func.xray.beans.node.ProxyNodeSet.*;
|
||||
|
||||
@Service
|
||||
@@ -88,17 +99,193 @@ public class XrayCoreServiceImpl implements XrayCoreService {
|
||||
|
||||
private void generateXrayJsonSinglePath(ArrayList<ProxyNode> networkPathList, HashMap<String, String> interfaceMap, HashMap<ProxyNode, XrayConfig> resultMap) {
|
||||
int pathLength = networkPathList.size();
|
||||
if (pathLength < 2) {
|
||||
log.error("网络路径节点不能小于2个");
|
||||
if (pathLength == 1) {
|
||||
log.error("网络路径节点仅为一个");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ArrayList<XrayConfig> tmpXrayConfigList = new ArrayList<>();
|
||||
|
||||
// 采用 VMESS + websocket的形式形成 链状代理
|
||||
// 由于 Vlss+XTLS的形式形成 链状结构
|
||||
String tag = generatePathTag(networkPathList);
|
||||
|
||||
// 通用内容生成
|
||||
String uuid = UUID
|
||||
.randomUUID()
|
||||
.toString();
|
||||
|
||||
ClientObject clientObject = ClientObject
|
||||
.builder()
|
||||
.id(uuid)
|
||||
.level(0)
|
||||
.alterId(23)
|
||||
.email(tag + "@octopus.io")
|
||||
.build();
|
||||
|
||||
|
||||
for (int pos = 0; pos < pathLength; pos++) {
|
||||
|
||||
XrayConfig xrayConfig = new XrayConfig();
|
||||
|
||||
if (pos == pathLength - 1) {
|
||||
// 最后一个节点,形式不一样
|
||||
|
||||
buildInbound(xrayConfig, clientObject);
|
||||
|
||||
// 设置FreeOut
|
||||
buildOutboundFree(xrayConfig, tag);
|
||||
|
||||
// 设置 路由信息
|
||||
buildRouting(xrayConfig, tag);
|
||||
|
||||
// 添加到临时缓存中
|
||||
tmpXrayConfigList.add(xrayConfig);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 设置Log属性
|
||||
xrayConfig.setLog(LogTemplate);
|
||||
|
||||
// 初始化 InBound
|
||||
buildInbound(xrayConfig, clientObject);
|
||||
|
||||
// 设置 outbounds的信息
|
||||
buildOutbound(xrayConfig, networkPathList, pos, clientObject);
|
||||
|
||||
// 设置 路由信息
|
||||
buildRouting(xrayConfig, tag);
|
||||
|
||||
// 添加到临时缓存中
|
||||
tmpXrayConfigList.add(xrayConfig);
|
||||
|
||||
// 调试
|
||||
System.out.println("xrayConfig = " + xrayConfig);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void buildOutboundFree(XrayConfig xrayConfig, String tag) {
|
||||
|
||||
OutboundObject freeOut = new OutboundObject();
|
||||
freeOut.setProtocol("freedom");
|
||||
freeOut.setTag(tag);
|
||||
|
||||
xrayConfig.setOutbounds(new ArrayList<>(
|
||||
List.of(freeOut)
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
private void buildRouting(XrayConfig xrayConfig, String tag) {
|
||||
|
||||
RoutingObject routingObject = new RoutingObject();
|
||||
routingObject.setDomainStrategy("IPIfNonMatch");
|
||||
|
||||
RuleObject ruleObject = RuleObject
|
||||
.builder()
|
||||
.type("field")
|
||||
.inboundTag(List.of(tag))
|
||||
.outboundTag(tag)
|
||||
.build();
|
||||
|
||||
routingObject.setRules(
|
||||
new ArrayList<>(
|
||||
List.of(ruleObject)
|
||||
)
|
||||
);
|
||||
|
||||
xrayConfig.setRouting(routingObject);
|
||||
}
|
||||
|
||||
private void buildOutbound(XrayConfig xrayConfig, ArrayList<ProxyNode> networkPathList, int pos, ClientObject clientObject) {
|
||||
OutboundObject outboundObject = new OutboundObject();
|
||||
try {
|
||||
BeanUtils.copyProperties(outboundObject,
|
||||
OutboundVmessHTTPTemplate
|
||||
);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
// 设置出口信息
|
||||
OutboundConfigurationObject.ServerObject serverObject = outboundObject
|
||||
.getSettings()
|
||||
.getVnext()
|
||||
.get(0);
|
||||
// 出口的IP应该为下一节点
|
||||
serverObject.setAddress(networkPathList.get(pos+1).getPublicIPv4());
|
||||
serverObject.setUsers(
|
||||
List.of(clientObject)
|
||||
);
|
||||
|
||||
xrayConfig.setOutbounds(
|
||||
new ArrayList<>(
|
||||
List.of(
|
||||
outboundObject,
|
||||
OutboundFree,
|
||||
OutboundBlackHole
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private void buildInbound(XrayConfig xrayConfig, ClientObject clientObject) {
|
||||
VMESS inboundObject = new VMESS();
|
||||
try {
|
||||
BeanUtils.copyProperties(inboundObject,
|
||||
InboundVmessHTTPTemplate
|
||||
);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
// todo port怎么办
|
||||
inboundObject.setPort(19999);
|
||||
// 设置 listen地址
|
||||
inboundObject.setListen(ListenAddress);
|
||||
|
||||
// 配置用户信息
|
||||
InboundConfigurationObject inboundConfigurationObject = InboundConfigurationObject
|
||||
.builder()
|
||||
.clients(List.of(clientObject))
|
||||
.build();
|
||||
|
||||
inboundObject.setSettings(inboundConfigurationObject);
|
||||
|
||||
xrayConfig.setInbounds(
|
||||
new ArrayList<>(
|
||||
List.of(
|
||||
inboundObject
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* shanghai->seoul2->tokyo2
|
||||
*
|
||||
* @param networkPathList 网络路径节点
|
||||
* @return 路径Tag
|
||||
*/
|
||||
private String generatePathTag(ArrayList<ProxyNode> networkPathList) {
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
networkPathList
|
||||
.stream()
|
||||
.forEach(
|
||||
networkPath -> {
|
||||
sb.append(networkPath.getName());
|
||||
sb.append("->");
|
||||
}
|
||||
);
|
||||
|
||||
return sb.toString();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user