From edbb8b37d2828aba2369f9a3999c8ca26eba5552 Mon Sep 17 00:00:00 2001 From: franzkafkayu Date: Thu, 30 Jun 2022 18:55:59 -0700 Subject: [PATCH 01/84] update --- README.md | 175 +++++++++++---------- README_EN.md | 98 ++++++++++++ media/2022-04-04_141259.png | Bin 0 -> 19600 bytes media/bda84fbc2ede834deaba1c173a932223.png | Bin 0 -> 26320 bytes media/d13ffd6a73f938d1037d0708e31433bf.png | Bin 0 -> 23148 bytes 5 files changed, 194 insertions(+), 79 deletions(-) create mode 100644 README_EN.md create mode 100644 media/2022-04-04_141259.png create mode 100644 media/bda84fbc2ede834deaba1c173a932223.png create mode 100644 media/d13ffd6a73f938d1037d0708e31433bf.png diff --git a/README.md b/README.md index cc1b9d9a97..6498b76ee8 100644 --- a/README.md +++ b/README.md @@ -1,79 +1,96 @@ -# 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 - -[![Stargazers over time](https://starchart.cc/vaxilu/x-ui.svg)](https://starchart.cc/vaxilu/x-ui) +# x-ui +CN|[EN](./README_EN.md) +支持多协议多用户的 xray 面板 +具体使用教程可以参考个人博客文章[链接](https://coderfan.net/how-to-use-x-ui-pannel-to-set-up-proxies-for-bypassing-gfw.html) +欢迎大家使用并反馈意见或提交Pr,帮助项目更好的改善~ + +# 功能介绍 + +- 系统状态监控 +- 支持多用户多协议,网页可视化操作 +- 支持的协议:vmess、vless、trojan、shadowsocks、dokodemo-door、socks、http +- 支持配置更多传输配置 +- 流量统计,限制流量,限制到期时间 +- 可自定义 xray 配置模板 +- 支持 https 访问面板(自备域名 + ssl 证书) +- 支持一键SSL证书申请且自动续签 +- Telegram bot通知、控制功能 +- 更多高级配置项,详见面板 + +具体使用、配置细节可参考[WIKI](https://github.com/FranzKafkaYu/x-ui/wiki) +# 安装 +在安装前请确保你的系统支持`bash`和`curl`,且系统网络正常 + +``` +bash <(curl -Ls https://raw.githubusercontent.com/FranzKafkaYu/x-ui/master/install.sh) +``` + +如果你的系统版本比较老旧,安装后报错:`GLIBC_2.28 not found`,请使用如下命令安装0.3.3.9版本 + +``` +bash <(curl -Ls https://raw.githubusercontent.com/FranzKafkaYu/x-ui/master/install.sh) 0.3.3.9 +``` + +但该版本会在切换xray内核时报错,建议尽快升级系统 +## 快捷方式 +安装成功后,通过键入`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]: +``` +## 建议系统 + +- CentOS 7+ +- Ubuntu 16+ +- Debian 8+ + +# 变更记录 + +- 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 + +[CoderfanBaby](https://t.me/CoderfanBaby) +[FranzKafka‘sPrivateGroup](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) + +## Stargazers over time + +[![Stargazers over time](https://starchart.cc/FranzKafkaYu/x-ui.svg)](https://starchart.cc/FranzKafkaYu/x-ui) diff --git a/README_EN.md b/README_EN.md new file mode 100644 index 0000000000..7a52792afb --- /dev/null +++ b/README_EN.md @@ -0,0 +1,98 @@ +# x-ui +[CN](./README.md)| EN +X-UI is a webUI pannel 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 +For some basic usages,please visit my [blog post](https://coderfan.net/how-to-use-x-ui-pannel-to-set-up-proxies-for-bypassing-gfw.html) + +# changes + +- 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) +``` + +If your system is too old and you got this error:`GLIBC_2.28 not found`,please use the specific version -- 0.3.3.9 + +``` +bash <(curl -Ls https://raw.githubusercontent.com/FranzKafkaYu/x-ui/master/install.sh) 0.3.3.9 +``` + +But this may cause some unexpected errors,plz upgrade you system as soon as possible + +## shortcut +After Installation,you can input `x-ui`to enter control menu,current menu details: +``` + 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]: +``` + +## Suggested system as follows: +- CentOS 7+ +- Ubuntu 16+ +- Debian 8+ + +# telegram + +[CoderfanBaby](https://t.me/CoderfanBaby) +[FranzKafka‘sPrivateGroup](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) + +## Stargazers over time + +[![Stargazers over time](https://starchart.cc/FranzKafkaYu/x-ui.svg)](https://starchart.cc/FranzKafkaYu/x-ui) diff --git a/media/2022-04-04_141259.png b/media/2022-04-04_141259.png new file mode 100644 index 0000000000000000000000000000000000000000..aaa46644316922b3608868434219251aeab33ac1 GIT binary patch literal 19600 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 X>Fc+MxPZ6P{H1Y6=XTC5bKm~~?+6)+ literal 0 HcmV?d00001 diff --git a/media/d13ffd6a73f938d1037d0708e31433bf.png b/media/d13ffd6a73f938d1037d0708e31433bf.png new file mode 100644 index 0000000000000000000000000000000000000000..b08277aaf570a347d1906e4482ade464d500d008 GIT binary patch literal 23148 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 Date: Fri, 1 Jul 2022 10:11:15 +0800 Subject: [PATCH 02/84] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6498b76ee8..92a691d81a 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ -# x-ui +# X-UI CN|[EN](./README_EN.md) +> ⚠️ 鉴于某些人喜欢在我的代码基础上添加私货,自此不再提供源码,介意者请勿使用! + 支持多协议多用户的 xray 面板 具体使用教程可以参考个人博客文章[链接](https://coderfan.net/how-to-use-x-ui-pannel-to-set-up-proxies-for-bypassing-gfw.html) 欢迎大家使用并反馈意见或提交Pr,帮助项目更好的改善~ From f781025a479e44675d3c623a49efd53ddb3a837b Mon Sep 17 00:00:00 2001 From: Yu FranzKafka Date: Fri, 1 Jul 2022 10:15:48 +0800 Subject: [PATCH 03/84] Update README_EN.md --- README_EN.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README_EN.md b/README_EN.md index 7a52792afb..3f64dfc86a 100644 --- a/README_EN.md +++ b/README_EN.md @@ -1,4 +1,6 @@ -# x-ui +# X-UI +> ⚠️For some reason,the source code is no longer provided, please do not use it if you mind this ~ + [CN](./README.md)| EN X-UI is a webUI pannel 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 From 88166ced6a4c52919578da97d8a49b75117666f7 Mon Sep 17 00:00:00 2001 From: FranzKafkayu Date: Sun, 3 Jul 2022 01:00:43 +0800 Subject: [PATCH 04/84] Update shell script --- install.sh | 57 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 16 deletions(-) diff --git a/install.sh b/install.sh index 205cffde43..f75491cb11 100644 --- a/install.sh +++ b/install.sh @@ -32,17 +32,17 @@ fi arch=$(arch) if [[ $arch == "x86_64" || $arch == "x64" || $arch == "amd64" ]]; then - arch="amd64" + 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 @@ -79,25 +79,48 @@ install_base() { 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}" + echo -e "${red}如属于全新安装,默认网页端口为 ${green}54321${plain},用户名与密码均为 ${green}admin${plain},请及时修改" + echo -e "${red}如属于版本升级,则保留之前设置项,登录方式保持不变,可输入x-ui后键入数字7查看登录信息${plain}" + fi +} + 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 -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}检测 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 +138,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 - 显示管理菜单 (功能更多)" From c33137529911a333cbd7552164738c29f3446522 Mon Sep 17 00:00:00 2001 From: FranzKafkayu Date: Sun, 3 Jul 2022 02:05:29 +0800 Subject: [PATCH 05/84] Upload shell scripts --- x-ui.sh | 295 +++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 218 insertions(+), 77 deletions(-) diff --git a/x-ui.sh b/x-ui.sh index dad3f8b031..303a9100c8 100644 --- a/x-ui.sh +++ b/x-ui.sh @@ -5,8 +5,20 @@ green='\033[0;32m' yellow='\033[0;33m' plain='\033[0m' +#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 +36,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 +51,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 +94,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 +107,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 +171,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 +196,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 +217,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 +239,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 +258,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 +271,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 +302,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 +331,7 @@ check_enabled() { if [[ x"${temp}" == x"enabled" ]]; then return 0 else - return 1; + return 1 fi } @@ -318,7 +339,7 @@ check_uninstall() { check_status if [[ $? != 2 ]]; then echo "" - echo -e "${red}面板已安装,请不要重复安装${plain}" + LOGE "面板已安装,请不要重复安装" if [[ $# == 0 ]]; then before_show_menu fi @@ -332,7 +353,7 @@ check_install() { check_status if [[ $? == 2 ]]; then echo "" - echo -e "${red}请先安装面板${plain}" + LOGE "请先安装面板" if [[ $# == 0 ]]; then before_show_menu fi @@ -345,16 +366,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 +408,91 @@ show_xray_status() { fi } +ssl_cert_issue() { + 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 + cd ~ + LOGI "安装Acme脚本" + curl https://get.acme.sh | sh + if [ $? -ne 0 ]; then + LOGE "安装acme脚本失败" + exit 1 + fi + CF_Domain="" + CF_GlobalKey="" + CF_AccountEmail="" + certPath=/root/cert + if [ ! -d "$certPath" ]; then + mkdir $certPath + else + rm -rf $certPath + 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 | tail -1 | awk '{print $1}') + if [ ${currentCert} == ${CF_Domain} ]; 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 "证书签发失败,脚本退出" + 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 "证书安装失败,脚本退出" + 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 +} + show_usage() { echo "x-ui 管理脚本使用方法: " echo "------------------------------------------" @@ -416,83 +523,117 @@ 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申请) " show_status - echo && read -p "请输入选择 [0-14]: " num + echo && read -p "请输入选择 [0-16]: " 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 + ;; + *) + LOGE "请输入正确的数字 [0-16]" ;; 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 + "stop") + check_install 0 && stop 0 ;; - "restart") check_install 0 && restart 0 + "restart") + check_install 0 && restart 0 ;; - "status") check_install 0 && status 0 + "status") + check_install 0 && status 0 ;; - "enable") check_install 0 && enable 0 + "enable") + check_install 0 && enable 0 ;; - "disable") check_install 0 && disable 0 + "disable") + check_install 0 && disable 0 ;; - "log") check_install 0 && show_log 0 + "log") + check_install 0 && show_log 0 ;; - "v2-ui") check_install 0 && migrate_v2_ui 0 + "v2-ui") + check_install 0 && migrate_v2_ui 0 ;; - "update") check_install 0 && update 0 + "update") + check_install 0 && update 0 ;; - "install") check_uninstall 0 && install 0 + "install") + check_uninstall 0 && install 0 ;; - "uninstall") check_install 0 && uninstall 0 + "uninstall") + check_install 0 && uninstall 0 ;; - *) show_usage + *) show_usage ;; esac else show_menu From 82cc83eaeb2365f02ae84c623d046c0db4b1a5bf Mon Sep 17 00:00:00 2001 From: FranzKafkayu Date: Sun, 3 Jul 2022 20:45:49 +0800 Subject: [PATCH 06/84] Update README.md --- README.md | 4 ++-- README_EN.md | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 92a691d81a..dbe0935f8c 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@ # X-UI CN|[EN](./README_EN.md) -> ⚠️ 鉴于某些人喜欢在我的代码基础上添加私货,自此不再提供源码,介意者请勿使用! - + 支持多协议多用户的 xray 面板 具体使用教程可以参考个人博客文章[链接](https://coderfan.net/how-to-use-x-ui-pannel-to-set-up-proxies-for-bypassing-gfw.html) 欢迎大家使用并反馈意见或提交Pr,帮助项目更好的改善~ @@ -75,6 +74,7 @@ xray 状态: 运行 # 变更记录 +- 2022.07.03:重构Telegram bot功能,指令控制不再需要键盘输入;增加Trojan底层传输配置 - 2022.06.19:增加Shadowsocs2022新的Cipher,增加节点搜索、一键清除流量功能 - 2022.05.14:增加Telegram bot Command控制功能,支持关闭/开启/删除节点等 - 2022.04.25:增加SSH登录提醒 diff --git a/README_EN.md b/README_EN.md index 3f64dfc86a..203d83cb9f 100644 --- a/README_EN.md +++ b/README_EN.md @@ -1,5 +1,4 @@ # X-UI -> ⚠️For some reason,the source code is no longer provided, please do not use it if you mind this ~ [CN](./README.md)| EN X-UI is a webUI pannel based on Xray-core which supports multi protocols and multi users From f61b7a8549016f53d100872cd630c60f60e56076 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka Date: Wed, 6 Jul 2022 11:41:04 +0800 Subject: [PATCH 07/84] Update README.md --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index dbe0935f8c..64faa1172c 100644 --- a/README.md +++ b/README.md @@ -20,11 +20,12 @@ CN|[EN](./README_EN.md) 具体使用、配置细节可参考[WIKI](https://github.com/FranzKafkaYu/x-ui/wiki) # 安装 -在安装前请确保你的系统支持`bash`和`curl`,且系统网络正常 +在安装前请确保你的系统支持`bash`环境,且系统网络正常 +⚡从原版升级也可使用该命令,数据不会丢失⚡ ``` bash <(curl -Ls https://raw.githubusercontent.com/FranzKafkaYu/x-ui/master/install.sh) -``` +``` 如果你的系统版本比较老旧,安装后报错:`GLIBC_2.28 not found`,请使用如下命令安装0.3.3.9版本 @@ -32,7 +33,8 @@ bash <(curl -Ls https://raw.githubusercontent.com/FranzKafkaYu/x-ui/master/insta bash <(curl -Ls https://raw.githubusercontent.com/FranzKafkaYu/x-ui/master/install.sh) 0.3.3.9 ``` -但该版本会在切换xray内核时报错,建议尽快升级系统 +但该版本会在切换xray内核时报错,建议尽快升级系统 + ## 快捷方式 安装成功后,通过键入`x-ui`进入控制选项菜单,目前菜单内容: ``` From 678ac92c56ac0ad6d53c3660107626814643ca69 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka Date: Wed, 6 Jul 2022 11:41:55 +0800 Subject: [PATCH 08/84] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 64faa1172c..a726f9fabb 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ CN|[EN](./README_EN.md) 具体使用、配置细节可参考[WIKI](https://github.com/FranzKafkaYu/x-ui/wiki) # 安装 在安装前请确保你的系统支持`bash`环境,且系统网络正常 + ⚡从原版升级也可使用该命令,数据不会丢失⚡ ``` @@ -79,7 +80,7 @@ xray 状态: 运行 - 2022.07.03:重构Telegram bot功能,指令控制不再需要键盘输入;增加Trojan底层传输配置 - 2022.06.19:增加Shadowsocs2022新的Cipher,增加节点搜索、一键清除流量功能 - 2022.05.14:增加Telegram bot Command控制功能,支持关闭/开启/删除节点等 -- 2022.04.25:增加SSH登录提醒 +- 2022.04.25:增加SSH登录提醒、面板登录提醒 - 2022.04.23:增加更多Telegram bot提醒功能 - 2022.04.16:增加面板设置Telegram bot功能 - 2022.04.12:优化Telegram Bot通知提醒 From ad832bda7d7e93bf611b4c5be269570939112a6d Mon Sep 17 00:00:00 2001 From: Yu FranzKafka Date: Wed, 13 Jul 2022 01:07:13 +0800 Subject: [PATCH 09/84] Update README.md --- README.md | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index a726f9fabb..d91d24ddb7 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ # X-UI CN|[EN](./README_EN.md) -支持多协议多用户的 xray 面板 +支持多协议多用户的 xray 面板,究极缝合怪 +通过内置的Telegram bot方便快捷地进行管理你的代理服务 具体使用教程可以参考个人博客文章[链接](https://coderfan.net/how-to-use-x-ui-pannel-to-set-up-proxies-for-bypassing-gfw.html) 欢迎大家使用并反馈意见或提交Pr,帮助项目更好的改善~ @@ -19,7 +20,7 @@ CN|[EN](./README_EN.md) - 更多高级配置项,详见面板 具体使用、配置细节可参考[WIKI](https://github.com/FranzKafkaYu/x-ui/wiki) -# 安装 +# 一键安装 在安装前请确保你的系统支持`bash`环境,且系统网络正常 ⚡从原版升级也可使用该命令,数据不会丢失⚡ @@ -36,7 +37,16 @@ bash <(curl -Ls https://raw.githubusercontent.com/FranzKafkaYu/x-ui/master/insta 但该版本会在切换xray内核时报错,建议尽快升级系统 -## 快捷方式 +# 效果预览 +`面板使用`: +![image](https://user-images.githubusercontent.com/38254177/178550844-2b77e853-184c-4e23-9d69-6ff53b9857b4.png) +`Bot使用`: +![image](https://user-images.githubusercontent.com/38254177/178551055-893936b7-b75f-4ee8-a773-eee7c6f43f51.png) + + + + +# 快捷方式 安装成功后,通过键入`x-ui`进入控制选项菜单,目前菜单内容: ``` x-ui 面板管理脚本 @@ -77,6 +87,7 @@ xray 状态: 运行 # 变更记录 +- 2022.07.11:增加节点到期提醒、流量预警策略,增加Telegram bot节点复制、获取分享链接等 - 2022.07.03:重构Telegram bot功能,指令控制不再需要键盘输入;增加Trojan底层传输配置 - 2022.06.19:增加Shadowsocs2022新的Cipher,增加节点搜索、一键清除流量功能 - 2022.05.14:增加Telegram bot Command控制功能,支持关闭/开启/删除节点等 @@ -87,8 +98,8 @@ xray 状态: 运行 - 2022.04.06:优化安装/更新流程,增加证书签发功能,添加Telegram bot机器人推送功能 # Telegram -[CoderfanBaby](https://t.me/CoderfanBaby) -[FranzKafka‘sPrivateGroup](https://t.me/franzkafayu) +[订阅频道](https://t.me/CoderfanBaby) +[讨论群组](https://t.me/franzkafayu) # 致谢 From dd6b4906f2fdad734cf7100a1438f6017d9e6ccd Mon Sep 17 00:00:00 2001 From: Yu FranzKafka Date: Thu, 21 Jul 2022 01:08:08 +0800 Subject: [PATCH 10/84] Update README.md --- README.md | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d91d24ddb7..f88c037b8b 100644 --- a/README.md +++ b/README.md @@ -39,9 +39,60 @@ bash <(curl -Ls https://raw.githubusercontent.com/FranzKafkaYu/x-ui/master/insta # 效果预览 `面板使用`: +
+点击查看效果预览 + ![image](https://user-images.githubusercontent.com/38254177/178550844-2b77e853-184c-4e23-9d69-6ff53b9857b4.png) +
+ `Bot使用`: -![image](https://user-images.githubusercontent.com/38254177/178551055-893936b7-b75f-4ee8-a773-eee7c6f43f51.png) +
+点击查看效果预览 + +![image](https://user-images.githubusercontent.com/38254177/178551055-893936b7-b75f-4ee8-a773-eee7c6f43f51.png) + +
+ +`流量提醒`: +
+点击查看效果预览 + +![image](https://user-images.githubusercontent.com/38254177/180039760-dc987a30-e21c-49a3-8e03-19666566a822.png) + +
+ +`SSH提醒`: +
+点击查看效果预览 + +![image](https://user-images.githubusercontent.com/38254177/180040129-2ec1a7c0-abd3-41dc-aab0-8cd22415c943.png) + +
+ +`限额提醒`: +
+点击查看效果预览 + +![image](https://user-images.githubusercontent.com/38254177/180040521-af6e9ef8-d7e5-44e8-834e-25b3b8e3e1b5.png) + +
+ +`到期提醒`: +
+点击查看效果预览 + +![image](https://user-images.githubusercontent.com/38254177/180041690-90ca4b1f-3a2d-470b-bc0c-eca9261a739a.png) + +
+ +`登录提醒`: +
+点击查看效果预览 + +![image](https://user-images.githubusercontent.com/38254177/180040913-b8bf2fe1-6fc1-43ab-a683-ae23db1866b2.png) +![image](https://user-images.githubusercontent.com/38254177/180041179-a5f4cd52-a1ba-4aa9-abb2-b94e36722385.png) + +
@@ -87,6 +138,7 @@ xray 状态: 运行 # 变更记录 +- 2022.07.21:增加节点IP接入变化提醒,Web面板增加停止/重启xray功能,优化部分翻译 - 2022.07.11:增加节点到期提醒、流量预警策略,增加Telegram bot节点复制、获取分享链接等 - 2022.07.03:重构Telegram bot功能,指令控制不再需要键盘输入;增加Trojan底层传输配置 - 2022.06.19:增加Shadowsocs2022新的Cipher,增加节点搜索、一键清除流量功能 From 05a206b2b4ac0131323f0c0b141502e87662d390 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka Date: Thu, 21 Jul 2022 01:21:05 +0800 Subject: [PATCH 11/84] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f88c037b8b..0d95f22292 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # X-UI CN|[EN](./README_EN.md) - + +> ⚠️ 该项目仅作为学习golang的实验性项目,请勿用于生产环境! + 支持多协议多用户的 xray 面板,究极缝合怪 通过内置的Telegram bot方便快捷地进行管理你的代理服务 具体使用教程可以参考个人博客文章[链接](https://coderfan.net/how-to-use-x-ui-pannel-to-set-up-proxies-for-bypassing-gfw.html) From cce9a340477d8dd95d96aa33b0021b3220f24834 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka Date: Thu, 21 Jul 2022 09:05:59 +0800 Subject: [PATCH 12/84] Update README.md --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0d95f22292..2feac66f7b 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,13 @@ # X-UI CN|[EN](./README_EN.md) -> ⚠️ 该项目仅作为学习golang的实验性项目,请勿用于生产环境! +> 该项目仅作为学习golang的实验性项目,请勿用于生产环境 支持多协议多用户的 xray 面板,究极缝合怪 通过内置的Telegram bot方便快捷地进行管理你的代理服务 具体使用教程可以参考个人博客文章[链接](https://coderfan.net/how-to-use-x-ui-pannel-to-set-up-proxies-for-bypassing-gfw.html) -欢迎大家使用并反馈意见或提交Pr,帮助项目更好的改善~ +欢迎大家使用并反馈意见或提交Pr,帮助项目更好的改善 +如果您觉得本项目对您有所帮助,不妨给个star:star2:支持我~ # 功能介绍 @@ -21,7 +22,7 @@ CN|[EN](./README_EN.md) - Telegram bot通知、控制功能 - 更多高级配置项,详见面板 -具体使用、配置细节可参考[WIKI](https://github.com/FranzKafkaYu/x-ui/wiki) +:bulb:具体**使用、配置细节以及问题排查**可参考[WIKI](https://github.com/FranzKafkaYu/x-ui/wiki) # 一键安装 在安装前请确保你的系统支持`bash`环境,且系统网络正常 From 11d49bec8bacc18ef212b5e5283f1a2f8cd0ba06 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka Date: Sun, 24 Jul 2022 10:26:20 +0800 Subject: [PATCH 13/84] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2feac66f7b..db92310195 100644 --- a/README.md +++ b/README.md @@ -140,7 +140,7 @@ xray 状态: 运行 - Debian 8+ # 变更记录 - +- 2022.07.24:增加自动生成面板根路径,节点流量自动重置功能,设备iP接入变化通知功能 - 2022.07.21:增加节点IP接入变化提醒,Web面板增加停止/重启xray功能,优化部分翻译 - 2022.07.11:增加节点到期提醒、流量预警策略,增加Telegram bot节点复制、获取分享链接等 - 2022.07.03:重构Telegram bot功能,指令控制不再需要键盘输入;增加Trojan底层传输配置 From 6d67708b3a606f657108f84fbf6c97296ba88657 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka Date: Sun, 24 Jul 2022 10:31:27 +0800 Subject: [PATCH 14/84] Update README.md --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index db92310195..2d4a809ba8 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,10 @@ bash <(curl -Ls https://raw.githubusercontent.com/FranzKafkaYu/x-ui/master/insta
点击查看效果预览 -![image](https://user-images.githubusercontent.com/38254177/178550844-2b77e853-184c-4e23-9d69-6ff53b9857b4.png) +![image](https://user-images.githubusercontent.com/38254177/180629631-f76a05c8-ecf0-4685-bbc7-a7058747d213.png) +![image](https://user-images.githubusercontent.com/38254177/180629662-b7a325fc-1ebb-47c9-992c-1e7c758a326b.png) + +
`Bot使用`: From bb2217950f6f4ecc8dd29df7bc40d92a0a92b311 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka Date: Sun, 24 Jul 2022 10:36:21 +0800 Subject: [PATCH 15/84] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2d4a809ba8..aba040a9d9 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ CN|[EN](./README_EN.md) > 该项目仅作为学习golang的实验性项目,请勿用于生产环境 支持多协议多用户的 xray 面板,究极缝合怪 -通过内置的Telegram bot方便快捷地进行管理你的代理服务 +通过免费的Telegram bot方便快捷地进行管理你的代理服务 具体使用教程可以参考个人博客文章[链接](https://coderfan.net/how-to-use-x-ui-pannel-to-set-up-proxies-for-bypassing-gfw.html) 欢迎大家使用并反馈意见或提交Pr,帮助项目更好的改善 如果您觉得本项目对您有所帮助,不妨给个star:star2:支持我~ @@ -13,7 +13,7 @@ CN|[EN](./README_EN.md) - 系统状态监控 - 支持多用户多协议,网页可视化操作 -- 支持的协议:vmess、vless、trojan、shadowsocks、dokodemo-door、socks、http +- 支持的协议:vmess、vless、trojan、shadowsocks、shadowsocks 2022、dokodemo-door、socks、http - 支持配置更多传输配置 - 流量统计,限制流量,限制到期时间 - 可自定义 xray 配置模板 From e15ca7f06720535bab462e0ece59e8fd5d78ea2a Mon Sep 17 00:00:00 2001 From: Yu FranzKafka Date: Tue, 26 Jul 2022 17:05:40 +0800 Subject: [PATCH 16/84] Update README.md --- README.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index aba040a9d9..f641ab8b58 100644 --- a/README.md +++ b/README.md @@ -7,22 +7,29 @@ CN|[EN](./README_EN.md) 通过免费的Telegram bot方便快捷地进行管理你的代理服务 具体使用教程可以参考个人博客文章[链接](https://coderfan.net/how-to-use-x-ui-pannel-to-set-up-proxies-for-bypassing-gfw.html) 欢迎大家使用并反馈意见或提交Pr,帮助项目更好的改善 -如果您觉得本项目对您有所帮助,不妨给个star:star2:支持我~ +如果您觉得本项目对您有所帮助,不妨给个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:具体**使用、配置细节以及问题排查**可参考[WIKI](https://github.com/FranzKafkaYu/x-ui/wiki) +:bulb:具体**使用、配置细节以及问题排查**请点击这里:point_right:[WIKI](https://github.com/FranzKafkaYu/x-ui/wiki):point_left: # 一键安装 在安装前请确保你的系统支持`bash`环境,且系统网络正常 From e63c3d44a6f3db7f846d8e2c95b9d32d14a2b930 Mon Sep 17 00:00:00 2001 From: FranzKafkayu Date: Thu, 28 Jul 2022 21:04:04 +0800 Subject: [PATCH 17/84] Update x-ui.sh for standalone mode cert issue --- x-ui.sh | 132 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 126 insertions(+), 6 deletions(-) diff --git a/x-ui.sh b/x-ui.sh index 303a9100c8..20914fd89b 100644 --- a/x-ui.sh +++ b/x-ui.sh @@ -1,4 +1,4 @@ -#!/bin/bash +!/bin/bash red='\033[0;31m' green='\033[0;32m' @@ -408,7 +408,129 @@ 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 "该脚本提供两种方式实现证书签发" + LOGI "方式1:acme standalone mode,需要保持端口开放" + LOGI "方式2:acme DNS API mode,需要提供Cloudflare Global API Key" + LOGI "优先推荐使用方式2进行申请,如方式2无法申请成功,可以再行尝试方式1" + read -p "请选择你想使用的方式": 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() { + #install acme first + install_acme + if [ $? -ne 0 ]; then + LOGE "无法安装acme,请检查错误日志" + exit 1 + 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 + else + rm -rf $certPath + 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 | tail -1 | awk '{print $1}') + if [ ${currentCert} == ${domain} ]; 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 "证书申请失败,原因请参见报错信息" + exit 1 + else + LOGE "证书申请成功,开始安装证书..." + 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 "证书安装失败,脚本退出" + 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脚本申请证书,使用时需保证:" @@ -418,11 +540,9 @@ ssl_cert_issue() { LOGI "4.该脚本申请证书默认安装路径为/root/cert目录" confirm "我已确认以上内容[y/n]" "y" if [ $? -eq 0 ]; then - cd ~ - LOGI "安装Acme脚本" - curl https://get.acme.sh | sh + install_acme if [ $? -ne 0 ]; then - LOGE "安装acme脚本失败" + LOGE "无法安装acme,请检查错误日志" exit 1 fi CF_Domain="" @@ -523,7 +643,7 @@ show_menu() { ${green}4.${plain} 重置用户名密码 ${green}5.${plain} 重置面板设置 ${green}6.${plain} 设置面板端口 - ${green}7.${plain} 查看当前面板设置 + ${green}7.${plain} 查看当前面板信息 ———————————————— ${green}8.${plain} 启动 x-ui ${green}9.${plain} 停止 x-ui From 99cfb5d0264832a2256aed6deb916e7f8cd95957 Mon Sep 17 00:00:00 2001 From: FranzKafkayu Date: Thu, 28 Jul 2022 21:10:50 +0800 Subject: [PATCH 18/84] fix log print --- x-ui.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/x-ui.sh b/x-ui.sh index 20914fd89b..7d6c07f55f 100644 --- a/x-ui.sh +++ b/x-ui.sh @@ -502,12 +502,12 @@ ssl_cert_issue_standalone() { LOGE "证书申请失败,原因请参见报错信息" exit 1 else - LOGE "证书申请成功,开始安装证书..." + 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 + --cert-file /root/cert/${domain}.cer --key-file /root/cert/${domain}.key \ + --fullchain-file /root/cert/fullchain.cer if [ $? -ne 0 ]; then LOGE "证书安装失败,脚本退出" @@ -589,8 +589,8 @@ ssl_cert_issue_by_cloudflare() { 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 + --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 "证书安装失败,脚本退出" exit 1 From af98a18630e8c0405563b30e3231c65a022bd595 Mon Sep 17 00:00:00 2001 From: FranzKafkayu Date: Thu, 28 Jul 2022 21:26:36 +0800 Subject: [PATCH 19/84] Optimize info --- x-ui.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/x-ui.sh b/x-ui.sh index 7d6c07f55f..b55ba73252 100644 --- a/x-ui.sh +++ b/x-ui.sh @@ -415,10 +415,11 @@ ssl_cert_issue() { local method="" echo -E "" LOGD "******使用说明******" - LOGI "该脚本提供两种方式实现证书签发" + LOGI "该脚本提供两种方式实现证书签发,证书安装路径均为/root/cert" LOGI "方式1:acme standalone mode,需要保持端口开放" LOGI "方式2:acme DNS API mode,需要提供Cloudflare Global API Key" - LOGI "优先推荐使用方式2进行申请,如方式2无法申请成功,可以再行尝试方式1" + LOGI "如域名属于免费域名,则推荐使用方式1进行申请" + LOGI "如域名非免费域名且使用Cloudflare进行解析使用方式2进行申请" read -p "请选择你想使用的方式": method LOGI "你所使用的方式为${method}" From 970646a7ae9adb63ee3ac0bdcdb85fc49d3489c0 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka Date: Mon, 1 Aug 2022 09:03:24 +0800 Subject: [PATCH 20/84] Update README.md --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f641ab8b58..21e76a2e45 100644 --- a/README.md +++ b/README.md @@ -149,8 +149,9 @@ xray 状态: 运行 - Ubuntu 16+ - Debian 8+ -# 变更记录 -- 2022.07.24:增加自动生成面板根路径,节点流量自动重置功能,设备iP接入变化通知功能 +# 变更记录 +- 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底层传输配置 From 54ad70fa15b7140529ae495b0cfec1c5c166a7a3 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka Date: Mon, 1 Aug 2022 11:18:36 +0800 Subject: [PATCH 21/84] Update x-ui.sh fix --- x-ui.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-ui.sh b/x-ui.sh index b55ba73252..572ac72a9b 100644 --- a/x-ui.sh +++ b/x-ui.sh @@ -1,4 +1,4 @@ -!/bin/bash +#!/bin/bash red='\033[0;31m' green='\033[0;32m' From c9a7c26ac3c5eb68732d4f6f01a2a3f7985b7d83 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka Date: Thu, 11 Aug 2022 00:39:50 +0800 Subject: [PATCH 22/84] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 21e76a2e45..1e79040784 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ # X-UI CN|[EN](./README_EN.md) -> 该项目仅作为学习golang的实验性项目,请勿用于生产环境 +> 免责声明:该项目仅供个人学习、交流,请勿用于非法用途 +> 使用声明:该项目仅作为学习golang的实验性项目,请勿用于生产环境 支持多协议多用户的 xray 面板,究极缝合怪 通过免费的Telegram bot方便快捷地进行管理你的代理服务 @@ -150,6 +151,7 @@ xray 状态: 运行 - Debian 8+ # 变更记录 +- 2022.08.11:实现Vmess/Vless/Trojan单端口多用户;增加CPU使用超限提醒 - 2022.07.28:增加acme standalone模式申请证书;增加x-ui自动保活机制;优化编译选项以适配更多系统 - 2022.07.24:增加自动生成面板根路径,节点流量自动重置功能,设备IP接入变化通知功能 - 2022.07.21:增加节点IP接入变化提醒,Web面板增加停止/重启xray功能,优化部分翻译 From b502595740d3173d8cb9c5d9236fad3777411f56 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka Date: Fri, 12 Aug 2022 09:36:36 +0800 Subject: [PATCH 23/84] Update README.md --- README.md | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 1e79040784..e5a184f580 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,10 @@ # X-UI CN|[EN](./README_EN.md) -> 免责声明:该项目仅供个人学习、交流,请勿用于非法用途 -> 使用声明:该项目仅作为学习golang的实验性项目,请勿用于生产环境 +> 免责声明:该项目仅供个人学习、交流,请勿用于非法用途,请勿用于生产环境 -支持多协议多用户的 xray 面板,究极缝合怪 -通过免费的Telegram bot方便快捷地进行管理你的代理服务 +支持单端口多用户、多协议的 xray 面板,究极缝合怪 +通过免费的Telegram bot方便快捷地进行监控、管理你的代理服务 具体使用教程可以参考个人博客文章[链接](https://coderfan.net/how-to-use-x-ui-pannel-to-set-up-proxies-for-bypassing-gfw.html) 欢迎大家使用并反馈意见或提交Pr,帮助项目更好的改善 如果您觉得本项目对您有所帮助,不妨给个star:star2:支持我~ @@ -20,7 +19,7 @@ CN|[EN](./README_EN.md) # 功能介绍 - 系统状态监控 -- 支持多用户多协议,网页可视化操作 +- 支持单端口多用户、多协议,网页可视化操作 - 支持的协议:vmess、vless、trojan、shadowsocks、shadowsocks 2022、dokodemo-door、socks、http - 支持配置更多传输配置:http、tcp、ws、grpc、kcp、quic - 流量统计,限制流量,限制到期时间,一键重置与设备监控 @@ -39,15 +38,6 @@ CN|[EN](./README_EN.md) ``` bash <(curl -Ls https://raw.githubusercontent.com/FranzKafkaYu/x-ui/master/install.sh) ``` - -如果你的系统版本比较老旧,安装后报错:`GLIBC_2.28 not found`,请使用如下命令安装0.3.3.9版本 - -``` -bash <(curl -Ls https://raw.githubusercontent.com/FranzKafkaYu/x-ui/master/install.sh) 0.3.3.9 -``` - -但该版本会在切换xray内核时报错,建议尽快升级系统 - # 效果预览 `面板使用`:
From dc18439b8630044d4c86847655c420e057da1d29 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka Date: Fri, 12 Aug 2022 10:03:17 +0800 Subject: [PATCH 24/84] Update README_EN.md --- README_EN.md | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/README_EN.md b/README_EN.md index 203d83cb9f..9bffb21177 100644 --- a/README_EN.md +++ b/README_EN.md @@ -1,12 +1,18 @@ # X-UI [CN](./README.md)| EN -X-UI is a webUI pannel based on Xray-core which supports multi protocols and multi users +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 -For some basic usages,please visit my [blog post](https://coderfan.net/how-to-use-x-ui-pannel-to-set-up-proxies-for-bypassing-gfw.html) - -# changes - +For some basic usages,please visit my [blog post](https://coderfan.net/how-to-use-x-ui-pannel-to-set-up-proxies-for-bypassing-gfw.html) +If you need more language options ,please open a issue and let me know that + +# changes +- 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 @@ -37,14 +43,6 @@ 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) ``` -If your system is too old and you got this error:`GLIBC_2.28 not found`,please use the specific version -- 0.3.3.9 - -``` -bash <(curl -Ls https://raw.githubusercontent.com/FranzKafkaYu/x-ui/master/install.sh) 0.3.3.9 -``` - -But this may cause some unexpected errors,plz upgrade you system as soon as possible - ## shortcut After Installation,you can input `x-ui`to enter control menu,current menu details: ``` From e505d973ffc403dd53d3408f8939a298346893c0 Mon Sep 17 00:00:00 2001 From: FranzKafkayu Date: Mon, 5 Sep 2022 16:02:33 +0800 Subject: [PATCH 25/84] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=AF=81=E4=B9=A6?= =?UTF-8?q?=E7=94=B3=E8=AF=B7=E6=8F=90=E7=A4=BA=E6=96=87=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- x-ui.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/x-ui.sh b/x-ui.sh index 572ac72a9b..3e3af599c6 100644 --- a/x-ui.sh +++ b/x-ui.sh @@ -420,7 +420,7 @@ ssl_cert_issue() { LOGI "方式2:acme DNS API mode,需要提供Cloudflare Global API Key" LOGI "如域名属于免费域名,则推荐使用方式1进行申请" LOGI "如域名非免费域名且使用Cloudflare进行解析使用方式2进行申请" - read -p "请选择你想使用的方式": method + read -p "请选择你想使用的方式,输入数字1或者2后回车": method LOGI "你所使用的方式为${method}" if [ "${method}" == "1" ]; then @@ -507,8 +507,8 @@ ssl_cert_issue_standalone() { 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 + --cert-file /root/cert/${domain}.cer --key-file /root/cert/${domain}.key \ + --fullchain-file /root/cert/fullchain.cer if [ $? -ne 0 ]; then LOGE "证书安装失败,脚本退出" @@ -590,8 +590,8 @@ ssl_cert_issue_by_cloudflare() { 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 + --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 "证书安装失败,脚本退出" exit 1 From a3bb1acdc8808e44eb0b2472c57dbd64c89f2987 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka Date: Mon, 10 Oct 2022 21:47:58 +0800 Subject: [PATCH 26/84] Update x-ui.sh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 优化证书申请提示文案 --- x-ui.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-ui.sh b/x-ui.sh index 3e3af599c6..566a74c100 100644 --- a/x-ui.sh +++ b/x-ui.sh @@ -486,7 +486,7 @@ ssl_cert_issue_standalone() { LOGI "$certInfo" exit 1 else - LOGI "证书有效性校验通过..." + LOGI "域名合法性校验通过..." fi #get needed port here local WebPort=80 @@ -567,7 +567,7 @@ ssl_cert_issue_by_cloudflare() { LOGI "$certInfo" exit 1 else - LOGI "证书有效性校验通过..." + LOGI "域名合法性校验通过..." fi LOGD "请设置API密钥:" read -p "Input your key here:" CF_GlobalKey From 42f934fbf4df47474746718036d11a2bc2b8ed52 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka Date: Mon, 10 Oct 2022 22:22:46 +0800 Subject: [PATCH 27/84] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=AF=81=E4=B9=A6?= =?UTF-8?q?=E7=AD=BE=E5=8F=91=E5=A4=B1=E8=B4=A5=E5=AF=BC=E8=87=B4=E5=90=8E?= =?UTF-8?q?=E7=BB=AD=E7=94=B3=E8=AF=B7=E6=97=B6=E5=9F=9F=E5=90=8D=E5=90=88?= =?UTF-8?q?=E6=B3=95=E6=80=A7=E6=A0=A1=E9=AA=8C=E5=A4=B1=E8=B4=A5=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- x-ui.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/x-ui.sh b/x-ui.sh index 566a74c100..84cc1c01d5 100644 --- a/x-ui.sh +++ b/x-ui.sh @@ -501,6 +501,7 @@ ssl_cert_issue_standalone() { ~/.acme.sh/acme.sh --issue -d ${domain} --standalone --httpport ${WebPort} if [ $? -ne 0 ]; then LOGE "证书申请失败,原因请参见报错信息" + rm -rf ~/.acme.sh/${domain} exit 1 else LOGI "证书申请成功,开始安装证书..." @@ -512,6 +513,7 @@ ssl_cert_issue_standalone() { if [ $? -ne 0 ]; then LOGE "证书安装失败,脚本退出" + rm -rf ~/.acme.sh/${domain} exit 1 else LOGI "证书安装成功,开启自动更新..." @@ -585,6 +587,7 @@ ssl_cert_issue_by_cloudflare() { ~/.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 "证书签发成功,安装中..." @@ -594,6 +597,7 @@ ssl_cert_issue_by_cloudflare() { --fullchain-file /root/cert/fullchain.cer if [ $? -ne 0 ]; then LOGE "证书安装失败,脚本退出" + rm -rf ~/.acme.sh/${CF_Domain} exit 1 else LOGI "证书安装成功,开启自动更新..." From b4ccca1baf77b8144db5dd8e80d188849b9d8fd4 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka Date: Wed, 19 Oct 2022 10:24:07 +0800 Subject: [PATCH 28/84] Create bug_report.yml --- .github/ISSUE_TEMPLATE/bug_report.yml | 70 +++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000000..30c5f5c1b7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,70 @@ +name: Issue Report +description: "Create a report to help us improve." +body: + - type: pre-requirement + 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'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 + placeholder: Your problem description + validations: + required: true + + - type: textarea + id: version + attributes: + label: Version of x-ui + value: |- +
+ + ```console + $ sing-box version + # Paste output here + ``` + +
+ validations: + required: true + + - type: textarea + id: config + attributes: + label: Server and client configuration file + value: |- +
+ + ```console + # paste json here + ``` + +
+ validations: + required: true + + - type: textarea + id: log + attributes: + label: x-ui log or xray log + value: |- +
+ + ```console + # paste log here + ``` + +
+ validations: + required: true From 13ce290c159738bf50c9102ce3bd1a6949e419bb Mon Sep 17 00:00:00 2001 From: Yu FranzKafka Date: Wed, 19 Oct 2022 10:24:34 +0800 Subject: [PATCH 29/84] Delete ------.md --- .github/ISSUE_TEMPLATE/------.md | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/------.md 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 From e22efd6fd8fd55079085633fcfcdaf5f38009df4 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka Date: Wed, 19 Oct 2022 10:28:12 +0800 Subject: [PATCH 30/84] Update bug_report.yml --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 30c5f5c1b7..5567dca096 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -1,7 +1,7 @@ name: Issue Report description: "Create a report to help us improve." body: - - type: pre-requirement + - type: checkboxes id: terms attributes: label: Welcome From a2515c2bb5a174ec7c1fae7ec81ffd52f49d858c Mon Sep 17 00:00:00 2001 From: Yu FranzKafka Date: Wed, 19 Oct 2022 10:32:39 +0800 Subject: [PATCH 31/84] Update bug_report.yml --- .github/ISSUE_TEMPLATE/bug_report.yml | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 5567dca096..360894c247 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -18,7 +18,7 @@ body: - type: textarea id: problem attributes: - label: Description of the problem + label: Description of the problem,screencshot would be good placeholder: Your problem description validations: required: true @@ -31,7 +31,7 @@ body:
```console - $ sing-box version + $ x-ui version # Paste output here ``` @@ -39,21 +39,6 @@ body: validations: required: true - - type: textarea - id: config - attributes: - label: Server and client configuration file - value: |- -
- - ```console - # paste json here - ``` - -
- validations: - required: true - - type: textarea id: log attributes: From 42a25494b53d6bb027610642913abfcbbdb2cb27 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka Date: Sun, 23 Oct 2022 16:59:36 +0800 Subject: [PATCH 32/84] Support for English --- install_en.sh | 168 +++++++++++ x-ui_en.sh | 763 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 931 insertions(+) create mode 100644 install_en.sh create mode 100644 x-ui_en.sh diff --git a/install_en.sh b/install_en.sh new file mode 100644 index 0000000000..70e098a5f1 --- /dev/null +++ b/install_en.sh @@ -0,0 +1,168 @@ +#!/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}" + echo -e "${red}if this is your first time to install,the default panel port is ${green}54321${plain},username and password both are${green}admin${plain},please change them in time" + echo -e "${red}if this is your upgrade,keep the old settings,if you forgot you login info,you can type x-ui and then type 7 to check${plain}" + 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}.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}.tar.gz + rm x-ui-linux-${arch}.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.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 "----------------------------------------------" +} + +echo -e "${green}excuting...${plain}" +install_base +install_x-ui $1 diff --git a/x-ui_en.sh b/x-ui_en.sh new file mode 100644 index 0000000000..b784e3bd63 --- /dev/null +++ b/x-ui_en.sh @@ -0,0 +1,763 @@ +#!/bin/bash + +red='\033[0;31m' +green='\033[0;32m' +yellow='\033[0;33m' +plain='\033[0m' + +#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() { + #install acme first + install_acme + if [ $? -ne 0 ]; then + LOGE "install acme failed,please check logs" + exit 1 + 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 + else + rm -rf $certPath + 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 | tail -1 | awk '{print $1}') + if [ ${currentCert} == ${domain} ]; 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 + else + rm -rf $certPath + 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 | tail -1 | awk '{print $1}') + if [ ${currentCert} == ${CF_Domain} ]; 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 +} + +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 "------------------------------------------" +} + +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 sysyem startup + ${green}14.${plain} disabel x-ui on sysyem startup +———————————————— + ${green}15.${plain} enable bbr + ${green}16.${plain} issuse certs + " + show_status + echo && read -p "please input a legal number[0-16]: " 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 + ;; + *) + LOGE "please input a legal number[0-16]" + ;; + 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 + ;; + *) show_usage ;; + esac +else + show_menu +fi From 9e73c8bf6c278e7bef9aa79ace4447055973d743 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka Date: Sun, 23 Oct 2022 18:05:32 +0800 Subject: [PATCH 33/84] Update README.md --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e5a184f580..0e6aa439ad 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,11 @@ CN|[EN](./README_EN.md) ``` bash <(curl -Ls https://raw.githubusercontent.com/FranzKafkaYu/x-ui/master/install.sh) -``` +``` +For English Users,plase use the following command to install english supported version: +``` +bash <(curl -Ls https://raw.githubusercontent.com/FranzKafkaYu/x-ui/master/install_en.sh) +``` # 效果预览 `面板使用`:
@@ -141,6 +145,7 @@ xray 状态: 运行 - Debian 8+ # 变更记录 +- 2022.10.23: 实现全英文支持;增加批量导出分享链接功能;优化Telegram通知文案 - 2022.08.11:实现Vmess/Vless/Trojan单端口多用户;增加CPU使用超限提醒 - 2022.07.28:增加acme standalone模式申请证书;增加x-ui自动保活机制;优化编译选项以适配更多系统 - 2022.07.24:增加自动生成面板根路径,节点流量自动重置功能,设备IP接入变化通知功能 From a96413814cb2742e5be168e8fe0b6161e92b01d9 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka Date: Sun, 23 Oct 2022 19:42:01 +0800 Subject: [PATCH 34/84] Update README.md --- README.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0e6aa439ad..ee9c22c211 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ CN|[EN](./README_EN.md) ``` bash <(curl -Ls https://raw.githubusercontent.com/FranzKafkaYu/x-ui/master/install.sh) ``` -For English Users,plase use the following command to install english supported version: +For English Users,plase use the following command to install English supported version: ``` bash <(curl -Ls https://raw.githubusercontent.com/FranzKafkaYu/x-ui/master/install_en.sh) ``` @@ -168,7 +168,14 @@ xray 状态: 运行 - [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) +- [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) ## Stargazers over time From d0b98f4b42650274ccd0f3f3697a06db35e5a0f7 Mon Sep 17 00:00:00 2001 From: FranzKafkayu Date: Mon, 24 Oct 2022 12:54:32 +0800 Subject: [PATCH 35/84] update README --- README.md | 7 ++++--- README_EN.md | 17 +++++++++++++++-- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ee9c22c211..76f21f50b4 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,8 @@ CN|[EN](./README_EN.md) 通过免费的Telegram bot方便快捷地进行监控、管理你的代理服务 具体使用教程可以参考个人博客文章[链接](https://coderfan.net/how-to-use-x-ui-pannel-to-set-up-proxies-for-bypassing-gfw.html) 欢迎大家使用并反馈意见或提交Pr,帮助项目更好的改善 -如果您觉得本项目对您有所帮助,不妨给个star:star2:支持我~ +如果您觉得本项目对您有所帮助,不妨给个star:star2:支持我 +或者你恰巧有购买服务器的需求,可以通过文末的赞助部分支持我~ # 文档目录 - [功能介绍](#功能介绍) @@ -38,7 +39,7 @@ CN|[EN](./README_EN.md) ``` bash <(curl -Ls https://raw.githubusercontent.com/FranzKafkaYu/x-ui/master/install.sh) ``` -For English Users,plase use the following command to install English supported version: +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) ``` @@ -145,7 +146,7 @@ xray 状态: 运行 - Debian 8+ # 变更记录 -- 2022.10.23: 实现全英文支持;增加批量导出分享链接功能;优化Telegram通知文案 +- 2022.10.23:实现全英文支持;增加批量导出分享链接功能;优化页面细节与Telegram通知 - 2022.08.11:实现Vmess/Vless/Trojan单端口多用户;增加CPU使用超限提醒 - 2022.07.28:增加acme standalone模式申请证书;增加x-ui自动保活机制;优化编译选项以适配更多系统 - 2022.07.24:增加自动生成面板根路径,节点流量自动重置功能,设备IP接入变化通知功能 diff --git a/README_EN.md b/README_EN.md index 9bffb21177..fdd2b21efc 100644 --- a/README_EN.md +++ b/README_EN.md @@ -6,7 +6,8 @@ This project is a fork of [vaxilu's project](https://github.com/vaxilu/x-ui) For some basic usages,please visit my [blog post](https://coderfan.net/how-to-use-x-ui-pannel-to-set-up-proxies-for-bypassing-gfw.html) If you need more language options ,please open a issue and let me know that -# changes +# changes +- 2022.10.23:Fully sport 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 @@ -41,7 +42,11 @@ 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: @@ -90,7 +95,15 @@ xray 状态: 运行 # 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) +- [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 From 53efeb707cef7617d8bb67fda7c09f769be0f691 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka Date: Tue, 25 Oct 2022 09:32:58 +0800 Subject: [PATCH 36/84] Update bug_report.yml --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 360894c247..39acf241a0 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -10,6 +10,8 @@ body: 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). From 6bb012e88c746a0c73f6f496ba8d29b1cc5321fa Mon Sep 17 00:00:00 2001 From: Yu FranzKafka Date: Tue, 25 Oct 2022 09:36:28 +0800 Subject: [PATCH 37/84] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 76f21f50b4..32a0efb97e 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ CN|[EN](./README_EN.md) - 更多高级配置项,详见面板 :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`环境,且系统网络正常 From a208b63658a404f5df17d3dba24313712dc73a92 Mon Sep 17 00:00:00 2001 From: tacrazymage <30746649+tacrazymage@users.noreply.github.com> Date: Tue, 25 Oct 2022 18:07:29 +0330 Subject: [PATCH 38/84] check if acme.sh already installed if it's installed no need to reinstall it --- x-ui_en.sh | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/x-ui_en.sh b/x-ui_en.sh index b784e3bd63..785bb6468c 100644 --- a/x-ui_en.sh +++ b/x-ui_en.sh @@ -449,11 +449,15 @@ install_acme() { #method for standalone mode ssl_cert_issue_standalone() { - #install acme first - install_acme - if [ $? -ne 0 ]; then - LOGE "install acme failed,please check logs" - exit 1 + #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 @@ -462,7 +466,7 @@ ssl_cert_issue_standalone() { apt install socat -y fi if [ $? -ne 0 ]; then - LOGE "install socat failed,please check logs" + LOGE "install socat failed, please check logs" exit 1 else LOGI "install socat succeed..." From 8d1009a9f7b33473d32f58d40b9e2f26b1cc8f1d Mon Sep 17 00:00:00 2001 From: tacrazymage <30746649+tacrazymage@users.noreply.github.com> Date: Tue, 25 Oct 2022 18:19:56 +0330 Subject: [PATCH 39/84] check if acme already installed --- x-ui.sh | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/x-ui.sh b/x-ui.sh index 84cc1c01d5..06045be594 100644 --- a/x-ui.sh +++ b/x-ui.sh @@ -448,11 +448,15 @@ install_acme() { #method for standalone mode ssl_cert_issue_standalone() { - #install acme first - install_acme - if [ $? -ne 0 ]; then - LOGE "无法安装acme,请检查错误日志" - exit 1 + #check for acme.sh first + if ! command -v ~/.acme.sh/acme.sh &> /dev/null + then + echo "acme.sh 无法找到。 我们将安装它" + install_acme + if [ $? -ne 0 ]; then + LOGE "安装 acme 失败,请检查日志" + exit 1 + fi fi #install socat second if [[ x"${release}" == x"centos" ]]; then From 67d34bd262a7403df830672aced055f5b1e7bce1 Mon Sep 17 00:00:00 2001 From: FranzKafkayu Date: Tue, 25 Oct 2022 23:38:03 +0800 Subject: [PATCH 40/84] Update --- README.md | 2 +- README_EN.md | 53 ++++++++++++++++++++++++++-------------------------- 2 files changed, 28 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 32a0efb97e..c2c355a4da 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # X-UI -CN|[EN](./README_EN.md) +简体中文|[ENGLISH](./README_EN.md) > 免责声明:该项目仅供个人学习、交流,请勿用于非法用途,请勿用于生产环境 diff --git a/README_EN.md b/README_EN.md index fdd2b21efc..2d4e6cfb18 100644 --- a/README_EN.md +++ b/README_EN.md @@ -1,13 +1,13 @@ # X-UI -[CN](./README.md)| EN +[简体中文](./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 For some basic usages,please visit my [blog post](https://coderfan.net/how-to-use-x-ui-pannel-to-set-up-proxies-for-bypassing-gfw.html) If you need more language options ,please open a issue and let me know that # changes -- 2022.10.23:Fully sport for English,add export links,add CPU cores display +- 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 @@ -51,35 +51,36 @@ bash <(curl -Ls https://raw.githubusercontent.com/FranzKafkaYu/x-ui/master/insta ## shortcut After Installation,you can input `x-ui`to enter control menu,current menu details: ``` - x-ui 面板管理脚本 - 0. 退出脚本 + + x-ui control menu + 0. exit ———————————————— - 1. 安装 x-ui - 2. 更新 x-ui - 3. 卸载 x-ui + 1. install x-ui + 2. update x-ui + 3. uninstall x-ui ———————————————— - 4. 重置用户名密码 - 5. 重置面板设置 - 6. 设置面板端口 - 7. 查看当前面板设置 + 4. reset username + 5. reset panel + 6. reset panel port + 7. check panel info ———————————————— - 8. 启动 x-ui - 9. 停止 x-ui - 10. 重启 x-ui - 11. 查看 x-ui 状态 - 12. 查看 x-ui 日志 + 8. start x-ui + 9. stop x-ui + 10. restart x-ui + 11. check x-ui status + 12. check x-ui logs ———————————————— - 13. 设置 x-ui 开机自启 - 14. 取消 x-ui 开机自启 + 13. enable x-ui on sysyem startup + 14. disabel x-ui on sysyem startup ———————————————— - 15. 一键安装 bbr (最新内核) - 16. 一键申请SSL证书(acme申请) + 15. enable bbr + 16. issuse certs -面板状态: 已运行 -是否开机自启: 是 -xray 状态: 运行 +x-ui status: running +enable on system startup: yes +xray status: running -请输入选择 [0-16]: +please input a legal number[0-16]: ``` ## Suggested system as follows: @@ -89,8 +90,8 @@ xray 状态: 运行 # telegram -[CoderfanBaby](https://t.me/CoderfanBaby) -[FranzKafka‘sPrivateGroup](https://t.me/franzkafayu) +[Channel](https://t.me/CoderfanBaby) +[Group](https://t.me/franzkafayu) # credits - [vaxilu/x-ui](https://github.com/vaxilu/x-ui) From 7dfce14dcfd9746a50afbf09b00d754ef8fec268 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka Date: Thu, 3 Nov 2022 00:07:29 +0800 Subject: [PATCH 41/84] Update x-ui.sh --- x-ui.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/x-ui.sh b/x-ui.sh index 06045be594..b05ceda824 100644 --- a/x-ui.sh +++ b/x-ui.sh @@ -451,7 +451,6 @@ ssl_cert_issue_standalone() { #check for acme.sh first if ! command -v ~/.acme.sh/acme.sh &> /dev/null then - echo "acme.sh 无法找到。 我们将安装它" install_acme if [ $? -ne 0 ]; then LOGE "安装 acme 失败,请检查日志" From 8be5f2d77908e02de97d77e850b4cb3832253daa Mon Sep 17 00:00:00 2001 From: FranzKafkayu Date: Thu, 3 Nov 2022 00:11:05 +0800 Subject: [PATCH 42/84] format scripts --- x-ui.sh | 7 +++---- x-ui_en.sh | 15 +++++++-------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/x-ui.sh b/x-ui.sh index b05ceda824..568ddec522 100644 --- a/x-ui.sh +++ b/x-ui.sh @@ -449,12 +449,11 @@ install_acme() { #method for standalone mode ssl_cert_issue_standalone() { #check for acme.sh first - if ! command -v ~/.acme.sh/acme.sh &> /dev/null - then + if ! command -v ~/.acme.sh/acme.sh &>/dev/null; then install_acme if [ $? -ne 0 ]; then - LOGE "安装 acme 失败,请检查日志" - exit 1 + LOGE "安装 acme 失败,请检查日志" + exit 1 fi fi #install socat second diff --git a/x-ui_en.sh b/x-ui_en.sh index 785bb6468c..2dcbba8a35 100644 --- a/x-ui_en.sh +++ b/x-ui_en.sh @@ -450,13 +450,12 @@ install_acme() { #method for standalone mode ssl_cert_issue_standalone() { #check for acme.sh first - if ! command -v ~/.acme.sh/acme.sh &> /dev/null - then + 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 + LOGE "install acme failed, please check logs" + exit 1 fi fi #install socat second @@ -513,8 +512,8 @@ ssl_cert_issue_standalone() { 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 + --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" @@ -596,8 +595,8 @@ ssl_cert_issue_by_cloudflare() { 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 + --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} From cf841eacf9203a205e3ce4569d9a0039ff8a1f46 Mon Sep 17 00:00:00 2001 From: FranzKafkayu Date: Wed, 9 Nov 2022 08:33:23 +0800 Subject: [PATCH 43/84] Update README.md --- README.md | 1 - README_EN.md | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index c2c355a4da..5249aa97e2 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,6 @@ 支持单端口多用户、多协议的 xray 面板,究极缝合怪 通过免费的Telegram bot方便快捷地进行监控、管理你的代理服务 -具体使用教程可以参考个人博客文章[链接](https://coderfan.net/how-to-use-x-ui-pannel-to-set-up-proxies-for-bypassing-gfw.html) 欢迎大家使用并反馈意见或提交Pr,帮助项目更好的改善 如果您觉得本项目对您有所帮助,不妨给个star:star2:支持我 或者你恰巧有购买服务器的需求,可以通过文末的赞助部分支持我~ diff --git a/README_EN.md b/README_EN.md index 2d4e6cfb18..31820d2e66 100644 --- a/README_EN.md +++ b/README_EN.md @@ -2,8 +2,7 @@ [简体中文](./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 -For some basic usages,please visit my [blog post](https://coderfan.net/how-to-use-x-ui-pannel-to-set-up-proxies-for-bypassing-gfw.html) +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 From b6e1a10e8ba6c1d195cf185f20a5dd5e09c5c5d9 Mon Sep 17 00:00:00 2001 From: FranzKafkayu Date: Sun, 13 Nov 2022 00:34:13 +0800 Subject: [PATCH 44/84] fix install shell for English version --- install_en.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/install_en.sh b/install_en.sh index 70e098a5f1..e2ee08a162 100644 --- a/install_en.sh +++ b/install_en.sh @@ -113,7 +113,7 @@ install_x-ui() { 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}.tar.gz https://github.com/FranzKafkaYu/x-ui/releases/download/${last_version}/x-ui-linux-${arch}-english.tar.gz + 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 @@ -133,13 +133,13 @@ install_x-ui() { rm /usr/local/x-ui/ -rf fi - tar zxvf x-ui-linux-${arch}.tar.gz - rm x-ui-linux-${arch}.tar.gz -f + 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.sh + chmod +x /usr/local/x-ui/x-ui_en.sh chmod +x /usr/bin/x-ui config_after_install systemctl daemon-reload From 1b088fb829d8ae10dacab934738c41bf6b7c7fb8 Mon Sep 17 00:00:00 2001 From: FranzKafkayu Date: Tue, 15 Nov 2022 09:15:26 +0800 Subject: [PATCH 45/84] Update README --- README.md | 1 + README_EN.md | 1 + 2 files changed, 2 insertions(+) diff --git a/README.md b/README.md index 5249aa97e2..041cf991f2 100644 --- a/README.md +++ b/README.md @@ -146,6 +146,7 @@ xray 状态: 运行 - Debian 8+ # 变更记录 +- 2022.11.14:添加xtls-rprx-vision流控选项 - 2022.10.23:实现全英文支持;增加批量导出分享链接功能;优化页面细节与Telegram通知 - 2022.08.11:实现Vmess/Vless/Trojan单端口多用户;增加CPU使用超限提醒 - 2022.07.28:增加acme standalone模式申请证书;增加x-ui自动保活机制;优化编译选项以适配更多系统 diff --git a/README_EN.md b/README_EN.md index 31820d2e66..0148356059 100644 --- a/README_EN.md +++ b/README_EN.md @@ -6,6 +6,7 @@ This project is a fork of [vaxilu's project](https://github.com/vaxilu/x-ui) If you need more language options ,please open a issue and let me know that # changes +- 2022.11.15:Add xtls-rprx-vision flow option - 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 From fabc6ce968693c030c5718a164b25532969cc8d0 Mon Sep 17 00:00:00 2001 From: FranzKafkayu Date: Wed, 23 Nov 2022 00:11:07 +0800 Subject: [PATCH 46/84] add cron job setting for updating geo data and xray log clear --- x-ui.sh | 171 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 167 insertions(+), 4 deletions(-) diff --git a/x-ui.sh b/x-ui.sh index 568ddec522..42dafee596 100644 --- a/x-ui.sh +++ b/x-ui.sh @@ -5,6 +5,15 @@ 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_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}" @@ -510,8 +519,8 @@ ssl_cert_issue_standalone() { 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 + --cert-file /root/cert/${domain}.cer --key-file /root/cert/${domain}.key \ + --fullchain-file /root/cert/fullchain.cer if [ $? -ne 0 ]; then LOGE "证书安装失败,脚本退出" @@ -595,8 +604,8 @@ ssl_cert_issue_by_cloudflare() { 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 + --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} @@ -620,6 +629,144 @@ ssl_cert_issue_by_cloudflare() { 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} ${PATH_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 filePath='' + read -p "请输入日志文件路径": filePath + if [[ ! -n ${filePath} ]]; then + LOGI "输入的日志文件路径无效,脚本退出" + exit 1 + fi + if [[ ! -f ${filePath} ]]; then + LOGE "${filePath}不存在,设置定时清除xray日志失败" + exit 1 + fi + crontab -l >/tmp/crontabTask.tmp + echo "30 4 */2 * * x-ui clear ${filePath} > /dev/null" >>/tmp/crontabTask.tmp + crontab /tmp/crontabTask.tmp + rm /tmp/crontabTask.tmp + LOGI "设置定时清除xray日志成功" +} + +#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 "------------------------------------------" @@ -635,6 +782,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 "------------------------------------------" } @@ -663,6 +813,7 @@ show_menu() { ———————————————— ${green}15.${plain} 一键安装 bbr (最新内核) ${green}16.${plain} 一键申请SSL证书(acme申请) + ${green}17.${plain} 配置x-ui定时任务 " show_status echo && read -p "请输入选择 [0-16]: " num @@ -719,6 +870,9 @@ show_menu() { 16) ssl_cert_issue ;; + 17) + check_install && cron_jobs + ;; *) LOGE "请输入正确的数字 [0-16]" ;; @@ -760,6 +914,15 @@ if [[ $# > 0 ]]; then "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 From 39ee5e019de8d2eec83e0d6c62259f1a6a5d1fbd Mon Sep 17 00:00:00 2001 From: FranzKafkayu Date: Wed, 23 Nov 2022 00:17:24 +0800 Subject: [PATCH 47/84] fix for geosite url --- x-ui.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-ui.sh b/x-ui.sh index 42dafee596..d39cd2aaab 100644 --- a/x-ui.sh +++ b/x-ui.sh @@ -677,7 +677,7 @@ update_geo() { 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} ${PATH_FOR_GEO_SITE} + 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} From 566507377eafe4e9819e4276e17e09f5674a8558 Mon Sep 17 00:00:00 2001 From: FranzKafkayu Date: Sun, 4 Dec 2022 09:36:35 +0800 Subject: [PATCH 48/84] update shell script --- install.sh | 1 + install_en.sh | 1 + x-ui_en.sh | 12 ++++++------ 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/install.sh b/install.sh index f75491cb11..2ead995472 100644 --- a/install.sh +++ b/install.sh @@ -167,6 +167,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 index e2ee08a162..0faa419c74 100644 --- a/install_en.sh +++ b/install_en.sh @@ -160,6 +160,7 @@ install_x-ui() { 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 "----------------------------------------------" } diff --git a/x-ui_en.sh b/x-ui_en.sh index 2dcbba8a35..80ddd01c3f 100644 --- a/x-ui_en.sh +++ b/x-ui_en.sh @@ -512,8 +512,8 @@ ssl_cert_issue_standalone() { 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 + --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" @@ -595,8 +595,8 @@ ssl_cert_issue_by_cloudflare() { 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 + --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} @@ -657,8 +657,8 @@ show_menu() { ${green}11.${plain} check x-ui status ${green}12.${plain} check x-ui logs ———————————————— - ${green}13.${plain} enable x-ui on sysyem startup - ${green}14.${plain} disabel x-ui on sysyem startup + ${green}13.${plain} enable x-ui on system startup + ${green}14.${plain} disabel x-ui on system startup ———————————————— ${green}15.${plain} enable bbr ${green}16.${plain} issuse certs From aabe4e9a491110bfe45219c17661b246a24db2eb Mon Sep 17 00:00:00 2001 From: FranzKafkayu Date: Tue, 6 Dec 2022 00:41:01 +0800 Subject: [PATCH 49/84] fix typo --- x-ui_en.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-ui_en.sh b/x-ui_en.sh index 80ddd01c3f..b220e32df7 100644 --- a/x-ui_en.sh +++ b/x-ui_en.sh @@ -658,7 +658,7 @@ show_menu() { ${green}12.${plain} check x-ui logs ———————————————— ${green}13.${plain} enable x-ui on system startup - ${green}14.${plain} disabel x-ui on system startup + ${green}14.${plain} disable x-ui on system startup ———————————————— ${green}15.${plain} enable bbr ${green}16.${plain} issuse certs From 9ee2582669373dcd3626b70a6cca8751c43586be Mon Sep 17 00:00:00 2001 From: Yu FranzKafka Date: Wed, 7 Dec 2022 09:17:31 +0800 Subject: [PATCH 50/84] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 041cf991f2..aaf44afb3d 100644 --- a/README.md +++ b/README.md @@ -146,6 +146,7 @@ xray 状态: 运行 - Debian 8+ # 变更记录 +- 2022.12.07:添加设备并发限制;细化tls配置 - 2022.11.14:添加xtls-rprx-vision流控选项 - 2022.10.23:实现全英文支持;增加批量导出分享链接功能;优化页面细节与Telegram通知 - 2022.08.11:实现Vmess/Vless/Trojan单端口多用户;增加CPU使用超限提醒 From 25b6bd5df006c7af8b5c301e1a719e02601ba531 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka Date: Thu, 8 Dec 2022 09:15:42 +0800 Subject: [PATCH 51/84] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index aaf44afb3d..88bdf3e262 100644 --- a/README.md +++ b/README.md @@ -146,7 +146,7 @@ xray 状态: 运行 - Debian 8+ # 变更记录 -- 2022.12.07:添加设备并发限制;细化tls配置 +- 2022.12.07:添加设备并发限制;细化tls配置,支持minVersion、maxVersion与cipherSuites选择 - 2022.11.14:添加xtls-rprx-vision流控选项 - 2022.10.23:实现全英文支持;增加批量导出分享链接功能;优化页面细节与Telegram通知 - 2022.08.11:实现Vmess/Vless/Trojan单端口多用户;增加CPU使用超限提醒 From 648351417125a4ad8adf580ce5e0767a234031ab Mon Sep 17 00:00:00 2001 From: Yu FranzKafka Date: Mon, 12 Dec 2022 23:29:16 +0800 Subject: [PATCH 52/84] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 88bdf3e262..74015f0929 100644 --- a/README.md +++ b/README.md @@ -179,6 +179,7 @@ xray 状态: 运行 - [搬瓦工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) +- USDT TRC20:`TYZ5MAq5YvtCMsjQDq1TJZnMWmjMVGLk2T` ## Stargazers over time From b7f3a1d4e99c672658e6f102d0ce2d5a510431c6 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka <38254177+FranzKafkaYu@users.noreply.github.com> Date: Thu, 9 Feb 2023 13:16:41 +0800 Subject: [PATCH 53/84] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 74015f0929..56d6555fc1 100644 --- a/README.md +++ b/README.md @@ -146,6 +146,7 @@ xray 状态: 运行 - Debian 8+ # 变更记录 +- 2023.02.09:支持单端口内用户流量限制与统计;支持VLESS utls配置与分享链接导出 - 2022.12.07:添加设备并发限制;细化tls配置,支持minVersion、maxVersion与cipherSuites选择 - 2022.11.14:添加xtls-rprx-vision流控选项 - 2022.10.23:实现全英文支持;增加批量导出分享链接功能;优化页面细节与Telegram通知 From dc7eb47848208994d30483232f7491d71f653e0c Mon Sep 17 00:00:00 2001 From: FranzKafkayu Date: Wed, 15 Feb 2023 00:23:11 +0800 Subject: [PATCH 54/84] =?UTF-8?q?=E5=88=9D=E6=AC=A1=E5=AE=89=E8=A3=85?= =?UTF-8?q?=E6=97=B6=E5=A2=9E=E5=8A=A0=E9=9A=8F=E6=9C=BA=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E5=90=8D=E4=B8=8E=E5=AF=86=E7=A0=81=E3=80=81=E7=AB=AF=E5=8F=A3?= =?UTF-8?q?=E7=9A=84=E8=AE=BE=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- install.sh | 20 +++++++++++++++++--- install_en.sh | 18 ++++++++++++++++-- x-ui.sh | 12 ++++++------ x-ui_en.sh | 12 ++++++------ 4 files changed, 45 insertions(+), 17 deletions(-) diff --git a/install.sh b/install.sh index 2ead995472..01a67bdf90 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' @@ -97,8 +97,22 @@ config_after_install() { echo -e "${yellow}面板端口设定完成${plain}" else echo -e "${red}已取消设定...${plain}" - echo -e "${red}如属于全新安装,默认网页端口为 ${green}54321${plain},用户名与密码均为 ${green}admin${plain},请及时修改" - echo -e "${red}如属于版本升级,则保留之前设置项,登录方式保持不变,可输入x-ui后键入数字7查看登录信息${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 } diff --git a/install_en.sh b/install_en.sh index 0faa419c74..cc532d04e5 100644 --- a/install_en.sh +++ b/install_en.sh @@ -97,8 +97,22 @@ config_after_install() { echo -e "${yellow}panel port set down!${plain}" else echo -e "${red}cancel...${plain}" - echo -e "${red}if this is your first time to install,the default panel port is ${green}54321${plain},username and password both are${green}admin${plain},please change them in time" - echo -e "${red}if this is your upgrade,keep the old settings,if you forgot you login info,you can type x-ui and then type 7 to check${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 } diff --git a/x-ui.sh b/x-ui.sh index d39cd2aaab..4284b540e4 100644 --- a/x-ui.sh +++ b/x-ui.sh @@ -519,8 +519,8 @@ ssl_cert_issue_standalone() { 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 + --cert-file /root/cert/${domain}.cer --key-file /root/cert/${domain}.key \ + --fullchain-file /root/cert/fullchain.cer if [ $? -ne 0 ]; then LOGE "证书安装失败,脚本退出" @@ -604,8 +604,8 @@ ssl_cert_issue_by_cloudflare() { 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 + --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} @@ -816,7 +816,7 @@ show_menu() { ${green}17.${plain} 配置x-ui定时任务 " show_status - echo && read -p "请输入选择 [0-16]: " num + echo && read -p "请输入选择 [0-17],查看面板登录信息请输入数字7:" num case "${num}" in 0) @@ -874,7 +874,7 @@ show_menu() { check_install && cron_jobs ;; *) - LOGE "请输入正确的数字 [0-16]" + LOGE "请输入正确的数字 [0-17],查看面板登录信息请输入数字7" ;; esac } diff --git a/x-ui_en.sh b/x-ui_en.sh index b220e32df7..5848646dc0 100644 --- a/x-ui_en.sh +++ b/x-ui_en.sh @@ -512,8 +512,8 @@ ssl_cert_issue_standalone() { 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 + --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" @@ -595,8 +595,8 @@ ssl_cert_issue_by_cloudflare() { 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 + --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} @@ -664,7 +664,7 @@ show_menu() { ${green}16.${plain} issuse certs " show_status - echo && read -p "please input a legal number[0-16]: " num + echo && read -p "please input a legal number[0-16],input 7 for checking login info:" num case "${num}" in 0) @@ -719,7 +719,7 @@ show_menu() { ssl_cert_issue ;; *) - LOGE "please input a legal number[0-16]" + LOGE "please input a legal number[0-16],input 7 for checking login info" ;; esac } From c6fd02aebacb12f45e82c726b4c1b1f6b401cd6c Mon Sep 17 00:00:00 2001 From: Yu FranzKafka <38254177+FranzKafkaYu@users.noreply.github.com> Date: Sun, 9 Apr 2023 15:58:21 +0800 Subject: [PATCH 55/84] Update README.md --- README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/README.md b/README.md index 56d6555fc1..0191f7c3da 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,21 @@ bash <(curl -Ls https://raw.githubusercontent.com/FranzKafkaYu/x-ui/master/insta
+`用户速览`: +
+点击查看效果预览 + +![image](https://user-images.githubusercontent.com/38254177/230761101-20431dd7-5bce-489e-9139-0ceb9ab9a2dc.png) + +
+ +`用户查询`: +
+点击查看效果预览 + +![image](https://user-images.githubusercontent.com/38254177/230761252-c283c02d-82a4-46ce-a180-dfab4048180d.png) + +
From 1e2cde2aeb7036b88e9e300080c0d8f16b28e203 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka <38254177+FranzKafkaYu@users.noreply.github.com> Date: Sun, 9 Apr 2023 18:37:56 +0800 Subject: [PATCH 56/84] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 0191f7c3da..772103f79e 100644 --- a/README.md +++ b/README.md @@ -161,6 +161,8 @@ xray 状态: 运行 - Debian 8+ # 变更记录 +- 2023.04.09:支持Relity;支持新的telegram bot控制指令 +- 2023.03.05:支持用户到期时间限制;随机用户名、密码与端口生成 - 2023.02.09:支持单端口内用户流量限制与统计;支持VLESS utls配置与分享链接导出 - 2022.12.07:添加设备并发限制;细化tls配置,支持minVersion、maxVersion与cipherSuites选择 - 2022.11.14:添加xtls-rprx-vision流控选项 From e3977d7248a2606071ea0e584f353106ef8be83d Mon Sep 17 00:00:00 2001 From: Yu FranzKafka <38254177+FranzKafkaYu@users.noreply.github.com> Date: Sun, 9 Apr 2023 21:51:03 +0800 Subject: [PATCH 57/84] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 772103f79e..f32a2ba51b 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ 支持单端口多用户、多协议的 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:支持我 或者你恰巧有购买服务器的需求,可以通过文末的赞助部分支持我~ From 4b444b33787e2fd9f466598b1741eddc156cfb86 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka <38254177+FranzKafkaYu@users.noreply.github.com> Date: Sun, 9 Apr 2023 22:17:35 +0800 Subject: [PATCH 58/84] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f32a2ba51b..585627b157 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ 支持单端口多用户、多协议的 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) +⚡`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:支持我 或者你恰巧有购买服务器的需求,可以通过文末的赞助部分支持我~ From a2c68ae6fbf6a4e2f2133f48b0a390beadd69a87 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka <38254177+FranzKafkaYu@users.noreply.github.com> Date: Mon, 10 Apr 2023 12:47:38 +0800 Subject: [PATCH 59/84] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 585627b157..a0f1989539 100644 --- a/README.md +++ b/README.md @@ -162,7 +162,7 @@ xray 状态: 运行 - Debian 8+ # 变更记录 -- 2023.04.09:支持Relity;支持新的telegram bot控制指令 +- 2023.04.09:支持Reality;支持新的telegram bot控制指令 - 2023.03.05:支持用户到期时间限制;随机用户名、密码与端口生成 - 2023.02.09:支持单端口内用户流量限制与统计;支持VLESS utls配置与分享链接导出 - 2022.12.07:添加设备并发限制;细化tls配置,支持minVersion、maxVersion与cipherSuites选择 From d817bbb45c4b2d6adda0d7ba731187b9b8fc7c5f Mon Sep 17 00:00:00 2001 From: PIDAN-HEIDASHUAI <130355261+PIDAN-HEIDASHUAI@users.noreply.github.com> Date: Mon, 10 Apr 2023 17:11:06 +0800 Subject: [PATCH 60/84] Update install.sh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加一键安装中s390x的分支 --- install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install.sh b/install.sh index 01a67bdf90..46a2563620 100644 --- a/install.sh +++ b/install.sh @@ -31,7 +31,7 @@ fi arch=$(arch) -if [[ $arch == "x86_64" || $arch == "x64" || $arch == "amd64" ]]; then +if [[ $arch == "x86_64" || $arch == "x64" || $arch == "s390x" || $arch == "amd64" ]]; then arch="amd64" elif [[ $arch == "aarch64" || $arch == "arm64" ]]; then arch="arm64" From 3ee33802c5e5410de561c113fcfae55cbaa2b66e Mon Sep 17 00:00:00 2001 From: Yu FranzKafka <38254177+FranzKafkaYu@users.noreply.github.com> Date: Tue, 18 Apr 2023 00:27:18 +0800 Subject: [PATCH 61/84] Update README.md --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a0f1989539..b5d761add1 100644 --- a/README.md +++ b/README.md @@ -155,8 +155,10 @@ xray 状态: 运行 请输入选择 [0-16]: ``` -## 建议系统 - +## 系统配置 +### 内存 +256MB+/128MB minimal +### OS - CentOS 7+ - Ubuntu 16+ - Debian 8+ From 4b3e19ffe6b067c747506b03817fff149e752c45 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka <38254177+FranzKafkaYu@users.noreply.github.com> Date: Fri, 5 May 2023 09:31:48 +0800 Subject: [PATCH 62/84] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b5d761add1..b39142dd20 100644 --- a/README.md +++ b/README.md @@ -155,9 +155,9 @@ xray 状态: 运行 请输入选择 [0-16]: ``` -## 系统配置 +## 配置要求 ### 内存 -256MB+/128MB minimal +- 128MB minimal/256MB+ recommend ### OS - CentOS 7+ - Ubuntu 16+ From 08a73f7cbe0fa6e6d28d4b25d0497415808b832c Mon Sep 17 00:00:00 2001 From: Yu FranzKafka <38254177+FranzKafkaYu@users.noreply.github.com> Date: Fri, 5 May 2023 09:38:06 +0800 Subject: [PATCH 63/84] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index b39142dd20..ce490c8bc7 100644 --- a/README.md +++ b/README.md @@ -155,10 +155,10 @@ xray 状态: 运行 请输入选择 [0-16]: ``` -## 配置要求 -### 内存 +# 配置要求 +## 内存 - 128MB minimal/256MB+ recommend -### OS +## OS - CentOS 7+ - Ubuntu 16+ - Debian 8+ From 078efe137e978cd2fc1475957852d11a1e332657 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka <38254177+FranzKafkaYu@users.noreply.github.com> Date: Fri, 5 May 2023 09:41:52 +0800 Subject: [PATCH 64/84] Update README_EN.md --- README_EN.md | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/README_EN.md b/README_EN.md index 0148356059..aeae1b2471 100644 --- a/README_EN.md +++ b/README_EN.md @@ -5,7 +5,11 @@ X-UI is a webUI panel based on Xray-core which supports multi protocols and mult 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 +# Changes +- 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 - 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 @@ -22,7 +26,7 @@ If you need more language options ,please open a issue and let me know that - 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 +# Basics - support system status info check - support multi protocols and multi users @@ -37,7 +41,7 @@ If you need more language options ,please open a issue and let me know that for more detailed usages,plz see [WIKI](https://github.com/FranzKafkaYu/x-ui/wiki) -# installation +# Installation Make sure your system `bash` and `curl` and `network` are ready,here we go ``` @@ -48,7 +52,7 @@ For English Users,please use the following command to install English supported bash <(curl -Ls https://raw.githubusercontent.com/FranzKafkaYu/x-ui/master/install_en.sh) ``` -## shortcut +## Shortcut After Installation,you can input `x-ui`to enter control menu,current menu details: ``` @@ -83,22 +87,25 @@ xray status: running please input a legal number[0-16]: ``` -## Suggested system as follows: +# System requirements: +## MEM +- 128MB minimal/256MB+ recommend +## OS - CentOS 7+ - Ubuntu 16+ - Debian 8+ -# telegram +# Telegram [Channel](https://t.me/CoderfanBaby) [Group](https://t.me/franzkafayu) -# credits +# 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 +# Sponsor if you want to purchase some virtual servers,you can purchase by my aff link: - [BandwagonHost](https://bandwagonhost.com/aff.php?aff=65703) From 75202869cf70be3ac8346a8b02cf61a23f231af6 Mon Sep 17 00:00:00 2001 From: FranzKafkayu Date: Sat, 6 May 2023 14:34:38 +0800 Subject: [PATCH 65/84] optimize for log auto clear in Chinese Version --- install.sh | 4 ++-- x-ui.sh | 45 +++++++++++++++++++++++++++++---------------- 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/install.sh b/install.sh index 46a2563620..41d71ae9a8 100644 --- a/install.sh +++ b/install.sh @@ -73,9 +73,9 @@ 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 } diff --git a/x-ui.sh b/x-ui.sh index 4284b540e4..36e06f68f3 100644 --- a/x-ui.sh +++ b/x-ui.sh @@ -10,6 +10,7 @@ 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' @@ -519,8 +520,8 @@ ssl_cert_issue_standalone() { 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 + --cert-file /root/cert/${domain}.cer --key-file /root/cert/${domain}.key \ + --fullchain-file /root/cert/fullchain.cer if [ $? -ne 0 ]; then LOGE "证书安装失败,脚本退出" @@ -604,8 +605,8 @@ ssl_cert_issue_by_cloudflare() { 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 + --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} @@ -740,21 +741,33 @@ clear_log() { #enable auto delete log,need file path as enable_auto_clear_log() { LOGI "设置定时清除xray日志..." - local filePath='' - read -p "请输入日志文件路径": filePath - if [[ ! -n ${filePath} ]]; then - LOGI "输入的日志文件路径无效,脚本退出" + 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 ${filePath} ]]; then - LOGE "${filePath}不存在,设置定时清除xray日志失败" - exit 1 + 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 - crontab -l >/tmp/crontabTask.tmp - echo "30 4 */2 * * x-ui clear ${filePath} > /dev/null" >>/tmp/crontabTask.tmp - crontab /tmp/crontabTask.tmp - rm /tmp/crontabTask.tmp - LOGI "设置定时清除xray日志成功" } #disable auto dlete log From 204edd35eebf8ea06807a9953bf8f1b7ff06de7a Mon Sep 17 00:00:00 2001 From: FranzKafkayu Date: Fri, 9 Jun 2023 17:16:33 +0800 Subject: [PATCH 66/84] Fix multi certs issue --- x-ui.sh | 14 ++++---------- x-ui_en.sh | 22 ++++++++-------------- 2 files changed, 12 insertions(+), 24 deletions(-) diff --git a/x-ui.sh b/x-ui.sh index 36e06f68f3..914c068a02 100644 --- a/x-ui.sh +++ b/x-ui.sh @@ -482,17 +482,14 @@ ssl_cert_issue_standalone() { certPath=/root/cert if [ ! -d "$certPath" ]; then mkdir $certPath - else - rm -rf $certPath - 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 | tail -1 | awk '{print $1}') - if [ ${currentCert} == ${domain} ]; then + 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" @@ -566,16 +563,13 @@ ssl_cert_issue_by_cloudflare() { certPath=/root/cert if [ ! -d "$certPath" ]; then mkdir $certPath - else - rm -rf $certPath - 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 | tail -1 | awk '{print $1}') - if [ ${currentCert} == ${CF_Domain} ]; then + 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" diff --git a/x-ui_en.sh b/x-ui_en.sh index 5848646dc0..4dbd6e0924 100644 --- a/x-ui_en.sh +++ b/x-ui_en.sh @@ -474,17 +474,14 @@ ssl_cert_issue_standalone() { certPath=/root/cert if [ ! -d "$certPath" ]; then mkdir $certPath - else - rm -rf $certPath - 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 | tail -1 | awk '{print $1}') - if [ ${currentCert} == ${domain} ]; then + 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" @@ -512,8 +509,8 @@ ssl_cert_issue_standalone() { 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 + --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" @@ -556,16 +553,13 @@ ssl_cert_issue_by_cloudflare() { certPath=/root/cert if [ ! -d "$certPath" ]; then mkdir $certPath - else - rm -rf $certPath - 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 | tail -1 | awk '{print $1}') - if [ ${currentCert} == ${CF_Domain} ]; then + 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" @@ -595,8 +589,8 @@ ssl_cert_issue_by_cloudflare() { 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 + --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} From 493065566030f1be3f89970419d2b0c1b77d3763 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka <38254177+FranzKafkaYu@users.noreply.github.com> Date: Sun, 11 Jun 2023 23:18:07 +0800 Subject: [PATCH 67/84] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ce490c8bc7..8de6675ca4 100644 --- a/README.md +++ b/README.md @@ -163,7 +163,8 @@ xray 状态: 运行 - Ubuntu 16+ - Debian 8+ -# 变更记录 +# 变更记录 +- 2023.06.10:开启TLS时自动复用面板证书与域名;增加证书热重载设定;优化设备限制功能 - 2023.04.09:支持Reality;支持新的telegram bot控制指令 - 2023.03.05:支持用户到期时间限制;随机用户名、密码与端口生成 - 2023.02.09:支持单端口内用户流量限制与统计;支持VLESS utls配置与分享链接导出 From 0c1341052daf2b1d40ff5db0ace19ae749bc0205 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka <38254177+FranzKafkaYu@users.noreply.github.com> Date: Sun, 11 Jun 2023 23:20:12 +0800 Subject: [PATCH 68/84] Update README_EN.md --- README_EN.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README_EN.md b/README_EN.md index aeae1b2471..1268e88b96 100644 --- a/README_EN.md +++ b/README_EN.md @@ -5,7 +5,8 @@ X-UI is a webUI panel based on Xray-core which supports multi protocols and mult 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 +# Changes +- 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 From a00f9d05905c720832056707c2889f6ea61d7315 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka <38254177+FranzKafkaYu@users.noreply.github.com> Date: Mon, 12 Jun 2023 08:58:04 +0800 Subject: [PATCH 69/84] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8de6675ca4..065ad97839 100644 --- a/README.md +++ b/README.md @@ -169,7 +169,7 @@ xray 状态: 运行 - 2023.03.05:支持用户到期时间限制;随机用户名、密码与端口生成 - 2023.02.09:支持单端口内用户流量限制与统计;支持VLESS utls配置与分享链接导出 - 2022.12.07:添加设备并发限制;细化tls配置,支持minVersion、maxVersion与cipherSuites选择 -- 2022.11.14:添加xtls-rprx-vision流控选项 +- 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自动保活机制;优化编译选项以适配更多系统 From 908de646687857a7d8b78e859e3a95df00b29398 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka <38254177+FranzKafkaYu@users.noreply.github.com> Date: Mon, 12 Jun 2023 08:59:18 +0800 Subject: [PATCH 70/84] Update README_EN.md --- README_EN.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README_EN.md b/README_EN.md index 1268e88b96..96cf364bf4 100644 --- a/README_EN.md +++ b/README_EN.md @@ -11,7 +11,7 @@ If you need more language options ,please open a issue and let me know that - 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 +- 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 From c3c010c918f37ac9eb0767cb8a1b8423a0168da3 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka <38254177+FranzKafkaYu@users.noreply.github.com> Date: Tue, 18 Jul 2023 09:19:33 +0800 Subject: [PATCH 71/84] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 065ad97839..ac410f6f41 100644 --- a/README.md +++ b/README.md @@ -164,6 +164,7 @@ xray 状态: 运行 - Debian 8+ # 变更记录 +- 2023.07.18:随机生成Reality dest与serverNames,去除微软域名;细化sniffing配置 - 2023.06.10:开启TLS时自动复用面板证书与域名;增加证书热重载设定;优化设备限制功能 - 2023.04.09:支持Reality;支持新的telegram bot控制指令 - 2023.03.05:支持用户到期时间限制;随机用户名、密码与端口生成 From 51d9ff6c8e0611e9b101daa329d66b524553edf3 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka <38254177+FranzKafkaYu@users.noreply.github.com> Date: Tue, 18 Jul 2023 09:21:31 +0800 Subject: [PATCH 72/84] Update README_EN.md --- README_EN.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README_EN.md b/README_EN.md index 96cf364bf4..a5ac37dc3f 100644 --- a/README_EN.md +++ b/README_EN.md @@ -6,6 +6,7 @@ This project is a fork of [vaxilu's project](https://github.com/vaxilu/x-ui) 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 From 7f0eb6b89f25ed620968cec40a08b53b470120a8 Mon Sep 17 00:00:00 2001 From: FranzKafkayu Date: Tue, 18 Jul 2023 14:17:37 +0800 Subject: [PATCH 73/84] update geo & clear xray logs and cron jobs support for En Version --- x-ui_en.sh | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 176 insertions(+), 1 deletion(-) diff --git a/x-ui_en.sh b/x-ui_en.sh index 4dbd6e0924..ee5376649d 100644 --- a/x-ui_en.sh +++ b/x-ui_en.sh @@ -5,6 +5,16 @@ 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}" @@ -614,6 +624,156 @@ ssl_cert_issue_by_cloudflare() { 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 "------------------------------------------" @@ -628,6 +788,8 @@ show_usage() { 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 "------------------------------------------" } @@ -656,6 +818,7 @@ show_menu() { ———————————————— ${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 @@ -712,8 +875,11 @@ show_menu() { 16) ssl_cert_issue ;; + 17) + check_install && cron_jobs + ;; *) - LOGE "please input a legal number[0-16],input 7 for checking login info" + LOGE "please input a legal number[0-17],input 7 for checking login info" ;; esac } @@ -753,6 +919,15 @@ if [[ $# > 0 ]]; then "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 From 956bf85bbac978d56c0e319c5fac2d6db7df9564 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka <38254177+FranzKafkaYu@users.noreply.github.com> Date: Thu, 20 Jul 2023 00:26:02 +0800 Subject: [PATCH 74/84] Update install.sh for curl related --- install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install.sh b/install.sh index 41d71ae9a8..ae2e43907f 100644 --- a/install.sh +++ b/install.sh @@ -121,7 +121,7 @@ install_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/') + 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 From 8fe0dd11ac920accf381bdda1babee20db1d55ce Mon Sep 17 00:00:00 2001 From: Yu FranzKafka <38254177+FranzKafkaYu@users.noreply.github.com> Date: Thu, 20 Jul 2023 09:15:33 +0800 Subject: [PATCH 75/84] Update README.md --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ac410f6f41..ad3bd5c378 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,12 @@ bash <(curl -Ls https://raw.githubusercontent.com/FranzKafkaYu/x-ui/master/insta 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 +``` + # 效果预览 `面板使用`:
From 6f885aa80d5a10aa88bb84e7f723c75c5aa399bc Mon Sep 17 00:00:00 2001 From: Yu FranzKafka <38254177+FranzKafkaYu@users.noreply.github.com> Date: Tue, 8 Aug 2023 15:03:44 +0800 Subject: [PATCH 76/84] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ad3bd5c378..ac0ec60b7c 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # X-UI 简体中文|[ENGLISH](./README_EN.md) -> 免责声明:该项目仅供个人学习、交流,请勿用于非法用途,请勿用于生产环境 +> 免责声明:该项目仅供个人学习、交流,请遵守当地法律法规,勿用于非法用途;请勿用于生产环境 支持单端口多用户、多协议的 xray 面板,究极缝合怪 通过免费的Telegram bot方便快捷地进行监控、管理你的代理服务 From 461a8409e5cae6de389e419e9c80e5ce144d5613 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka <38254177+FranzKafkaYu@users.noreply.github.com> Date: Thu, 21 Sep 2023 01:10:27 +0800 Subject: [PATCH 77/84] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index ac0ec60b7c..34957e6864 100644 --- a/README.md +++ b/README.md @@ -206,8 +206,7 @@ xray 状态: 运行 如果你觉得本项目对你有用,而且你也恰巧有这方面的需求,你也可以选择通过我的购买链接赞助我 - [搬瓦工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) -- USDT TRC20:`TYZ5MAq5YvtCMsjQDq1TJZnMWmjMVGLk2T` +- [Spartan三网4837性价比主机](https://billing.spartanhost.net/aff.php?aff=1875) ## Stargazers over time From 3512ac8c7a079e4d628b69911d785d12542e0742 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka <38254177+FranzKafkaYu@users.noreply.github.com> Date: Thu, 21 Sep 2023 23:52:49 +0800 Subject: [PATCH 78/84] Update README.md --- README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 34957e6864..3f46f30c13 100644 --- a/README.md +++ b/README.md @@ -201,12 +201,17 @@ xray 状态: 运行 - [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) +- [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) +- [邀请制小机场](https://breakwalls.us/#/register?code=n1RkASl6) ## Stargazers over time From 8a8faae1cc889e75666b5786b00b262fec57c09a Mon Sep 17 00:00:00 2001 From: Yu FranzKafka <38254177+FranzKafkaYu@users.noreply.github.com> Date: Tue, 26 Sep 2023 22:35:04 +0800 Subject: [PATCH 79/84] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 3f46f30c13..5073cbf44f 100644 --- a/README.md +++ b/README.md @@ -210,8 +210,7 @@ xray 状态: 运行 如果你希望购买一些现成的代理服务,可选择下述代理服务 - [搬瓦工关联机场](https://justmysocks.net/members/aff.php?aff=18177) -- [高端奶昔机场](https://nxboom.com/signupbyemail.aspx?MemberCode=2fd79885e45549049c66698f1eea154620230921234746) -- [邀请制小机场](https://breakwalls.us/#/register?code=n1RkASl6) +- [高端奶昔机场](https://nxboom.com/signupbyemail.aspx?MemberCode=2fd79885e45549049c66698f1eea154620230921234746) ## Stargazers over time From 25a0a4293d395d58d583a049fe28b32b0d46cfd6 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka <38254177+FranzKafkaYu@users.noreply.github.com> Date: Thu, 26 Oct 2023 22:14:46 +0800 Subject: [PATCH 80/84] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 5073cbf44f..6533fd9062 100644 --- a/README.md +++ b/README.md @@ -207,6 +207,7 @@ xray 状态: 运行 - [搬瓦工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) +- USDT TRC20:`TY5qQLx8x3oaMxhL3MAFo74dRwBq3Mo7pE` 如果你希望购买一些现成的代理服务,可选择下述代理服务 - [搬瓦工关联机场](https://justmysocks.net/members/aff.php?aff=18177) From 00b9e5e2caa67e26e83752988029b403daae268f Mon Sep 17 00:00:00 2001 From: Yu FranzKafka <38254177+FranzKafkaYu@users.noreply.github.com> Date: Thu, 26 Oct 2023 22:18:01 +0800 Subject: [PATCH 81/84] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6533fd9062..4c585d9ff0 100644 --- a/README.md +++ b/README.md @@ -207,7 +207,7 @@ xray 状态: 运行 - [搬瓦工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) -- USDT TRC20:`TY5qQLx8x3oaMxhL3MAFo74dRwBq3Mo7pE` +- USDT TRC20:`TYZ5MAq5YvtCMsjQDq1TJZnMWmjMVGLk2T` 如果你希望购买一些现成的代理服务,可选择下述代理服务 - [搬瓦工关联机场](https://justmysocks.net/members/aff.php?aff=18177) From a5495048b25076fde8fc611a4d38abdeb0023bf4 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka <38254177+FranzKafkaYu@users.noreply.github.com> Date: Thu, 26 Oct 2023 22:23:43 +0800 Subject: [PATCH 82/84] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4c585d9ff0..483c9b29d0 100644 --- a/README.md +++ b/README.md @@ -207,7 +207,9 @@ xray 状态: 运行 - [搬瓦工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) -- USDT TRC20:`TYZ5MAq5YvtCMsjQDq1TJZnMWmjMVGLk2T` +- USDT TRC20:`TYZ5MAq5YvtCMsjQDq1TJZnMWmjMVGLk2T` +![image](https://github.com/FranzKafkaYu/x-ui/assets/38254177/3e185f19-d19d-4bce-ac4f-24989215fd51) + 如果你希望购买一些现成的代理服务,可选择下述代理服务 - [搬瓦工关联机场](https://justmysocks.net/members/aff.php?aff=18177) From 2c5010538eb881f11f273b6b68129e689fffa471 Mon Sep 17 00:00:00 2001 From: Yu FranzKafka <38254177+FranzKafkaYu@users.noreply.github.com> Date: Tue, 5 Dec 2023 11:27:03 +0800 Subject: [PATCH 83/84] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 483c9b29d0..fa9aab88f9 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ # X-UI 简体中文|[ENGLISH](./README_EN.md) -> 免责声明:该项目仅供个人学习、交流,请遵守当地法律法规,勿用于非法用途;请勿用于生产环境 +> 声明:该项目仅供个人学习、交流,请遵守当地法律法规,勿用于非法用途;请勿用于生产环境 +> 声明:该项目已闭源,介意者请勿使用;如您需要开源代码,请附上您的Github Profile邮箱联系 支持单端口多用户、多协议的 xray 面板,究极缝合怪 通过免费的Telegram bot方便快捷地进行监控、管理你的代理服务 From 9fc75e8121d648cd9d33630af4b573632feb43fd Mon Sep 17 00:00:00 2001 From: Yu FranzKafka <38254177+FranzKafkaYu@users.noreply.github.com> Date: Fri, 8 Mar 2024 21:56:48 +0800 Subject: [PATCH 84/84] Update README.md --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index fa9aab88f9..2af5b4791d 100644 --- a/README.md +++ b/README.md @@ -208,8 +208,6 @@ xray 状态: 运行 - [搬瓦工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) -- USDT TRC20:`TYZ5MAq5YvtCMsjQDq1TJZnMWmjMVGLk2T` -![image](https://github.com/FranzKafkaYu/x-ui/assets/38254177/3e185f19-d19d-4bce-ac4f-24989215fd51) 如果你希望购买一些现成的代理服务,可选择下述代理服务