mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2025-09-08 19:26:19 +00:00
Merge remote-tracking branch 'origin/main' into subscription
# Conflicts: # web/html/xui/client_modal.html # web/html/xui/inbounds.html
This commit is contained in:
commit
10328ad17b
16 changed files with 324 additions and 237 deletions
4
.github/workflows/docker.yml
vendored
4
.github/workflows/docker.yml
vendored
|
@ -1,4 +1,4 @@
|
|||
name: Release 3X-UI dockerhub
|
||||
name: Release 3X-UI for Docker
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
|
@ -36,6 +36,6 @@ jobs:
|
|||
with:
|
||||
context: .
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
platforms: linux/amd64, linux/arm64/v8, linux/arm/v7, linux/arm/v6
|
||||
platforms: linux/amd64, linux/arm64/v8, linux/arm/v7, linux/arm/v6, linux/386, linux/arm/v5
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
|
|
31
.github/workflows/release.yml
vendored
31
.github/workflows/release.yml
vendored
|
@ -15,6 +15,8 @@ jobs:
|
|||
- arm64
|
||||
- armv7
|
||||
- armv6
|
||||
- 386
|
||||
- armv5
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
|
@ -30,8 +32,14 @@ jobs:
|
|||
sudo apt-get update
|
||||
if [ "${{ matrix.platform }}" == "arm64" ]; then
|
||||
sudo apt install gcc-aarch64-linux-gnu
|
||||
elif [ "${{ matrix.platform }}" == "armv7" ] || [ "${{ matrix.platform }}" == "armv6" ]; then
|
||||
elif [ "${{ matrix.platform }}" == "armv7" ]; then
|
||||
sudo apt install gcc-arm-linux-gnueabihf
|
||||
elif [ "${{ matrix.platform }}" == "armv6" ]; then
|
||||
sudo apt install gcc-arm-linux-gnueabihf
|
||||
elif [ "${{ matrix.platform }}" == "386" ]; then
|
||||
sudo apt install gcc-i686-linux-gnu
|
||||
elif [ "${{ matrix.platform }}" == "armv5" ]; then
|
||||
sudo apt install gcc-arm-linux-gnueabi
|
||||
fi
|
||||
|
||||
- name: Build x-ui
|
||||
|
@ -42,10 +50,21 @@ jobs:
|
|||
if [ "${{ matrix.platform }}" == "arm64" ]; then
|
||||
export GOARCH=arm64
|
||||
export CC=aarch64-linux-gnu-gcc
|
||||
elif [ "${{ matrix.platform }}" == "armv7" ] || [ "${{ matrix.platform }}" == "armv6" ]; then
|
||||
elif [ "${{ matrix.platform }}" == "armv7" ]; then
|
||||
export GOARCH=arm
|
||||
export GOARM=7
|
||||
export CC=arm-linux-gnueabihf-gcc
|
||||
elif [ "${{ matrix.platform }}" == "armv6" ]; then
|
||||
export GOARCH=arm
|
||||
export GOARM=6
|
||||
export CC=arm-linux-gnueabihf-gcc
|
||||
elif [ "${{ matrix.platform }}" == "386" ]; then
|
||||
export GOARCH=386
|
||||
export CC=i686-linux-gnu-gcc
|
||||
elif [ "${{ matrix.platform }}" == "armv5" ]; then
|
||||
export GOARCH=arm
|
||||
export GOARM=5
|
||||
export CC=arm-linux-gnueabi-gcc
|
||||
fi
|
||||
go build -o xui-release -v main.go
|
||||
|
||||
|
@ -75,6 +94,14 @@ jobs:
|
|||
wget ${Xray_URL}Xray-linux-arm32-v6.zip
|
||||
unzip Xray-linux-arm32-v6.zip
|
||||
rm -f Xray-linux-arm32-v6.zip
|
||||
elif [ "${{ matrix.platform }}" == "386" ]; then
|
||||
wget ${Xray_URL}Xray-linux-32.zip
|
||||
unzip Xray-linux-32.zip
|
||||
rm -f Xray-linux-32.zip
|
||||
elif [ "${{ matrix.platform }}" == "armv5" ]; then
|
||||
wget ${Xray_URL}Xray-linux-arm32-v5.zip
|
||||
unzip Xray-linux-arm32-v5.zip
|
||||
rm -f Xray-linux-arm32-v5.zip
|
||||
fi
|
||||
rm -f geoip.dat geosite.dat
|
||||
wget https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat
|
||||
|
|
|
@ -5,6 +5,10 @@ case $1 in
|
|||
ARCH="64"
|
||||
FNAME="amd64"
|
||||
;;
|
||||
i386)
|
||||
ARCH="32"
|
||||
FNAME="i386"
|
||||
;;
|
||||
armv8 | arm64 | aarch64)
|
||||
ARCH="arm64-v8a"
|
||||
FNAME="arm64"
|
||||
|
@ -17,6 +21,10 @@ case $1 in
|
|||
ARCH="arm32-v6"
|
||||
FNAME="armv6"
|
||||
;;
|
||||
armv5)
|
||||
ARCH="arm32-v5"
|
||||
FNAME="armv5"
|
||||
;;
|
||||
*)
|
||||
ARCH="64"
|
||||
FNAME="amd64"
|
||||
|
@ -29,7 +37,7 @@ cd build/bin
|
|||
|
||||
wget "https://github.com/XTLS/Xray-core/releases/download/v1.8.7/Xray-linux-${ARCH}.zip"
|
||||
unzip "Xray-linux-${ARCH}.zip"
|
||||
rm -f "Xray-linux-${ARCH}.zip" geoip.dat geosite.dat geoip_IR.dat geosite_IR.dat geoip_VN.dat geosite_VN.dat
|
||||
rm -f "Xray-linux-${ARCH}.zip" geoip.dat geosite.dat
|
||||
mv xray "xray-linux-${FNAME}"
|
||||
|
||||
wget https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat
|
||||
|
|
29
README.md
29
README.md
|
@ -127,7 +127,22 @@ update to latest version
|
|||
- AlmaLinux 9+
|
||||
- Rockylinux 9+
|
||||
|
||||
## Compatible Architectures & Devices
|
||||
|
||||
Supports a variety of different architectures and devices. Here are some of the main architectures that we support:
|
||||
|
||||
- **amd64**: This is the most common architecture for personal computers and servers. It supports most modern operating systems.
|
||||
|
||||
- **x86 / i386**: This architecture is prevalent in desktop and laptop computers. It's widely supported by various operating systems and applications. (Ex: Most Windows, macOS, and Linux systems)
|
||||
|
||||
- **armv8 / arm64 / aarch64**: This is the architecture for modern mobile and embedded devices, including smartphones and tablets. (Ex: Raspberry Pi 4, Raspberry Pi 3, Raspberry Pi Zero 2/Zero 2 W, Orange Pi 3 LTS,...)
|
||||
|
||||
- **armv7 / arm / arm32**: This is the architecture for older mobile and embedded devices. It is still widely used in many devices. (Ex: Orange Pi Zero LTS, Orange Pi PC Plus, Raspberry Pi 2,...)
|
||||
|
||||
- **armv6 / arm / arm32**: This is the architecture for very old embedded devices. While not as common as before, there are still some devices using this architecture. (Ex: Raspberry Pi 1, Raspberry Pi Zero/Zero W,...)
|
||||
|
||||
- **armv5 / arm / arm32**: This is an older architecture primarily used in early embedded systems. While it's less common today, some legacy devices may still rely on this architecture. (Ex: Early versions of Raspberry Pi, some older smartphones)
|
||||
|
||||
## Languages
|
||||
|
||||
- English
|
||||
|
@ -398,20 +413,6 @@ XUI_BIN_FOLDER="bin" XUI_DB_FOLDER="/etc/x-ui" go build main.go
|
|||
|
||||
</details>
|
||||
|
||||
|
||||
## Supported Architectures and Devices
|
||||
|
||||
Supports a variety of different architectures and devices. Here are some of the main architectures that we support:
|
||||
|
||||
- **amd64**: This is the most common architecture for personal computers and servers. It supports most modern operating systems.
|
||||
|
||||
- **armv8 / arm64 / aarch64**: This is the architecture for modern mobile and embedded devices, including smartphones and tablets. (Ex: Raspberry Pi 4, Raspberry Pi 3, Raspberry Pi Zero 2/Zero 2 W, Orange Pi 3 LTS,...)
|
||||
|
||||
- **armv7 / arm / arm32**: This is the architecture for older mobile and embedded devices. It is still widely used in many devices. (Ex: Orange Pi Zero LTS, Orange Pi PC Plus, Raspberry Pi 2,...)
|
||||
|
||||
- **armv6 / arm / arm32**: This is the architecture for very old embedded devices. While not as common as before, there are still some devices using this architecture. (Ex: Raspberry Pi 1, Raspberry Pi Zero/Zero W,...)
|
||||
|
||||
|
||||
## Preview
|
||||
|
||||

|
||||
|
|
2
go.mod
2
go.mod
|
@ -36,7 +36,7 @@ require (
|
|||
github.com/go-ole/go-ole v1.3.0 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.16.0 // indirect
|
||||
github.com/go-playground/validator/v10 v10.17.0 // indirect
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/google/btree v1.1.2 // indirect
|
||||
|
|
4
go.sum
4
go.sum
|
@ -76,8 +76,8 @@ github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl
|
|||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
|
||||
github.com/go-playground/validator/v10 v10.16.0 h1:x+plE831WK4vaKHO/jpgUGsvLKIqRRkz6M78GuJAfGE=
|
||||
github.com/go-playground/validator/v10 v10.16.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
|
||||
github.com/go-playground/validator/v10 v10.17.0 h1:SmVVlfAOtlZncTxRuinDPomC2DkXJ4E5T9gDA0AIH74=
|
||||
github.com/go-playground/validator/v10 v10.17.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
||||
github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
|
|
36
install.sh
36
install.sh
|
@ -26,12 +26,15 @@ echo "The OS release is: $release"
|
|||
arch3xui() {
|
||||
case "$(uname -m)" in
|
||||
x86_64 | x64 | amd64) echo 'amd64' ;;
|
||||
i*86 | x86) echo '386' ;;
|
||||
armv8* | armv8 | arm64 | aarch64) echo 'arm64' ;;
|
||||
armv7* | armv7 | arm) echo 'armv7' ;;
|
||||
armv6* | armv6 | arm) echo 'armv6' ;;
|
||||
armv6* | armv6) echo 'armv6' ;;
|
||||
armv5* | armv5) echo 'armv5' ;;
|
||||
*) echo -e "${green}Unsupported CPU architecture! ${plain}" && rm -f install.sh && exit 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
echo "arch: $(arch3xui)"
|
||||
|
||||
os_version=""
|
||||
|
@ -78,19 +81,21 @@ fi
|
|||
|
||||
install_base() {
|
||||
case "${release}" in
|
||||
centos|fedora|almalinux|rocky)
|
||||
yum -y update && yum install -y -q wget curl tar
|
||||
;;
|
||||
arch|manjaro)
|
||||
pacman -Syu && pacman -Syu --noconfirm wget curl tar
|
||||
;;
|
||||
*)
|
||||
apt-get update && apt install -y -q wget curl tar
|
||||
;;
|
||||
centos | almalinux | rocky)
|
||||
yum -y update && yum install -y -q wget curl tar
|
||||
;;
|
||||
fedora)
|
||||
dnf -y update && dnf install -y -q wget curl tar
|
||||
;;
|
||||
arch | manjaro)
|
||||
pacman -Syu && pacman -Syu --noconfirm wget curl tar
|
||||
;;
|
||||
*)
|
||||
apt-get update && apt install -y -q wget curl tar
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
|
||||
# This function will be called when user installed x-ui out of security
|
||||
config_after_install() {
|
||||
echo -e "${yellow}Install/update finished! For security it's recommended to modify panel settings ${plain}"
|
||||
|
@ -163,11 +168,11 @@ install_x-ui() {
|
|||
chmod +x x-ui
|
||||
|
||||
# Check the system's architecture and rename the file accordingly
|
||||
if [[ $(arch3xui) == "armv6" || $(arch3xui) == "armv7" ]]; then
|
||||
mv bin/xray-linux-$(arch3xui) bin/xray-linux-arm
|
||||
chmod +x bin/xray-linux-arm
|
||||
if [[ $(arch3xui) == "armv5" || $(arch3xui) == "armv6" || $(arch3xui) == "armv7" ]]; then
|
||||
mv bin/xray-linux-$(arch3xui) bin/xray-linux-arm
|
||||
chmod +x bin/xray-linux-arm
|
||||
fi
|
||||
|
||||
|
||||
chmod +x x-ui bin/xray-linux-$(arch3xui)
|
||||
cp -f x-ui.service /etc/systemd/system/
|
||||
wget --no-check-certificate -O /usr/bin/x-ui https://raw.githubusercontent.com/MHSanaei/3x-ui/main/x-ui.sh
|
||||
|
@ -197,7 +202,6 @@ install_x-ui() {
|
|||
echo -e "----------------------------------------------"
|
||||
}
|
||||
|
||||
|
||||
echo -e "${green}Running...${plain}"
|
||||
install_base
|
||||
install_x-ui $1
|
||||
|
|
|
@ -162,24 +162,31 @@ func (a *InboundController) clearClientIps(c *gin.Context) {
|
|||
}
|
||||
|
||||
func (a *InboundController) addInboundClient(c *gin.Context) {
|
||||
data := &model.Inbound{}
|
||||
err := c.ShouldBind(data)
|
||||
if err != nil {
|
||||
jsonMsg(c, I18nWeb(c, "pages.inbounds.update"), err)
|
||||
return
|
||||
}
|
||||
var requestData []model.Inbound
|
||||
|
||||
needRestart := true
|
||||
err := c.ShouldBindJSON(&requestData)
|
||||
|
||||
if err != nil {
|
||||
jsonMsg(c, I18nWeb(c, "pages.inbounds.update"), err)
|
||||
return
|
||||
}
|
||||
|
||||
needRestart := true
|
||||
|
||||
for _, data := range requestData {
|
||||
|
||||
needRestart, err = a.inboundService.AddInboundClient(&data)
|
||||
if err != nil {
|
||||
jsonMsg(c, "Something went wrong!", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
jsonMsg(c, "Client(s) added", nil)
|
||||
if err == nil && needRestart {
|
||||
a.xrayService.SetToNeedRestart()
|
||||
}
|
||||
|
||||
needRestart, err = a.inboundService.AddInboundClient(data)
|
||||
if err != nil {
|
||||
jsonMsg(c, "Something went wrong!", err)
|
||||
return
|
||||
}
|
||||
jsonMsg(c, "Client(s) added", nil)
|
||||
if err == nil && needRestart {
|
||||
a.xrayService.SetToNeedRestart()
|
||||
}
|
||||
}
|
||||
|
||||
func (a *InboundController) addGroupInboundClient(c *gin.Context) {
|
||||
|
|
|
@ -16,17 +16,18 @@ import (
|
|||
"x-ui/xray"
|
||||
)
|
||||
|
||||
type CheckClientIpJob struct{}
|
||||
type CheckClientIpJob struct {
|
||||
disAllowedIps []string
|
||||
}
|
||||
|
||||
var job *CheckClientIpJob
|
||||
var disAllowedIps []string
|
||||
var ipFiles = []string{
|
||||
xray.GetIPLimitLogPath(),
|
||||
xray.GetIPLimitPrevLogPath(),
|
||||
xray.GetIPLimitPrevLogPath(),
|
||||
xray.GetIPLimitBannedLogPath(),
|
||||
xray.GetIPLimitBannedPrevLogPath(),
|
||||
xray.GetIPLimitBannedPrevLogPath(),
|
||||
xray.GetAccessPersistentLogPath(),
|
||||
xray.GetAccessPersistentPrevLogPath(),
|
||||
xray.GetAccessPersistentPrevLogPath(),
|
||||
}
|
||||
|
||||
func NewCheckClientIpJob() *CheckClientIpJob {
|
||||
|
@ -130,7 +131,6 @@ func (j *CheckClientIpJob) processLogFile() {
|
|||
}
|
||||
}
|
||||
|
||||
disAllowedIps = []string{}
|
||||
shouldCleanLog := false
|
||||
|
||||
for clientEmail, ips := range InboundClientIps {
|
||||
|
@ -237,6 +237,7 @@ func (j *CheckClientIpJob) updateInboundClientIps(inboundClientIps *model.Inboun
|
|||
json.Unmarshal([]byte(inbound.Settings), &settings)
|
||||
clients := settings["clients"]
|
||||
shouldCleanLog := false
|
||||
j.disAllowedIps = []string{}
|
||||
|
||||
// create iplimit log file channel
|
||||
logIpFile, err := os.OpenFile(xray.GetIPLimitLogPath(), os.O_CREATE|os.O_APPEND|os.O_RDWR, 0644)
|
||||
|
@ -255,7 +256,7 @@ func (j *CheckClientIpJob) updateInboundClientIps(inboundClientIps *model.Inboun
|
|||
shouldCleanLog = true
|
||||
|
||||
if limitIp < len(ips) && inbound.Enable {
|
||||
disAllowedIps = append(disAllowedIps, ips[limitIp:]...)
|
||||
j.disAllowedIps = append(j.disAllowedIps, ips[limitIp:]...)
|
||||
for i := limitIp; i < len(ips); i++ {
|
||||
log.Printf("[LIMIT_IP] Email = %s || SRC = %s", clientEmail, ips[i])
|
||||
}
|
||||
|
@ -263,8 +264,12 @@ func (j *CheckClientIpJob) updateInboundClientIps(inboundClientIps *model.Inboun
|
|||
}
|
||||
}
|
||||
}
|
||||
logger.Debug("disAllowedIps ", disAllowedIps)
|
||||
sort.Strings(disAllowedIps)
|
||||
|
||||
sort.Strings(j.disAllowedIps)
|
||||
|
||||
if len(j.disAllowedIps) > 0 {
|
||||
logger.Debug("disAllowedIps ", j.disAllowedIps)
|
||||
}
|
||||
|
||||
db := database.GetDB()
|
||||
err = db.Save(inboundClientIps).Error
|
||||
|
|
|
@ -178,7 +178,7 @@
|
|||
"info" = "Info"
|
||||
"same" = "Same"
|
||||
"inboundData" = "Inbound's Data"
|
||||
"copyToClipboard" = "Copy to Clipboard"
|
||||
"exportInbound" = "Export Inbound"
|
||||
"import" = "Import"
|
||||
"importInbound" = "Import an Inbound"
|
||||
"isGroupEdit" = "Group editing"
|
||||
|
|
|
@ -178,7 +178,7 @@
|
|||
"info" = "Info"
|
||||
"same" = "misma"
|
||||
"inboundData" = "Datos de entrada"
|
||||
"copyToClipboard" = "Copiar al portapapeles"
|
||||
"exportInbound" = "Exportación entrante"
|
||||
"import" = "Importar"
|
||||
"importInbound" = "Importar un entrante"
|
||||
"isGroupEdit" = "Edición de grupo"
|
||||
|
|
|
@ -178,7 +178,7 @@
|
|||
"info" = "اطلاعات"
|
||||
"same" = "همسان"
|
||||
"inboundData" = "دادههای ورودی"
|
||||
"copyToClipboard" = "کپی در حافظه"
|
||||
"exportInbound" = "استخراج ورودی"
|
||||
"import" = "افزودن"
|
||||
"importInbound" = "افزودن یک ورودی"
|
||||
"isGroupEdit" = "ویرایش گروهی"
|
||||
|
|
|
@ -178,7 +178,7 @@
|
|||
"info" = "Информация"
|
||||
"same" = "Тот же"
|
||||
"inboundData" = "Входящие данные"
|
||||
"copyToClipboard" = "Копировать в буфер обмена"
|
||||
"exportInbound" = "Экспорт входящих"
|
||||
"import" = "Импортировать"
|
||||
"importInbound" = "Импортировать входящее сообщение"
|
||||
"isGroupEdit" = "Редактирование группы"
|
||||
|
|
|
@ -74,9 +74,9 @@
|
|||
|
||||
[pages.index]
|
||||
"title" = "Trạng thái hệ thống"
|
||||
"memory" = "Bộ nhớ"
|
||||
"memory" = "Ram"
|
||||
"hard" = "Dung lượng"
|
||||
"xrayStatus" = "Trạng thái"
|
||||
"xrayStatus" = "Trạng thái Xray"
|
||||
"stopXray" = "Dừng lại"
|
||||
"restartXray" = "Khởi động lại"
|
||||
"xraySwitch" = "Phiên bản"
|
||||
|
@ -178,7 +178,7 @@
|
|||
"info" = "Thông tin"
|
||||
"same" = "Giống nhau"
|
||||
"inboundData" = "Dữ liệu gửi đến"
|
||||
"copyToClipboard" = "Sao chép vào bảng nhớ tạm"
|
||||
"exportInbound" = "Xuất nhập khẩu"
|
||||
"import" = "Nhập"
|
||||
"importInbound" = "Nhập inbound"
|
||||
"isGroupEdit" = "Chỉnh sửa nhóm"
|
||||
|
|
|
@ -178,7 +178,7 @@
|
|||
"info" = "信息"
|
||||
"same" = "相同"
|
||||
"inboundData" = "入站数据"
|
||||
"copyToClipboard" = "复制到剪贴板"
|
||||
"exportInbound" = "出口 入境"
|
||||
"import"="导入"
|
||||
"importInbound" = "导入入站"
|
||||
"isGroupEdit" = "分组编辑"
|
||||
|
|
367
x-ui.sh
367
x-ui.sh
|
@ -70,13 +70,11 @@ elif [[ "${release}" == "armbian" ]]; then
|
|||
echo "Your OS is Armbian"
|
||||
fi
|
||||
|
||||
|
||||
# Declare Variables
|
||||
log_folder="${XUI_LOG_FOLDER:=/var/log}"
|
||||
iplimit_log_path="${log_folder}/3xipl.log"
|
||||
iplimit_banned_log_path="${log_folder}/3xipl-banned.log"
|
||||
|
||||
|
||||
confirm() {
|
||||
if [[ $# > 1 ]]; then
|
||||
echo && read -p "$1 [Default $2]: " temp
|
||||
|
@ -140,7 +138,7 @@ custom_version() {
|
|||
|
||||
if [ -z "$panel_version" ]; then
|
||||
echo "Panel version cannot be empty. Exiting."
|
||||
exit 1
|
||||
exit 1
|
||||
fi
|
||||
|
||||
download_link="https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh"
|
||||
|
@ -329,15 +327,15 @@ show_log() {
|
|||
}
|
||||
|
||||
show_banlog() {
|
||||
if test -f "${iplimit_banned_log_path}"; then
|
||||
if [[ -s "${iplimit_banned_log_path}" ]]; then
|
||||
cat ${iplimit_banned_log_path}
|
||||
if test -f "${iplimit_banned_log_path}"; then
|
||||
if [[ -s "${iplimit_banned_log_path}" ]]; then
|
||||
cat ${iplimit_banned_log_path}
|
||||
else
|
||||
echo -e "${red}Log file is empty.${plain}\n"
|
||||
fi
|
||||
else
|
||||
echo -e "${red}Log file is empty.${plain}\n"
|
||||
echo -e "${red}Log file not found. Please Install Fail2ban and IP Limit first.${plain}\n"
|
||||
fi
|
||||
else
|
||||
echo -e "${red}Log file not found. Please Install Fail2ban and IP Limit first.${plain}\n"
|
||||
fi
|
||||
}
|
||||
|
||||
enable_bbr() {
|
||||
|
@ -348,19 +346,19 @@ enable_bbr() {
|
|||
|
||||
# Check the OS and install necessary packages
|
||||
case "${release}" in
|
||||
ubuntu|debian)
|
||||
apt-get update && apt-get install -yqq --no-install-recommends ca-certificates
|
||||
;;
|
||||
centos|almalinux|rocky)
|
||||
yum -y update && yum -y install ca-certificates
|
||||
;;
|
||||
fedora)
|
||||
dnf -y update && dnf -y install ca-certificates
|
||||
;;
|
||||
*)
|
||||
echo -e "${red}Unsupported operating system. Please check the script and install the necessary packages manually.${plain}\n"
|
||||
exit 1
|
||||
;;
|
||||
ubuntu | debian)
|
||||
apt-get update && apt-get install -yqq --no-install-recommends ca-certificates
|
||||
;;
|
||||
centos | almalinux | rocky)
|
||||
yum -y update && yum -y install ca-certificates
|
||||
;;
|
||||
fedora)
|
||||
dnf -y update && dnf -y install ca-certificates
|
||||
;;
|
||||
*)
|
||||
echo -e "${red}Unsupported operating system. Please check the script and install the necessary packages manually.${plain}\n"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Enable BBR
|
||||
|
@ -581,21 +579,24 @@ ssl_cert_issue_main() {
|
|||
echo -e "${green}\t0.${plain} Back to Main Menu"
|
||||
read -p "Choose an option: " choice
|
||||
case "$choice" in
|
||||
0)
|
||||
show_menu ;;
|
||||
1)
|
||||
ssl_cert_issue ;;
|
||||
2)
|
||||
local domain=""
|
||||
read -p "Please enter your domain name to revoke the certificate: " domain
|
||||
~/.acme.sh/acme.sh --revoke -d ${domain}
|
||||
LOGI "Certificate revoked"
|
||||
;;
|
||||
3)
|
||||
local domain=""
|
||||
read -p "Please enter your domain name to forcefully renew an SSL certificate: " domain
|
||||
~/.acme.sh/acme.sh --renew -d ${domain} --force ;;
|
||||
*) echo "Invalid choice" ;;
|
||||
0)
|
||||
show_menu
|
||||
;;
|
||||
1)
|
||||
ssl_cert_issue
|
||||
;;
|
||||
2)
|
||||
local domain=""
|
||||
read -p "Please enter your domain name to revoke the certificate: " domain
|
||||
~/.acme.sh/acme.sh --revoke -d ${domain}
|
||||
LOGI "Certificate revoked"
|
||||
;;
|
||||
3)
|
||||
local domain=""
|
||||
read -p "Please enter your domain name to forcefully renew an SSL certificate: " domain
|
||||
~/.acme.sh/acme.sh --renew -d ${domain} --force
|
||||
;;
|
||||
*) echo "Invalid choice" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
|
@ -611,15 +612,19 @@ ssl_cert_issue() {
|
|||
fi
|
||||
# install socat second
|
||||
case "${release}" in
|
||||
ubuntu|debian|armbian)
|
||||
apt update && apt install socat -y ;;
|
||||
centos|almalinux|rocky)
|
||||
yum -y update && yum -y install socat ;;
|
||||
fedora)
|
||||
dnf -y update && dnf -y install socat ;;
|
||||
*)
|
||||
echo -e "${red}Unsupported operating system. Please check the script and install the necessary packages manually.${plain}\n"
|
||||
exit 1 ;;
|
||||
ubuntu | debian | armbian)
|
||||
apt update && apt install socat -y
|
||||
;;
|
||||
centos | almalinux | rocky)
|
||||
yum -y update && yum -y install socat
|
||||
;;
|
||||
fedora)
|
||||
dnf -y update && dnf -y install socat
|
||||
;;
|
||||
*)
|
||||
echo -e "${red}Unsupported operating system. Please check the script and install the necessary packages manually.${plain}\n"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
if [ $? -ne 0 ]; then
|
||||
LOGE "install socat failed, please check logs"
|
||||
|
@ -750,8 +755,8 @@ ssl_cert_issue_CF() {
|
|||
LOGI "Certificate issued Successfully, 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 "Certificate installation failed, script exiting..."
|
||||
exit 1
|
||||
|
@ -782,21 +787,22 @@ warp_cloudflare() {
|
|||
echo -e "${green}\t0.${plain} Back to Main Menu"
|
||||
read -p "Choose an option: " choice
|
||||
case "$choice" in
|
||||
0)
|
||||
show_menu ;;
|
||||
1)
|
||||
bash <(curl -sSL https://raw.githubusercontent.com/hamid-gh98/x-ui-scripts/main/install_warp_proxy.sh)
|
||||
;;
|
||||
2)
|
||||
warp a
|
||||
;;
|
||||
3)
|
||||
warp y
|
||||
;;
|
||||
4)
|
||||
warp u
|
||||
;;
|
||||
*) echo "Invalid choice" ;;
|
||||
0)
|
||||
show_menu
|
||||
;;
|
||||
1)
|
||||
bash <(curl -sSL https://raw.githubusercontent.com/hamid-gh98/x-ui-scripts/main/install_warp_proxy.sh)
|
||||
;;
|
||||
2)
|
||||
warp a
|
||||
;;
|
||||
3)
|
||||
warp y
|
||||
;;
|
||||
4)
|
||||
warp u
|
||||
;;
|
||||
*) echo "Invalid choice" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
|
@ -809,45 +815,46 @@ multi_protocol() {
|
|||
echo -e "${green}\t0.${plain} Back to Main Menu"
|
||||
read -p "Choose an option: " choice
|
||||
case "$choice" in
|
||||
0)
|
||||
show_menu ;;
|
||||
1)
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/M4mmad/3xui-multi-protocol/master/install.sh --ipv4)
|
||||
;;
|
||||
2)
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/M4mmad/3xui-multi-protocol/master/unistall.sh --ipv4)
|
||||
;;
|
||||
3)
|
||||
systemctl start 3xui-multi-protocol
|
||||
;;
|
||||
4)
|
||||
systemctl stop 3xui-multi-protocol
|
||||
;;
|
||||
*) echo "Invalid choice" ;;
|
||||
0)
|
||||
show_menu
|
||||
;;
|
||||
1)
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/M4mmad/3xui-multi-protocol/master/install.sh --ipv4)
|
||||
;;
|
||||
2)
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/M4mmad/3xui-multi-protocol/master/unistall.sh --ipv4)
|
||||
;;
|
||||
3)
|
||||
systemctl start 3xui-multi-protocol
|
||||
;;
|
||||
4)
|
||||
systemctl stop 3xui-multi-protocol
|
||||
;;
|
||||
*) echo "Invalid choice" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
run_speedtest() {
|
||||
# Check if Speedtest is already installed
|
||||
if ! command -v speedtest &> /dev/null; then
|
||||
if ! command -v speedtest &>/dev/null; then
|
||||
# If not installed, install it
|
||||
local pkg_manager=""
|
||||
local speedtest_install_script=""
|
||||
|
||||
if command -v dnf &> /dev/null; then
|
||||
|
||||
if command -v dnf &>/dev/null; then
|
||||
pkg_manager="dnf"
|
||||
speedtest_install_script="https://packagecloud.io/install/repositories/ookla/speedtest-cli/script.rpm.sh"
|
||||
elif command -v yum &> /dev/null; then
|
||||
elif command -v yum &>/dev/null; then
|
||||
pkg_manager="yum"
|
||||
speedtest_install_script="https://packagecloud.io/install/repositories/ookla/speedtest-cli/script.rpm.sh"
|
||||
elif command -v apt-get &> /dev/null; then
|
||||
elif command -v apt-get &>/dev/null; then
|
||||
pkg_manager="apt-get"
|
||||
speedtest_install_script="https://packagecloud.io/install/repositories/ookla/speedtest-cli/script.deb.sh"
|
||||
elif command -v apt &> /dev/null; then
|
||||
elif command -v apt &>/dev/null; then
|
||||
pkg_manager="apt"
|
||||
speedtest_install_script="https://packagecloud.io/install/repositories/ookla/speedtest-cli/script.deb.sh"
|
||||
fi
|
||||
|
||||
|
||||
if [[ -z $pkg_manager ]]; then
|
||||
echo "Error: Package manager not found. You may need to install Speedtest manually."
|
||||
return 1
|
||||
|
@ -862,8 +869,11 @@ run_speedtest() {
|
|||
}
|
||||
|
||||
create_iplimit_jails() {
|
||||
# Use default bantime if not passed => 5 minutes
|
||||
local bantime="${1:-5}"
|
||||
# Use default bantime if not passed => 30 minutes
|
||||
local bantime="${1:-30}"
|
||||
|
||||
# Uncomment 'allowipv6 = auto' in fail2ban.conf
|
||||
sed -i 's/#allowipv6 = auto/allowipv6 = auto/g' /etc/fail2ban/fail2ban.conf
|
||||
|
||||
cat << EOF > /etc/fail2ban/jail.d/3x-ipl.conf
|
||||
[3x-ipl]
|
||||
|
@ -907,7 +917,7 @@ actionunban = <iptables> -D f2b-<name> -s <ip> -j <blocktype>
|
|||
[Init]
|
||||
EOF
|
||||
|
||||
echo -e "${green}Created Ip Limit jail files with a bantime of ${bantime} minutes.${plain}"
|
||||
echo -e "${green}Ip Limit jail files created with a bantime of ${bantime} minutes.${plain}"
|
||||
}
|
||||
|
||||
iplimit_remove_conflicts() {
|
||||
|
@ -935,61 +945,73 @@ iplimit_main() {
|
|||
echo -e "${green}\t0.${plain} Back to Main Menu"
|
||||
read -p "Choose an option: " choice
|
||||
case "$choice" in
|
||||
0)
|
||||
show_menu ;;
|
||||
1)
|
||||
confirm "Proceed with installation of Fail2ban & IP Limit?" "y"
|
||||
if [[ $? == 0 ]]; then
|
||||
install_iplimit
|
||||
else
|
||||
iplimit_main
|
||||
fi ;;
|
||||
2)
|
||||
read -rp "Please enter new Ban Duration in Minutes [default 5]: " NUM
|
||||
if [[ $NUM =~ ^[0-9]+$ ]]; then
|
||||
create_iplimit_jails ${NUM}
|
||||
systemctl restart fail2ban
|
||||
else
|
||||
echo -e "${red}${NUM} is not a number! Please, try again.${plain}"
|
||||
fi
|
||||
iplimit_main ;;
|
||||
3)
|
||||
confirm "Proceed with Unbanning everyone from IP Limit jail?" "y"
|
||||
if [[ $? == 0 ]]; then
|
||||
fail2ban-client reload --restart --unban 3x-ipl
|
||||
echo -e "${green}All users Unbanned successfully.${plain}"
|
||||
iplimit_main
|
||||
else
|
||||
echo -e "${yellow}Cancelled.${plain}"
|
||||
fi
|
||||
iplimit_main ;;
|
||||
4)
|
||||
show_banlog
|
||||
;;
|
||||
5)
|
||||
service fail2ban status
|
||||
;;
|
||||
0)
|
||||
show_menu
|
||||
;;
|
||||
1)
|
||||
confirm "Proceed with installation of Fail2ban & IP Limit?" "y"
|
||||
if [[ $? == 0 ]]; then
|
||||
install_iplimit
|
||||
else
|
||||
iplimit_main
|
||||
fi
|
||||
;;
|
||||
2)
|
||||
read -rp "Please enter new Ban Duration in Minutes [default 30]: " NUM
|
||||
if [[ $NUM =~ ^[0-9]+$ ]]; then
|
||||
create_iplimit_jails ${NUM}
|
||||
systemctl restart fail2ban
|
||||
else
|
||||
echo -e "${red}${NUM} is not a number! Please, try again.${plain}"
|
||||
fi
|
||||
iplimit_main
|
||||
;;
|
||||
3)
|
||||
confirm "Proceed with Unbanning everyone from IP Limit jail?" "y"
|
||||
if [[ $? == 0 ]]; then
|
||||
fail2ban-client reload --restart --unban 3x-ipl
|
||||
truncate -s 0 "${iplimit_banned_log_path}"
|
||||
echo -e "${green}All users Unbanned successfully.${plain}"
|
||||
iplimit_main
|
||||
else
|
||||
echo -e "${yellow}Cancelled.${plain}"
|
||||
fi
|
||||
iplimit_main
|
||||
;;
|
||||
4)
|
||||
show_banlog
|
||||
;;
|
||||
5)
|
||||
service fail2ban status
|
||||
;;
|
||||
|
||||
6)
|
||||
remove_iplimit ;;
|
||||
*) echo "Invalid choice" ;;
|
||||
6)
|
||||
remove_iplimit
|
||||
;;
|
||||
*) echo "Invalid choice" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
install_iplimit() {
|
||||
if ! command -v fail2ban-client &>/dev/null; then
|
||||
echo -e "${green}Fail2ban is not installed. Installing now...!${plain}\n"
|
||||
|
||||
# Check the OS and install necessary packages
|
||||
case "${release}" in
|
||||
ubuntu|debian)
|
||||
apt update && apt install fail2ban -y ;;
|
||||
centos|almalinux|rocky)
|
||||
yum -y update && yum -y install fail2ban ;;
|
||||
fedora)
|
||||
dnf -y update && dnf -y install fail2ban ;;
|
||||
*)
|
||||
echo -e "${red}Unsupported operating system. Please check the script and install the necessary packages manually.${plain}\n"
|
||||
exit 1 ;;
|
||||
ubuntu | debian)
|
||||
apt update && apt install fail2ban -y
|
||||
;;
|
||||
centos | almalinux | rocky)
|
||||
yum update -y && yum install epel-release -y
|
||||
yum -y install fail2ban
|
||||
;;
|
||||
fedora)
|
||||
dnf -y update && dnf -y install fail2ban
|
||||
;;
|
||||
*)
|
||||
echo -e "${red}Unsupported operating system. Please check the script and install the necessary packages manually.${plain}\n"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
if ! command -v fail2ban-client &>/dev/null; then
|
||||
|
@ -1024,6 +1046,7 @@ install_iplimit() {
|
|||
# Launching fail2ban
|
||||
if ! systemctl is-active --quiet fail2ban; then
|
||||
systemctl start fail2ban
|
||||
systemctl enable fail2ban
|
||||
else
|
||||
systemctl restart fail2ban
|
||||
fi
|
||||
|
@ -1033,41 +1056,53 @@ install_iplimit() {
|
|||
before_show_menu
|
||||
}
|
||||
|
||||
remove_iplimit(){
|
||||
remove_iplimit() {
|
||||
echo -e "${green}\t1.${plain} Only remove IP Limit configurations"
|
||||
echo -e "${green}\t2.${plain} Uninstall Fail2ban and IP Limit"
|
||||
echo -e "${green}\t0.${plain} Abort"
|
||||
read -p "Choose an option: " num
|
||||
case "$num" in
|
||||
1)
|
||||
rm -f /etc/fail2ban/filter.d/3x-ipl.conf
|
||||
rm -f /etc/fail2ban/action.d/3x-ipl.conf
|
||||
rm -f /etc/fail2ban/jail.d/3x-ipl.conf
|
||||
systemctl restart fail2ban
|
||||
echo -e "${green}IP Limit removed successfully!${plain}\n"
|
||||
before_show_menu ;;
|
||||
2)
|
||||
rm -rf /etc/fail2ban
|
||||
systemctl stop fail2ban
|
||||
case "${release}" in
|
||||
ubuntu|debian)
|
||||
apt-get purge fail2ban -y;;
|
||||
centos|almalinux|rocky)
|
||||
yum remove fail2ban -y;;
|
||||
fedora)
|
||||
dnf remove fail2ban -y;;
|
||||
*)
|
||||
echo -e "${red}Unsupported operating system. Please uninstall Fail2ban manually.${plain}\n"
|
||||
exit 1 ;;
|
||||
esac
|
||||
echo -e "${green}Fail2ban and IP Limit removed successfully!${plain}\n"
|
||||
before_show_menu ;;
|
||||
0)
|
||||
echo -e "${yellow}Cancelled.${plain}\n"
|
||||
iplimit_main ;;
|
||||
*)
|
||||
echo -e "${red}Invalid option. Please select a valid number.${plain}\n"
|
||||
remove_iplimit ;;
|
||||
1)
|
||||
rm -f /etc/fail2ban/filter.d/3x-ipl.conf
|
||||
rm -f /etc/fail2ban/action.d/3x-ipl.conf
|
||||
rm -f /etc/fail2ban/jail.d/3x-ipl.conf
|
||||
systemctl restart fail2ban
|
||||
echo -e "${green}IP Limit removed successfully!${plain}\n"
|
||||
before_show_menu
|
||||
;;
|
||||
2)
|
||||
rm -rf /etc/fail2ban
|
||||
systemctl stop fail2ban
|
||||
case "${release}" in
|
||||
ubuntu | debian)
|
||||
apt-get remove -y fail2ban
|
||||
apt-get purge -y fail2ban -y
|
||||
apt-get autoremove -y
|
||||
;;
|
||||
centos | almalinux | rocky)
|
||||
yum remove fail2ban -y
|
||||
yum autoremove -y
|
||||
;;
|
||||
fedora)
|
||||
dnf remove fail2ban -y
|
||||
dnf autoremove -y
|
||||
;;
|
||||
*)
|
||||
echo -e "${red}Unsupported operating system. Please uninstall Fail2ban manually.${plain}\n"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
echo -e "${green}Fail2ban and IP Limit removed successfully!${plain}\n"
|
||||
before_show_menu
|
||||
;;
|
||||
0)
|
||||
echo -e "${yellow}Cancelled.${plain}\n"
|
||||
iplimit_main
|
||||
;;
|
||||
*)
|
||||
echo -e "${red}Invalid option. Please select a valid number.${plain}\n"
|
||||
remove_iplimit
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
|
@ -1202,7 +1237,7 @@ show_menu() {
|
|||
;;
|
||||
24)
|
||||
run_speedtest
|
||||
;;
|
||||
;;
|
||||
*)
|
||||
LOGE "Please enter the correct number [0-24]"
|
||||
;;
|
||||
|
|
Loading…
Reference in a new issue