diff --git a/.github/ISSUE_TEMPLATE/------.md b/.github/ISSUE_TEMPLATE/------.md
deleted file mode 100644
index f1ccef8b4e..0000000000
--- a/.github/ISSUE_TEMPLATE/------.md
+++ /dev/null
@@ -1,14 +0,0 @@
----
-name: 提问题点这里
-about: issue 模板
-title: ''
-labels: ''
-assignees: ''
-
----
-
-任何由于自己的配置错误导致的情况,请自行解决,issues 只用于解决面板自身的 bug
-
-如果你确定面板的功能实现有 bug,请尽可能提供更多更精确的描述信息、复现方法与复现结果等等,而不是草草一句话了事,这对于问题的解决没有帮助
-
-提问的艺术: https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/blob/master/README-zh_CN.md
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
new file mode 100644
index 0000000000..39acf241a0
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -0,0 +1,57 @@
+name: Issue Report
+description: "Create a report to help us improve."
+body:
+ - type: checkboxes
+ id: terms
+ attributes:
+ label: Welcome
+ options:
+ - label: Yes, I'm using the latest major release. Only such installations are supported.
+ required: true
+ - label: Yes, I'm using the supported system. Only such systems are supported.
+ required: true
+ - label: Yes, I have read all WIKI document,nothing can help me in my problem.
+ required: true
+ - label: Yes, I've searched similar issues on GitHub and didn't find any.
+ required: true
+ - label: Yes, I've included all information below (version, config, log, etc).
+ required: true
+
+ - type: textarea
+ id: problem
+ attributes:
+ label: Description of the problem,screencshot would be good
+ placeholder: Your problem description
+ validations:
+ required: true
+
+ - type: textarea
+ id: version
+ attributes:
+ label: Version of x-ui
+ value: |-
+
+
+ ```console
+ $ x-ui version
+ # Paste output here
+ ```
+
+
+ validations:
+ required: true
+
+ - type: textarea
+ id: log
+ attributes:
+ label: x-ui log or xray log
+ value: |-
+
+
+ ```console
+ # paste log here
+ ```
+
+
+ validations:
+ required: true
diff --git a/README.md b/README.md
index cc1b9d9a97..b2d7cbaa14 100644
--- a/README.md
+++ b/README.md
@@ -1,79 +1,221 @@
-# x-ui
-支持多协议多用户的 xray 面板
-
-# 功能介绍
-- 系统状态监控
-- 支持多用户多协议,网页可视化操作
-- 支持的协议:vmess、vless、trojan、shadowsocks、dokodemo-door、socks、http
-- 支持配置更多传输配置
-- 流量统计,限制流量,限制到期时间
-- 可自定义 xray 配置模板
-- 支持 https 访问面板(自备域名 + ssl 证书)
-- 更多高级配置项,详见面板
-
-# 安装&升级
-```
-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
-```
-
-## 使用docker安装
-
-> 此 docker 教程与 docker 镜像由[Chasing66](https://github.com/Chasing66)提供
-
-1. 安装docker
-```shell
-curl -fsSL https://get.docker.com | sh
-```
-2. 安装x-ui
-```shell
-mkdir x-ui && cd x-ui
-docker run -itd --network=host \
- -v $PWD/db/:/etc/x-ui/ \
- -v $PWD/cert/:/root/cert/ \
- --name x-ui --restart=unless-stopped \
- enwaiax/x-ui:latest
-```
->Build 自己的镜像
-```shell
-docker build -t x-ui .
-```
-
-## 建议系统
-- CentOS 7+
-- Ubuntu 16+
-- Debian 8+
-
-# 常见问题
-
-## 从 v2-ui 迁移
-首先在安装了 v2-ui 的服务器上安装最新版 x-ui,然后使用以下命令进行迁移,将迁移本机 v2-ui 的`所有 inbound 账号数据`至 x-ui,`面板设置和用户名密码不会迁移`
-> 迁移成功后请`关闭 v2-ui`并且`重启 x-ui`,否则 v2-ui 的 inbound 会与 x-ui 的 inbound 会产生`端口冲突`
-```
-x-ui v2-ui
-```
-
-## issue 关闭
-各种小白问题看得血压很高
-
-## Stargazers over time
-
-[](https://starchart.cc/vaxilu/x-ui)
+# X-UI
+简体中文|[ENGLISH](./README_EN.md)
+
+> 声明:该项目仅供个人学习、交流,请遵守当地法律法规,勿用于非法用途;请勿用于生产环境
+> 声明:该项目已闭源,介意者请勿使用;如您需要开源代码,请附上您的Github Profile邮箱联系
+
+支持单端口多用户、多协议的 xray 面板,究极缝合怪
+通过免费的Telegram bot方便快捷地进行监控、管理你的代理服务
+⚡`xtls-rprx-vision`与`reality`快速入手请看[这里](https://github.com/FranzKafkaYu/x-ui/wiki/%E8%8A%82%E7%82%B9%E9%85%8D%E7%BD%AE)
+欢迎大家使用并反馈意见或提交Pr,帮助项目更好的改善
+如果您觉得本项目对您有所帮助,不妨给个star:star2:支持我
+或者你恰巧有购买服务器的需求,可以通过文末的赞助部分支持我~
+
+# 文档目录
+- [功能介绍](#功能介绍)
+- [一键安装](#一键安装)
+- [效果预览](#效果预览)
+- [快捷方式](#快捷方式)
+- [变更记录](#变更记录)
+
+# 功能介绍
+
+- 系统状态监控
+- 支持单端口多用户、多协议,网页可视化操作
+- 支持的协议:vmess、vless、trojan、shadowsocks、shadowsocks 2022、dokodemo-door、socks、http
+- 支持配置更多传输配置:http、tcp、ws、grpc、kcp、quic
+- 流量统计,限制流量,限制到期时间,一键重置与设备监控
+- 可自定义 xray 配置模板
+- 支持 https 访问面板(自备域名 + ssl 证书)
+- 支持一键SSL证书申请且自动续签
+- Telegram bot通知、控制功能
+- 更多高级配置项,详见面板
+
+:bulb:具体**使用、配置细节以及问题排查**请点击这里:point_right:[WIKI](https://github.com/FranzKafkaYu/x-ui/wiki):point_left:
+ Specific **Usages、Configurations and Debug** please refer to [WIKI](https://github.com/FranzKafkaYu/x-ui/wiki)
+# 一键安装
+在安装前请确保你的系统支持`bash`环境,且系统网络正常
+
+⚡从原版升级也可使用该命令,数据不会丢失⚡
+
+```
+bash <(curl -Ls https://raw.githubusercontent.com/FranzKafkaYu/x-ui/master/install.sh)
+```
+For English Users,please use the following command to install English supported version:
+```
+bash <(curl -Ls https://raw.githubusercontent.com/FranzKafkaYu/x-ui/master/install_en.sh)
+```
+如需安装指定的版本,可以在上述命令中指定版本号,如指定版本为`0.3.4.4`,安装命令如下:
+```
+bash <(curl -Ls https://raw.githubusercontent.com/FranzKafkaYu/x-ui/master/install.sh) 0.3.4.4
+```
+
+# 效果预览
+`面板使用`:
+
+点击查看效果预览
+
+
+
+
+
+
+
+`Bot使用`:
+
+点击查看效果预览
+
+
+
+
+
+`流量提醒`:
+
+点击查看效果预览
+
+
+
+
+
+`SSH提醒`:
+
+点击查看效果预览
+
+
+
+
+
+`限额提醒`:
+
+点击查看效果预览
+
+
+
+
+
+`到期提醒`:
+
+点击查看效果预览
+
+
+
+
+
+`登录提醒`:
+
+点击查看效果预览
+
+
+
+
+
+
+`用户速览`:
+
+点击查看效果预览
+
+
+
+
+
+`用户查询`:
+
+点击查看效果预览
+
+
+
+
+
+
+
+# 快捷方式
+安装成功后,通过键入`x-ui`进入控制选项菜单,目前菜单内容:
+```
+ x-ui 面板管理脚本
+ 0. 退出脚本
+————————————————
+ 1. 安装 x-ui
+ 2. 更新 x-ui
+ 3. 卸载 x-ui
+————————————————
+ 4. 重置用户名密码
+ 5. 重置面板设置
+ 6. 设置面板端口
+ 7. 查看当前面板设置
+————————————————
+ 8. 启动 x-ui
+ 9. 停止 x-ui
+ 10. 重启 x-ui
+ 11. 查看 x-ui 状态
+ 12. 查看 x-ui 日志
+————————————————
+ 13. 设置 x-ui 开机自启
+ 14. 取消 x-ui 开机自启
+————————————————
+ 15. 一键安装 bbr (最新内核)
+ 16. 一键申请SSL证书(acme申请)
+
+面板状态: 已运行
+是否开机自启: 是
+xray 状态: 运行
+
+请输入选择 [0-16]:
+```
+# 配置要求
+## 内存
+- 128MB minimal/256MB+ recommend
+## OS
+- CentOS 7+
+- Ubuntu 16+
+- Debian 8+
+
+# 变更记录
+- 2023.07.18:随机生成Reality dest与serverNames,去除微软域名;细化sniffing配置
+- 2023.06.10:开启TLS时自动复用面板证书与域名;增加证书热重载设定;优化设备限制功能
+- 2023.04.09:支持Reality;支持新的telegram bot控制指令
+- 2023.03.05:支持用户到期时间限制;随机用户名、密码与端口生成
+- 2023.02.09:支持单端口内用户流量限制与统计;支持VLESS utls配置与分享链接导出
+- 2022.12.07:添加设备并发限制;细化tls配置,支持minVersion、maxVersion与cipherSuites选择
+- 2022.11.14:添加xtls-rprx-vision流控选项;定时自动更新geo与清除日志
+- 2022.10.23:实现全英文支持;增加批量导出分享链接功能;优化页面细节与Telegram通知
+- 2022.08.11:实现Vmess/Vless/Trojan单端口多用户;增加CPU使用超限提醒
+- 2022.07.28:增加acme standalone模式申请证书;增加x-ui自动保活机制;优化编译选项以适配更多系统
+- 2022.07.24:增加自动生成面板根路径,节点流量自动重置功能,设备IP接入变化通知功能
+- 2022.07.21:增加节点IP接入变化提醒,Web面板增加停止/重启xray功能,优化部分翻译
+- 2022.07.11:增加节点到期提醒、流量预警策略,增加Telegram bot节点复制、获取分享链接等
+- 2022.07.03:重构Telegram bot功能,指令控制不再需要键盘输入;增加Trojan底层传输配置
+- 2022.06.19:增加Shadowsocs2022新的Cipher,增加节点搜索、一键清除流量功能
+- 2022.05.14:增加Telegram bot Command控制功能,支持关闭/开启/删除节点等
+- 2022.04.25:增加SSH登录提醒、面板登录提醒
+- 2022.04.23:增加更多Telegram bot提醒功能
+- 2022.04.16:增加面板设置Telegram bot功能
+- 2022.04.12:优化Telegram Bot通知提醒
+- 2022.04.06:优化安装/更新流程,增加证书签发功能,添加Telegram bot机器人推送功能
+# Telegram
+
+[订阅频道](https://t.me/CoderfanBaby)
+[讨论群组](https://t.me/franzkafayu)
+
+# 致谢
+
+- [vaxilu/x-ui](https://github.com/vaxilu/x-ui)
+- [XTLS/Xray-core](https://github.com/XTLS/Xray-core)
+- [telegram-bot-api](https://github.com/go-telegram-bot-api/telegram-bot-api)
+
+# 广告赞助
+
+如果你觉得本项目对你有用,而且你也恰巧有这方面的需求,你也可以选择通过我的购买链接赞助我
+- [搬瓦工GIA高端线路](https://bandwagonhost.com/aff.php?aff=65703),仅推荐购买GIA套餐
+- [Cloudcone性价比主机提供商](https://app.cloudcone.com/?ref=7536)
+- [Spartan三网4837性价比主机](https://billing.spartanhost.net/aff.php?aff=1875)
+
+
+如果你希望购买一些现成的代理服务,可选择下述代理服务
+- [搬瓦工关联机场](https://justmysocks.net/members/aff.php?aff=18177)
+- [高端奶昔机场](https://nxboom.com/signupbyemail.aspx?MemberCode=2fd79885e45549049c66698f1eea154620230921234746)
+
+VPS推送可关注电报[频道](https://t.me/VpsReStockAlert)
+
+## Stargazers over time
+
+[](https://starchart.cc/FranzKafkaYu/x-ui)
diff --git a/README_EN.md b/README_EN.md
new file mode 100644
index 0000000000..a5ac37dc3f
--- /dev/null
+++ b/README_EN.md
@@ -0,0 +1,120 @@
+# X-UI
+
+[简体中文](./README.md)| ENGLISH
+X-UI is a webUI panel based on Xray-core which supports multi protocols and multi users
+This project is a fork of [vaxilu's project](https://github.com/vaxilu/x-ui),and it is a experiental project which used by myself for learning golang
+If you need more language options ,please open a issue and let me know that
+
+# Changes
+- 2023.07.18:Random Reality dest and serverNames;more detailed sniffing settings available
+- 2023.06.10:Enable TLS will reuse panel's certs and domain;add setting for ocspStapling;refactor device limit
+- 2023.04.09:Support REALITY for now
+- 2023.03.05:User expiry time limit for each user
+- 2023.02.09:User traffic limit for each user,support utls sharing link
+- 2022.12.07:Add device limit and more tls configuration
+- 2022.11.15:Add xtls-rprx-vision flow option;cron job for geo update and log clear
+- 2022.10.23:Fully support for English,add export links,add CPU cores display
+- 2022.08.11:Support multi users on the same port;add CPU limit exceed alert
+- 2022.07.28:Add acme standalone mode for cert issue;add mechanism to keep X-UI alive even there exist crashes
+- 2022.07.24:Add base path auto generate feature for security;add traffice reset automatically;add device alert
+- 2022.07.21:Add more translations;add restart/stop xray service in Web panel
+- 2022.07.11:Add time expiration notify for each inbound;add traffic limit notify for each inbound;add get url link command/inbound copy command in telegram bot
+- 2022.07.03:Add transport options in Trojan protocol;restruct Telegram bot for convenience
+- 2022.06.19:Add shadowsocks 2022 Ciphers,add inbounds search,traffic clear function in WebUI
+- 2022.05.14:Add Telegram bot commands,support enable/disable/delete/status check
+- 2022.04.25:Add SSH login notify
+- 2022.04.23:Add WebUi login notify
+- 2022.04.16:Add Telegram bot set up in WebUi pannel
+- 2022.04.12:Optimize Telegram bot notify,more human friendly
+- 2022.04.06:Add cert issue function,optimize installation/update and add telegram bot notify
+
+# Basics
+
+- support system status info check
+- support multi protocols and multi users
+- support protocols:vmess、vless、trojan、shadowsocks、dokodemo-door、socks、http
+- support many transport method including tcp、udp、ws、kcp etc
+- traffic counting,traffic restrict and time restrcit
+- support custom configuration template
+- support https access fot WebUI
+- support SSL cert issue by Acme
+- support telegram bot notify and control
+- more functions in control menu
+
+for more detailed usages,plz see [WIKI](https://github.com/FranzKafkaYu/x-ui/wiki)
+
+# Installation
+Make sure your system `bash` and `curl` and `network` are ready,here we go
+
+```
+bash <(curl -Ls https://raw.githubusercontent.com/FranzKafkaYu/x-ui/master/install.sh)
+```
+For English Users,please use the following command to install English supported version:
+```
+bash <(curl -Ls https://raw.githubusercontent.com/FranzKafkaYu/x-ui/master/install_en.sh)
+```
+
+## Shortcut
+After Installation,you can input `x-ui`to enter control menu,current menu details:
+```
+
+ x-ui control menu
+ 0. exit
+————————————————
+ 1. install x-ui
+ 2. update x-ui
+ 3. uninstall x-ui
+————————————————
+ 4. reset username
+ 5. reset panel
+ 6. reset panel port
+ 7. check panel info
+————————————————
+ 8. start x-ui
+ 9. stop x-ui
+ 10. restart x-ui
+ 11. check x-ui status
+ 12. check x-ui logs
+————————————————
+ 13. enable x-ui on sysyem startup
+ 14. disabel x-ui on sysyem startup
+————————————————
+ 15. enable bbr
+ 16. issuse certs
+
+x-ui status: running
+enable on system startup: yes
+xray status: running
+
+please input a legal number[0-16]:
+```
+
+# System requirements:
+## MEM
+- 128MB minimal/256MB+ recommend
+## OS
+- CentOS 7+
+- Ubuntu 16+
+- Debian 8+
+
+# Telegram
+
+[Channel](https://t.me/CoderfanBaby)
+[Group](https://t.me/franzkafayu)
+
+# Credits
+- [vaxilu/x-ui](https://github.com/vaxilu/x-ui)
+- [XTLS/Xray-core](https://github.com/XTLS/Xray-core)
+- [telegram-bot-api](https://github.com/go-telegram-bot-api/telegram-bot-api)
+
+# Sponsor
+
+if you want to purchase some virtual servers,you can purchase by my aff link:
+- [BandwagonHost](https://bandwagonhost.com/aff.php?aff=65703)
+- [Cloudcone](https://app.cloudcone.com/?ref=7536)
+- [SpartanHost](https://billing.spartanhost.net/aff.php?aff=1875)
+
+
+## Stargazers over time
+
+[](https://starchart.cc/FranzKafkaYu/x-ui)
diff --git a/install.sh b/install.sh
index 205cffde43..ae2e43907f 100644
--- a/install.sh
+++ b/install.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
red='\033[0;31m'
green='\033[0;32m'
@@ -31,18 +31,18 @@ fi
arch=$(arch)
-if [[ $arch == "x86_64" || $arch == "x64" || $arch == "amd64" ]]; then
- arch="amd64"
+if [[ $arch == "x86_64" || $arch == "x64" || $arch == "s390x" || $arch == "amd64" ]]; then
+ arch="amd64"
elif [[ $arch == "aarch64" || $arch == "arm64" ]]; then
- arch="arm64"
+ arch="arm64"
else
- arch="amd64"
- echo -e "${red}检测架构失败,使用默认架构: ${arch}${plain}"
+ arch="amd64"
+ echo -e "${red}检测架构失败,使用默认架构: ${arch}${plain}"
fi
echo "架构: ${arch}"
-if [ $(getconf WORD_BIT) != '32' ] && [ $(getconf LONG_BIT) != '64' ] ; then
+if [ $(getconf WORD_BIT) != '32' ] && [ $(getconf LONG_BIT) != '64' ]; then
echo "本软件不支持 32 位系统(x86),请使用 64 位系统(x86_64),如果检测有误,请联系作者"
exit -1
fi
@@ -73,9 +73,46 @@ fi
install_base() {
if [[ x"${release}" == x"centos" ]]; then
- yum install wget curl tar -y
+ yum install wget curl tar jq -y
else
- apt install wget curl tar -y
+ apt install wget curl tar jq -y
+ fi
+}
+
+#This function will be called when user installed x-ui out of sercurity
+config_after_install() {
+ echo -e "${yellow}出于安全考虑,安装/更新完成后需要强制修改端口与账户密码${plain}"
+ read -p "确认是否继续,如选择n则跳过本次端口与账户密码设定[y/n]": config_confirm
+ if [[ x"${config_confirm}" == x"y" || x"${config_confirm}" == x"Y" ]]; then
+ read -p "请设置您的账户名:" config_account
+ echo -e "${yellow}您的账户名将设定为:${config_account}${plain}"
+ read -p "请设置您的账户密码:" config_password
+ echo -e "${yellow}您的账户密码将设定为:${config_password}${plain}"
+ read -p "请设置面板访问端口:" config_port
+ echo -e "${yellow}您的面板访问端口将设定为:${config_port}${plain}"
+ echo -e "${yellow}确认设定,设定中${plain}"
+ /usr/local/x-ui/x-ui setting -username ${config_account} -password ${config_password}
+ echo -e "${yellow}账户密码设定完成${plain}"
+ /usr/local/x-ui/x-ui setting -port ${config_port}
+ echo -e "${yellow}面板端口设定完成${plain}"
+ else
+ echo -e "${red}已取消设定...${plain}"
+ if [[ ! -f "/etc/x-ui/x-ui.db" ]]; then
+ local usernameTemp=$(head -c 6 /dev/urandom | base64)
+ local passwordTemp=$(head -c 6 /dev/urandom | base64)
+ local portTemp=$(echo $RANDOM)
+ /usr/local/x-ui/x-ui setting -username ${usernameTemp} -password ${passwordTemp}
+ /usr/local/x-ui/x-ui setting -port ${portTemp}
+ echo -e "检测到您属于全新安装,出于安全考虑已自动为您生成随机用户与端口:"
+ echo -e "###############################################"
+ echo -e "${green}面板登录用户名:${usernameTemp}${plain}"
+ echo -e "${green}面板登录用户密码:${passwordTemp}${plain}"
+ echo -e "${red}面板登录端口:${portTemp}${plain}"
+ echo -e "###############################################"
+ echo -e "${red}如您遗忘了面板登录相关信息,可在安装完成后输入x-ui,输入选项7查看面板登录信息${plain}"
+ else
+ echo -e "${red}当前属于版本升级,保留之前设置项,登录方式保持不变,可输入x-ui后键入数字7查看面板登录信息${plain}"
+ fi
fi
}
@@ -83,21 +120,21 @@ install_x-ui() {
systemctl stop x-ui
cd /usr/local/
- if [ $# == 0 ] ;then
- last_version=$(curl -Ls "https://api.github.com/repos/vaxilu/x-ui/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
+ if [ $# == 0 ]; then
+ last_version=$(curl -Lsk "https://api.github.com/repos/FranzKafkaYu/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/vaxilu/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/FranzKafkaYu/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/vaxilu/x-ui/releases/download/${last_version}/x-ui-linux-${arch}.tar.gz"
+ url="https://github.com/FranzKafkaYu/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
@@ -115,19 +152,21 @@ install_x-ui() {
cd x-ui
chmod +x x-ui bin/xray-linux-${arch}
cp -f x-ui.service /etc/systemd/system/
- wget --no-check-certificate -O /usr/bin/x-ui https://raw.githubusercontent.com/vaxilu/x-ui/main/x-ui.sh
+ wget --no-check-certificate -O /usr/bin/x-ui https://raw.githubusercontent.com/FranzKafkaYu/x-ui/main/x-ui.sh
+ chmod +x /usr/local/x-ui/x-ui.sh
chmod +x /usr/bin/x-ui
+ config_after_install
+ #echo -e "如果是全新安装,默认网页端口为 ${green}54321${plain},用户名和密码默认都是 ${green}admin${plain}"
+ #echo -e "请自行确保此端口没有被其他程序占用,${yellow}并且确保 54321 端口已放行${plain}"
+ # echo -e "若想将 54321 修改为其它端口,输入 x-ui 命令进行修改,同样也要确保你修改的端口也是放行的"
+ #echo -e ""
+ #echo -e "如果是更新面板,则按你之前的方式访问面板"
+ #echo -e ""
systemctl daemon-reload
systemctl enable x-ui
systemctl start x-ui
echo -e "${green}x-ui v${last_version}${plain} 安装完成,面板已启动,"
echo -e ""
- echo -e "如果是全新安装,默认网页端口为 ${green}54321${plain},用户名和密码默认都是 ${green}admin${plain}"
- echo -e "请自行确保此端口没有被其他程序占用,${yellow}并且确保 54321 端口已放行${plain}"
-# echo -e "若想将 54321 修改为其它端口,输入 x-ui 命令进行修改,同样也要确保你修改的端口也是放行的"
- echo -e ""
- echo -e "如果是更新面板,则按你之前的方式访问面板"
- echo -e ""
echo -e "x-ui 管理脚本使用方法: "
echo -e "----------------------------------------------"
echo -e "x-ui - 显示管理菜单 (功能更多)"
@@ -142,6 +181,7 @@ install_x-ui() {
echo -e "x-ui update - 更新 x-ui 面板"
echo -e "x-ui install - 安装 x-ui 面板"
echo -e "x-ui uninstall - 卸载 x-ui 面板"
+ echo -e "x-ui geo - 更新 geo 数据"
echo -e "----------------------------------------------"
}
diff --git a/install_en.sh b/install_en.sh
new file mode 100644
index 0000000000..cc532d04e5
--- /dev/null
+++ b/install_en.sh
@@ -0,0 +1,183 @@
+#!/bin/bash
+
+red='\033[0;31m'
+green='\033[0;32m'
+yellow='\033[0;33m'
+plain='\033[0m'
+
+cur_dir=$(pwd)
+
+# check root
+[[ $EUID -ne 0 ]] && echo -e "${red}Fatal error:${plain}please run this script with root privilege\n" && exit 1
+
+# check os
+if [[ -f /etc/redhat-release ]]; then
+ release="centos"
+elif cat /etc/issue | grep -Eqi "debian"; then
+ release="debian"
+elif cat /etc/issue | grep -Eqi "ubuntu"; then
+ release="ubuntu"
+elif cat /etc/issue | grep -Eqi "centos|red hat|redhat"; then
+ release="centos"
+elif cat /proc/version | grep -Eqi "debian"; then
+ release="debian"
+elif cat /proc/version | grep -Eqi "ubuntu"; then
+ release="ubuntu"
+elif cat /proc/version | grep -Eqi "centos|red hat|redhat"; then
+ release="centos"
+else
+ echo -e "${red}check system os failed,please contact with author!${plain}\n" && exit 1
+fi
+
+arch=$(arch)
+
+if [[ $arch == "x86_64" || $arch == "x64" || $arch == "amd64" ]]; then
+ arch="amd64"
+elif [[ $arch == "aarch64" || $arch == "arm64" ]]; then
+ arch="arm64"
+else
+ arch="amd64"
+ echo -e "${red}fail to check system arch,will use default arch here: ${arch}${plain}"
+fi
+
+echo "架构: ${arch}"
+
+if [ $(getconf WORD_BIT) != '32' ] && [ $(getconf LONG_BIT) != '64' ]; then
+ echo "x-ui dosen't support 32bit(x86) system,please use 64 bit operating system(x86_64) instead,if there is something wrong,plz let me know"
+ exit -1
+fi
+
+os_version=""
+
+# os version
+if [[ -f /etc/os-release ]]; then
+ os_version=$(awk -F'[= ."]' '/VERSION_ID/{print $3}' /etc/os-release)
+fi
+if [[ -z "$os_version" && -f /etc/lsb-release ]]; then
+ os_version=$(awk -F'[= ."]+' '/DISTRIB_RELEASE/{print $2}' /etc/lsb-release)
+fi
+
+if [[ x"${release}" == x"centos" ]]; then
+ if [[ ${os_version} -le 6 ]]; then
+ echo -e "${red}please use CentOS 7 or higher version${plain}\n" && exit 1
+ fi
+elif [[ x"${release}" == x"ubuntu" ]]; then
+ if [[ ${os_version} -lt 16 ]]; then
+ echo -e "${red}please use Ubuntu 16 or higher version${plain}\n" && exit 1
+ fi
+elif [[ x"${release}" == x"debian" ]]; then
+ if [[ ${os_version} -lt 8 ]]; then
+ echo -e "${red}please use Debian 8 or higher version${plain}\n" && exit 1
+ fi
+fi
+
+install_base() {
+ if [[ x"${release}" == x"centos" ]]; then
+ yum install wget curl tar -y
+ else
+ apt install wget curl tar -y
+ fi
+}
+
+#This function will be called when user installed x-ui out of sercurity
+config_after_install() {
+ echo -e "${yellow}Install/update finished need to modify panel settings out of security${plain}"
+ read -p "are you continue,if you type n will skip this at this time[y/n]": config_confirm
+ if [[ x"${config_confirm}" == x"y" || x"${config_confirm}" == x"Y" ]]; then
+ read -p "please set up your username:" config_account
+ echo -e "${yellow}your username will be:${config_account}${plain}"
+ read -p "please set up your password:" config_password
+ echo -e "${yellow}your password will be:${config_password}${plain}"
+ read -p "please set up the panel port:" config_port
+ echo -e "${yellow}your panel port is:${config_port}${plain}"
+ echo -e "${yellow}initializing,wait some time here...${plain}"
+ /usr/local/x-ui/x-ui setting -username ${config_account} -password ${config_password}
+ echo -e "${yellow}account name and password set down!${plain}"
+ /usr/local/x-ui/x-ui setting -port ${config_port}
+ echo -e "${yellow}panel port set down!${plain}"
+ else
+ echo -e "${red}cancel...${plain}"
+ if [[ ! -f "/etc/x-ui/x-ui.db" ]]; then
+ local usernameTemp=$(head -c 6 /dev/urandom | base64)
+ local passwordTemp=$(head -c 6 /dev/urandom | base64)
+ local portTemp=$(echo $RANDOM)
+ /usr/local/x-ui/x-ui setting -username ${usernameTemp} -password ${passwordTemp}
+ /usr/local/x-ui/x-ui setting -port ${portTemp}
+ echo -e "this is a fresh installation,will generate random login info for security concerns:"
+ echo -e "###############################################"
+ echo -e "${green}user name:${usernameTemp}${plain}"
+ echo -e "${green}user password:${passwordTemp}${plain}"
+ echo -e "${red}web port:${portTemp}${plain}"
+ echo -e "###############################################"
+ echo -e "${red}if you forgot your login info,you can type x-ui and then type 7 to check after installation${plain}"
+ else
+ echo -e "${red} this is your upgrade,will keep old settings,if you forgot your login info,you can type x-ui and then type 7 to check${plain}"
+ fi
+ fi
+}
+
+install_x-ui() {
+ systemctl stop x-ui
+ cd /usr/local/
+
+ if [ $# == 0 ]; then
+ last_version=$(curl -Ls "https://api.github.com/repos/FranzKafkaYu/x-ui/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
+ if [[ ! -n "$last_version" ]]; then
+ echo -e "${red}refresh x-ui version failed,it may due to Github API restriction,please try it later${plain}"
+ exit 1
+ fi
+ echo -e "get x-ui latest version succeed:${last_version},begin to install..."
+ wget -N --no-check-certificate -O /usr/local/x-ui-linux-${arch}-english.tar.gz https://github.com/FranzKafkaYu/x-ui/releases/download/${last_version}/x-ui-linux-${arch}-english.tar.gz
+ if [[ $? -ne 0 ]]; then
+ echo -e "${red}dowanload x-ui failed,please be sure that your server can access Github{plain}"
+ exit 1
+ fi
+ else
+ last_version=$1
+ url="https://github.com/FranzKafkaYu/x-ui/releases/download/${last_version}/x-ui-linux-${arch}-english.tar.gz"
+ echo -e "begin to install x-ui v$1 ..."
+ wget -N --no-check-certificate -O /usr/local/x-ui-linux-${arch}-english.tar.gz ${url}
+ if [[ $? -ne 0 ]]; then
+ echo -e "${red}dowanload x-ui v$1 failed,please check the verison exists${plain}"
+ exit 1
+ fi
+ fi
+
+ if [[ -e /usr/local/x-ui/ ]]; then
+ rm /usr/local/x-ui/ -rf
+ fi
+
+ tar zxvf x-ui-linux-${arch}-english.tar.gz
+ rm x-ui-linux-${arch}-english.tar.gz -f
+ cd x-ui
+ chmod +x x-ui bin/xray-linux-${arch}
+ cp -f x-ui.service /etc/systemd/system/
+ wget --no-check-certificate -O /usr/bin/x-ui https://raw.githubusercontent.com/FranzKafkaYu/x-ui/main/x-ui_en.sh
+ chmod +x /usr/local/x-ui/x-ui_en.sh
+ chmod +x /usr/bin/x-ui
+ config_after_install
+ systemctl daemon-reload
+ systemctl enable x-ui
+ systemctl start x-ui
+ echo -e "${green}x-ui v${last_version}${plain} install finished,it is working now..."
+ echo -e ""
+ echo -e "x-ui control menu usages: "
+ echo -e "----------------------------------------------"
+ echo -e "x-ui - Enter control menu"
+ echo -e "x-ui start - Start x-ui "
+ echo -e "x-ui stop - Stop x-ui "
+ echo -e "x-ui restart - Restart x-ui "
+ echo -e "x-ui status - Show x-ui status"
+ echo -e "x-ui enable - Enable x-ui on system startup"
+ echo -e "x-ui disable - Disable x-ui on system startup"
+ echo -e "x-ui log - Check x-ui logs"
+ echo -e "x-ui update - Update x-ui "
+ echo -e "x-ui install - Install x-ui "
+ echo -e "x-ui uninstall - Uninstall x-ui "
+ echo -e "x-ui geo - Update geo data"
+ echo -e "----------------------------------------------"
+}
+
+echo -e "${green}excuting...${plain}"
+install_base
+install_x-ui $1
diff --git a/media/2022-04-04_141259.png b/media/2022-04-04_141259.png
new file mode 100644
index 0000000000..aaa4664431
Binary files /dev/null and b/media/2022-04-04_141259.png differ
diff --git a/media/bda84fbc2ede834deaba1c173a932223.png b/media/bda84fbc2ede834deaba1c173a932223.png
new file mode 100644
index 0000000000..9cc3c380d0
Binary files /dev/null and b/media/bda84fbc2ede834deaba1c173a932223.png differ
diff --git a/media/d13ffd6a73f938d1037d0708e31433bf.png b/media/d13ffd6a73f938d1037d0708e31433bf.png
new file mode 100644
index 0000000000..b08277aaf5
Binary files /dev/null and b/media/d13ffd6a73f938d1037d0708e31433bf.png differ
diff --git a/x-ui.sh b/x-ui.sh
index dad3f8b031..914c068a02 100644
--- a/x-ui.sh
+++ b/x-ui.sh
@@ -5,8 +5,30 @@ green='\033[0;32m'
yellow='\033[0;33m'
plain='\033[0m'
+#consts for log check and clear,unit:M
+declare -r DEFAULT_LOG_FILE_DELETE_TRIGGER=35
+
+# consts for geo update
+PATH_FOR_GEO_IP='/usr/local/x-ui/bin/geoip.dat'
+PATH_FOR_CONFIG='/usr/local/x-ui/bin/config.json'
+PATH_FOR_GEO_SITE='/usr/local/x-ui/bin/geosite.dat'
+URL_FOR_GEO_IP='https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat'
+URL_FOR_GEO_SITE='https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat'
+
+#Add some basic function here
+function LOGD() {
+ echo -e "${yellow}[DEG] $* ${plain}"
+}
+
+function LOGE() {
+ echo -e "${red}[ERR] $* ${plain}"
+}
+
+function LOGI() {
+ echo -e "${green}[INF] $* ${plain}"
+}
# check root
-[[ $EUID -ne 0 ]] && echo -e "${red}错误: ${plain} 必须使用root用户运行此脚本!\n" && exit 1
+[[ $EUID -ne 0 ]] && LOGE "错误: 必须使用root用户运行此脚本!\n" && exit 1
# check os
if [[ -f /etc/redhat-release ]]; then
@@ -24,7 +46,7 @@ elif cat /proc/version | grep -Eqi "ubuntu"; then
elif cat /proc/version | grep -Eqi "centos|red hat|redhat"; then
release="centos"
else
- echo -e "${red}未检测到系统版本,请联系脚本作者!${plain}\n" && exit 1
+ LOGE "未检测到系统版本,请联系脚本作者!\n" && exit 1
fi
os_version=""
@@ -39,15 +61,15 @@ fi
if [[ x"${release}" == x"centos" ]]; then
if [[ ${os_version} -le 6 ]]; then
- echo -e "${red}请使用 CentOS 7 或更高版本的系统!${plain}\n" && exit 1
+ LOGE "请使用 CentOS 7 或更高版本的系统!\n" && exit 1
fi
elif [[ x"${release}" == x"ubuntu" ]]; then
if [[ ${os_version} -lt 16 ]]; then
- echo -e "${red}请使用 Ubuntu 16 或更高版本的系统!${plain}\n" && exit 1
+ LOGE "请使用 Ubuntu 16 或更高版本的系统!\n" && exit 1
fi
elif [[ x"${release}" == x"debian" ]]; then
if [[ ${os_version} -lt 8 ]]; then
- echo -e "${red}请使用 Debian 8 或更高版本的系统!${plain}\n" && exit 1
+ LOGE "请使用 Debian 8 或更高版本的系统!\n" && exit 1
fi
fi
@@ -82,7 +104,7 @@ before_show_menu() {
}
install() {
- bash <(curl -Ls https://raw.githubusercontent.com/vaxilu/x-ui/master/install.sh)
+ bash <(curl -Ls https://raw.githubusercontent.com/FranzKafkaYu/x-ui/master/install.sh)
if [[ $? == 0 ]]; then
if [[ $# == 0 ]]; then
start
@@ -95,21 +117,21 @@ install() {
update() {
confirm "本功能会强制重装当前最新版,数据不会丢失,是否继续?" "n"
if [[ $? != 0 ]]; then
- echo -e "${red}已取消${plain}"
+ LOGE "已取消"
if [[ $# == 0 ]]; then
before_show_menu
fi
return 0
fi
- bash <(curl -Ls https://raw.githubusercontent.com/vaxilu/x-ui/master/install.sh)
+ bash <(curl -Ls https://raw.githubusercontent.com/FranzKafkaYu/x-ui/master/install.sh)
if [[ $? == 0 ]]; then
- echo -e "${green}更新完成,已自动重启面板${plain}"
+ LOGI "更新完成,已自动重启面板 "
exit 0
fi
}
uninstall() {
- confirm "确定要卸载面板吗,xray 也会卸载?" "n"
+ confirm "确定要卸载面板吗,xray 也会卸载?" "n"
if [[ $? != 0 ]]; then
if [[ $# == 0 ]]; then
show_menu
@@ -159,10 +181,19 @@ reset_config() {
confirm_restart
}
+check_config() {
+ info=$(/usr/local/x-ui/x-ui setting -show true)
+ if [[ $? != 0 ]]; then
+ LOGE "get current settings error,please check logs"
+ show_menu
+ fi
+ LOGI "${info}"
+}
+
set_port() {
echo && echo -n -e "输入端口号[1-65535]: " && read port
if [[ -z "${port}" ]]; then
- echo -e "${yellow}已取消${plain}"
+ LOGD "已取消"
before_show_menu
else
/usr/local/x-ui/x-ui setting -port ${port}
@@ -175,15 +206,15 @@ start() {
check_status
if [[ $? == 0 ]]; then
echo ""
- echo -e "${green}面板已运行,无需再次启动,如需重启请选择重启${plain}"
+ LOGI "面板已运行,无需再次启动,如需重启请选择重启"
else
systemctl start x-ui
sleep 2
check_status
if [[ $? == 0 ]]; then
- echo -e "${green}x-ui 启动成功${plain}"
+ LOGI "x-ui 启动成功"
else
- echo -e "${red}面板启动失败,可能是因为启动时间超过了两秒,请稍后查看日志信息${plain}"
+ LOGE "面板启动失败,可能是因为启动时间超过了两秒,请稍后查看日志信息"
fi
fi
@@ -196,15 +227,15 @@ stop() {
check_status
if [[ $? == 1 ]]; then
echo ""
- echo -e "${green}面板已停止,无需再次停止${plain}"
+ LOGI "面板已停止,无需再次停止"
else
systemctl stop x-ui
sleep 2
check_status
if [[ $? == 1 ]]; then
- echo -e "${green}x-ui 与 xray 停止成功${plain}"
+ LOGI "x-ui 与 xray 停止成功"
else
- echo -e "${red}面板停止失败,可能是因为停止时间超过了两秒,请稍后查看日志信息${plain}"
+ LOGE "面板停止失败,可能是因为停止时间超过了两秒,请稍后查看日志信息"
fi
fi
@@ -218,9 +249,9 @@ restart() {
sleep 2
check_status
if [[ $? == 0 ]]; then
- echo -e "${green}x-ui 与 xray 重启成功${plain}"
+ LOGI "x-ui 与 xray 重启成功"
else
- echo -e "${red}面板重启失败,可能是因为启动时间超过了两秒,请稍后查看日志信息${plain}"
+ LOGE "面板重启失败,可能是因为启动时间超过了两秒,请稍后查看日志信息"
fi
if [[ $# == 0 ]]; then
before_show_menu
@@ -237,9 +268,9 @@ status() {
enable() {
systemctl enable x-ui
if [[ $? == 0 ]]; then
- echo -e "${green}x-ui 设置开机自启成功${plain}"
+ LOGI "x-ui 设置开机自启成功"
else
- echo -e "${red}x-ui 设置开机自启失败${plain}"
+ LOGE "x-ui 设置开机自启失败"
fi
if [[ $# == 0 ]]; then
@@ -250,9 +281,9 @@ enable() {
disable() {
systemctl disable x-ui
if [[ $? == 0 ]]; then
- echo -e "${green}x-ui 取消开机自启成功${plain}"
+ LOGI "x-ui 取消开机自启成功"
else
- echo -e "${red}x-ui 取消开机自启失败${plain}"
+ LOGE "x-ui 取消开机自启失败"
fi
if [[ $# == 0 ]]; then
@@ -281,14 +312,14 @@ install_bbr() {
}
update_shell() {
- wget -O /usr/bin/x-ui -N --no-check-certificate https://github.com/vaxilu/x-ui/raw/master/x-ui.sh
+ wget -O /usr/bin/x-ui -N --no-check-certificate https://github.com/FranzKafkaYu/x-ui/raw/master/x-ui.sh
if [[ $? != 0 ]]; then
echo ""
- echo -e "${red}下载脚本失败,请检查本机能否连接 Github${plain}"
+ LOGE "下载脚本失败,请检查本机能否连接 Github"
before_show_menu
else
chmod +x /usr/bin/x-ui
- echo -e "${green}升级脚本成功,请重新运行脚本${plain}" && exit 0
+ LOGI "升级脚本成功,请重新运行脚本" && exit 0
fi
}
@@ -310,7 +341,7 @@ check_enabled() {
if [[ x"${temp}" == x"enabled" ]]; then
return 0
else
- return 1;
+ return 1
fi
}
@@ -318,7 +349,7 @@ check_uninstall() {
check_status
if [[ $? != 2 ]]; then
echo ""
- echo -e "${red}面板已安装,请不要重复安装${plain}"
+ LOGE "面板已安装,请不要重复安装"
if [[ $# == 0 ]]; then
before_show_menu
fi
@@ -332,7 +363,7 @@ check_install() {
check_status
if [[ $? == 2 ]]; then
echo ""
- echo -e "${red}请先安装面板${plain}"
+ LOGE "请先安装面板"
if [[ $# == 0 ]]; then
before_show_menu
fi
@@ -345,16 +376,17 @@ check_install() {
show_status() {
check_status
case $? in
- 0)
- echo -e "面板状态: ${green}已运行${plain}"
- show_enable_status
- ;;
- 1)
- echo -e "面板状态: ${yellow}未运行${plain}"
- show_enable_status
- ;;
- 2)
- echo -e "面板状态: ${red}未安装${plain}"
+ 0)
+ echo -e "面板状态: ${green}已运行${plain}"
+ show_enable_status
+ ;;
+ 1)
+ echo -e "面板状态: ${yellow}未运行${plain}"
+ show_enable_status
+ ;;
+ 2)
+ echo -e "面板状态: ${red}未安装${plain}"
+ ;;
esac
show_xray_status
}
@@ -386,6 +418,362 @@ show_xray_status() {
fi
}
+#this will be an entrance for ssl cert issue
+#here we can provide two different methods to issue cert
+#first.standalone mode second.DNS API mode
+ssl_cert_issue() {
+ local method=""
+ echo -E ""
+ LOGD "******使用说明******"
+ LOGI "该脚本提供两种方式实现证书签发,证书安装路径均为/root/cert"
+ LOGI "方式1:acme standalone mode,需要保持端口开放"
+ LOGI "方式2:acme DNS API mode,需要提供Cloudflare Global API Key"
+ LOGI "如域名属于免费域名,则推荐使用方式1进行申请"
+ LOGI "如域名非免费域名且使用Cloudflare进行解析使用方式2进行申请"
+ read -p "请选择你想使用的方式,输入数字1或者2后回车": method
+ LOGI "你所使用的方式为${method}"
+
+ if [ "${method}" == "1" ]; then
+ ssl_cert_issue_standalone
+ elif [ "${method}" == "2" ]; then
+ ssl_cert_issue_by_cloudflare
+ else
+ LOGE "输入无效,请检查你的输入,脚本将退出..."
+ exit 1
+ fi
+}
+
+install_acme() {
+ cd ~
+ LOGI "开始安装acme脚本..."
+ curl https://get.acme.sh | sh
+ if [ $? -ne 0 ]; then
+ LOGE "acme安装失败"
+ return 1
+ else
+ LOGI "acme安装成功"
+ fi
+ return 0
+}
+
+#method for standalone mode
+ssl_cert_issue_standalone() {
+ #check for acme.sh first
+ if ! command -v ~/.acme.sh/acme.sh &>/dev/null; then
+ install_acme
+ if [ $? -ne 0 ]; then
+ LOGE "安装 acme 失败,请检查日志"
+ exit 1
+ fi
+ fi
+ #install socat second
+ if [[ x"${release}" == x"centos" ]]; then
+ yum install socat -y
+ else
+ apt install socat -y
+ fi
+ if [ $? -ne 0 ]; then
+ LOGE "无法安装socat,请检查错误日志"
+ exit 1
+ else
+ LOGI "socat安装成功..."
+ fi
+ #creat a directory for install cert
+ certPath=/root/cert
+ if [ ! -d "$certPath" ]; then
+ mkdir $certPath
+ fi
+ #get the domain here,and we need verify it
+ local domain=""
+ read -p "请输入你的域名:" domain
+ LOGD "你输入的域名为:${domain},正在进行域名合法性校验..."
+ #here we need to judge whether there exists cert already
+ local currentCert=$(~/.acme.sh/acme.sh --list | grep ${domain} | wc -l)
+ if [ ${currentCert} -ne 0 ]; then
+ local certInfo=$(~/.acme.sh/acme.sh --list)
+ LOGE "域名合法性校验失败,当前环境已有对应域名证书,不可重复申请,当前证书详情:"
+ LOGI "$certInfo"
+ exit 1
+ else
+ LOGI "域名合法性校验通过..."
+ fi
+ #get needed port here
+ local WebPort=80
+ read -p "请输入你所希望使用的端口,如回车将使用默认80端口:" WebPort
+ if [[ ${WebPort} -gt 65535 || ${WebPort} -lt 1 ]]; then
+ LOGE "你所选择的端口${WebPort}为无效值,将使用默认80端口进行申请"
+ fi
+ LOGI "将会使用${WebPort}进行证书申请,请确保端口处于开放状态..."
+ #NOTE:This should be handled by user
+ #open the port and kill the occupied progress
+ ~/.acme.sh/acme.sh --set-default-ca --server letsencrypt
+ ~/.acme.sh/acme.sh --issue -d ${domain} --standalone --httpport ${WebPort}
+ if [ $? -ne 0 ]; then
+ LOGE "证书申请失败,原因请参见报错信息"
+ rm -rf ~/.acme.sh/${domain}
+ exit 1
+ else
+ LOGI "证书申请成功,开始安装证书..."
+ fi
+ #install cert
+ ~/.acme.sh/acme.sh --installcert -d ${domain} --ca-file /root/cert/ca.cer \
+ --cert-file /root/cert/${domain}.cer --key-file /root/cert/${domain}.key \
+ --fullchain-file /root/cert/fullchain.cer
+
+ if [ $? -ne 0 ]; then
+ LOGE "证书安装失败,脚本退出"
+ rm -rf ~/.acme.sh/${domain}
+ exit 1
+ else
+ LOGI "证书安装成功,开启自动更新..."
+ fi
+ ~/.acme.sh/acme.sh --upgrade --auto-upgrade
+ if [ $? -ne 0 ]; then
+ LOGE "自动更新设置失败,脚本退出"
+ ls -lah cert
+ chmod 755 $certPath
+ exit 1
+ else
+ LOGI "证书已安装且已开启自动更新,具体信息如下"
+ ls -lah cert
+ chmod 755 $certPath
+ fi
+
+}
+
+#method for DNS API mode
+ssl_cert_issue_by_cloudflare() {
+ echo -E ""
+ LOGD "******使用说明******"
+ LOGI "该脚本将使用Acme脚本申请证书,使用时需保证:"
+ LOGI "1.知晓Cloudflare 注册邮箱"
+ LOGI "2.知晓Cloudflare Global API Key"
+ LOGI "3.域名已通过Cloudflare进行解析到当前服务器"
+ LOGI "4.该脚本申请证书默认安装路径为/root/cert目录"
+ confirm "我已确认以上内容[y/n]" "y"
+ if [ $? -eq 0 ]; then
+ install_acme
+ if [ $? -ne 0 ]; then
+ LOGE "无法安装acme,请检查错误日志"
+ exit 1
+ fi
+ CF_Domain=""
+ CF_GlobalKey=""
+ CF_AccountEmail=""
+ certPath=/root/cert
+ if [ ! -d "$certPath" ]; then
+ mkdir $certPath
+ fi
+ LOGD "请设置域名:"
+ read -p "Input your domain here:" CF_Domain
+ LOGD "你的域名设置为:${CF_Domain},正在进行域名合法性校验..."
+ #here we need to judge whether there exists cert already
+ local currentCert=$(~/.acme.sh/acme.sh --list | grep ${CF_Domain} | wc -l)
+ if [ ${currentCert} -ne 0 ]; then
+ local certInfo=$(~/.acme.sh/acme.sh --list)
+ LOGE "域名合法性校验失败,当前环境已有对应域名证书,不可重复申请,当前证书详情:"
+ LOGI "$certInfo"
+ exit 1
+ else
+ LOGI "域名合法性校验通过..."
+ fi
+ LOGD "请设置API密钥:"
+ read -p "Input your key here:" CF_GlobalKey
+ LOGD "你的API密钥为:${CF_GlobalKey}"
+ LOGD "请设置注册邮箱:"
+ read -p "Input your email here:" CF_AccountEmail
+ LOGD "你的注册邮箱为:${CF_AccountEmail}"
+ ~/.acme.sh/acme.sh --set-default-ca --server letsencrypt
+ if [ $? -ne 0 ]; then
+ LOGE "修改默认CA为Lets'Encrypt失败,脚本退出"
+ exit 1
+ fi
+ export CF_Key="${CF_GlobalKey}"
+ export CF_Email=${CF_AccountEmail}
+ ~/.acme.sh/acme.sh --issue --dns dns_cf -d ${CF_Domain} -d *.${CF_Domain} --log
+ if [ $? -ne 0 ]; then
+ LOGE "证书签发失败,脚本退出"
+ rm -rf ~/.acme.sh/${CF_Domain}
+ exit 1
+ else
+ LOGI "证书签发成功,安装中..."
+ fi
+ ~/.acme.sh/acme.sh --installcert -d ${CF_Domain} -d *.${CF_Domain} --ca-file /root/cert/ca.cer \
+ --cert-file /root/cert/${CF_Domain}.cer --key-file /root/cert/${CF_Domain}.key \
+ --fullchain-file /root/cert/fullchain.cer
+ if [ $? -ne 0 ]; then
+ LOGE "证书安装失败,脚本退出"
+ rm -rf ~/.acme.sh/${CF_Domain}
+ exit 1
+ else
+ LOGI "证书安装成功,开启自动更新..."
+ fi
+ ~/.acme.sh/acme.sh --upgrade --auto-upgrade
+ if [ $? -ne 0 ]; then
+ LOGE "自动更新设置失败,脚本退出"
+ ls -lah cert
+ chmod 755 $certPath
+ exit 1
+ else
+ LOGI "证书已安装且已开启自动更新,具体信息如下"
+ ls -lah cert
+ chmod 755 $certPath
+ fi
+ else
+ show_menu
+ fi
+}
+
+#add for cron jobs,including sync geo data,check logs and restart x-ui
+cron_jobs() {
+ clear
+ echo -e "
+ ${green}定时任务管理${plain}
+ ${green}0.${plain} 返回主菜单
+ ${green}1.${plain} 开启定时更新geo
+ ${green}2.${plain} 关闭定时更新geo
+ ${green}3.${plain} 开启定时删除xray日志
+ ${green}4.${plain} 关闭定时删除xray日志
+ "
+ echo && read -p "请输入选择 [0-4]: " num
+ case "${num}" in
+ 0)
+ show_menu
+ ;;
+ 1)
+ enable_auto_update_geo
+ ;;
+ 2)
+ disable_auto_update_geo
+ ;;
+ 3)
+ enable_auto_clear_log
+ ;;
+ 4)
+ disable_auto_clear_log
+ ;;
+ *)
+ LOGE "请输入正确的数字 [0-4]"
+ ;;
+ esac
+}
+
+#update geo data
+update_geo() {
+ #back up first
+ mv ${PATH_FOR_GEO_IP} ${PATH_FOR_GEO_IP}.bak
+ #update data
+ curl -s -L -o ${PATH_FOR_GEO_IP} ${URL_FOR_GEO_IP}
+ if [[ $? -ne 0 ]]; then
+ echo "update geoip.dat failed"
+ mv ${PATH_FOR_GEO_IP}.bak ${PATH_FOR_GEO_IP}
+ else
+ echo "update geoip.dat succeed"
+ rm -f ${PATH_FOR_GEO_IP}.bak
+ fi
+ mv ${PATH_FOR_GEO_SITE} ${PATH_FOR_GEO_SITE}.bak
+ curl -s -L -o ${PATH_FOR_GEO_SITE} ${URL_FOR_GEO_SITE}
+ if [[ $? -ne 0 ]]; then
+ echo "update geosite.dat failed"
+ mv ${PATH_FOR_GEO_SITE}.bak ${PATH_FOR_GEO_SITE}
+ else
+ echo "update geosite.dat succeed"
+ rm -f ${PATH_FOR_GEO_SITE}.bak
+ fi
+ #restart x-ui
+ systemctl restart x-ui
+}
+
+enable_auto_update_geo() {
+ LOGI "正在开启自动更新geo数据..."
+ crontab -l >/tmp/crontabTask.tmp
+ echo "00 4 */2 * * x-ui geo > /dev/null" >>/tmp/crontabTask.tmp
+ crontab /tmp/crontabTask.tmp
+ rm /tmp/crontabTask.tmp
+ LOGI "开启自动更新geo数据成功"
+}
+
+disable_auto_update_geo() {
+ crontab -l | grep -v "x-ui geo" | crontab -
+ if [[ $? -ne 0 ]]; then
+ LOGI "取消x-ui 自动更新geo数据失败"
+ else
+ LOGI "取消x-ui 自动更新geo数据成功"
+ fi
+}
+
+#clear xray log,need enable log in config template
+#here we need input an absolute path for log
+clear_log() {
+ LOGI "清除xray日志中..."
+ local filePath=''
+ if [[ $# -gt 0 ]]; then
+ filePath=$1
+ else
+ LOGE "未输入有效文件路径,脚本退出"
+ exit 1
+ fi
+ LOGI "日志路径为:${filePath}"
+ if [[ ! -f ${filePath} ]]; then
+ LOGE "清除xray日志文件失败,${filePath}不存在,请确认"
+ exit 1
+ fi
+ fileSize=$(ls -la ${filePath} --block-size=M | awk '{print $5}' | awk -F 'M' '{print$1}')
+ if [[ ${fileSize} -gt ${DEFAULT_LOG_FILE_DELETE_TRIGGER} ]]; then
+ rm $1
+ if [[ $? -ne 0 ]]; then
+ LOGE "清除xray日志文件:${filePath}失败"
+ else
+ LOGI "清除xray日志文件:${filePath}成功"
+ systemctl restart x-ui
+ fi
+ else
+ LOGI "当前日志大小为${fileSize}M,小于${DEFAULT_LOG_FILE_DELETE_TRIGGER}M,将不会清除"
+ fi
+}
+
+#enable auto delete log,need file path as
+enable_auto_clear_log() {
+ LOGI "设置定时清除xray日志..."
+ local accessfilePath=''
+ local errorfilePath=''
+ accessfilePath=$(cat ${PATH_FOR_CONFIG} | jq .log.access | tr -d '"')
+ errorfilePath=$(cat ${PATH_FOR_CONFIG} | jq .log.error | tr -d '"')
+ if [[ ! -n ${accessfilePath} && ! -n ${errorfilePath} ]]; then
+ LOGI "配置文件中的日志文件路径无效,脚本退出"
+ exit 1
+ fi
+ if [[ -f ${accessfilePath} ]]; then
+ crontab -l >/tmp/crontabTask.tmp
+ echo "30 4 */2 * * x-ui clear ${accessfilePath} > /dev/null" >>/tmp/crontabTask.tmp
+ crontab /tmp/crontabTask.tmp
+ rm /tmp/crontabTask.tmp
+ LOGI "设置定时清除xray日志:${accessfilePath}成功"
+ else
+ LOGE "accesslog不存在,将不会为其设置定时清除"
+ fi
+
+ if [[ -f ${errorfilePath} ]]; then
+ crontab -l >/tmp/crontabTask.tmp
+ echo "30 4 */2 * * x-ui clear ${errorfilePath} > /dev/null" >>/tmp/crontabTask.tmp
+ crontab /tmp/crontabTask.tmp
+ rm /tmp/crontabTask.tmp
+ LOGI "设置定时清除xray日志:${errorfilePath}成功"
+ else
+ LOGE "errorlog不存在,将不会为其设置定时清除"
+ fi
+}
+
+#disable auto dlete log
+disable_auto_clear_log() {
+ crontab -l | grep -v "x-ui clear" | crontab -
+ if [[ $? -ne 0 ]]; then
+ LOGI "取消 定时清除xray日志失败"
+ else
+ LOGI "取消 定时清除xray日志成功"
+ fi
+}
+
show_usage() {
echo "x-ui 管理脚本使用方法: "
echo "------------------------------------------"
@@ -401,6 +789,9 @@ show_usage() {
echo "x-ui update - 更新 x-ui 面板"
echo "x-ui install - 安装 x-ui 面板"
echo "x-ui uninstall - 卸载 x-ui 面板"
+ echo "x-ui clear - 清除 x-ui 日志"
+ echo "x-ui geo - 更新 x-ui geo数据"
+ echo "x-ui cron - 配置 x-ui 定时任务"
echo "------------------------------------------"
}
@@ -416,83 +807,130 @@ show_menu() {
${green}4.${plain} 重置用户名密码
${green}5.${plain} 重置面板设置
${green}6.${plain} 设置面板端口
+ ${green}7.${plain} 查看当前面板信息
————————————————
- ${green}7.${plain} 启动 x-ui
- ${green}8.${plain} 停止 x-ui
- ${green}9.${plain} 重启 x-ui
- ${green}10.${plain} 查看 x-ui 状态
- ${green}11.${plain} 查看 x-ui 日志
+ ${green}8.${plain} 启动 x-ui
+ ${green}9.${plain} 停止 x-ui
+ ${green}10.${plain} 重启 x-ui
+ ${green}11.${plain} 查看 x-ui 状态
+ ${green}12.${plain} 查看 x-ui 日志
————————————————
- ${green}12.${plain} 设置 x-ui 开机自启
- ${green}13.${plain} 取消 x-ui 开机自启
+ ${green}13.${plain} 设置 x-ui 开机自启
+ ${green}14.${plain} 取消 x-ui 开机自启
————————————————
- ${green}14.${plain} 一键安装 bbr (最新内核)
+ ${green}15.${plain} 一键安装 bbr (最新内核)
+ ${green}16.${plain} 一键申请SSL证书(acme申请)
+ ${green}17.${plain} 配置x-ui定时任务
"
show_status
- echo && read -p "请输入选择 [0-14]: " num
+ echo && read -p "请输入选择 [0-17],查看面板登录信息请输入数字7:" num
case "${num}" in
- 0) exit 0
+ 0)
+ exit 0
+ ;;
+ 1)
+ check_uninstall && install
;;
- 1) check_uninstall && install
+ 2)
+ check_install && update
;;
- 2) check_install && update
+ 3)
+ check_install && uninstall
;;
- 3) check_install && uninstall
+ 4)
+ check_install && reset_user
;;
- 4) check_install && reset_user
+ 5)
+ check_install && reset_config
;;
- 5) check_install && reset_config
+ 6)
+ check_install && set_port
;;
- 6) check_install && set_port
+ 7)
+ check_install && check_config
;;
- 7) check_install && start
+ 8)
+ check_install && start
;;
- 8) check_install && stop
+ 9)
+ check_install && stop
;;
- 9) check_install && restart
+ 10)
+ check_install && restart
;;
- 10) check_install && status
+ 11)
+ check_install && status
;;
- 11) check_install && show_log
+ 12)
+ check_install && show_log
;;
- 12) check_install && enable
+ 13)
+ check_install && enable
;;
- 13) check_install && disable
+ 14)
+ check_install && disable
;;
- 14) install_bbr
+ 15)
+ install_bbr
;;
- *) echo -e "${red}请输入正确的数字 [0-14]${plain}"
+ 16)
+ ssl_cert_issue
+ ;;
+ 17)
+ check_install && cron_jobs
+ ;;
+ *)
+ LOGE "请输入正确的数字 [0-17],查看面板登录信息请输入数字7"
;;
esac
}
-
if [[ $# > 0 ]]; then
case $1 in
- "start") check_install 0 && start 0
+ "start")
+ check_install 0 && start 0
+ ;;
+ "stop")
+ check_install 0 && stop 0
+ ;;
+ "restart")
+ check_install 0 && restart 0
+ ;;
+ "status")
+ check_install 0 && status 0
;;
- "stop") check_install 0 && stop 0
+ "enable")
+ check_install 0 && enable 0
;;
- "restart") check_install 0 && restart 0
+ "disable")
+ check_install 0 && disable 0
;;
- "status") check_install 0 && status 0
+ "log")
+ check_install 0 && show_log 0
;;
- "enable") check_install 0 && enable 0
+ "v2-ui")
+ check_install 0 && migrate_v2_ui 0
;;
- "disable") check_install 0 && disable 0
+ "update")
+ check_install 0 && update 0
;;
- "log") check_install 0 && show_log 0
+ "install")
+ check_uninstall 0 && install 0
;;
- "v2-ui") check_install 0 && migrate_v2_ui 0
+ "uninstall")
+ check_install 0 && uninstall 0
;;
- "update") check_install 0 && update 0
+ "geo")
+ check_install 0 && update_geo
;;
- "install") check_uninstall 0 && install 0
+ "clear")
+ check_install 0 && clear_log $2
;;
- "uninstall") check_install 0 && uninstall 0
+ "cron")
+ check_install && cron_jobs
;;
- *) show_usage
+ *) show_usage ;;
esac
else
show_menu
diff --git a/x-ui_en.sh b/x-ui_en.sh
new file mode 100644
index 0000000000..ee5376649d
--- /dev/null
+++ b/x-ui_en.sh
@@ -0,0 +1,935 @@
+#!/bin/bash
+
+red='\033[0;31m'
+green='\033[0;32m'
+yellow='\033[0;33m'
+plain='\033[0m'
+
+#consts for log check and clear,unit:M
+declare -r DEFAULT_LOG_FILE_DELETE_TRIGGER=35
+
+# consts for geo update
+PATH_FOR_GEO_IP='/usr/local/x-ui/bin/geoip.dat'
+PATH_FOR_CONFIG='/usr/local/x-ui/bin/config.json'
+PATH_FOR_GEO_SITE='/usr/local/x-ui/bin/geosite.dat'
+URL_FOR_GEO_IP='https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat'
+URL_FOR_GEO_SITE='https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat'
+
+#Add some basic function here
+function LOGD() {
+ echo -e "${yellow}[DEG] $* ${plain}"
+}
+
+function LOGE() {
+ echo -e "${red}[ERR] $* ${plain}"
+}
+
+function LOGI() {
+ echo -e "${green}[INF] $* ${plain}"
+}
+# check root
+[[ $EUID -ne 0 ]] && LOGE "${red}fatal error:please run this script with root privilege${plain}\n" && exit 1
+
+# check os
+if [[ -f /etc/redhat-release ]]; then
+ release="centos"
+elif cat /etc/issue | grep -Eqi "debian"; then
+ release="debian"
+elif cat /etc/issue | grep -Eqi "ubuntu"; then
+ release="ubuntu"
+elif cat /etc/issue | grep -Eqi "centos|red hat|redhat"; then
+ release="centos"
+elif cat /proc/version | grep -Eqi "debian"; then
+ release="debian"
+elif cat /proc/version | grep -Eqi "ubuntu"; then
+ release="ubuntu"
+elif cat /proc/version | grep -Eqi "centos|red hat|redhat"; then
+ release="centos"
+else
+ LOGE "check system os failed,please contact with author!\n" && exit 1
+fi
+
+os_version=""
+
+# os version
+if [[ -f /etc/os-release ]]; then
+ os_version=$(awk -F'[= ."]' '/VERSION_ID/{print $3}' /etc/os-release)
+fi
+if [[ -z "$os_version" && -f /etc/lsb-release ]]; then
+ os_version=$(awk -F'[= ."]+' '/DISTRIB_RELEASE/{print $2}' /etc/lsb-release)
+fi
+
+if [[ x"${release}" == x"centos" ]]; then
+ if [[ ${os_version} -le 6 ]]; then
+ LOGE "${red}please use CentOS 7 or higher version${plain}\n" && exit 1
+ fi
+elif [[ x"${release}" == x"ubuntu" ]]; then
+ if [[ ${os_version} -lt 16 ]]; then
+ LOGE "${red}please use Ubuntu 16 or higher version${plain}\n" && exit 1
+ fi
+elif [[ x"${release}" == x"debian" ]]; then
+ if [[ ${os_version} -lt 8 ]]; then
+ LOGE "${red}please use Debian 8 or higher version${plain}\n" && exit 1
+ fi
+fi
+
+confirm() {
+ if [[ $# > 1 ]]; then
+ echo && read -p "$1 [default:$2]: " temp
+ if [[ x"${temp}" == x"" ]]; then
+ temp=$2
+ fi
+ else
+ read -p "$1 [y/n]: " temp
+ fi
+ if [[ x"${temp}" == x"y" || x"${temp}" == x"Y" ]]; then
+ return 0
+ else
+ return 1
+ fi
+}
+
+confirm_restart() {
+ confirm "confirm to restart x-ui,xray service will be restart" "y"
+ if [[ $? == 0 ]]; then
+ restart
+ else
+ show_menu
+ fi
+}
+
+before_show_menu() {
+ echo && echo -n -e "${yellow}enter to return to the control menu: ${plain}" && read temp
+ show_menu
+}
+
+install() {
+ bash <(curl -Ls https://raw.githubusercontent.com/FranzKafkaYu/x-ui/master/install_en.sh)
+ if [[ $? == 0 ]]; then
+ if [[ $# == 0 ]]; then
+ start
+ else
+ start 0
+ fi
+ fi
+}
+
+update() {
+ confirm "will upgrade to the latest,continue?" "n"
+ if [[ $? != 0 ]]; then
+ LOGE "cancelled..."
+ if [[ $# == 0 ]]; then
+ before_show_menu
+ fi
+ return 0
+ fi
+ bash <(curl -Ls https://raw.githubusercontent.com/FranzKafkaYu/x-ui/master/install_en.sh)
+ if [[ $? == 0 ]]; then
+ LOGI "upgrade finished,restart completed"
+ exit 0
+ fi
+}
+
+uninstall() {
+ confirm "sure you want to uninstall x-ui?" "n"
+ if [[ $? != 0 ]]; then
+ if [[ $# == 0 ]]; then
+ show_menu
+ fi
+ return 0
+ fi
+ systemctl stop x-ui
+ systemctl disable x-ui
+ rm /etc/systemd/system/x-ui.service -f
+ systemctl daemon-reload
+ systemctl reset-failed
+ rm /etc/x-ui/ -rf
+ rm /usr/local/x-ui/ -rf
+
+ echo ""
+ echo -e "uninstall x-ui succeed,you can delete this script by ${green}rm /usr/bin/x-ui -f${plain}"
+ echo ""
+
+ if [[ $# == 0 ]]; then
+ before_show_menu
+ fi
+}
+
+reset_user() {
+ confirm "are you sure you want to reset the username and password to ${green}admin${plain} ?" "n"
+ if [[ $? != 0 ]]; then
+ if [[ $# == 0 ]]; then
+ show_menu
+ fi
+ return 0
+ fi
+ /usr/local/x-ui/x-ui setting -username admin -password admin
+ echo -e "your username and password are reset to ${green}admin${plain},restart x-ui to take effect"
+ confirm_restart
+}
+
+reset_config() {
+ confirm "are you sure you want to reset all settings,user data will not be lost" "n"
+ if [[ $? != 0 ]]; then
+ if [[ $# == 0 ]]; then
+ show_menu
+ fi
+ return 0
+ fi
+ /usr/local/x-ui/x-ui setting -reset
+ echo -e "all settings are reset to default,please restart x-ui,and use default port ${green}54321${plain} to access panel"
+ confirm_restart
+}
+
+check_config() {
+ info=$(/usr/local/x-ui/x-ui setting -show true)
+ if [[ $? != 0 ]]; then
+ LOGE "get current settings error,please check logs"
+ show_menu
+ fi
+ LOGI "${info}"
+}
+
+set_port() {
+ echo && echo -n -e "please set a port[1-65535]: " && read port
+ if [[ -z "${port}" ]]; then
+ LOGD "cancelled..."
+ before_show_menu
+ else
+ /usr/local/x-ui/x-ui setting -port ${port}
+ echo -e "set port done,please restart x-ui,and use this new port ${green}${port}${plain} to access panel"
+ confirm_restart
+ fi
+}
+
+start() {
+ check_status
+ if [[ $? == 0 ]]; then
+ echo ""
+ LOGI "x-ui is running,no need to start agin"
+ else
+ systemctl start x-ui
+ sleep 2
+ check_status
+ if [[ $? == 0 ]]; then
+ LOGI "start x-ui succeed"
+ else
+ LOGE "start x-ui failed,please check logs"
+ fi
+ fi
+
+ if [[ $# == 0 ]]; then
+ before_show_menu
+ fi
+}
+
+stop() {
+ check_status
+ if [[ $? == 1 ]]; then
+ echo ""
+ LOGI "x-ui is stopped,no need to stop again"
+ else
+ systemctl stop x-ui
+ sleep 2
+ check_status
+ if [[ $? == 1 ]]; then
+ LOGI "stop x-ui succeed"
+ else
+ LOGE "stop x-ui failed,please check logs"
+ fi
+ fi
+
+ if [[ $# == 0 ]]; then
+ before_show_menu
+ fi
+}
+
+restart() {
+ systemctl restart x-ui
+ sleep 2
+ check_status
+ if [[ $? == 0 ]]; then
+ LOGI "restart x-ui succeed"
+ else
+ LOGE "stop x-ui failed,please check logs"
+ fi
+ if [[ $# == 0 ]]; then
+ before_show_menu
+ fi
+}
+
+status() {
+ systemctl status x-ui -l
+ if [[ $# == 0 ]]; then
+ before_show_menu
+ fi
+}
+
+enable() {
+ systemctl enable x-ui
+ if [[ $? == 0 ]]; then
+ LOGI "enable x-ui on system startup succeed"
+ else
+ LOGE "enable x-ui on system startup failed"
+ fi
+
+ if [[ $# == 0 ]]; then
+ before_show_menu
+ fi
+}
+
+disable() {
+ systemctl disable x-ui
+ if [[ $? == 0 ]]; then
+ LOGI "disable x-ui on system startup succeed"
+ else
+ LOGE "disable x-ui on system startup failed"
+ fi
+
+ if [[ $# == 0 ]]; then
+ before_show_menu
+ fi
+}
+
+show_log() {
+ journalctl -u x-ui.service -e --no-pager -f
+ if [[ $# == 0 ]]; then
+ before_show_menu
+ fi
+}
+
+migrate_v2_ui() {
+ /usr/local/x-ui/x-ui v2-ui
+
+ before_show_menu
+}
+
+install_bbr() {
+ # 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/FranzKafkaYu/x-ui/raw/master/x-ui_en.sh
+ if [[ $? != 0 ]]; then
+ echo ""
+ LOGE "update shell script failed,please check whether your server can access github"
+ before_show_menu
+ else
+ chmod +x /usr/bin/x-ui
+ LOGI "update shell script succeed" && exit 0
+ fi
+}
+
+# 0: running, 1: not running, 2: not installed
+check_status() {
+ if [[ ! -f /etc/systemd/system/x-ui.service ]]; then
+ return 2
+ fi
+ temp=$(systemctl status x-ui | grep Active | awk '{print $3}' | cut -d "(" -f2 | cut -d ")" -f1)
+ if [[ x"${temp}" == x"running" ]]; then
+ return 0
+ else
+ return 1
+ fi
+}
+
+check_enabled() {
+ temp=$(systemctl is-enabled x-ui)
+ if [[ x"${temp}" == x"enabled" ]]; then
+ return 0
+ else
+ return 1
+ fi
+}
+
+check_uninstall() {
+ check_status
+ if [[ $? != 2 ]]; then
+ echo ""
+ LOGE "x-ui is installed already"
+ if [[ $# == 0 ]]; then
+ before_show_menu
+ fi
+ return 1
+ else
+ return 0
+ fi
+}
+
+check_install() {
+ check_status
+ if [[ $? == 2 ]]; then
+ echo ""
+ LOGE "please install x-ui first"
+ if [[ $# == 0 ]]; then
+ before_show_menu
+ fi
+ return 1
+ else
+ return 0
+ fi
+}
+
+show_status() {
+ check_status
+ case $? in
+ 0)
+ echo -e "x-ui status: ${green}running${plain}"
+ show_enable_status
+ ;;
+ 1)
+ echo -e "x-ui status: ${yellow}stopped${plain}"
+ show_enable_status
+ ;;
+ 2)
+ echo -e "x-ui status: ${red}not installed${plain}"
+ ;;
+ esac
+ show_xray_status
+}
+
+show_enable_status() {
+ check_enabled
+ if [[ $? == 0 ]]; then
+ echo -e "enable on system startup: ${green}yes${plain}"
+ else
+ echo -e "enable on system startup: ${red}no${plain}"
+ fi
+}
+
+check_xray_status() {
+ count=$(ps -ef | grep "xray-linux" | grep -v "grep" | wc -l)
+ if [[ count -ne 0 ]]; then
+ return 0
+ else
+ return 1
+ fi
+}
+
+show_xray_status() {
+ check_xray_status
+ if [[ $? == 0 ]]; then
+ echo -e "xray status: ${green}running${plain}"
+ else
+ echo -e "xray status: ${red}stopped${plain}"
+ fi
+}
+
+#this will be an entrance for ssl cert issue
+#here we can provide two different methods to issue cert
+#first.standalone mode second.DNS API mode
+ssl_cert_issue() {
+ local method=""
+ echo -E ""
+ LOGD "********Usage********"
+ LOGI "this shell script will use acme to help issue certs."
+ LOGI "here we provide two methods for issuing certs:"
+ LOGI "method 1:acme standalone mode,need to keep port:80 open"
+ LOGI "method 2:acme DNS API mode,need provide Cloudflare Global API Key"
+ LOGI "recommend method 2 first,if it fails,you can try method 1."
+ LOGI "certs will be installed in /root/cert directory"
+ read -p "please choose which method do you want,type 1 or 2": method
+ LOGI "you choosed method:${method}"
+
+ if [ "${method}" == "1" ]; then
+ ssl_cert_issue_standalone
+ elif [ "${method}" == "2" ]; then
+ ssl_cert_issue_by_cloudflare
+ else
+ LOGE "invalid input,please check it..."
+ exit 1
+ fi
+}
+
+install_acme() {
+ cd ~
+ LOGI "install acme..."
+ curl https://get.acme.sh | sh
+ if [ $? -ne 0 ]; then
+ LOGE "install acme failed"
+ return 1
+ else
+ LOGI "install acme succeed"
+ fi
+ return 0
+}
+
+#method for standalone mode
+ssl_cert_issue_standalone() {
+ #check for acme.sh first
+ if ! command -v ~/.acme.sh/acme.sh &>/dev/null; then
+ echo "acme.sh could not be found. we will install it"
+ install_acme
+ if [ $? -ne 0 ]; then
+ LOGE "install acme failed, please check logs"
+ exit 1
+ fi
+ fi
+ #install socat second
+ if [[ x"${release}" == x"centos" ]]; then
+ yum install socat -y
+ else
+ apt install socat -y
+ fi
+ if [ $? -ne 0 ]; then
+ LOGE "install socat failed, please check logs"
+ exit 1
+ else
+ LOGI "install socat succeed..."
+ fi
+ #creat a directory for install cert
+ certPath=/root/cert
+ if [ ! -d "$certPath" ]; then
+ mkdir $certPath
+ fi
+ #get the domain here,and we need verify it
+ local domain=""
+ read -p "please input your domain:" domain
+ LOGD "your domain is:${domain},check it..."
+ #here we need to judge whether there exists cert already
+ local currentCert=$(~/.acme.sh/acme.sh --list | grep ${domain} | wc -l)
+ if [ ${currentCert} -ne 0 ]; then
+ local certInfo=$(~/.acme.sh/acme.sh --list)
+ LOGE "system already have certs here,can not issue again,current certs details:"
+ LOGI "$certInfo"
+ exit 1
+ else
+ LOGI "your domain is ready for issuing cert now..."
+ fi
+ #get needed port here
+ local WebPort=80
+ read -p "please choose which port do you use,default will be 80 port:" WebPort
+ if [[ ${WebPort} -gt 65535 || ${WebPort} -lt 1 ]]; then
+ LOGE "your input ${WebPort} is invalid,will use default port"
+ fi
+ LOGI "will use port:${WebPort} to issue certs,please make sure this port is open..."
+ #NOTE:This should be handled by user
+ #open the port and kill the occupied progress
+ ~/.acme.sh/acme.sh --set-default-ca --server letsencrypt
+ ~/.acme.sh/acme.sh --issue -d ${domain} --standalone --httpport ${WebPort}
+ if [ $? -ne 0 ]; then
+ LOGE "issue certs failed,please check logs"
+ rm -rf ~/.acme.sh/${domain}
+ exit 1
+ else
+ LOGE "issue certs succeed,installing certs..."
+ fi
+ #install cert
+ ~/.acme.sh/acme.sh --installcert -d ${domain} --ca-file /root/cert/ca.cer \
+ --cert-file /root/cert/${domain}.cer --key-file /root/cert/${domain}.key \
+ --fullchain-file /root/cert/fullchain.cer
+
+ if [ $? -ne 0 ]; then
+ LOGE "install certs failed,exit"
+ rm -rf ~/.acme.sh/${domain}
+ exit 1
+ else
+ LOGI "install certs succeed,enable auto renew..."
+ fi
+ ~/.acme.sh/acme.sh --upgrade --auto-upgrade
+ if [ $? -ne 0 ]; then
+ LOGE "auto renew failed,certs details:"
+ ls -lah cert
+ chmod 755 $certPath
+ exit 1
+ else
+ LOGI "auto renew succeed,certs details:"
+ ls -lah cert
+ chmod 755 $certPath
+ fi
+
+}
+
+#method for DNS API mode
+ssl_cert_issue_by_cloudflare() {
+ echo -E ""
+ LOGD "******Preconditions******"
+ LOGI "1.need Cloudflare account associated email"
+ LOGI "2.need Cloudflare Global API Key"
+ LOGI "3.your domain use Cloudflare as resolver"
+ confirm "I have confirmed all these info above[y/n]" "y"
+ if [ $? -eq 0 ]; then
+ install_acme
+ if [ $? -ne 0 ]; then
+ LOGE "install acme failed,please check logs"
+ exit 1
+ fi
+ CF_Domain=""
+ CF_GlobalKey=""
+ CF_AccountEmail=""
+ certPath=/root/cert
+ if [ ! -d "$certPath" ]; then
+ mkdir $certPath
+ fi
+ LOGD "please input your domain:"
+ read -p "Input your domain here:" CF_Domain
+ LOGD "your domain is:${CF_Domain},check it..."
+ #here we need to judge whether there exists cert already
+ local currentCert=$(~/.acme.sh/acme.sh --list | grep ${CF_Domain} | wc -l)
+ if [ ${currentCert} -ne 0 ]; then
+ local certInfo=$(~/.acme.sh/acme.sh --list)
+ LOGE "system already have certs here,can not issue again,current certs details:"
+ LOGI "$certInfo"
+ exit 1
+ else
+ LOGI "your domain is ready for issuing cert now..."
+ fi
+ LOGD "please inout your cloudflare global API key:"
+ read -p "Input your key here:" CF_GlobalKey
+ LOGD "your cloudflare global API key is:${CF_GlobalKey}"
+ LOGD "please input your cloudflare account email:"
+ read -p "Input your email here:" CF_AccountEmail
+ LOGD "your cloudflare account email:${CF_AccountEmail}"
+ ~/.acme.sh/acme.sh --set-default-ca --server letsencrypt
+ if [ $? -ne 0 ]; then
+ LOGE "change the default CA to Lets'Encrypt failed,exit"
+ exit 1
+ fi
+ export CF_Key="${CF_GlobalKey}"
+ export CF_Email=${CF_AccountEmail}
+ ~/.acme.sh/acme.sh --issue --dns dns_cf -d ${CF_Domain} -d *.${CF_Domain} --log
+ if [ $? -ne 0 ]; then
+ LOGE "issue cert failed,exit"
+ rm -rf ~/.acme.sh/${CF_Domain}
+ exit 1
+ else
+ LOGI "issue cert succeed,installing..."
+ fi
+ ~/.acme.sh/acme.sh --installcert -d ${CF_Domain} -d *.${CF_Domain} --ca-file /root/cert/ca.cer \
+ --cert-file /root/cert/${CF_Domain}.cer --key-file /root/cert/${CF_Domain}.key \
+ --fullchain-file /root/cert/fullchain.cer
+ if [ $? -ne 0 ]; then
+ LOGE "install cert failed,exit"
+ rm -rf ~/.acme.sh/${CF_Domain}
+ exit 1
+ else
+ LOGI "install cert succeed,enable auto renew..."
+ fi
+ ~/.acme.sh/acme.sh --upgrade --auto-upgrade
+ if [ $? -ne 0 ]; then
+ LOGE "enable auto renew failed,exit"
+ ls -lah cert
+ chmod 755 $certPath
+ exit 1
+ else
+ LOGI "enable auto renew succeed,cert details:"
+ ls -lah cert
+ chmod 755 $certPath
+ fi
+ else
+ show_menu
+ fi
+}
+
+#add for cron jobs,including sync geo data,check logs and restart x-ui
+cron_jobs() {
+ clear
+ echo -e "
+ ${green}x-ui cron jobs${plain}
+ ${green}0.${plain} return main menu
+ ${green}1.${plain} enable automatically update geo data
+ ${green}2.${plain} disable automatically update geo data
+ ${green}3.${plain} enable automatically clear xray log
+ ${green}4.${plain} disable automatically clear xray log
+ "
+ echo && read -p "plz input your choice [0-4]: " num
+ case "${num}" in
+ 0)
+ show_menu
+ ;;
+ 1)
+ enable_auto_update_geo
+ ;;
+ 2)
+ disable_auto_update_geo
+ ;;
+ 3)
+ enable_auto_clear_log
+ ;;
+ 4)
+ disable_auto_clear_log
+ ;;
+ *)
+ LOGE "plz input a valid choice [0-4]"
+ ;;
+ esac
+}
+
+#update geo data
+update_geo() {
+ #back up first
+ mv ${PATH_FOR_GEO_IP} ${PATH_FOR_GEO_IP}.bak
+ #update data
+ curl -s -L -o ${PATH_FOR_GEO_IP} ${URL_FOR_GEO_IP}
+ if [[ $? -ne 0 ]]; then
+ echo "update geoip.dat failed"
+ mv ${PATH_FOR_GEO_IP}.bak ${PATH_FOR_GEO_IP}
+ else
+ echo "update geoip.dat succeed"
+ rm -f ${PATH_FOR_GEO_IP}.bak
+ fi
+ mv ${PATH_FOR_GEO_SITE} ${PATH_FOR_GEO_SITE}.bak
+ curl -s -L -o ${PATH_FOR_GEO_SITE} ${URL_FOR_GEO_SITE}
+ if [[ $? -ne 0 ]]; then
+ echo "update geosite.dat failed"
+ mv ${PATH_FOR_GEO_SITE}.bak ${PATH_FOR_GEO_SITE}
+ else
+ echo "update geosite.dat succeed"
+ rm -f ${PATH_FOR_GEO_SITE}.bak
+ fi
+ #restart x-ui
+ systemctl restart x-ui
+}
+
+enable_auto_update_geo() {
+ LOGI "enable automatically update geo data..."
+ crontab -l >/tmp/crontabTask.tmp
+ echo "00 4 */2 * * x-ui geo > /dev/null" >>/tmp/crontabTask.tmp
+ crontab /tmp/crontabTask.tmp
+ rm /tmp/crontabTask.tmp
+ LOGI "enable automatically update geo data succeed"
+}
+
+disable_auto_update_geo() {
+ crontab -l | grep -v "x-ui geo" | crontab -
+ if [[ $? -ne 0 ]]; then
+ LOGI "cancel x-ui automatically update geo data failed"
+ else
+ LOGI "cancel x-ui automatically update geo data succeed"
+ fi
+}
+
+#clear xray log,need enable log in config template
+#here we need input an absolute path for log
+clear_log() {
+ LOGI "clear xray logs..."
+ local filePath=''
+ if [[ $# -gt 0 ]]; then
+ filePath=$1
+ else
+ LOGE "invalid file path,will exit"
+ exit 1
+ fi
+ LOGI "log file:${filePath}"
+ if [[ ! -f ${filePath} ]]; then
+ LOGE "clear xray log failed,${filePath} didn't exist,plz check it"
+ exit 1
+ fi
+ fileSize=$(ls -la ${filePath} --block-size=M | awk '{print $5}' | awk -F 'M' '{print$1}')
+ if [[ ${fileSize} -gt ${DEFAULT_LOG_FILE_DELETE_TRIGGER} ]]; then
+ rm $1
+ if [[ $? -ne 0 ]]; then
+ LOGE "clear xray log :${filePath} failed"
+ else
+ LOGI "clear xray log :${filePath} succeed"
+ systemctl restart x-ui
+ fi
+ else
+ LOGI "current size of xray log is:${fileSize}M,smaller that ${DEFAULT_LOG_FILE_DELETE_TRIGGER}M,won't clear"
+ fi
+}
+
+#enable auto delete log,need file path as
+enable_auto_clear_log() {
+ LOGI "enable automatically clear xray logs..."
+ local accessfilePath=''
+ local errorfilePath=''
+ accessfilePath=$(cat ${PATH_FOR_CONFIG} | jq .log.access | tr -d '"')
+ errorfilePath=$(cat ${PATH_FOR_CONFIG} | jq .log.error | tr -d '"')
+ if [[ ! -n ${accessfilePath} && ! -n ${errorfilePath} ]]; then
+ LOGI "current configuration didn't set valid logs,will exited"
+ exit 1
+ fi
+ if [[ -f ${accessfilePath} ]]; then
+ crontab -l >/tmp/crontabTask.tmp
+ echo "30 4 */2 * * x-ui clear ${accessfilePath} > /dev/null" >>/tmp/crontabTask.tmp
+ crontab /tmp/crontabTask.tmp
+ rm /tmp/crontabTask.tmp
+ LOGI "enable automatically clear xray log:${accessfilePath} succeed"
+ else
+ LOGE "accesslog didn't existed,won't automatically clear it"
+ fi
+
+ if [[ -f ${errorfilePath} ]]; then
+ crontab -l >/tmp/crontabTask.tmp
+ echo "30 4 */2 * * x-ui clear ${errorfilePath} > /dev/null" >>/tmp/crontabTask.tmp
+ crontab /tmp/crontabTask.tmp
+ rm /tmp/crontabTask.tmp
+ LOGI "enable automatically clear xray log:${errorfilePath} succeed"
+ else
+ LOGE "errorlog didn't existed,won't automatically clear it"
+ fi
+}
+
+#disable auto dlete log
+disable_auto_clear_log() {
+ crontab -l | grep -v "x-ui clear" | crontab -
+ if [[ $? -ne 0 ]]; then
+ LOGI "cancel automatically clear xray logs failed"
+ else
+ LOGI "cancel automatically clear xray logs succeed"
+ fi
+}
+
+show_usage() {
+ echo "x-ui control menu usages: "
+ echo "------------------------------------------"
+ echo -e "x-ui - Enter control menu"
+ echo -e "x-ui start - Start x-ui "
+ echo -e "x-ui stop - Stop x-ui "
+ echo -e "x-ui restart - Restart x-ui "
+ echo -e "x-ui status - Show x-ui status"
+ echo -e "x-ui enable - Enable x-ui on system startup"
+ echo -e "x-ui disable - Disable x-ui on system startup"
+ echo -e "x-ui log - Check x-ui logs"
+ echo -e "x-ui update - Update x-ui "
+ echo -e "x-ui install - Install x-ui "
+ echo -e "x-ui uninstall - Uninstall x-ui "
+ echo "x-ui geo - Update x-ui geo "
+ echo "x-ui cron - Cron x-ui jobs"
+ echo "------------------------------------------"
+}
+
+show_menu() {
+ echo -e "
+ ${green}x-ui control menu${plain}
+ ${green}0.${plain} exit
+————————————————
+ ${green}1.${plain} install x-ui
+ ${green}2.${plain} update x-ui
+ ${green}3.${plain} uninstall x-ui
+————————————————
+ ${green}4.${plain} reset username
+ ${green}5.${plain} reset panel
+ ${green}6.${plain} reset panel port
+ ${green}7.${plain} check panel info
+————————————————
+ ${green}8.${plain} start x-ui
+ ${green}9.${plain} stop x-ui
+ ${green}10.${plain} restart x-ui
+ ${green}11.${plain} check x-ui status
+ ${green}12.${plain} check x-ui logs
+————————————————
+ ${green}13.${plain} enable x-ui on system startup
+ ${green}14.${plain} disable x-ui on system startup
+————————————————
+ ${green}15.${plain} enable bbr
+ ${green}16.${plain} issuse certs
+ ${green}17.${plain} x-ui cron jobs
+ "
+ show_status
+ echo && read -p "please input a legal number[0-16],input 7 for checking login info:" num
+
+ case "${num}" in
+ 0)
+ exit 0
+ ;;
+ 1)
+ check_uninstall && install
+ ;;
+ 2)
+ check_install && update
+ ;;
+ 3)
+ check_install && uninstall
+ ;;
+ 4)
+ check_install && reset_user
+ ;;
+ 5)
+ check_install && reset_config
+ ;;
+ 6)
+ check_install && set_port
+ ;;
+ 7)
+ check_install && check_config
+ ;;
+ 8)
+ check_install && start
+ ;;
+ 9)
+ check_install && stop
+ ;;
+ 10)
+ check_install && restart
+ ;;
+ 11)
+ check_install && status
+ ;;
+ 12)
+ check_install && show_log
+ ;;
+ 13)
+ check_install && enable
+ ;;
+ 14)
+ check_install && disable
+ ;;
+ 15)
+ install_bbr
+ ;;
+ 16)
+ ssl_cert_issue
+ ;;
+ 17)
+ check_install && cron_jobs
+ ;;
+ *)
+ LOGE "please input a legal number[0-17],input 7 for checking login info"
+ ;;
+ esac
+}
+
+if [[ $# > 0 ]]; then
+ case $1 in
+ "start")
+ check_install 0 && start 0
+ ;;
+ "stop")
+ check_install 0 && stop 0
+ ;;
+ "restart")
+ check_install 0 && restart 0
+ ;;
+ "status")
+ check_install 0 && status 0
+ ;;
+ "enable")
+ check_install 0 && enable 0
+ ;;
+ "disable")
+ check_install 0 && disable 0
+ ;;
+ "log")
+ check_install 0 && show_log 0
+ ;;
+ "v2-ui")
+ check_install 0 && migrate_v2_ui 0
+ ;;
+ "update")
+ check_install 0 && update 0
+ ;;
+ "install")
+ check_uninstall 0 && install 0
+ ;;
+ "uninstall")
+ check_install 0 && uninstall 0
+ ;;
+ "geo")
+ check_install 0 && update_geo
+ ;;
+ "clear")
+ check_install 0 && clear_log $2
+ ;;
+ "cron")
+ check_install && cron_jobs
+ ;;
+ *) show_usage ;;
+ esac
+else
+ show_menu
+fi