18 Commits
0.3.0 ... 0.3.2

Author SHA1 Message Date
vaxilu
f335c8d39a Update version 2021-08-25 17:16:19 +08:00
vaxilu
36d9a43421 Update common_sider.html 2021-08-25 17:06:23 +08:00
vaxilu
5d118afb07 Update x-ui.sh 2021-08-25 16:59:11 +08:00
vaxilu
56c30d4d0c Merge pull request #74 from jukrb0x/patch-1
fix: workaround for installing bbr
2021-08-25 16:55:31 +08:00
sprov
4c4a70e742 fix vless link 2021-08-25 09:42:20 +08:00
vaxilu
581e3b835a Merge pull request #64 from GSWXXN/main
add fallbacks feature & flow control mode for trojan
2021-08-25 08:46:27 +08:00
Jabriel
ccfeb28492 fix: workaround for installing bbr
The former link for installing bbr is not found anymore.
2021-08-25 04:21:28 +08:00
GSWXXN
100bd29c92 add flow control mode for trojan
Signed-off-by: GSWXXN <819269088@qq.com>
2021-08-22 16:20:22 +08:00
GSWXXN
6ed818cd67 add fallbacks feature for trojan
Signed-off-by: GSWXXN <819269088@qq.com>
2021-08-21 01:06:01 +08:00
vaxilu
698bf1d390 Merge pull request #60 from tshipenchko/patch-1
Change sprov065 to vaxilu
2021-08-17 19:52:04 +08:00
Łukasz Tshipenchko
aeed8db419 Change sprov065 to vaxilu 2021-08-15 14:55:17 +06:00
vaxilu
10191887af Update README.md 2021-08-10 14:24:53 +08:00
sprov
b240b843c8 Update version
0.3.1
2021-07-26 22:02:35 +08:00
sprov
500b08b112 Update inbound.go
fix expiry time
2021-07-26 22:02:08 +08:00
sprov
64c5ecce99 Update install.sh 2021-07-26 14:15:34 +08:00
sprov
3e08b794be Update README.md 2021-07-26 14:07:25 +08:00
sprov
e473b7393e Update README.md 2021-07-26 14:07:03 +08:00
sprov
942ac7f562 Update README.md 2021-07-26 13:41:38 +08:00
11 changed files with 154 additions and 51 deletions

1
.gitignore vendored
View File

@@ -6,3 +6,4 @@ dist/
x-ui-*.tar.gz
/x-ui
/release.sh
.sync*

View File

@@ -6,14 +6,33 @@
- 支持多用户多协议,网页可视化操作
- 支持的协议vmess、vless、trojan、shadowsocks、dokodemo-door、socks、http
- 支持配置更多传输配置
- 账号流量统计
- 流量统计,限制流量,限制到期时间
- 可自定义 xray 配置模板
- 支持 https 访问面板(自备域名 + ssl 证书)
- 更多高级配置项,详见面板
# 安装&升级
```
bash <(curl -Ls https://raw.githubusercontent.com/sprov065/x-ui/master/install.sh) 0.2.0
bash <(curl -Ls https://raw.githubusercontent.com/vaxilu/x-ui/master/install.sh)
```
## 手动安装&升级
1. 首先从 https://github.com/vaxilu/x-ui/releases 下载最新的压缩包,一般选择`amd64`架构
2. 然后将这个压缩包上传到服务器的`/root/`目录下,并使用`root`用户登录服务器
> 如果你的服务器 cpu 架构不是`amd64`,自行将命令中的`amd64`替换为其他架构
```
cd /root/
rm x-ui/ /usr/local/x-ui/ /usr/bin/x-ui -rf
tar zxvf x-ui-linux-amd64.tar.gz
chmod +x x-ui/x-ui x-ui/bin/xray-linux-* x-ui/x-ui.sh
cp x-ui/x-ui.sh /usr/bin/x-ui
cp -f x-ui/x-ui.service /etc/systemd/system/
mv x-ui/ /usr/local/
systemctl daemon-reload
systemctl enable x-ui
systemctl restart x-ui
```
## 建议系统
@@ -34,11 +53,6 @@ x-ui 可与 v2-ui 并存,数据不互通,不影响对方的运行
x-ui v2-ui
```
# Telegram
群组https://t.me/sprov_blog
频道https://t.me/sprov_channel
## Stargazers over time
[![Stargazers over time](https://starchart.cc/sprov065/x-ui.svg)](https://starchart.cc/sprov065/x-ui)
[![Stargazers over time](https://starchart.cc/vaxilu/x-ui.svg)](https://starchart.cc/vaxilu/x-ui)

View File

@@ -1 +1 @@
0.3.0
0.3.2

View File

@@ -82,25 +82,22 @@ install_base() {
install_x-ui() {
systemctl stop x-ui
cd /usr/local/
if [[ -e /usr/local/x-ui/ ]]; then
rm /usr/local/x-ui/ -rf
fi
if [ $# == 0 ] ;then
last_version=$(curl -Ls "https://api.github.com/repos/sprov065/x-ui/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
last_version=$(curl -Ls "https://api.github.com/repos/vaxilu/x-ui/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
if [[ ! -n "$last_version" ]]; then
echo -e "${red}检测 x-ui 版本失败,可能是超出 Github API 限制,请稍后再试,或手动指定 x-ui 版本安装${plain}"
exit 1
fi
echo -e "检测到 x-ui 最新版本:${last_version},开始安装"
wget -N --no-check-certificate -O /usr/local/x-ui-linux-${arch}.tar.gz https://github.com/sprov065/x-ui/releases/download/${last_version}/x-ui-linux-${arch}.tar.gz
wget -N --no-check-certificate -O /usr/local/x-ui-linux-${arch}.tar.gz https://github.com/vaxilu/x-ui/releases/download/${last_version}/x-ui-linux-${arch}.tar.gz
if [[ $? -ne 0 ]]; then
echo -e "${red}下载 x-ui 失败,请确保你的服务器能够下载 Github 的文件${plain}"
exit 1
fi
else
last_version=$1
url="https://github.com/sprov065/x-ui/releases/download/${last_version}/x-ui-linux-${arch}.tar.gz"
url="https://github.com/vaxilu/x-ui/releases/download/${last_version}/x-ui-linux-${arch}.tar.gz"
echo -e "开始安装 x-ui v$1"
wget -N --no-check-certificate -O /usr/local/x-ui-linux-${arch}.tar.gz ${url}
if [[ $? -ne 0 ]]; then
@@ -109,11 +106,16 @@ install_x-ui() {
fi
fi
if [[ -e /usr/local/x-ui/ ]]; then
rm /usr/local/x-ui/ -rf
fi
tar zxvf x-ui-linux-${arch}.tar.gz
rm x-ui-linux-${arch}.tar.gz -f
cd x-ui
chmod +x x-ui bin/xray-linux-${arch}
chmod +x x-ui bin/xray-linux-${arch} x-ui.sh
cp -f x-ui.service /etc/systemd/system/
cp -f x-ui.sh /usr/bin/x-ui
systemctl daemon-reload
systemctl enable x-ui
systemctl start x-ui
@@ -125,8 +127,6 @@ install_x-ui() {
echo -e ""
echo -e "如果是更新面板,则按你之前的方式访问面板"
echo -e ""
curl -o /usr/bin/x-ui -Ls https://raw.githubusercontent.com/sprov065/x-ui/master/x-ui.sh
chmod +x /usr/bin/x-ui
echo -e "x-ui 管理脚本使用方法: "
echo -e "----------------------------------------------"
echo -e "x-ui - 显示管理菜单 (功能更多)"

View File

@@ -40,7 +40,7 @@ const RULE_DOMAIN = {
SPEEDTEST: 'geosite:speedtest',
};
const VLESS_FLOW = {
const FLOW_CONTROL = {
ORIGIN: "xtls-rprx-origin",
DIRECT: "xtls-rprx-direct",
};
@@ -50,7 +50,7 @@ Object.freeze(VmessMethods);
Object.freeze(SSMethods);
Object.freeze(RULE_IP);
Object.freeze(RULE_DOMAIN);
Object.freeze(VLESS_FLOW);
Object.freeze(FLOW_CONTROL);
class XrayCommonClass {
@@ -697,11 +697,13 @@ class Inbound extends XrayCommonClass {
}
}
// VLess
// VLess & Trojan
get flow() {
switch (this.protocol) {
case Protocols.VLESS:
return this.settings.vlesses[0].flow;
case Protocols.TROJAN:
return this.settings.clients[0].flow;
default:
return "";
}
@@ -1008,18 +1010,6 @@ class Inbound extends XrayCommonClass {
params.set("flow", this.settings.vlesses[0].flow);
}
for (const [key, value] of params) {
switch (key) {
case "host":
case "path":
case "seed":
case "key":
case "alpn":
params.set(key, encodeURIComponent(value));
break;
}
}
const link = `vless://${uuid}@${address}:${port}`;
const url = new URL(link);
for (const [key, value] of params) {
@@ -1217,7 +1207,7 @@ Inbound.VLESSSettings = class extends Inbound.Settings {
};
Inbound.VLESSSettings.VLESS = class extends XrayCommonClass {
constructor(id=RandomUtil.randomUUID(), flow=VLESS_FLOW.DIRECT) {
constructor(id=RandomUtil.randomUUID(), flow=FLOW_CONTROL.DIRECT) {
super();
this.id = id;
this.flow = flow;
@@ -1270,14 +1260,26 @@ Inbound.VLESSSettings.Fallback = class extends XrayCommonClass {
};
Inbound.TrojanSettings = class extends Inbound.Settings {
constructor(protocol, clients=[new Inbound.TrojanSettings.Client()]) {
constructor(protocol,
clients=[new Inbound.TrojanSettings.Client()],
fallbacks=[],) {
super(protocol);
this.clients = clients;
this.fallbacks = fallbacks;
}
addTrojanFallback() {
this.fallbacks.push(new Inbound.TrojanSettings.Fallback());
}
delTrojanFallback(index) {
this.fallbacks.splice(index, 1);
}
toJson() {
return {
clients: Inbound.TrojanSettings.toJsonArray(this.clients),
fallbacks: Inbound.TrojanSettings.toJsonArray(this.fallbacks),
};
}
@@ -1286,27 +1288,74 @@ Inbound.TrojanSettings = class extends Inbound.Settings {
for (const c of json.clients) {
clients.push(Inbound.TrojanSettings.Client.fromJson(c));
}
return new Inbound.TrojanSettings(Protocols.TROJAN, clients);
return new Inbound.TrojanSettings(
Protocols.TROJAN,
clients,
Inbound.TrojanSettings.Fallback.fromJson(json.fallbacks),);
}
};
Inbound.TrojanSettings.Client = class extends XrayCommonClass {
constructor(password=RandomUtil.randomSeq(10)) {
constructor(password=RandomUtil.randomSeq(10), flow=FLOW_CONTROL.DIRECT) {
super();
this.password = password;
this.flow = flow;
}
toJson() {
return {
password: this.password,
flow: this.flow,
};
}
static fromJson(json={}) {
return new Inbound.TrojanSettings.Client(json.password);
return new Inbound.TrojanSettings.Client(
json.password,
json.flow,
);
}
};
Inbound.TrojanSettings.Fallback = class extends XrayCommonClass {
constructor(name="", alpn='', path='', dest='', xver=0) {
super();
this.name = name;
this.alpn = alpn;
this.path = path;
this.dest = dest;
this.xver = xver;
}
toJson() {
let xver = this.xver;
if (!Number.isInteger(xver)) {
xver = 0;
}
return {
name: this.name,
alpn: this.alpn,
path: this.path,
dest: this.dest,
xver: xver,
}
}
static fromJson(json=[]) {
const fallbacks = [];
for (let fallback of json) {
fallbacks.push(new Inbound.TrojanSettings.Fallback(
fallback.name,
fallback.alpn,
fallback.path,
fallback.dest,
fallback.xver,
))
}
return fallbacks;
}
};
Inbound.ShadowsocksSettings = class extends Inbound.Settings {
constructor(protocol,
method=SSMethods.AES_256_GCM,

View File

@@ -20,7 +20,7 @@
<a-icon type="link"></a-icon>
<span>其他</span>
</template>
<a-menu-item key="https://github.com/sprov065/x-ui/">
<a-menu-item key="https://github.com/vaxilu/x-ui/">
<a-icon type="github"></a-icon>
<span>Github</span>
</a-menu-item>

View File

@@ -3,5 +3,47 @@
<a-form-item label="密码">
<a-input v-model.trim="inbound.settings.clients[0].password"></a-input>
</a-form-item>
<a-form-item v-if="inbound.xtls" label="flow">
<a-select v-model="inbound.settings.clients[0].flow" style="width: 150px">
<a-select-option value=""></a-select-option>
<a-select-option v-for="key in FLOW_CONTROL" :value="key">[[ key ]]</a-select-option>
</a-select>
</a-form-item>
</a-form>
<a-form layout="inline">
<a-form-item label="fallbacks">
<a-row>
<a-button type="primary" size="small"
@click="inbound.settings.addTrojanFallback()">
+
</a-button>
</a-row>
</a-form-item>
</a-form>
<!-- trojan fallbacks -->
<a-form v-for="(fallback, index) in inbound.settings.fallbacks" layout="inline">
<a-divider>
fallback[[ index + 1 ]]
<a-icon type="delete" @click="() => inbound.settings.delTrojanFallback(index)"
style="color: rgb(255, 77, 79);cursor: pointer;"/>
</a-divider>
<a-form-item label="name">
<a-input v-model="fallback.name"></a-input>
</a-form-item>
<a-form-item label="alpn">
<a-input v-model="fallback.alpn"></a-input>
</a-form-item>
<a-form-item label="path">
<a-input v-model="fallback.path"></a-input>
</a-form-item>
<a-form-item label="dest">
<a-input v-model="fallback.dest"></a-input>
</a-form-item>
<a-form-item label="xver">
<a-input type="number" v-model.number="fallback.xver"></a-input>
</a-form-item>
<a-divider v-if="inbound.settings.fallbacks.length - 1 === index"/>
</a-form>
{{end}}

View File

@@ -6,7 +6,7 @@
<a-form-item v-if="inbound.xtls" label="flow">
<a-select v-model="inbound.settings.vlesses[0].flow" style="width: 150px">
<a-select-option value=""></a-select-option>
<a-select-option v-for="key in VLESS_FLOW" :value="key">[[ key ]]</a-select-option>
<a-select-option v-for="key in FLOW_CONTROL" :value="key">[[ key ]]</a-select-option>
</a-select>
</a-form-item>
</a-form>

View File

@@ -167,7 +167,7 @@ func (s *InboundService) AddTraffic(traffics []*xray.Traffic) (err error) {
func (s *InboundService) DisableInvalidInbounds() (int64, error) {
db := database.GetDB()
now := time.Now()
now := time.Now().Unix() * 1000
result := db.Model(model.Inbound{}).
Where("((total > 0 and up + down >= total) or (expiry_time > 0 and expiry_time <= ?)) and enable = ?", now, true).
Update("enable", false)

View File

@@ -87,7 +87,7 @@ func (s *XrayService) GetXrayTraffic() ([]*xray.Traffic, error) {
func (s *XrayService) RestartXray(isForce bool) error {
lock.Lock()
defer lock.Unlock()
logger.Debug("restart xray")
logger.Debug("restart xray, force:", isForce)
xrayConfig, err := s.GetXrayConfig()
if err != nil {

13
x-ui.sh
View File

@@ -82,7 +82,7 @@ before_show_menu() {
}
install() {
bash <(curl -Ls https://blog.sprov.xyz/x-ui.sh)
bash <(curl -Ls https://raw.githubusercontent.com/vaxilu/x-ui/master/install.sh)
if [[ $? == 0 ]]; then
if [[ $# == 0 ]]; then
start
@@ -101,7 +101,7 @@ update() {
fi
return 0
fi
bash <(curl -Ls https://raw.githubusercontent.com/sprov065/x-ui/master/install.sh)
bash <(curl -Ls https://raw.githubusercontent.com/vaxilu/x-ui/master/install.sh)
if [[ $? == 0 ]]; then
echo -e "${green}更新完成,已自动重启面板${plain}"
exit 0
@@ -127,9 +127,6 @@ uninstall() {
echo ""
echo -e "卸载成功,如果你想删除此脚本,则退出脚本后运行 ${green}rm /usr/bin/x-ui -f${plain} 进行删除"
echo ""
echo -e "Telegram 群组: ${green}https://t.me/sprov_blog${plain}"
echo -e "Github issues: ${green}https://github.com/sprov065/x-ui/issues${plain}"
echo -e "博客: ${green}https://blog.sprov.xyz/x-ui${plain}"
if [[ $# == 0 ]]; then
before_show_menu
@@ -277,13 +274,14 @@ migrate_v2_ui() {
}
install_bbr() {
bash <(curl -L -s https://raw.githubusercontent.com/sprov065/blog/master/bbr.sh)
# temporary workaround for installing bbr
bash <(curl -L -s https://raw.githubusercontent.com/teddysun/across/master/bbr.sh)
echo ""
before_show_menu
}
update_shell() {
wget -O /usr/bin/x-ui -N --no-check-certificate https://github.com/sprov065/x-ui/raw/master/x-ui.sh
wget -O /usr/bin/x-ui -N --no-check-certificate https://github.com/vaxilu/x-ui/raw/master/x-ui.sh
if [[ $? != 0 ]]; then
echo ""
echo -e "${red}下载脚本失败,请检查本机能否连接 Github${plain}"
@@ -409,7 +407,6 @@ show_usage() {
show_menu() {
echo -e "
${green}x-ui 面板管理脚本${plain}
--- https://blog.sprov.xyz/x-ui ---
${green}0.${plain} 退出脚本
————————————————
${green}1.${plain} 安装 x-ui