Skip to content

Commit

Permalink
new - vmess security (inbound client side - outbound)
Browse files Browse the repository at this point in the history
  • Loading branch information
MHSanaei committed Aug 10, 2024
1 parent bda5c2c commit 93d52bc
Show file tree
Hide file tree
Showing 15 changed files with 116 additions and 36 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ Our platform offers compatibility with a diverse range of architectures and devi
- Spanish
- Indonesian
- Ukrainian
- Turkish


## Features
Expand All @@ -258,7 +259,7 @@ Our platform offers compatibility with a diverse range of architectures and devi
- Search within all inbounds and clients
- Dark/Light theme
- Supports multi-user and multi-protocol
- Supports protocols, including VMess, VLESS, Trojan, Shadowsocks, Dokodemo-door, Socks, HTTP, wireguard
- Supports protocols, including VMESS, VLESS, Trojan, Shadowsocks, Dokodemo-door, Socks, HTTP, wireguard
- Supports XTLS native Protocols, including RPRX-Direct, Vision, REALITY
- Traffic statistics, traffic limit, expiration time limit
- Customizable Xray configuration templates
Expand Down
3 changes: 2 additions & 1 deletion database/model/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
type Protocol string

const (
VMess Protocol = "vmess"
VMESS Protocol = "vmess"
VLESS Protocol = "vless"
DOKODEMO Protocol = "dokodemo-door"
HTTP Protocol = "http"
Expand Down Expand Up @@ -86,6 +86,7 @@ type Setting struct {

type Client struct {
ID string `json:"id"`
Security string `json:"security"`
Password string `json:"password"`
Flow string `json:"flow"`
Email string `json:"email"`
Expand Down
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -85,16 +85,16 @@ require (
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect
golang.org/x/arch v0.9.0 // indirect
golang.org/x/crypto v0.26.0 // indirect
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect
golang.org/x/mod v0.20.0 // indirect
golang.org/x/net v0.28.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.23.0 // indirect
golang.org/x/sys v0.24.0 // indirect
golang.org/x/time v0.6.0 // indirect
golang.org/x/tools v0.24.0 // indirect
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240805194559-2c9e96a0b5d4 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240808171019-573a1156607a // indirect
google.golang.org/protobuf v1.34.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gvisor.dev/gvisor v0.0.0-20231202080848-1f7806d17489 // indirect
Expand Down
12 changes: 6 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -299,8 +299,8 @@ golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACk
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI=
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ=
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
Expand Down Expand Up @@ -339,8 +339,8 @@ golang.org/x/sys v0.0.0-20220804214406-8e32c043e418/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM=
golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
Expand Down Expand Up @@ -371,8 +371,8 @@ google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoA
google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg=
google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240805194559-2c9e96a0b5d4 h1:OsSGQeIIsyOEOimVxLEIL4rwGcnrjOydQaiA2bOnZUM=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240805194559-2c9e96a0b5d4/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240808171019-573a1156607a h1:EKiZZXueP9/T68B8Nl0GAx9cjbQnCId0yP3qPMgaaHs=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240808171019-573a1156607a/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
Expand Down
4 changes: 4 additions & 0 deletions sub/subJsonService.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,9 @@ func (s *SubJsonService) genVnext(inbound *model.Inbound, streamSettings json_ut

usersData[0].ID = client.ID
usersData[0].Level = 8
if inbound.Protocol == model.VMESS {
usersData[0].Security = client.Security
}
if inbound.Protocol == model.VLESS {
usersData[0].Flow = client.Flow
usersData[0].Encryption = "none"
Expand Down Expand Up @@ -371,6 +374,7 @@ type UserVnext struct {
Encryption string `json:"encryption,omitempty"`
Flow string `json:"flow,omitempty"`
ID string `json:"id"`
Security string `json:"security,omitempty"`
Level int `json:"level"`
}

Expand Down
3 changes: 2 additions & 1 deletion sub/subService.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ func (s *SubService) getLink(inbound *model.Inbound, email string) string {
}

func (s *SubService) genVmessLink(inbound *model.Inbound, email string) string {
if inbound.Protocol != model.VMess {
if inbound.Protocol != model.VMESS {
return ""
}
obj := map[string]interface{}{
Expand Down Expand Up @@ -281,6 +281,7 @@ func (s *SubService) genVmessLink(inbound *model.Inbound, email string) string {
}
}
obj["id"] = clients[clientIndex].ID
obj["scy"] = clients[clientIndex].Security

externalProxies, _ := stream["externalProxy"].([]interface{})

Expand Down
17 changes: 14 additions & 3 deletions web/assets/js/model/outbound.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,22 @@ const WireguardDomainStrategy = [
"ForceIPv6v4"
];

const USERS_SECURITY = {
AES_128_GCM: "aes-128-gcm",
CHACHA20_POLY1305: "chacha20-poly1305",
AUTO: "auto",
NONE: "none",
ZERO: "zero",
};

Object.freeze(Protocols);
Object.freeze(SSMethods);
Object.freeze(TLS_FLOW_CONTROL);
Object.freeze(UTLS_FINGERPRINT);
Object.freeze(ALPN_OPTION);
Object.freeze(OutboundDomainStrategies);
Object.freeze(WireguardDomainStrategy);
Object.freeze(USERS_SECURITY);


class CommonClass {
Expand Down Expand Up @@ -721,7 +730,7 @@ class Outbound extends CommonClass {

const port = json.port * 1;

return new Outbound(json.ps, Protocols.VMess, new Outbound.VmessSettings(json.add, port, json.id), stream);
return new Outbound(json.ps, Protocols.VMess, new Outbound.VmessSettings(json.add, port, json.id, json.scy), stream);
}

static fromParamLink(link) {
Expand Down Expand Up @@ -923,11 +932,12 @@ Outbound.DNSSettings = class extends CommonClass {
}
};
Outbound.VmessSettings = class extends CommonClass {
constructor(address, port, id) {
constructor(address, port, id, security) {
super();
this.address = address;
this.port = port;
this.id = id;
this.security = security;
}

static fromJson(json = {}) {
Expand All @@ -936,6 +946,7 @@ Outbound.VmessSettings = class extends CommonClass {
json.vnext[0].address,
json.vnext[0].port,
json.vnext[0].users[0].id,
json.vnext[0].users[0].security,
);
}

Expand All @@ -944,7 +955,7 @@ Outbound.VmessSettings = class extends CommonClass {
vnext: [{
address: this.address,
port: this.port,
users: [{ id: this.id }],
users: [{ id: this.id, security: this.security }],
}],
};
}
Expand Down
73 changes: 55 additions & 18 deletions web/assets/js/model/xray.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,14 @@ const TCP_CONGESTION_OPTION = {
RENO: "reno",
};

const USERS_SECURITY = {
AES_128_GCM: "aes-128-gcm",
CHACHA20_POLY1305: "chacha20-poly1305",
AUTO: "auto",
NONE: "none",
ZERO: "zero",
};

Object.freeze(Protocols);
Object.freeze(SSMethods);
Object.freeze(XTLS_FLOW_CONTROL);
Expand All @@ -122,6 +130,7 @@ Object.freeze(SNIFFING_OPTION);
Object.freeze(USAGE_OPTION);
Object.freeze(DOMAIN_STRATEGY_OPTION);
Object.freeze(TCP_CONGESTION_OPTION);
Object.freeze(USERS_SECURITY);

class XrayCommonClass {

Expand Down Expand Up @@ -1446,20 +1455,21 @@ class Inbound extends XrayCommonClass {
this.sniffing = new Sniffing();
}

genVmessLink(address = '', port = this.port, forceTls, remark = '', clientId) {
genVmessLink(address = '', port = this.port, forceTls, remark = '', clientId, security) {
if (this.protocol !== Protocols.VMESS) {
return '';
}
const security = forceTls == 'same' ? this.stream.security : forceTls;
const tls = forceTls == 'same' ? this.stream.security : forceTls;
let obj = {
v: '2',
ps: remark,
add: address,
port: port,
id: clientId,
scy: security,
net: this.stream.network,
type: 'none',
tls: security,
tls: tls,
};
const network = this.stream.network;
if (network === 'tcp') {
Expand Down Expand Up @@ -1870,7 +1880,7 @@ class Inbound extends XrayCommonClass {
genLink(address = '', port = this.port, forceTls = 'same', remark = '', client) {
switch (this.protocol) {
case Protocols.VMESS:
return this.genVmessLink(address, port, forceTls, remark, client.id);
return this.genVmessLink(address, port, forceTls, remark, client.id, client.security);
case Protocols.VLESS:
return this.genVLESSLink(address, port, forceTls, remark, client.id, client.flow);
case Protocols.SHADOWSOCKS:
Expand Down Expand Up @@ -2007,24 +2017,24 @@ Inbound.Settings = class extends XrayCommonClass {

Inbound.VmessSettings = class extends Inbound.Settings {
constructor(protocol,
vmesses = [new Inbound.VmessSettings.Vmess()]) {
vmesses = [new Inbound.VmessSettings.VMESS()]) {
super(protocol);
this.vmesses = vmesses;
}

indexOfVmessById(id) {
return this.vmesses.findIndex(vmess => vmess.id === id);
return this.vmesses.findIndex(VMESS => VMESS.id === id);
}

addVmess(vmess) {
if (this.indexOfVmessById(vmess.id) >= 0) {
addVmess(VMESS) {
if (this.indexOfVmessById(VMESS.id) >= 0) {
return false;
}
this.vmesses.push(vmess);
this.vmesses.push(VMESS);
}

delVmess(vmess) {
const i = this.indexOfVmessById(vmess.id);
delVmess(VMESS) {
const i = this.indexOfVmessById(VMESS.id);
if (i >= 0) {
this.vmesses.splice(i, 1);
}
Expand All @@ -2033,7 +2043,7 @@ Inbound.VmessSettings = class extends Inbound.Settings {
static fromJson(json = {}) {
return new Inbound.VmessSettings(
Protocols.VMESS,
json.clients.map(client => Inbound.VmessSettings.Vmess.fromJson(client)),
json.clients.map(client => Inbound.VmessSettings.VMESS.fromJson(client)),
);
}

Expand All @@ -2043,10 +2053,23 @@ Inbound.VmessSettings = class extends Inbound.Settings {
};
}
};
Inbound.VmessSettings.Vmess = class extends XrayCommonClass {
constructor(id = RandomUtil.randomUUID(), email = RandomUtil.randomLowerAndNum(8), limitIp = 0, totalGB = 0, expiryTime = 0, enable = true, tgId = '', subId = RandomUtil.randomLowerAndNum(16), reset = 0) {

Inbound.VmessSettings.VMESS = class extends XrayCommonClass {
constructor(
id = RandomUtil.randomUUID(),
security = USERS_SECURITY.AUTO,
email = RandomUtil.randomLowerAndNum(8),
limitIp = 0,
totalGB = 0,
expiryTime = 0,
enable = true,
tgId = '',
subId = RandomUtil.randomLowerAndNum(16),
reset = 0
) {
super();
this.id = id;
this.security = security;
this.email = email;
this.limitIp = limitIp;
this.totalGB = totalGB;
Expand All @@ -2058,8 +2081,9 @@ Inbound.VmessSettings.Vmess = class extends XrayCommonClass {
}

static fromJson(json = {}) {
return new Inbound.VmessSettings.Vmess(
return new Inbound.VmessSettings.VMESS(
json.id,
json.security,
json.email,
json.limitIp,
json.totalGB,
Expand Down Expand Up @@ -2098,10 +2122,12 @@ Inbound.VmessSettings.Vmess = class extends XrayCommonClass {
};

Inbound.VLESSSettings = class extends Inbound.Settings {
constructor(protocol,
constructor(
protocol,
vlesses = [new Inbound.VLESSSettings.VLESS()],
decryption = 'none',
fallbacks = []) {
fallbacks = []
) {
super(protocol);
this.vlesses = vlesses;
this.decryption = decryption;
Expand Down Expand Up @@ -2135,7 +2161,18 @@ Inbound.VLESSSettings = class extends Inbound.Settings {
};

Inbound.VLESSSettings.VLESS = class extends XrayCommonClass {
constructor(id = RandomUtil.randomUUID(), flow = '', email = RandomUtil.randomLowerAndNum(8), limitIp = 0, totalGB = 0, expiryTime = 0, enable = true, tgId = '', subId = RandomUtil.randomLowerAndNum(16), reset = 0) {
constructor(
id = RandomUtil.randomUUID(),
flow = '',
email = RandomUtil.randomLowerAndNum(8),
limitIp = 0,
totalGB = 0,
expiryTime = 0,
enable = true,
tgId = '',
subId = RandomUtil.randomLowerAndNum(16),
reset = 0
) {
super();
this.id = id;
this.flow = flow;
Expand Down
10 changes: 9 additions & 1 deletion web/html/xui/client_bulk_modal.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@
<a-form-item label='{{ i18n "pages.client.clientCount" }}' v-if="clientsBulkModal.emailMethod < 2">
<a-input-number v-model="clientsBulkModal.quantity" :min="1" :max="100"></a-input-number>
</a-form-item>
<a-form-item v-if="inbound.protocol === Protocols.VMESS" label='Security'>
<a-select v-model="clientsBulkModal.security" :dropdown-class-name="themeSwitcher.currentTheme">
<a-select-option v-for="key in USERS_SECURITY" :value="key">[[ key ]]</a-select-option>
</a-select>
</a-form-item>
<a-form-item label='Flow' v-if="clientsBulkModal.inbound.canEnableTlsFlow()">
<a-select v-model="clientsBulkModal.flow" :dropdown-class-name="themeSwitcher.currentTheme">
<a-select-option value="" selected>{{ i18n "none" }}</a-select-option>
Expand Down Expand Up @@ -146,6 +151,7 @@
emailPostfix: "",
subId: "",
tgId: '',
security: "auto",
flow: "",
delayedStart: false,
reset: 0,
Expand All @@ -168,6 +174,7 @@
newClient.email += useNum ? prefix + i.toString() + postfix : prefix + postfix;
if (clientsBulkModal.subId.length > 0) newClient.subId = clientsBulkModal.subId;
newClient.tgId = clientsBulkModal.tgId;
newClient.security = clientsBulkModal.security;
newClient.limitIp = clientsBulkModal.limitIp;
newClient._totalGB = clientsBulkModal.totalGB;
newClient._expiryTime = clientsBulkModal.expiryTime;
Expand Down Expand Up @@ -203,6 +210,7 @@
this.emailPostfix = "";
this.subId = "";
this.tgId = '';
this.security = "auto";
this.flow = "";
this.dbInbound = new DBInbound(dbInbound);
this.inbound = dbInbound.toInbound();
Expand All @@ -211,7 +219,7 @@
},
newClient(protocol) {
switch (protocol) {
case Protocols.VMESS: return new Inbound.VmessSettings.Vmess();
case Protocols.VMESS: return new Inbound.VmessSettings.VMESS();
case Protocols.VLESS: return new Inbound.VLESSSettings.VLESS();
case Protocols.TROJAN: return new Inbound.TrojanSettings.Trojan();
case Protocols.SHADOWSOCKS: return new Inbound.ShadowsocksSettings.Shadowsocks(clientsBulkModal.inbound.settings.shadowsockses[0].method);
Expand Down
Loading

0 comments on commit 93d52bc

Please sign in to comment.