diff --git a/server/src/main/java/io/wdd/func/xray/beans/config/InboundVmessHTTPTemplate.java b/server/src/main/java/io/wdd/func/xray/beans/config/InboundVmessHTTPTemplateClass.java similarity index 70% rename from server/src/main/java/io/wdd/func/xray/beans/config/InboundVmessHTTPTemplate.java rename to server/src/main/java/io/wdd/func/xray/beans/config/InboundVmessHTTPTemplateClass.java index 5051fbf..4ea5127 100644 --- a/server/src/main/java/io/wdd/func/xray/beans/config/InboundVmessHTTPTemplate.java +++ b/server/src/main/java/io/wdd/func/xray/beans/config/InboundVmessHTTPTemplateClass.java @@ -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); } } diff --git a/server/src/main/java/io/wdd/func/xray/beans/config/LogTemplateClass.java b/server/src/main/java/io/wdd/func/xray/beans/config/LogTemplateClass.java new file mode 100644 index 0000000..d69a9d1 --- /dev/null +++ b/server/src/main/java/io/wdd/func/xray/beans/config/LogTemplateClass.java @@ -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"); + + } +} diff --git a/server/src/main/java/io/wdd/func/xray/beans/config/OutboundVmessHTTPTemplate.java b/server/src/main/java/io/wdd/func/xray/beans/config/OutboundVmessHTTPTemplate.java deleted file mode 100644 index 836a8f7..0000000 --- a/server/src/main/java/io/wdd/func/xray/beans/config/OutboundVmessHTTPTemplate.java +++ /dev/null @@ -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); - - - - - } -} diff --git a/server/src/main/java/io/wdd/func/xray/beans/config/OutboundVmessHTTPTemplateClass.java b/server/src/main/java/io/wdd/func/xray/beans/config/OutboundVmessHTTPTemplateClass.java new file mode 100644 index 0000000..2f1c603 --- /dev/null +++ b/server/src/main/java/io/wdd/func/xray/beans/config/OutboundVmessHTTPTemplateClass.java @@ -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"); + + } +} diff --git a/server/src/main/java/io/wdd/func/xray/beans/xray/Client.java b/server/src/main/java/io/wdd/func/xray/beans/xray/Client.java index 2999cb9..4656c8a 100644 --- a/server/src/main/java/io/wdd/func/xray/beans/xray/Client.java +++ b/server/src/main/java/io/wdd/func/xray/beans/xray/Client.java @@ -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; diff --git a/server/src/main/java/io/wdd/func/xray/beans/xray/RoutingObject.java b/server/src/main/java/io/wdd/func/xray/beans/xray/RoutingObject.java index c11f03b..76387d4 100644 --- a/server/src/main/java/io/wdd/func/xray/beans/xray/RoutingObject.java +++ b/server/src/main/java/io/wdd/func/xray/beans/xray/RoutingObject.java @@ -13,25 +13,6 @@ public class RoutingObject { } -@Data -class RuleObject { - - private String type; - private List domain; - private List ip; - private String port; - private String sourcePort; - private String network; - private List source; - private List user; - private List inboundTag; - private String protocol; - private String attrs; - private String outboundTag; - private String balancerTag; - -} - @Data class BalancerObject { diff --git a/server/src/main/java/io/wdd/func/xray/beans/xray/RuleObject.java b/server/src/main/java/io/wdd/func/xray/beans/xray/RuleObject.java new file mode 100644 index 0000000..2a0ff8e --- /dev/null +++ b/server/src/main/java/io/wdd/func/xray/beans/xray/RuleObject.java @@ -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 domain; + private List ip; + private String port; + private String sourcePort; + private String network; + private List source; + private List user; + private List inboundTag; + private String protocol; + private String attrs; + private String outboundTag; + private String balancerTag; + +} diff --git a/server/src/main/java/io/wdd/func/xray/beans/xray/XrayConfig.java b/server/src/main/java/io/wdd/func/xray/beans/xray/XrayConfig.java index b103c12..ece20e9 100644 --- a/server/src/main/java/io/wdd/func/xray/beans/xray/XrayConfig.java +++ b/server/src/main/java/io/wdd/func/xray/beans/xray/XrayConfig.java @@ -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; diff --git a/server/src/main/java/io/wdd/func/xray/beans/xray/protocol/inbound/vmess/ClientObject.java b/server/src/main/java/io/wdd/func/xray/beans/xray/protocol/inbound/vmess/ClientObject.java index 2402d18..52ebdf2 100644 --- a/server/src/main/java/io/wdd/func/xray/beans/xray/protocol/inbound/vmess/ClientObject.java +++ b/server/src/main/java/io/wdd/func/xray/beans/xray/protocol/inbound/vmess/ClientObject.java @@ -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; diff --git a/server/src/main/java/io/wdd/func/xray/beans/xray/protocol/inbound/vmess/InboundConfigurationObject.java b/server/src/main/java/io/wdd/func/xray/beans/xray/protocol/inbound/vmess/InboundConfigurationObject.java new file mode 100644 index 0000000..3f94120 --- /dev/null +++ b/server/src/main/java/io/wdd/func/xray/beans/xray/protocol/inbound/vmess/InboundConfigurationObject.java @@ -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 clients; + private DetourObject detour; + + @JsonProperty("default") + private DefaultObject _default; + + /** + * 是否禁止客户端使用不安全的加密方式,当客户端指定下列加密方式时,服务器会主动断开连接。默认值为false。 + */ + boolean disableInsecureEncryption; + +} diff --git a/server/src/main/java/io/wdd/func/xray/beans/xray/protocol/inbound/vmess/VMESS.java b/server/src/main/java/io/wdd/func/xray/beans/xray/protocol/inbound/vmess/VMESS.java index b00cdbd..d8c8a48 100644 --- a/server/src/main/java/io/wdd/func/xray/beans/xray/protocol/inbound/vmess/VMESS.java +++ b/server/src/main/java/io/wdd/func/xray/beans/xray/protocol/inbound/vmess/VMESS.java @@ -5,6 +5,6 @@ import lombok.Data; @Data public class VMESS extends InboundObject { - private VmessConfig settings; + private InboundConfigurationObject settings; } diff --git a/server/src/main/java/io/wdd/func/xray/beans/xray/protocol/inbound/vmess/VmessConfig.java b/server/src/main/java/io/wdd/func/xray/beans/xray/protocol/inbound/vmess/VmessConfig.java deleted file mode 100644 index c5436d7..0000000 --- a/server/src/main/java/io/wdd/func/xray/beans/xray/protocol/inbound/vmess/VmessConfig.java +++ /dev/null @@ -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 clients; - private DetourObject detour; - @JsonProperty("default") - private DefaultObject _default; - -} diff --git a/server/src/main/java/io/wdd/func/xray/beans/xray/protocol/outbound/OutboundConfigurationObject.java b/server/src/main/java/io/wdd/func/xray/beans/xray/protocol/outbound/OutboundConfigurationObject.java index 94a40c2..1cb5783 100644 --- a/server/src/main/java/io/wdd/func/xray/beans/xray/protocol/outbound/OutboundConfigurationObject.java +++ b/server/src/main/java/io/wdd/func/xray/beans/xray/protocol/outbound/OutboundConfigurationObject.java @@ -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 users; + private List users; @NoArgsConstructor @Data diff --git a/server/src/main/java/io/wdd/func/xray/beans/xray/protocol/outbound/VMESS.java b/server/src/main/java/io/wdd/func/xray/beans/xray/protocol/outbound/VMESS.java index fd271aa..0e0223a 100644 --- a/server/src/main/java/io/wdd/func/xray/beans/xray/protocol/outbound/VMESS.java +++ b/server/src/main/java/io/wdd/func/xray/beans/xray/protocol/outbound/VMESS.java @@ -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 { } diff --git a/server/src/main/java/io/wdd/func/xray/beans/xray/transport/MuxObject.java b/server/src/main/java/io/wdd/func/xray/beans/xray/transport/MuxObject.java new file mode 100644 index 0000000..27acb5c --- /dev/null +++ b/server/src/main/java/io/wdd/func/xray/beans/xray/transport/MuxObject.java @@ -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; + +} diff --git a/server/src/main/java/io/wdd/func/xray/beans/xray/transport/OutboundObject.java b/server/src/main/java/io/wdd/func/xray/beans/xray/transport/OutboundObject.java index cb7bf40..5aaa0ac 100644 --- a/server/src/main/java/io/wdd/func/xray/beans/xray/transport/OutboundObject.java +++ b/server/src/main/java/io/wdd/func/xray/beans/xray/transport/OutboundObject.java @@ -31,10 +31,3 @@ class ProxySettingsObject { private String tag; } -@Data -class MuxObject { - - private Boolean enabled; - private Integer concurrency; - -} \ No newline at end of file diff --git a/server/src/main/java/io/wdd/func/xray/service/XrayCoreServiceImpl.java b/server/src/main/java/io/wdd/func/xray/service/XrayCoreServiceImpl.java index 3297386..f133da4 100644 --- a/server/src/main/java/io/wdd/func/xray/service/XrayCoreServiceImpl.java +++ b/server/src/main/java/io/wdd/func/xray/service/XrayCoreServiceImpl.java @@ -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 networkPathList, HashMap interfaceMap, HashMap resultMap) { int pathLength = networkPathList.size(); - if (pathLength < 2) { - log.error("网络路径节点不能小于2个"); + if (pathLength == 1) { + log.error("网络路径节点仅为一个"); + return; } + ArrayList 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 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 networkPathList) { + + StringBuilder sb = new StringBuilder(); + networkPathList + .stream() + .forEach( + networkPath -> { + sb.append(networkPath.getName()); + sb.append("->"); + } + ); + + return sb.toString(); } }