Merge branch 'main' into main
2
.github/workflows/release.yml
vendored
|
@ -83,7 +83,7 @@ jobs:
|
||||||
cd x-ui/bin
|
cd x-ui/bin
|
||||||
|
|
||||||
# Download dependencies
|
# Download dependencies
|
||||||
Xray_URL="https://github.com/XTLS/Xray-core/releases/download/v24.10.31/"
|
Xray_URL="https://github.com/XTLS/Xray-core/releases/download/v24.11.21/"
|
||||||
if [ "${{ matrix.platform }}" == "amd64" ]; then
|
if [ "${{ matrix.platform }}" == "amd64" ]; then
|
||||||
wget ${Xray_URL}Xray-linux-64.zip
|
wget ${Xray_URL}Xray-linux-64.zip
|
||||||
unzip Xray-linux-64.zip
|
unzip Xray-linux-64.zip
|
||||||
|
|
|
@ -27,7 +27,7 @@ case $1 in
|
||||||
esac
|
esac
|
||||||
mkdir -p build/bin
|
mkdir -p build/bin
|
||||||
cd build/bin
|
cd build/bin
|
||||||
wget "https://github.com/XTLS/Xray-core/releases/download/v24.10.31/Xray-linux-${ARCH}.zip"
|
wget "https://github.com/XTLS/Xray-core/releases/download/v24.11.21/Xray-linux-${ARCH}.zip"
|
||||||
unzip "Xray-linux-${ARCH}.zip"
|
unzip "Xray-linux-${ARCH}.zip"
|
||||||
rm -f "Xray-linux-${ARCH}.zip" geoip.dat geosite.dat
|
rm -f "Xray-linux-${ARCH}.zip" geoip.dat geosite.dat
|
||||||
mv xray "xray-linux-${FNAME}"
|
mv xray "xray-linux-${FNAME}"
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
[English](/README.md) | [中文](/README.zh_CN.md) | [Español](/README.es_ES.md) | [Русский](/README.ru_RU.md)
|
[English](/README.md) | [中文](/README.zh_CN.md) | [Español](/README.es_ES.md) | [Русский](/README.ru_RU.md)
|
||||||
|
|
||||||
<p align="center"><a href="#"><img src="./media/3X-UI.png" alt="Image"></a></p>
|
<p align="center">
|
||||||
|
<picture>
|
||||||
|
<source media="(prefers-color-scheme: dark)" srcset="./media/3x-ui-dark.png">
|
||||||
|
<img alt="3x-ui" src="./media/3x-ui-light.png">
|
||||||
|
</picture>
|
||||||
|
</p>
|
||||||
|
|
||||||
**Un Panel Web Avanzado • Construido sobre Xray Core**
|
**Un Panel Web Avanzado • Construido sobre Xray Core**
|
||||||
|
|
||||||
|
@ -253,6 +258,7 @@ location /sub {
|
||||||
- Oracle Linux 8+
|
- Oracle Linux 8+
|
||||||
- OpenSUSE Tubleweed
|
- OpenSUSE Tubleweed
|
||||||
- Amazon Linux 2023
|
- Amazon Linux 2023
|
||||||
|
- Windows x64
|
||||||
|
|
||||||
## Arquitecturas y Dispositivos Compatibles
|
## Arquitecturas y Dispositivos Compatibles
|
||||||
|
|
||||||
|
@ -276,14 +282,18 @@ Nuestra plataforma ofrece compatibilidad con una amplia gama de arquitecturas y
|
||||||
|
|
||||||
## Idiomas
|
## Idiomas
|
||||||
|
|
||||||
- Inglés
|
- English (inglés)
|
||||||
- Farsi
|
- Persian (persa)
|
||||||
- Chino
|
- Traditional Chinese (chino tradicional)
|
||||||
- Ruso
|
- Simplified Chinese (chino simplificado)
|
||||||
- Vietnamita
|
- Japanese (japonés)
|
||||||
- Español
|
- Russian (ruso)
|
||||||
- Indonesio
|
- Vietnamese (vietnamita)
|
||||||
- Ucraniano
|
- Spanish (español)
|
||||||
|
- Indonesian (indonesio)
|
||||||
|
- Ukrainian (ucraniano)
|
||||||
|
- Turkish (turco)
|
||||||
|
- Português (Brazil) (portugués (Brasil))
|
||||||
|
|
||||||
|
|
||||||
## Características
|
## Características
|
||||||
|
@ -476,7 +486,7 @@ Ingresa el ID de chat de usuario en el campo de entrada número 4. Las cuentas d
|
||||||
|
|
||||||
#### Uso
|
#### Uso
|
||||||
|
|
||||||
- [Documentación de API](https://documenter.getpostman.com/view/5146551/2sAXxP8Y12)
|
- [Documentación de API](https://www.postman.com/hsanaei/3x-ui/collection/q1l5l0u/3x-ui)
|
||||||
- `/login` con `POST` datos de usuario: `{username: '', password: ''}` para iniciar sesión
|
- `/login` con `POST` datos de usuario: `{username: '', password: ''}` para iniciar sesión
|
||||||
- `/panel/api/inbounds` base para las siguientes acciones:
|
- `/panel/api/inbounds` base para las siguientes acciones:
|
||||||
|
|
||||||
|
@ -506,7 +516,7 @@ Ingresa el ID de chat de usuario en el campo de entrada número 4. Las cuentas d
|
||||||
- `client.password` para TROJAN
|
- `client.password` para TROJAN
|
||||||
- `client.email` para Shadowsocks
|
- `client.email` para Shadowsocks
|
||||||
|
|
||||||
- [<img src="https://run.pstmn.io/button.svg" alt="Run In Postman" style="width: 128px; height: 32px;">](https://god.gw.postman.com/run-collection/5146551-e6aac565-e0e2-46df-acff-2607a51bbd04?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D5146551-e6aac565-e0e2-46df-acff-2607a51bbd04%26entityType%3Dcollection%26workspaceId%3Dd64f609f-485a-4951-9b8f-876b3f917124)
|
- [<img src="https://run.pstmn.io/button.svg" alt="Run In Postman" style="width: 128px; height: 32px;">](https://app.getpostman.com/run-collection/5146551-dda3cab3-0e33-485f-96f9-d4262f437ac5?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D5146551-dda3cab3-0e33-485f-96f9-d4262f437ac5%26entityType%3Dcollection%26workspaceId%3Dd64f609f-485a-4951-9b8f-876b3f917124)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## Variables de Entorno
|
## Variables de Entorno
|
||||||
|
@ -534,13 +544,33 @@ XUI_BIN_FOLDER="bin" XUI_DB_FOLDER="/etc/x-ui" go build main.go
|
||||||
|
|
||||||
## Vista previa
|
## Vista previa
|
||||||
|
|
||||||

|
<picture>
|
||||||

|
<source media="(prefers-color-scheme: dark)" srcset="./media/01-overview-dark.png">
|
||||||

|
<img alt="3x-ui" src="./media/01-overview-light.png">
|
||||||

|
</picture>
|
||||||

|
<picture>
|
||||||

|
<source media="(prefers-color-scheme: dark)" srcset="./media/02-inbounds-dark.png">
|
||||||

|
<img alt="3x-ui" src="./media/02-inbounds-light.png">
|
||||||
|
</picture>
|
||||||
|
<picture>
|
||||||
|
<source media="(prefers-color-scheme: dark)" srcset="./media/03-add-inbound-dark.png">
|
||||||
|
<img alt="3x-ui" src="./media/03-add-inbound-light.png">
|
||||||
|
</picture>
|
||||||
|
<picture>
|
||||||
|
<source media="(prefers-color-scheme: dark)" srcset="./media/04-add-client-dark.png">
|
||||||
|
<img alt="3x-ui" src="./media/04-add-client-light.png">
|
||||||
|
</picture>
|
||||||
|
<picture>
|
||||||
|
<source media="(prefers-color-scheme: dark)" srcset="./media/05-settings-dark.png">
|
||||||
|
<img alt="3x-ui" src="./media/05-settings-light.png">
|
||||||
|
</picture>
|
||||||
|
<picture>
|
||||||
|
<source media="(prefers-color-scheme: dark)" srcset="./media/06-configs-dark.png">
|
||||||
|
<img alt="3x-ui" src="./media/06-configs-light.png">
|
||||||
|
</picture>
|
||||||
|
<picture>
|
||||||
|
<img alt="3x-ui" src="./media/7.png">
|
||||||
|
</picture>
|
||||||
|
|
||||||
## Un agradecimiento especial a
|
## Un agradecimiento especial a
|
||||||
|
|
||||||
|
|
49
README.md
|
@ -1,6 +1,11 @@
|
||||||
[English](/README.md) | [中文](/README.zh_CN.md) | [Español](/README.es_ES.md) | [Русский](/README.ru_RU.md)
|
[English](/README.md) | [中文](/README.zh_CN.md) | [Español](/README.es_ES.md) | [Русский](/README.ru_RU.md)
|
||||||
|
|
||||||
<p align="center"><a href="#"><img src="./media/3X-UI.png" alt="Image"></a></p>
|
<p align="center">
|
||||||
|
<picture>
|
||||||
|
<source media="(prefers-color-scheme: dark)" srcset="./media/3x-ui-dark.png">
|
||||||
|
<img alt="3x-ui" src="./media/3x-ui-light.png">
|
||||||
|
</picture>
|
||||||
|
</p>
|
||||||
|
|
||||||
**An Advanced Web Panel • Built on Xray Core**
|
**An Advanced Web Panel • Built on Xray Core**
|
||||||
|
|
||||||
|
@ -258,6 +263,7 @@ location /sub {
|
||||||
- Oracle Linux 8+
|
- Oracle Linux 8+
|
||||||
- OpenSUSE Tubleweed
|
- OpenSUSE Tubleweed
|
||||||
- Amazon Linux 2023
|
- Amazon Linux 2023
|
||||||
|
- Windows x64
|
||||||
|
|
||||||
## Supported Architectures and Devices
|
## Supported Architectures and Devices
|
||||||
|
|
||||||
|
@ -284,9 +290,10 @@ Our platform offers compatibility with a diverse range of architectures and devi
|
||||||
## Languages
|
## Languages
|
||||||
|
|
||||||
- English
|
- English
|
||||||
- Farsi
|
- Persian
|
||||||
- Traditional Chinese
|
- Traditional Chinese
|
||||||
- Simplified Chinese
|
- Simplified Chinese
|
||||||
|
- Japanese
|
||||||
- Russian
|
- Russian
|
||||||
- Vietnamese
|
- Vietnamese
|
||||||
- Spanish
|
- Spanish
|
||||||
|
@ -487,7 +494,7 @@ Enter the user ID in input field number 4. The Telegram accounts with this id wi
|
||||||
|
|
||||||
#### Usage
|
#### Usage
|
||||||
|
|
||||||
- [API Documentation](https://documenter.getpostman.com/view/5146551/2sAXxP8Y12)
|
- [API Documentation](https://www.postman.com/hsanaei/3x-ui/collection/q1l5l0u/3x-ui)
|
||||||
- `/login` with `POST` user data: `{username: '', password: ''}` for login
|
- `/login` with `POST` user data: `{username: '', password: ''}` for login
|
||||||
- `/panel/api/inbounds` base for following actions:
|
- `/panel/api/inbounds` base for following actions:
|
||||||
|
|
||||||
|
@ -518,7 +525,7 @@ Enter the user ID in input field number 4. The Telegram accounts with this id wi
|
||||||
- `client.password` for TROJAN
|
- `client.password` for TROJAN
|
||||||
- `client.email` for Shadowsocks
|
- `client.email` for Shadowsocks
|
||||||
|
|
||||||
- [<img src="https://run.pstmn.io/button.svg" alt="Run In Postman" style="width: 128px; height: 32px;">](https://god.gw.postman.com/run-collection/5146551-e6aac565-e0e2-46df-acff-2607a51bbd04?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D5146551-e6aac565-e0e2-46df-acff-2607a51bbd04%26entityType%3Dcollection%26workspaceId%3Dd64f609f-485a-4951-9b8f-876b3f917124)
|
- [<img src="https://run.pstmn.io/button.svg" alt="Run In Postman" style="width: 128px; height: 32px;">](https://app.getpostman.com/run-collection/5146551-dda3cab3-0e33-485f-96f9-d4262f437ac5?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D5146551-dda3cab3-0e33-485f-96f9-d4262f437ac5%26entityType%3Dcollection%26workspaceId%3Dd64f609f-485a-4951-9b8f-876b3f917124)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## Environment Variables
|
## Environment Variables
|
||||||
|
@ -546,13 +553,33 @@ XUI_BIN_FOLDER="bin" XUI_DB_FOLDER="/etc/x-ui" go build main.go
|
||||||
|
|
||||||
## Preview
|
## Preview
|
||||||
|
|
||||||

|
<picture>
|
||||||

|
<source media="(prefers-color-scheme: dark)" srcset="./media/01-overview-dark.png">
|
||||||

|
<img alt="3x-ui" src="./media/01-overview-light.png">
|
||||||

|
</picture>
|
||||||

|
<picture>
|
||||||

|
<source media="(prefers-color-scheme: dark)" srcset="./media/02-inbounds-dark.png">
|
||||||

|
<img alt="3x-ui" src="./media/02-inbounds-light.png">
|
||||||
|
</picture>
|
||||||
|
<picture>
|
||||||
|
<source media="(prefers-color-scheme: dark)" srcset="./media/03-add-inbound-dark.png">
|
||||||
|
<img alt="3x-ui" src="./media/03-add-inbound-light.png">
|
||||||
|
</picture>
|
||||||
|
<picture>
|
||||||
|
<source media="(prefers-color-scheme: dark)" srcset="./media/04-add-client-dark.png">
|
||||||
|
<img alt="3x-ui" src="./media/04-add-client-light.png">
|
||||||
|
</picture>
|
||||||
|
<picture>
|
||||||
|
<source media="(prefers-color-scheme: dark)" srcset="./media/05-settings-dark.png">
|
||||||
|
<img alt="3x-ui" src="./media/05-settings-light.png">
|
||||||
|
</picture>
|
||||||
|
<picture>
|
||||||
|
<source media="(prefers-color-scheme: dark)" srcset="./media/06-configs-dark.png">
|
||||||
|
<img alt="3x-ui" src="./media/06-configs-light.png">
|
||||||
|
</picture>
|
||||||
|
<picture>
|
||||||
|
<img alt="3x-ui" src="./media/7.png">
|
||||||
|
</picture>
|
||||||
|
|
||||||
## A Special Thanks to
|
## A Special Thanks to
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
[English](/README.md) | [中文](/README.zh_CN.md) | [Español](/README.es_ES.md) | [Русский](/README.ru_RU.md)
|
[English](/README.md) | [中文](/README.zh_CN.md) | [Español](/README.es_ES.md) | [Русский](/README.ru_RU.md)
|
||||||
|
|
||||||
<p align="center"><a href="#"><img src="./media/3X-UI.png" alt="Image"></a></p>
|
<p align="center">
|
||||||
|
<picture>
|
||||||
|
<source media="(prefers-color-scheme: dark)" srcset="./media/3x-ui-dark.png">
|
||||||
|
<img alt="3x-ui" src="./media/3x-ui-light.png">
|
||||||
|
</picture>
|
||||||
|
</p>
|
||||||
|
|
||||||
**Продвинутая веб-панель • Построена на основе Xray Core**
|
**Продвинутая веб-панель • Построена на основе Xray Core**
|
||||||
|
|
||||||
|
@ -257,6 +262,7 @@ location /sub {
|
||||||
- Oracle Linux 8+
|
- Oracle Linux 8+
|
||||||
- OpenSUSE Tubleweed
|
- OpenSUSE Tubleweed
|
||||||
- Amazon Linux 2023
|
- Amazon Linux 2023
|
||||||
|
- Windows x64
|
||||||
|
|
||||||
## Поддерживаемые архитектуры и устройства
|
## Поддерживаемые архитектуры и устройства
|
||||||
|
|
||||||
|
@ -282,16 +288,18 @@ location /sub {
|
||||||
|
|
||||||
## Языки
|
## Языки
|
||||||
|
|
||||||
- Английский
|
- English (английский)
|
||||||
- Фарси
|
- Persian (персидский)
|
||||||
- Китайский
|
- Traditional Chinese (традиционный китайский)
|
||||||
- Русский
|
- Simplified Chinese (упрощенный китайский)
|
||||||
- Вьетнамский
|
- Japanese (японский)
|
||||||
- Испанский
|
- Russian (русский)
|
||||||
- Индонезийский
|
- Vietnamese (вьетнамский)
|
||||||
- Украинский
|
- Spanish (испанский)
|
||||||
- Турецкий
|
- Indonesian (индонезийский)
|
||||||
- Португальский (Бразилия)
|
- Ukrainian (украинский)
|
||||||
|
- Turkish (турецкий)
|
||||||
|
- Português (Brazil) (португальский (Бразилия))
|
||||||
|
|
||||||
## Возможности
|
## Возможности
|
||||||
|
|
||||||
|
@ -481,7 +489,7 @@ WARP встроен, и дополнительная установка не т
|
||||||
|
|
||||||
#### Использование
|
#### Использование
|
||||||
|
|
||||||
- [API документация](https://documenter.getpostman.com/view/5146551/2sAXxP8Y12)
|
- [API документация](https://www.postman.com/hsanaei/3x-ui/collection/q1l5l0u/3x-ui)
|
||||||
- `/login` с `POST`-данными: `{username: '', password: ''}` для входа
|
- `/login` с `POST`-данными: `{username: '', password: ''}` для входа
|
||||||
- `/panel/api/inbounds` это базовый путь для следующих действий:
|
- `/panel/api/inbounds` это базовый путь для следующих действий:
|
||||||
|
|
||||||
|
@ -515,7 +523,7 @@ WARP встроен, и дополнительная установка не т
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
|
||||||
- [<img src="https://run.pstmn.io/button.svg" alt="Run In Postman" style="width: 128px; height: 32px;">](https://god.gw.postman.com/run-collection/5146551-e6aac565-e0e2-46df-acff-2607a51bbd04?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D5146551-e6aac565-e0e2-46df-acff-2607a51bbd04%26entityType%3Dcollection%26workspaceId%3Dd64f609f-485a-4951-9b8f-876b3f917124)
|
- [<img src="https://run.pstmn.io/button.svg" alt="Run In Postman" style="width: 128px; height: 32px;">](https://app.getpostman.com/run-collection/5146551-dda3cab3-0e33-485f-96f9-d4262f437ac5?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D5146551-dda3cab3-0e33-485f-96f9-d4262f437ac5%26entityType%3Dcollection%26workspaceId%3Dd64f609f-485a-4951-9b8f-876b3f917124)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## Переменные среды
|
## Переменные среды
|
||||||
|
@ -543,13 +551,33 @@ XUI_BIN_FOLDER="bin" XUI_DB_FOLDER="/etc/x-ui" go build main.go
|
||||||
|
|
||||||
## Предварительный Просмотр
|
## Предварительный Просмотр
|
||||||
|
|
||||||

|
<picture>
|
||||||

|
<source media="(prefers-color-scheme: dark)" srcset="./media/01-overview-dark.png">
|
||||||

|
<img alt="3x-ui" src="./media/01-overview-light.png">
|
||||||

|
</picture>
|
||||||

|
<picture>
|
||||||

|
<source media="(prefers-color-scheme: dark)" srcset="./media/02-inbounds-dark.png">
|
||||||

|
<img alt="3x-ui" src="./media/02-inbounds-light.png">
|
||||||
|
</picture>
|
||||||
|
<picture>
|
||||||
|
<source media="(prefers-color-scheme: dark)" srcset="./media/03-add-inbound-dark.png">
|
||||||
|
<img alt="3x-ui" src="./media/03-add-inbound-light.png">
|
||||||
|
</picture>
|
||||||
|
<picture>
|
||||||
|
<source media="(prefers-color-scheme: dark)" srcset="./media/04-add-client-dark.png">
|
||||||
|
<img alt="3x-ui" src="./media/04-add-client-light.png">
|
||||||
|
</picture>
|
||||||
|
<picture>
|
||||||
|
<source media="(prefers-color-scheme: dark)" srcset="./media/05-settings-dark.png">
|
||||||
|
<img alt="3x-ui" src="./media/05-settings-light.png">
|
||||||
|
</picture>
|
||||||
|
<picture>
|
||||||
|
<source media="(prefers-color-scheme: dark)" srcset="./media/06-configs-dark.png">
|
||||||
|
<img alt="3x-ui" src="./media/06-configs-light.png">
|
||||||
|
</picture>
|
||||||
|
<picture>
|
||||||
|
<img alt="3x-ui" src="./media/7.png">
|
||||||
|
</picture>
|
||||||
|
|
||||||
## Особая благодарность
|
## Особая благодарность
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
[English](/README.md) | [中文](/README.zh_CN.md) | [Español](/README.es_ES.md) | [Русский](/README.ru_RU.md)
|
[English](/README.md) | [中文](/README.zh_CN.md) | [Español](/README.es_ES.md) | [Русский](/README.ru_RU.md)
|
||||||
|
|
||||||
<p align="center"><a href="#"><img src="./media/3X-UI.png" alt="Image"></a></p>
|
<p align="center">
|
||||||
|
<picture>
|
||||||
|
<source media="(prefers-color-scheme: dark)" srcset="./media/3x-ui-dark.png">
|
||||||
|
<img alt="3x-ui" src="./media/3x-ui-light.png">
|
||||||
|
</picture>
|
||||||
|
</p>
|
||||||
|
|
||||||
**一个更好的面板 • 基于Xray Core构建**
|
**一个更好的面板 • 基于Xray Core构建**
|
||||||
|
|
||||||
|
@ -254,6 +259,7 @@ location /sub {
|
||||||
- Oracle Linux 8+
|
- Oracle Linux 8+
|
||||||
- OpenSUSE Tubleweed
|
- OpenSUSE Tubleweed
|
||||||
- Amazon Linux 2023
|
- Amazon Linux 2023
|
||||||
|
- Windows x64
|
||||||
|
|
||||||
## 支持的架构和设备
|
## 支持的架构和设备
|
||||||
<details>
|
<details>
|
||||||
|
@ -277,13 +283,17 @@ location /sub {
|
||||||
## Languages
|
## Languages
|
||||||
|
|
||||||
- English(英语)
|
- English(英语)
|
||||||
- Farsi(伊朗语)
|
- Persian(波斯语)
|
||||||
- Chinese(中文)
|
- Traditional Chinese(繁体中文)
|
||||||
|
- Simplified Chinese(简体中文)
|
||||||
|
- Japanese(日语)
|
||||||
- Russian(俄语)
|
- Russian(俄语)
|
||||||
- Vietnamese(越南语)
|
- Vietnamese(越南语)
|
||||||
- Spanish(西班牙语)
|
- Spanish(西班牙语)
|
||||||
- Indonesian (印度尼西亚语)
|
- Indonesian(印尼语)
|
||||||
- Ukrainian(乌克兰语)
|
- Ukrainian(乌克兰语)
|
||||||
|
- Turkish(土耳其语)
|
||||||
|
- Português (Brazil)(葡萄牙语(巴西))
|
||||||
|
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
@ -476,7 +486,7 @@ Web 面板通过 Telegram Bot 支持每日流量、面板登录、数据库备
|
||||||
|
|
||||||
#### 使用
|
#### 使用
|
||||||
|
|
||||||
- [API 文档](https://documenter.getpostman.com/view/5146551/2sAXxP8Y12)
|
- [API 文档](https://www.postman.com/hsanaei/3x-ui/collection/q1l5l0u/3x-ui)
|
||||||
- `/login` 使用 `POST` 用户名称 & 密码: `{username: '', password: ''}` 登录
|
- `/login` 使用 `POST` 用户名称 & 密码: `{username: '', password: ''}` 登录
|
||||||
- `/panel/api/inbounds` 以下操作的基础:
|
- `/panel/api/inbounds` 以下操作的基础:
|
||||||
|
|
||||||
|
@ -506,7 +516,7 @@ Web 面板通过 Telegram Bot 支持每日流量、面板登录、数据库备
|
||||||
- `client.password` TROJAN
|
- `client.password` TROJAN
|
||||||
- `client.email` Shadowsocks
|
- `client.email` Shadowsocks
|
||||||
|
|
||||||
- [<img src="https://run.pstmn.io/button.svg" alt="Run In Postman" style="width: 128px; height: 32px;">](https://god.gw.postman.com/run-collection/5146551-e6aac565-e0e2-46df-acff-2607a51bbd04?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D5146551-e6aac565-e0e2-46df-acff-2607a51bbd04%26entityType%3Dcollection%26workspaceId%3Dd64f609f-485a-4951-9b8f-876b3f917124)
|
- [<img src="https://run.pstmn.io/button.svg" alt="Run In Postman" style="width: 128px; height: 32px;">](https://app.getpostman.com/run-collection/5146551-dda3cab3-0e33-485f-96f9-d4262f437ac5?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D5146551-dda3cab3-0e33-485f-96f9-d4262f437ac5%26entityType%3Dcollection%26workspaceId%3Dd64f609f-485a-4951-9b8f-876b3f917124)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## 环境变量
|
## 环境变量
|
||||||
|
@ -534,13 +544,33 @@ XUI_BIN_FOLDER="bin" XUI_DB_FOLDER="/etc/x-ui" go build main.go
|
||||||
|
|
||||||
## 预览
|
## 预览
|
||||||
|
|
||||||

|
<picture>
|
||||||

|
<source media="(prefers-color-scheme: dark)" srcset="./media/01-overview-dark.png">
|
||||||

|
<img alt="3x-ui" src="./media/01-overview-light.png">
|
||||||

|
</picture>
|
||||||

|
<picture>
|
||||||

|
<source media="(prefers-color-scheme: dark)" srcset="./media/02-inbounds-dark.png">
|
||||||

|
<img alt="3x-ui" src="./media/02-inbounds-light.png">
|
||||||
|
</picture>
|
||||||
|
<picture>
|
||||||
|
<source media="(prefers-color-scheme: dark)" srcset="./media/03-add-inbound-dark.png">
|
||||||
|
<img alt="3x-ui" src="./media/03-add-inbound-light.png">
|
||||||
|
</picture>
|
||||||
|
<picture>
|
||||||
|
<source media="(prefers-color-scheme: dark)" srcset="./media/04-add-client-dark.png">
|
||||||
|
<img alt="3x-ui" src="./media/04-add-client-light.png">
|
||||||
|
</picture>
|
||||||
|
<picture>
|
||||||
|
<source media="(prefers-color-scheme: dark)" srcset="./media/05-settings-dark.png">
|
||||||
|
<img alt="3x-ui" src="./media/05-settings-light.png">
|
||||||
|
</picture>
|
||||||
|
<picture>
|
||||||
|
<source media="(prefers-color-scheme: dark)" srcset="./media/06-configs-dark.png">
|
||||||
|
<img alt="3x-ui" src="./media/06-configs-light.png">
|
||||||
|
</picture>
|
||||||
|
<picture>
|
||||||
|
<img alt="3x-ui" src="./media/7.png">
|
||||||
|
</picture>
|
||||||
|
|
||||||
## 特别感谢
|
## 特别感谢
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
2.4.6
|
2.4.8
|
48
go.mod
|
@ -1,30 +1,30 @@
|
||||||
module x-ui
|
module x-ui
|
||||||
|
|
||||||
go 1.23.2
|
go 1.23.3
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/gin-contrib/gzip v1.0.1
|
github.com/gin-contrib/gzip v1.0.1
|
||||||
github.com/gin-contrib/sessions v1.0.1
|
github.com/gin-contrib/sessions v1.0.1
|
||||||
github.com/gin-gonic/gin v1.10.0
|
github.com/gin-gonic/gin v1.10.0
|
||||||
github.com/goccy/go-json v0.10.3
|
github.com/goccy/go-json v0.10.3
|
||||||
github.com/mymmrac/telego v0.31.3
|
github.com/mymmrac/telego v0.31.4
|
||||||
github.com/nicksnyder/go-i18n/v2 v2.4.1
|
github.com/nicksnyder/go-i18n/v2 v2.4.1
|
||||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
|
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
|
||||||
github.com/pelletier/go-toml/v2 v2.2.3
|
github.com/pelletier/go-toml/v2 v2.2.3
|
||||||
github.com/robfig/cron/v3 v3.0.1
|
github.com/robfig/cron/v3 v3.0.1
|
||||||
github.com/shirou/gopsutil/v4 v4.24.10
|
github.com/shirou/gopsutil/v4 v4.24.10
|
||||||
github.com/valyala/fasthttp v1.57.0
|
github.com/valyala/fasthttp v1.57.0
|
||||||
github.com/xtls/xray-core v1.8.25-0.20241031075831-4ec5c78c3453
|
github.com/xtls/xray-core v1.8.25-0.20241121054707-513f18bf531e
|
||||||
go.uber.org/atomic v1.11.0
|
go.uber.org/atomic v1.11.0
|
||||||
golang.org/x/text v0.19.0
|
golang.org/x/text v0.20.0
|
||||||
google.golang.org/grpc v1.67.1
|
google.golang.org/grpc v1.68.0
|
||||||
gorm.io/driver/sqlite v1.5.6
|
gorm.io/driver/sqlite v1.5.6
|
||||||
gorm.io/gorm v1.25.12
|
gorm.io/gorm v1.25.12
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/andybalholm/brotli v1.1.1 // indirect
|
github.com/andybalholm/brotli v1.1.1 // indirect
|
||||||
github.com/bytedance/sonic v1.12.3 // indirect
|
github.com/bytedance/sonic v1.12.4 // indirect
|
||||||
github.com/bytedance/sonic/loader v0.2.1 // indirect
|
github.com/bytedance/sonic/loader v0.2.1 // indirect
|
||||||
github.com/cloudflare/circl v1.5.0 // indirect
|
github.com/cloudflare/circl v1.5.0 // indirect
|
||||||
github.com/cloudwego/base64x v0.1.4 // indirect
|
github.com/cloudwego/base64x v0.1.4 // indirect
|
||||||
|
@ -32,15 +32,15 @@ require (
|
||||||
github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 // indirect
|
github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 // indirect
|
||||||
github.com/ebitengine/purego v0.8.1 // indirect
|
github.com/ebitengine/purego v0.8.1 // indirect
|
||||||
github.com/fasthttp/router v1.5.2 // indirect
|
github.com/fasthttp/router v1.5.2 // indirect
|
||||||
github.com/gabriel-vasile/mimetype v1.4.6 // indirect
|
github.com/gabriel-vasile/mimetype v1.4.7 // indirect
|
||||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||||
github.com/go-ole/go-ole v1.3.0 // indirect
|
github.com/go-ole/go-ole v1.3.0 // indirect
|
||||||
github.com/go-playground/locales v0.14.1 // indirect
|
github.com/go-playground/locales v0.14.1 // indirect
|
||||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
github.com/go-playground/validator/v10 v10.22.1 // indirect
|
github.com/go-playground/validator/v10 v10.23.0 // indirect
|
||||||
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
|
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
|
||||||
github.com/google/btree v1.1.3 // indirect
|
github.com/google/btree v1.1.3 // indirect
|
||||||
github.com/google/pprof v0.0.0-20241023014458-598669927662 // indirect
|
github.com/google/pprof v0.0.0-20241101162523-b92577c0c142 // indirect
|
||||||
github.com/gorilla/context v1.1.2 // indirect
|
github.com/gorilla/context v1.1.2 // indirect
|
||||||
github.com/gorilla/securecookie v1.1.2 // indirect
|
github.com/gorilla/securecookie v1.1.2 // indirect
|
||||||
github.com/gorilla/sessions v1.4.0 // indirect
|
github.com/gorilla/sessions v1.4.0 // indirect
|
||||||
|
@ -50,7 +50,7 @@ require (
|
||||||
github.com/jinzhu/now v1.1.5 // indirect
|
github.com/jinzhu/now v1.1.5 // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
github.com/klauspost/compress v1.17.11 // indirect
|
github.com/klauspost/compress v1.17.11 // indirect
|
||||||
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
|
github.com/klauspost/cpuid/v2 v2.2.9 // indirect
|
||||||
github.com/kr/text v0.2.0 // indirect
|
github.com/kr/text v0.2.0 // indirect
|
||||||
github.com/leodido/go-urn v1.4.0 // indirect
|
github.com/leodido/go-urn v1.4.0 // indirect
|
||||||
github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683 // indirect
|
github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683 // indirect
|
||||||
|
@ -58,7 +58,7 @@ require (
|
||||||
github.com/mattn/go-sqlite3 v1.14.24 // indirect
|
github.com/mattn/go-sqlite3 v1.14.24 // indirect
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
github.com/onsi/ginkgo/v2 v2.20.2 // indirect
|
github.com/onsi/ginkgo/v2 v2.21.0 // indirect
|
||||||
github.com/pires/go-proxyproto v0.8.0 // indirect
|
github.com/pires/go-proxyproto v0.8.0 // indirect
|
||||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
|
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
|
||||||
github.com/quic-go/qpack v0.5.1 // indirect
|
github.com/quic-go/qpack v0.5.1 // indirect
|
||||||
|
@ -67,7 +67,7 @@ require (
|
||||||
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect
|
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect
|
||||||
github.com/rogpeppe/go-internal v1.13.1 // indirect
|
github.com/rogpeppe/go-internal v1.13.1 // indirect
|
||||||
github.com/rvinnie/yookassa-sdk-go v0.0.0-20240629113713-dfd7cc31b343 // indirect
|
github.com/rvinnie/yookassa-sdk-go v0.0.0-20240629113713-dfd7cc31b343 // indirect
|
||||||
github.com/sagernet/sing v0.4.3 // indirect
|
github.com/sagernet/sing v0.5.1 // indirect
|
||||||
github.com/sagernet/sing-shadowsocks v0.2.7 // indirect
|
github.com/sagernet/sing-shadowsocks v0.2.7 // indirect
|
||||||
github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38 // indirect
|
github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38 // indirect
|
||||||
github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771 // indirect
|
github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771 // indirect
|
||||||
|
@ -79,24 +79,24 @@ require (
|
||||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||||
github.com/valyala/fastjson v1.6.4 // indirect
|
github.com/valyala/fastjson v1.6.4 // indirect
|
||||||
github.com/vishvananda/netlink v1.3.0 // indirect
|
github.com/vishvananda/netlink v1.3.0 // indirect
|
||||||
github.com/vishvananda/netns v0.0.4 // indirect
|
github.com/vishvananda/netns v0.0.5 // indirect
|
||||||
github.com/xtls/reality v0.0.0-20240909153216-e26ae2305463 // indirect
|
github.com/xtls/reality v0.0.0-20240909153216-e26ae2305463 // indirect
|
||||||
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||||
go.uber.org/mock v0.5.0 // indirect
|
go.uber.org/mock v0.5.0 // indirect
|
||||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect
|
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect
|
||||||
golang.org/x/arch v0.11.0 // indirect
|
golang.org/x/arch v0.12.0 // indirect
|
||||||
golang.org/x/crypto v0.28.0 // indirect
|
golang.org/x/crypto v0.29.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect
|
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f // indirect
|
||||||
golang.org/x/mod v0.21.0 // indirect
|
golang.org/x/mod v0.22.0 // indirect
|
||||||
golang.org/x/net v0.30.0 // indirect
|
golang.org/x/net v0.31.0 // indirect
|
||||||
golang.org/x/sync v0.8.0 // indirect
|
golang.org/x/sync v0.9.0 // indirect
|
||||||
golang.org/x/sys v0.26.0 // indirect
|
golang.org/x/sys v0.27.0 // indirect
|
||||||
golang.org/x/time v0.7.0 // indirect
|
golang.org/x/time v0.8.0 // indirect
|
||||||
golang.org/x/tools v0.26.0 // indirect
|
golang.org/x/tools v0.27.0 // indirect
|
||||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
|
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
|
||||||
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 // indirect
|
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38 // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697 // indirect
|
||||||
google.golang.org/protobuf v1.35.1 // indirect
|
google.golang.org/protobuf v1.35.2 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
gvisor.dev/gvisor v0.0.0-20231202080848-1f7806d17489 // indirect
|
gvisor.dev/gvisor v0.0.0-20231202080848-1f7806d17489 // indirect
|
||||||
lukechampine.com/blake3 v1.3.0 // indirect
|
lukechampine.com/blake3 v1.3.0 // indirect
|
||||||
|
|
98
go.sum
|
@ -4,8 +4,8 @@ github.com/OmarTariq612/goech v0.0.0-20240405204721-8e2e1dafd3a0 h1:Wo41lDOevRJS
|
||||||
github.com/OmarTariq612/goech v0.0.0-20240405204721-8e2e1dafd3a0/go.mod h1:FVGavL/QEBQDcBpr3fAojoK17xX5k9bicBphrOpP7uM=
|
github.com/OmarTariq612/goech v0.0.0-20240405204721-8e2e1dafd3a0/go.mod h1:FVGavL/QEBQDcBpr3fAojoK17xX5k9bicBphrOpP7uM=
|
||||||
github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA=
|
github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA=
|
||||||
github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
|
github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
|
||||||
github.com/bytedance/sonic v1.12.3 h1:W2MGa7RCU1QTeYRTPE3+88mVC0yXmsRQRChiyVocVjU=
|
github.com/bytedance/sonic v1.12.4 h1:9Csb3c9ZJhfUWeMtpCDCq6BUoH5ogfDFLUgQ/jG+R0k=
|
||||||
github.com/bytedance/sonic v1.12.3/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk=
|
github.com/bytedance/sonic v1.12.4/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk=
|
||||||
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||||
github.com/bytedance/sonic/loader v0.2.1 h1:1GgorWTqf12TA8mma4DDSbaQigE2wOgQo7iCjjJv3+E=
|
github.com/bytedance/sonic/loader v0.2.1 h1:1GgorWTqf12TA8mma4DDSbaQigE2wOgQo7iCjjJv3+E=
|
||||||
github.com/bytedance/sonic/loader v0.2.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
github.com/bytedance/sonic/loader v0.2.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||||
|
@ -26,8 +26,8 @@ github.com/ebitengine/purego v0.8.1 h1:sdRKd6plj7KYW33EH5As6YKfe8m9zbN9JMrOjNVF/
|
||||||
github.com/ebitengine/purego v0.8.1/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
|
github.com/ebitengine/purego v0.8.1/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
|
||||||
github.com/fasthttp/router v1.5.2 h1:ckJCCdV7hWkkrMeId3WfEhz+4Gyyf6QPwxi/RHIMZ6I=
|
github.com/fasthttp/router v1.5.2 h1:ckJCCdV7hWkkrMeId3WfEhz+4Gyyf6QPwxi/RHIMZ6I=
|
||||||
github.com/fasthttp/router v1.5.2/go.mod h1:C8EY53ozOwpONyevc/V7Gr8pqnEjwnkFFqPo1alAGs0=
|
github.com/fasthttp/router v1.5.2/go.mod h1:C8EY53ozOwpONyevc/V7Gr8pqnEjwnkFFqPo1alAGs0=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.6 h1:3+PzJTKLkvgjeTbts6msPJt4DixhT4YtFNf1gtGe3zc=
|
github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW8ZzUMYCA=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.6/go.mod h1:JX1qVKqZd40hUPpAfiNTe0Sne7hdfKSbOqqmkq8GCXc=
|
github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU=
|
||||||
github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344 h1:Arcl6UOIS/kgO2nW3A65HN+7CMjSDP/gofXL4CZt1V4=
|
github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344 h1:Arcl6UOIS/kgO2nW3A65HN+7CMjSDP/gofXL4CZt1V4=
|
||||||
github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I=
|
github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I=
|
||||||
github.com/gin-contrib/gzip v1.0.1 h1:HQ8ENHODeLY7a4g1Au/46Z92bdGFl74OhxcZble9WJE=
|
github.com/gin-contrib/gzip v1.0.1 h1:HQ8ENHODeLY7a4g1Au/46Z92bdGFl74OhxcZble9WJE=
|
||||||
|
@ -49,14 +49,16 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o
|
||||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
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/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||||
github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA=
|
github.com/go-playground/validator/v10 v10.23.0 h1:/PwmTwZhS0dPkav3cdK9kV1FsAmrL8sThn8IHr/sO+o=
|
||||||
github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
github.com/go-playground/validator/v10 v10.23.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
||||||
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||||
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
|
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
|
||||||
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||||
github.com/golang/mock v1.7.0-rc.1 h1:YojYx61/OLFsiv6Rw1Z96LpldJIy31o+UHmwAUMJ6/U=
|
github.com/golang/mock v1.7.0-rc.1 h1:YojYx61/OLFsiv6Rw1Z96LpldJIy31o+UHmwAUMJ6/U=
|
||||||
github.com/golang/mock v1.7.0-rc.1/go.mod h1:s42URUywIqd+OcERslBJvOjepvNymP31m3q8d/GkuRs=
|
github.com/golang/mock v1.7.0-rc.1/go.mod h1:s42URUywIqd+OcERslBJvOjepvNymP31m3q8d/GkuRs=
|
||||||
|
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||||
|
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||||
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
|
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
|
||||||
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
|
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
|
||||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||||
|
@ -64,8 +66,8 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/pprof v0.0.0-20241023014458-598669927662 h1:SKMkD83p7FwUqKmBsPdLHF5dNyxq3jOWwu9w9UyH5vA=
|
github.com/google/pprof v0.0.0-20241101162523-b92577c0c142 h1:sAGdeJj0bnMgUNVeUpp6AYlVdCt3/GdI3pGRqsNSQLs=
|
||||||
github.com/google/pprof v0.0.0-20241023014458-598669927662/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
|
github.com/google/pprof v0.0.0-20241101162523-b92577c0c142/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
|
||||||
github.com/gorilla/context v1.1.2 h1:WRkNAv2uoa03QNIc1A6u4O7DAGMUVoopZhkiXWA2V1o=
|
github.com/gorilla/context v1.1.2 h1:WRkNAv2uoa03QNIc1A6u4O7DAGMUVoopZhkiXWA2V1o=
|
||||||
github.com/gorilla/context v1.1.2/go.mod h1:KDPwT9i/MeWHiLl90fuTgrt4/wPcv75vFAZLaOOcbxM=
|
github.com/gorilla/context v1.1.2/go.mod h1:KDPwT9i/MeWHiLl90fuTgrt4/wPcv75vFAZLaOOcbxM=
|
||||||
github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA=
|
github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA=
|
||||||
|
@ -85,8 +87,8 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm
|
||||||
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
|
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
|
||||||
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
|
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
|
||||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||||
github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM=
|
github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY=
|
||||||
github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8=
|
||||||
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
||||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||||
|
@ -107,14 +109,14 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
github.com/mymmrac/telego v0.31.3 h1:yZlD+dm+1W6p3OmCG8K+MbS02Y6paUgwPnqfZN3RWQQ=
|
github.com/mymmrac/telego v0.31.4 h1:NpiNl0P/8eydknka/k6XaaaWVj5BKMlM3Ibba63QTBU=
|
||||||
github.com/mymmrac/telego v0.31.3/go.mod h1:coOoqXVmjFnwBlzusjfEezbQ7RH9wQnDowJdMm+bnEo=
|
github.com/mymmrac/telego v0.31.4/go.mod h1:T12js1PgbYDYznvoN05MSMuPMfWTYo7D9LKl5cPFWiI=
|
||||||
github.com/nicksnyder/go-i18n/v2 v2.4.1 h1:zwzjtX4uYyiaU02K5Ia3zSkpJZrByARkRB4V3YPrr0g=
|
github.com/nicksnyder/go-i18n/v2 v2.4.1 h1:zwzjtX4uYyiaU02K5Ia3zSkpJZrByARkRB4V3YPrr0g=
|
||||||
github.com/nicksnyder/go-i18n/v2 v2.4.1/go.mod h1:++Pl70FR6Cki7hdzZRnEEqdc2dJt+SAGotyFg/SvZMk=
|
github.com/nicksnyder/go-i18n/v2 v2.4.1/go.mod h1:++Pl70FR6Cki7hdzZRnEEqdc2dJt+SAGotyFg/SvZMk=
|
||||||
github.com/onsi/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4=
|
github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM=
|
||||||
github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag=
|
github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
|
||||||
github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k=
|
github.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8=
|
||||||
github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY=
|
github.com/onsi/gomega v1.34.2/go.mod h1:v1xfxRgk0KIsG+QOdm7p8UosrOzPYRo60fd3B/1Dukc=
|
||||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88=
|
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88=
|
||||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
||||||
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
|
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
|
||||||
|
@ -141,8 +143,8 @@ github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR
|
||||||
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
||||||
github.com/rvinnie/yookassa-sdk-go v0.0.0-20240629113713-dfd7cc31b343 h1:oVZiMHABPKz0OZgx/h1BxMNkRFK4DOBdDpSrMebYmsI=
|
github.com/rvinnie/yookassa-sdk-go v0.0.0-20240629113713-dfd7cc31b343 h1:oVZiMHABPKz0OZgx/h1BxMNkRFK4DOBdDpSrMebYmsI=
|
||||||
github.com/rvinnie/yookassa-sdk-go v0.0.0-20240629113713-dfd7cc31b343/go.mod h1:flatybkcu+7YLaB7mMnj9JTNKeim4jZ+ZrXNFjVA0pA=
|
github.com/rvinnie/yookassa-sdk-go v0.0.0-20240629113713-dfd7cc31b343/go.mod h1:flatybkcu+7YLaB7mMnj9JTNKeim4jZ+ZrXNFjVA0pA=
|
||||||
github.com/sagernet/sing v0.4.3 h1:Ty/NAiNnVd6844k7ujlL5lkzydhcTH5Psc432jXA4Y8=
|
github.com/sagernet/sing v0.5.1 h1:mhL/MZVq0TjuvHcpYcFtmSD1BFOxZ/+8ofbNZcg1k1Y=
|
||||||
github.com/sagernet/sing v0.4.3/go.mod h1:ieZHA/+Y9YZfXs2I3WtuwgyCZ6GPsIR7HdKb1SdEnls=
|
github.com/sagernet/sing v0.5.1/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
|
||||||
github.com/sagernet/sing-shadowsocks v0.2.7 h1:zaopR1tbHEw5Nk6FAkM05wCslV6ahVegEZaKMv9ipx8=
|
github.com/sagernet/sing-shadowsocks v0.2.7 h1:zaopR1tbHEw5Nk6FAkM05wCslV6ahVegEZaKMv9ipx8=
|
||||||
github.com/sagernet/sing-shadowsocks v0.2.7/go.mod h1:0rIKJZBR65Qi0zwdKezt4s57y/Tl1ofkaq6NlkzVuyE=
|
github.com/sagernet/sing-shadowsocks v0.2.7/go.mod h1:0rIKJZBR65Qi0zwdKezt4s57y/Tl1ofkaq6NlkzVuyE=
|
||||||
github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38 h1:D0vL7YNisV2yqE55+q0lFuGse6U8lxlg7fYTctlT5Gc=
|
github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38 h1:D0vL7YNisV2yqE55+q0lFuGse6U8lxlg7fYTctlT5Gc=
|
||||||
|
@ -180,12 +182,13 @@ github.com/valyala/fastjson v1.6.4 h1:uAUNq9Z6ymTgGhcm0UynUAB6tlbakBrz6CQFax3BXV
|
||||||
github.com/valyala/fastjson v1.6.4/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY=
|
github.com/valyala/fastjson v1.6.4/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY=
|
||||||
github.com/vishvananda/netlink v1.3.0 h1:X7l42GfcV4S6E4vHTsw48qbrV+9PVojNfIhZcwQdrZk=
|
github.com/vishvananda/netlink v1.3.0 h1:X7l42GfcV4S6E4vHTsw48qbrV+9PVojNfIhZcwQdrZk=
|
||||||
github.com/vishvananda/netlink v1.3.0/go.mod h1:i6NetklAujEcC6fK0JPjT8qSwWyO0HLn4UKG+hGqeJs=
|
github.com/vishvananda/netlink v1.3.0/go.mod h1:i6NetklAujEcC6fK0JPjT8qSwWyO0HLn4UKG+hGqeJs=
|
||||||
github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8=
|
|
||||||
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
|
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
|
||||||
|
github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY=
|
||||||
|
github.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
|
||||||
github.com/xtls/reality v0.0.0-20240909153216-e26ae2305463 h1:g1Cj7d+my6k/HHxLAyxPwyX8i7FGRr6ulBDMkBzg2BM=
|
github.com/xtls/reality v0.0.0-20240909153216-e26ae2305463 h1:g1Cj7d+my6k/HHxLAyxPwyX8i7FGRr6ulBDMkBzg2BM=
|
||||||
github.com/xtls/reality v0.0.0-20240909153216-e26ae2305463/go.mod h1:BjIOLmkEEtAgloAiVUcYj0Mt+YU00JARZw8AEU0IwAg=
|
github.com/xtls/reality v0.0.0-20240909153216-e26ae2305463/go.mod h1:BjIOLmkEEtAgloAiVUcYj0Mt+YU00JARZw8AEU0IwAg=
|
||||||
github.com/xtls/xray-core v1.8.25-0.20241031075831-4ec5c78c3453 h1:2piT7IYX0SKhYjD+XiJMDZAbY01MkP1HYO54njmisaQ=
|
github.com/xtls/xray-core v1.8.25-0.20241121054707-513f18bf531e h1:J5sTv0Sw+BonaI+rBh4Jkw9BfBqDjfAts81/HbIaqNg=
|
||||||
github.com/xtls/xray-core v1.8.25-0.20241031075831-4ec5c78c3453/go.mod h1:OlJhs59caMUabGbOamwTc2khBSOfd34qtVJVXFhpfWM=
|
github.com/xtls/xray-core v1.8.25-0.20241121054707-513f18bf531e/go.mod h1:wByClH1yrH8I611sREjG62gxbP5hFtdAWYJfydQF/zI=
|
||||||
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
|
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
|
||||||
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
|
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
|
||||||
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
|
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
|
||||||
|
@ -196,43 +199,42 @@ go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
|
||||||
go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
|
go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
|
||||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M=
|
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M=
|
||||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
|
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
|
||||||
golang.org/x/arch v0.11.0 h1:KXV8WWKCXm6tRpLirl2szsO5j/oOODwZf4hATmGVNs4=
|
golang.org/x/arch v0.12.0 h1:UsYJhbzPYGsT0HbEdmYcqtCv8UNGvnaL561NnIUvaKg=
|
||||||
golang.org/x/arch v0.11.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
golang.org/x/arch v0.12.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||||
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
|
golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
|
||||||
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
|
golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
|
||||||
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY=
|
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f h1:XdNn9LlyWAhLVp6P/i8QYBW+hlyhrhei9uErw2B5GJo=
|
||||||
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8=
|
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f/go.mod h1:D5SMRVC3C2/4+F/DB1wZsLRnSNimn2Sp/NPsCrsv8ak=
|
||||||
golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
|
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
|
||||||
golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||||
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
|
golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo=
|
||||||
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
|
golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM=
|
||||||
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
|
||||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
|
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
|
||||||
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
|
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
|
||||||
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
|
||||||
golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ=
|
golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg=
|
||||||
golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||||
golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ=
|
golang.org/x/tools v0.27.0 h1:qEKojBykQkQ4EynWy4S8Weg69NumxKdn40Fce3uc/8o=
|
||||||
golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
|
golang.org/x/tools v0.27.0/go.mod h1:sUi0ZgbwW9ZPAq26Ekut+weQPR5eIM6GQLQ1Yjm1H0Q=
|
||||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg=
|
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg=
|
||||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
|
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
|
||||||
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 h1:/jFs0duh4rdb8uIfPMv78iAJGcPKDeqAFnaLBropIC4=
|
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 h1:/jFs0duh4rdb8uIfPMv78iAJGcPKDeqAFnaLBropIC4=
|
||||||
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173/go.mod h1:tkCQ4FQXmpAgYVh++1cq16/dH4QJtmvpRv19DWGAHSA=
|
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173/go.mod h1:tkCQ4FQXmpAgYVh++1cq16/dH4QJtmvpRv19DWGAHSA=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38 h1:zciRKQ4kBpFgpfC5QQCVtnnNAcLIqweL7plyZRQHVpI=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697 h1:LWZqQOEjDyONlF1H6afSWpAL/znlREo2tHfLoe+8LMA=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU=
|
||||||
google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E=
|
google.golang.org/grpc v1.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0=
|
||||||
google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
|
google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA=
|
||||||
google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
|
google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io=
|
||||||
google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
|
|
BIN
media/01-overview-dark.png
Normal file
After Width: | Height: | Size: 89 KiB |
BIN
media/01-overview-light.png
Normal file
After Width: | Height: | Size: 96 KiB |
BIN
media/02-inbounds-dark.png
Normal file
After Width: | Height: | Size: 104 KiB |
BIN
media/02-inbounds-light.png
Normal file
After Width: | Height: | Size: 106 KiB |
BIN
media/03-add-inbound-dark.png
Normal file
After Width: | Height: | Size: 44 KiB |
BIN
media/03-add-inbound-light.png
Normal file
After Width: | Height: | Size: 44 KiB |
BIN
media/04-add-client-dark.png
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
media/04-add-client-light.png
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
media/05-settings-dark.png
Normal file
After Width: | Height: | Size: 84 KiB |
BIN
media/05-settings-light.png
Normal file
After Width: | Height: | Size: 84 KiB |
BIN
media/06-configs-dark.png
Normal file
After Width: | Height: | Size: 65 KiB |
BIN
media/06-configs-light.png
Normal file
After Width: | Height: | Size: 66 KiB |
BIN
media/1.png
Before Width: | Height: | Size: 59 KiB |
BIN
media/2.png
Before Width: | Height: | Size: 91 KiB |
BIN
media/3.png
Before Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 226 KiB After Width: | Height: | Size: 226 KiB |
BIN
media/3x-ui-light.png
Normal file
After Width: | Height: | Size: 224 KiB |
BIN
media/4.png
Before Width: | Height: | Size: 26 KiB |
BIN
media/5.png
Before Width: | Height: | Size: 71 KiB |
BIN
media/6.png
Before Width: | Height: | Size: 42 KiB |
|
@ -47,7 +47,7 @@
|
||||||
"tag": "direct",
|
"tag": "direct",
|
||||||
"protocol": "freedom",
|
"protocol": "freedom",
|
||||||
"settings": {
|
"settings": {
|
||||||
"domainStrategy": "UseIP",
|
"domainStrategy": "AsIs",
|
||||||
"redirect": "",
|
"redirect": "",
|
||||||
"noises": []
|
"noises": []
|
||||||
}
|
}
|
||||||
|
|
|
@ -238,6 +238,7 @@ func (s *SubService) genVmessLink(inbound *model.Inbound, email string) string {
|
||||||
headers, _ := splithttp["headers"].(map[string]interface{})
|
headers, _ := splithttp["headers"].(map[string]interface{})
|
||||||
obj["host"] = searchHost(headers)
|
obj["host"] = searchHost(headers)
|
||||||
}
|
}
|
||||||
|
obj["mode"] = splithttp["mode"].(string)
|
||||||
}
|
}
|
||||||
security, _ := stream["security"].(string)
|
security, _ := stream["security"].(string)
|
||||||
obj["tls"] = security
|
obj["tls"] = security
|
||||||
|
@ -389,6 +390,7 @@ func (s *SubService) genVlessLink(inbound *model.Inbound, email string) string {
|
||||||
headers, _ := splithttp["headers"].(map[string]interface{})
|
headers, _ := splithttp["headers"].(map[string]interface{})
|
||||||
params["host"] = searchHost(headers)
|
params["host"] = searchHost(headers)
|
||||||
}
|
}
|
||||||
|
params["mode"] = splithttp["mode"].(string)
|
||||||
}
|
}
|
||||||
security, _ := stream["security"].(string)
|
security, _ := stream["security"].(string)
|
||||||
if security == "tls" {
|
if security == "tls" {
|
||||||
|
@ -586,6 +588,7 @@ func (s *SubService) genTrojanLink(inbound *model.Inbound, email string) string
|
||||||
headers, _ := splithttp["headers"].(map[string]interface{})
|
headers, _ := splithttp["headers"].(map[string]interface{})
|
||||||
params["host"] = searchHost(headers)
|
params["host"] = searchHost(headers)
|
||||||
}
|
}
|
||||||
|
params["mode"] = splithttp["mode"].(string)
|
||||||
}
|
}
|
||||||
security, _ := stream["security"].(string)
|
security, _ := stream["security"].(string)
|
||||||
if security == "tls" {
|
if security == "tls" {
|
||||||
|
@ -783,6 +786,7 @@ func (s *SubService) genShadowsocksLink(inbound *model.Inbound, email string) st
|
||||||
headers, _ := splithttp["headers"].(map[string]interface{})
|
headers, _ := splithttp["headers"].(map[string]interface{})
|
||||||
params["host"] = searchHost(headers)
|
params["host"] = searchHost(headers)
|
||||||
}
|
}
|
||||||
|
params["mode"] = splithttp["mode"].(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
security, _ := stream["security"].(string)
|
security, _ := stream["security"].(string)
|
||||||
|
|
|
@ -63,7 +63,7 @@
|
||||||
return scriptHint(editor, javascriptKeywords,
|
return scriptHint(editor, javascriptKeywords,
|
||||||
function (e, cur) {return e.getTokenAt(cur);},
|
function (e, cur) {return e.getTokenAt(cur);},
|
||||||
options);
|
options);
|
||||||
};
|
}
|
||||||
CodeMirror.registerHelper("hint", "javascript", javascriptHint);
|
CodeMirror.registerHelper("hint", "javascript", javascriptHint);
|
||||||
|
|
||||||
function getCoffeeScriptToken(editor, cur) {
|
function getCoffeeScriptToken(editor, cur) {
|
||||||
|
|
|
@ -362,7 +362,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||||
if (type == wanted) return cont();
|
if (type == wanted) return cont();
|
||||||
else if (wanted == ";" || type == "}" || type == ")" || type == "]") return pass();
|
else if (wanted == ";" || type == "}" || type == ")" || type == "]") return pass();
|
||||||
else return cont(exp);
|
else return cont(exp);
|
||||||
};
|
}
|
||||||
return exp;
|
return exp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
.CodeMirror-lint-tooltip {
|
.CodeMirror-lint-tooltip {
|
||||||
background-color: #ffd;
|
background-color: #ffd;
|
||||||
border: 1px solid black;
|
border: 1px solid black;
|
||||||
border-radius: 4px 4px 4px 4px;
|
border-radius: 4px;
|
||||||
color: black;
|
color: black;
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
font-size: 10pt;
|
font-size: 10pt;
|
||||||
|
|
|
@ -19,6 +19,11 @@ const supportLangs = [
|
||||||
value: "zh-TW",
|
value: "zh-TW",
|
||||||
icon: "🇹🇼",
|
icon: "🇹🇼",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "日本語",
|
||||||
|
value: "ja-JP",
|
||||||
|
icon: "🇯🇵",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "Русский",
|
name: "Русский",
|
||||||
value: "ru-RU",
|
value: "ru-RU",
|
||||||
|
|
|
@ -113,6 +113,12 @@ const USERS_SECURITY = {
|
||||||
ZERO: "zero",
|
ZERO: "zero",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const MODE_OPTION = {
|
||||||
|
AUTO: "auto",
|
||||||
|
PACKET_UP: "packet-up",
|
||||||
|
STREAM_UP: "stream-up",
|
||||||
|
};
|
||||||
|
|
||||||
Object.freeze(Protocols);
|
Object.freeze(Protocols);
|
||||||
Object.freeze(SSMethods);
|
Object.freeze(SSMethods);
|
||||||
Object.freeze(TLS_FLOW_CONTROL);
|
Object.freeze(TLS_FLOW_CONTROL);
|
||||||
|
@ -125,6 +131,7 @@ Object.freeze(USAGE_OPTION);
|
||||||
Object.freeze(DOMAIN_STRATEGY_OPTION);
|
Object.freeze(DOMAIN_STRATEGY_OPTION);
|
||||||
Object.freeze(TCP_CONGESTION_OPTION);
|
Object.freeze(TCP_CONGESTION_OPTION);
|
||||||
Object.freeze(USERS_SECURITY);
|
Object.freeze(USERS_SECURITY);
|
||||||
|
Object.freeze(MODE_OPTION);
|
||||||
|
|
||||||
class XrayCommonClass {
|
class XrayCommonClass {
|
||||||
|
|
||||||
|
@ -528,7 +535,9 @@ class SplitHTTPStreamSettings extends XrayCommonClass {
|
||||||
maxConnections: 0,
|
maxConnections: 0,
|
||||||
cMaxReuseTimes: "64-128",
|
cMaxReuseTimes: "64-128",
|
||||||
cMaxLifetimeMs: 0
|
cMaxLifetimeMs: 0
|
||||||
}
|
},
|
||||||
|
mode = MODE_OPTION.AUTO,
|
||||||
|
noGRPCHeader = false,
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
this.path = path;
|
this.path = path;
|
||||||
|
@ -540,6 +549,8 @@ class SplitHTTPStreamSettings extends XrayCommonClass {
|
||||||
this.noSSEHeader = noSSEHeader;
|
this.noSSEHeader = noSSEHeader;
|
||||||
this.xPaddingBytes = xPaddingBytes;
|
this.xPaddingBytes = xPaddingBytes;
|
||||||
this.xmux = xmux;
|
this.xmux = xmux;
|
||||||
|
this.mode = mode;
|
||||||
|
this.noGRPCHeader = noGRPCHeader;
|
||||||
}
|
}
|
||||||
|
|
||||||
addHeader(name, value) {
|
addHeader(name, value) {
|
||||||
|
@ -561,6 +572,8 @@ class SplitHTTPStreamSettings extends XrayCommonClass {
|
||||||
json.noSSEHeader,
|
json.noSSEHeader,
|
||||||
json.xPaddingBytes,
|
json.xPaddingBytes,
|
||||||
json.xmux,
|
json.xmux,
|
||||||
|
json.mode,
|
||||||
|
json.noGRPCHeader
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -579,7 +592,9 @@ class SplitHTTPStreamSettings extends XrayCommonClass {
|
||||||
maxConnections: this.xmux.maxConnections,
|
maxConnections: this.xmux.maxConnections,
|
||||||
cMaxReuseTimes: this.xmux.cMaxReuseTimes,
|
cMaxReuseTimes: this.xmux.cMaxReuseTimes,
|
||||||
cMaxLifetimeMs: this.xmux.cMaxLifetimeMs
|
cMaxLifetimeMs: this.xmux.cMaxLifetimeMs
|
||||||
}
|
},
|
||||||
|
mode: this.mode,
|
||||||
|
noGRPCHeader: this.noGRPCHeader
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1329,6 +1344,7 @@ class Inbound extends XrayCommonClass {
|
||||||
const splithttp = this.stream.splithttp;
|
const splithttp = this.stream.splithttp;
|
||||||
obj.path = splithttp.path;
|
obj.path = splithttp.path;
|
||||||
obj.host = splithttp.host?.length > 0 ? splithttp.host : this.getHeader(splithttp, 'host');
|
obj.host = splithttp.host?.length > 0 ? splithttp.host : this.getHeader(splithttp, 'host');
|
||||||
|
obj.mode = splithttp.mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (security === 'tls') {
|
if (security === 'tls') {
|
||||||
|
@ -1401,6 +1417,7 @@ class Inbound extends XrayCommonClass {
|
||||||
const splithttp = this.stream.splithttp;
|
const splithttp = this.stream.splithttp;
|
||||||
params.set("path", splithttp.path);
|
params.set("path", splithttp.path);
|
||||||
params.set("host", splithttp.host?.length > 0 ? splithttp.host : this.getHeader(splithttp, 'host'));
|
params.set("host", splithttp.host?.length > 0 ? splithttp.host : this.getHeader(splithttp, 'host'));
|
||||||
|
params.set("mode", splithttp.mode);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1504,6 +1521,7 @@ class Inbound extends XrayCommonClass {
|
||||||
const splithttp = this.stream.splithttp;
|
const splithttp = this.stream.splithttp;
|
||||||
params.set("path", splithttp.path);
|
params.set("path", splithttp.path);
|
||||||
params.set("host", splithttp.host?.length > 0 ? splithttp.host : this.getHeader(splithttp, 'host'));
|
params.set("host", splithttp.host?.length > 0 ? splithttp.host : this.getHeader(splithttp, 'host'));
|
||||||
|
params.set("mode", splithttp.mode);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1586,6 +1604,7 @@ class Inbound extends XrayCommonClass {
|
||||||
const splithttp = this.stream.splithttp;
|
const splithttp = this.stream.splithttp;
|
||||||
params.set("path", splithttp.path);
|
params.set("path", splithttp.path);
|
||||||
params.set("host", splithttp.host?.length > 0 ? splithttp.host : this.getHeader(splithttp, 'host'));
|
params.set("host", splithttp.host?.length > 0 ? splithttp.host : this.getHeader(splithttp, 'host'));
|
||||||
|
params.set("mode", splithttp.mode);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2198,13 +2217,15 @@ Inbound.ShadowsocksSettings = class extends Inbound.Settings {
|
||||||
method = SSMethods.BLAKE3_AES_256_GCM,
|
method = SSMethods.BLAKE3_AES_256_GCM,
|
||||||
password = RandomUtil.randomShadowsocksPassword(),
|
password = RandomUtil.randomShadowsocksPassword(),
|
||||||
network = 'tcp,udp',
|
network = 'tcp,udp',
|
||||||
shadowsockses = [new Inbound.ShadowsocksSettings.Shadowsocks()]
|
shadowsockses = [new Inbound.ShadowsocksSettings.Shadowsocks()],
|
||||||
|
ivCheck = false,
|
||||||
) {
|
) {
|
||||||
super(protocol);
|
super(protocol);
|
||||||
this.method = method;
|
this.method = method;
|
||||||
this.password = password;
|
this.password = password;
|
||||||
this.network = network;
|
this.network = network;
|
||||||
this.shadowsockses = shadowsockses;
|
this.shadowsockses = shadowsockses;
|
||||||
|
this.ivCheck = ivCheck;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromJson(json = {}) {
|
static fromJson(json = {}) {
|
||||||
|
@ -2214,6 +2235,7 @@ Inbound.ShadowsocksSettings = class extends Inbound.Settings {
|
||||||
json.password,
|
json.password,
|
||||||
json.network,
|
json.network,
|
||||||
json.clients.map(client => Inbound.ShadowsocksSettings.Shadowsocks.fromJson(client)),
|
json.clients.map(client => Inbound.ShadowsocksSettings.Shadowsocks.fromJson(client)),
|
||||||
|
json.ivCheck,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2222,7 +2244,8 @@ Inbound.ShadowsocksSettings = class extends Inbound.Settings {
|
||||||
method: this.method,
|
method: this.method,
|
||||||
password: this.password,
|
password: this.password,
|
||||||
network: this.network,
|
network: this.network,
|
||||||
clients: Inbound.ShadowsocksSettings.toJsonArray(this.shadowsockses)
|
clients: Inbound.ShadowsocksSettings.toJsonArray(this.shadowsockses),
|
||||||
|
ivCheck: this.ivCheck,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -77,6 +77,12 @@ const USERS_SECURITY = {
|
||||||
ZERO: "zero",
|
ZERO: "zero",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const MODE_OPTION = {
|
||||||
|
AUTO: "auto",
|
||||||
|
PACKET_UP: "packet-up",
|
||||||
|
STREAM_UP: "stream-up",
|
||||||
|
};
|
||||||
|
|
||||||
Object.freeze(Protocols);
|
Object.freeze(Protocols);
|
||||||
Object.freeze(SSMethods);
|
Object.freeze(SSMethods);
|
||||||
Object.freeze(TLS_FLOW_CONTROL);
|
Object.freeze(TLS_FLOW_CONTROL);
|
||||||
|
@ -85,6 +91,7 @@ Object.freeze(ALPN_OPTION);
|
||||||
Object.freeze(OutboundDomainStrategies);
|
Object.freeze(OutboundDomainStrategies);
|
||||||
Object.freeze(WireguardDomainStrategy);
|
Object.freeze(WireguardDomainStrategy);
|
||||||
Object.freeze(USERS_SECURITY);
|
Object.freeze(USERS_SECURITY);
|
||||||
|
Object.freeze(MODE_OPTION);
|
||||||
|
|
||||||
|
|
||||||
class CommonClass {
|
class CommonClass {
|
||||||
|
@ -320,16 +327,22 @@ class HttpUpgradeStreamSettings extends CommonClass {
|
||||||
}
|
}
|
||||||
|
|
||||||
class SplitHTTPStreamSettings extends CommonClass {
|
class SplitHTTPStreamSettings extends CommonClass {
|
||||||
constructor(path = '/', host = '') {
|
constructor(
|
||||||
|
path = '/',
|
||||||
|
host = '',
|
||||||
|
mode = '',
|
||||||
|
) {
|
||||||
super();
|
super();
|
||||||
this.path = path;
|
this.path = path;
|
||||||
this.host = host;
|
this.host = host;
|
||||||
|
this.mode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromJson(json = {}) {
|
static fromJson(json = {}) {
|
||||||
return new SplitHTTPStreamSettings(
|
return new SplitHTTPStreamSettings(
|
||||||
json.path,
|
json.path,
|
||||||
json.host,
|
json.host,
|
||||||
|
json.mode,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,6 +350,7 @@ class SplitHTTPStreamSettings extends CommonClass {
|
||||||
return {
|
return {
|
||||||
path: this.path,
|
path: this.path,
|
||||||
host: this.host,
|
host: this.host,
|
||||||
|
mode: this.mode,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -710,7 +724,7 @@ class Outbound extends CommonClass {
|
||||||
} else if (network === 'httpupgrade') {
|
} else if (network === 'httpupgrade') {
|
||||||
stream.httpupgrade = new HttpUpgradeStreamSettings(json.path, json.host);
|
stream.httpupgrade = new HttpUpgradeStreamSettings(json.path, json.host);
|
||||||
} else if (network === 'splithttp') {
|
} else if (network === 'splithttp') {
|
||||||
stream.splithttp = new SplitHTTPStreamSettings(json.path, json.host);
|
stream.splithttp = new SplitHTTPStreamSettings(json.path, json.host, json.mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (json.tls && json.tls == 'tls') {
|
if (json.tls && json.tls == 'tls') {
|
||||||
|
@ -754,7 +768,7 @@ class Outbound extends CommonClass {
|
||||||
} else if (type === 'httpupgrade') {
|
} else if (type === 'httpupgrade') {
|
||||||
stream.httpupgrade = new HttpUpgradeStreamSettings(path, host);
|
stream.httpupgrade = new HttpUpgradeStreamSettings(path, host);
|
||||||
} else if (type === 'splithttp') {
|
} else if (type === 'splithttp') {
|
||||||
stream.splithttp = new SplitHTTPStreamSettings(path, host);
|
stream.splithttp = new SplitHTTPStreamSettings(path, host, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (security == 'tls') {
|
if (security == 'tls') {
|
||||||
|
|
|
@ -380,6 +380,11 @@
|
||||||
<a-form-item label='{{ i18n "path" }}'>
|
<a-form-item label='{{ i18n "path" }}'>
|
||||||
<a-input v-model.trim="outbound.stream.splithttp.path"></a-input>
|
<a-input v-model.trim="outbound.stream.splithttp.path"></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
<a-form-item label='Mode'>
|
||||||
|
<a-select v-model="outbound.stream.splithttp.mode" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
|
<a-select-option v-for="key in MODE_OPTION" :value="key">[[ key ]]</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -43,5 +43,8 @@
|
||||||
<a-select-option value="udp">UDP</a-select-option>
|
<a-select-option value="udp">UDP</a-select-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
<a-form-item label='ivCheck'>
|
||||||
|
<a-switch v-model="inbound.settings.ivCheck"></a-switch>
|
||||||
|
</a-form-item>
|
||||||
</a-form>
|
</a-form>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
@ -22,6 +22,12 @@
|
||||||
</a-input>
|
</a-input>
|
||||||
</a-input-group>
|
</a-input-group>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
<a-form-item label='Mode'>
|
||||||
|
<a-select v-model="inbound.stream.splithttp.mode" style="width: 50%"
|
||||||
|
:dropdown-class-name="themeSwitcher.currentTheme">
|
||||||
|
<a-select-option v-for="key in MODE_OPTION" :value="key">[[ key ]]</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
<a-form-item label="Max Concurrent Upload">
|
<a-form-item label="Max Concurrent Upload">
|
||||||
<a-input v-model.trim="inbound.stream.splithttp.scMaxConcurrentPosts"></a-input>
|
<a-input v-model.trim="inbound.stream.splithttp.scMaxConcurrentPosts"></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
@ -49,5 +55,8 @@
|
||||||
<a-form-item label="Max Lifetime (ms)">
|
<a-form-item label="Max Lifetime (ms)">
|
||||||
<a-input v-model="inbound.stream.splithttp.xmux.cMaxLifetimeMs"></a-input>
|
<a-input v-model="inbound.stream.splithttp.xmux.cMaxLifetimeMs"></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
<a-form-item label="No gRPC Header">
|
||||||
|
<a-switch v-model="inbound.stream.splithttp.noGRPCHeader"></a-switch>
|
||||||
|
</a-form-item>
|
||||||
</a-form>
|
</a-form>
|
||||||
{{end}}
|
{{end}}
|
|
@ -58,6 +58,14 @@
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</template>
|
</template>
|
||||||
|
<template v-if="inbound.isSplithttp">
|
||||||
|
<tr>
|
||||||
|
<td>Mode</td>
|
||||||
|
<td>
|
||||||
|
<a-tag>[[ inbound.stream.splithttp.mode ]]</a-tag>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
<template v-if="inbound.isKcp">
|
<template v-if="inbound.isKcp">
|
||||||
<tr>
|
<tr>
|
||||||
<td>kcp {{ i18n "encryption" }}</td>
|
<td>kcp {{ i18n "encryption" }}</td>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
}
|
}
|
||||||
.ant-table .ant-table-content .ant-table-tbody tr:last-child .ant-table-wrapper {
|
.ant-table .ant-table-content .ant-table-tbody tr:last-child .ant-table-wrapper {
|
||||||
margin:-10px 22px -10px !important;
|
margin:-10px 22px !important;
|
||||||
}
|
}
|
||||||
.ant-table .ant-table-content .ant-table-tbody tr:last-child .ant-table-wrapper .ant-table {
|
.ant-table .ant-table-content .ant-table-tbody tr:last-child .ant-table-wrapper .ant-table {
|
||||||
border-bottom-left-radius: 1rem;
|
border-bottom-left-radius: 1rem;
|
||||||
|
@ -40,7 +40,7 @@
|
||||||
padding: .5rem;
|
padding: .5rem;
|
||||||
}
|
}
|
||||||
.ant-table .ant-table-content .ant-table-tbody tr:last-child .ant-table-wrapper {
|
.ant-table .ant-table-content .ant-table-tbody tr:last-child .ant-table-wrapper {
|
||||||
margin:-10px 2px -10px !important;
|
margin:-10px 2px !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.ant-col-sm-24 {
|
.ant-col-sm-24 {
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
padding: .5rem 1rem;
|
padding: .5rem 1rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background: rgb(255 145 0 / 15%);
|
background: rgb(255 145 0 / 15%);
|
||||||
margin: 1.5rem 2.5rem 0rem 2.5rem;
|
margin: 1.5rem 2.5rem 0rem;
|
||||||
border-radius: .5rem;
|
border-radius: .5rem;
|
||||||
transition: all 0.5s;
|
transition: all 0.5s;
|
||||||
animation: signal 3s cubic-bezier(0.18, 0.89, 0.32, 1.28) infinite;
|
animation: signal 3s cubic-bezier(0.18, 0.89, 0.32, 1.28) infinite;
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
}
|
}
|
||||||
.ant-collapse-content-box>li {
|
.ant-collapse-content-box>li {
|
||||||
padding: 12px 0 0 0 !important;
|
padding: 12px 0 0 !important;
|
||||||
}
|
}
|
||||||
.ant-list-item>li {
|
.ant-list-item>li {
|
||||||
padding: 10px 20px !important;
|
padding: 10px 20px !important;
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
"tag": "direct",
|
"tag": "direct",
|
||||||
"protocol": "freedom",
|
"protocol": "freedom",
|
||||||
"settings": {
|
"settings": {
|
||||||
"domainStrategy": "UseIP",
|
"domainStrategy": "AsIs",
|
||||||
"redirect": "",
|
"redirect": "",
|
||||||
"noises": []
|
"noises": []
|
||||||
}
|
}
|
||||||
|
|
|
@ -588,9 +588,13 @@ func (s *InboundService) DelInboundClient(inboundId int, clientId string) (bool,
|
||||||
logger.Debug("Client deleted by api:", email)
|
logger.Debug("Client deleted by api:", email)
|
||||||
needRestart = false
|
needRestart = false
|
||||||
} else {
|
} else {
|
||||||
logger.Debug("Unable to del client by api:", err1)
|
if strings.Contains(err1.Error(), fmt.Sprintf("User %s not found.", email)) {
|
||||||
|
logger.Debug("User is already deleted. Nothing to do more...")
|
||||||
|
} else {
|
||||||
|
logger.Debug("Error in deleting client by api:", err1)
|
||||||
needRestart = true
|
needRestart = true
|
||||||
}
|
}
|
||||||
|
}
|
||||||
s.xrayApi.Close()
|
s.xrayApi.Close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -713,12 +717,16 @@ func (s *InboundService) UpdateInboundClient(data *model.Inbound, clientId strin
|
||||||
if oldClients[clientIndex].Enable {
|
if oldClients[clientIndex].Enable {
|
||||||
err1 := s.xrayApi.RemoveUser(oldInbound.Tag, oldEmail)
|
err1 := s.xrayApi.RemoveUser(oldInbound.Tag, oldEmail)
|
||||||
if err1 == nil {
|
if err1 == nil {
|
||||||
logger.Debug("Old client deleted by api:", clients[0].Email)
|
logger.Debug("Old client deleted by api:", oldEmail)
|
||||||
|
} else {
|
||||||
|
if strings.Contains(err1.Error(), fmt.Sprintf("User %s not found.", oldEmail)) {
|
||||||
|
logger.Debug("User is already deleted. Nothing to do more...")
|
||||||
} else {
|
} else {
|
||||||
logger.Debug("Error in deleting client by api:", err1)
|
logger.Debug("Error in deleting client by api:", err1)
|
||||||
needRestart = true
|
needRestart = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if clients[0].Enable {
|
if clients[0].Enable {
|
||||||
cipher := ""
|
cipher := ""
|
||||||
if oldInbound.Protocol == "shadowsocks" {
|
if oldInbound.Protocol == "shadowsocks" {
|
||||||
|
@ -1037,14 +1045,10 @@ func (s *InboundService) disableInvalidInbounds(tx *gorm.DB) (bool, int64, error
|
||||||
if err1 == nil {
|
if err1 == nil {
|
||||||
logger.Debug("Inbound disabled by api:", tag)
|
logger.Debug("Inbound disabled by api:", tag)
|
||||||
} else {
|
} else {
|
||||||
if strings.Contains(err1.Error(), fmt.Sprintf("User %s not found.", tag)) {
|
logger.Debug("Error in disabling inbound by api:", err1)
|
||||||
logger.Debug("User is already disabled. Nothing to do more...")
|
|
||||||
} else {
|
|
||||||
logger.Debug("Error in disabling client by api:", err1)
|
|
||||||
needRestart = true
|
needRestart = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
s.xrayApi.Close()
|
s.xrayApi.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -286,7 +286,7 @@ func (s *ServerService) GetXrayVersions() ([]string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (major == 1 && minor == 8 && patch == 24) ||
|
if (major == 1 && minor == 8 && patch == 24) ||
|
||||||
(major == 24 && ((minor > 10) || (minor == 10 && patch >= 16))) ||
|
(major == 24 && ((minor > 11) || (minor == 11 && patch >= 11))) ||
|
||||||
(major > 24) {
|
(major > 24) {
|
||||||
versions = append(versions, release.TagName)
|
versions = append(versions, release.TagName)
|
||||||
}
|
}
|
||||||
|
|
595
web/translation/translate.ja_JP.toml
Normal file
|
@ -0,0 +1,595 @@
|
||||||
|
"username" = "ユーザー名"
|
||||||
|
"password" = "パスワード"
|
||||||
|
"login" = "ログイン"
|
||||||
|
"confirm" = "確認"
|
||||||
|
"cancel" = "キャンセル"
|
||||||
|
"close" = "閉じる"
|
||||||
|
"copy" = "コピー"
|
||||||
|
"copied" = "コピー済み"
|
||||||
|
"download" = "ダウンロード"
|
||||||
|
"remark" = "備考"
|
||||||
|
"enable" = "有効化"
|
||||||
|
"protocol" = "プロトコル"
|
||||||
|
"search" = "検索"
|
||||||
|
"filter" = "フィルター"
|
||||||
|
"loading" = "読み込み中..."
|
||||||
|
"second" = "秒"
|
||||||
|
"minute" = "分"
|
||||||
|
"hour" = "時間"
|
||||||
|
"day" = "日"
|
||||||
|
"check" = "確認"
|
||||||
|
"indefinite" = "無期限"
|
||||||
|
"unlimited" = "無制限"
|
||||||
|
"none" = "なし"
|
||||||
|
"qrCode" = "QRコード"
|
||||||
|
"info" = "詳細情報"
|
||||||
|
"edit" = "編集"
|
||||||
|
"delete" = "削除"
|
||||||
|
"reset" = "リセット"
|
||||||
|
"copySuccess" = "コピー成功"
|
||||||
|
"sure" = "確定"
|
||||||
|
"encryption" = "暗号化"
|
||||||
|
"transmission" = "伝送"
|
||||||
|
"host" = "ホスト"
|
||||||
|
"path" = "パス"
|
||||||
|
"camouflage" = "偽装"
|
||||||
|
"status" = "ステータス"
|
||||||
|
"enabled" = "有効"
|
||||||
|
"disabled" = "無効"
|
||||||
|
"depleted" = "消耗済み"
|
||||||
|
"depletingSoon" = "間もなく消耗"
|
||||||
|
"offline" = "オフライン"
|
||||||
|
"online" = "オンライン"
|
||||||
|
"domainName" = "ドメイン名"
|
||||||
|
"monitor" = "監視"
|
||||||
|
"certificate" = "証明書"
|
||||||
|
"fail" = "失敗"
|
||||||
|
"success" = "成功"
|
||||||
|
"getVersion" = "バージョン取得"
|
||||||
|
"install" = "インストール"
|
||||||
|
"clients" = "クライアント"
|
||||||
|
"usage" = "利用状況"
|
||||||
|
"secretToken" = "シークレットトークン"
|
||||||
|
"remained" = "残り"
|
||||||
|
"security" = "セキュリティ"
|
||||||
|
"secAlertTitle" = "セキュリティアラート"
|
||||||
|
"secAlertSsl" = "この接続は安全ではありません。TLSを有効にしてデータ保護を行うまで、機密情報を入力しないでください。"
|
||||||
|
"secAlertConf" = "一部の設定は脆弱です。潜在的な脆弱性を防ぐために、セキュリティプロトコルを強化することをお勧めします。"
|
||||||
|
"secAlertSSL" = "セキュアな接続がありません。データ保護のためにTLS証明書をインストールしてください。"
|
||||||
|
"secAlertPanelPort" = "デフォルトのポートにはセキュリティリスクがあります。ランダムなポートまたは特定のポートを設定してください。"
|
||||||
|
"secAlertPanelURI" = "デフォルトのURIパスは安全ではありません。複雑なURIパスを設定してください。"
|
||||||
|
"secAlertSubURI" = "サブスクリプションのデフォルトURIパスは安全ではありません。複雑なURIパスを設定してください。"
|
||||||
|
"secAlertSubJsonURI" = "JSONサブスクリプションのデフォルトURIパスは安全ではありません。複雑なURIパスを設定してください。"
|
||||||
|
|
||||||
|
[menu]
|
||||||
|
"dashboard" = "ダッシュボード"
|
||||||
|
"inbounds" = "インバウンド一覧"
|
||||||
|
"settings" = "パネル設定"
|
||||||
|
"xray" = "Xray設定"
|
||||||
|
"logout" = "ログアウト"
|
||||||
|
"link" = "リンク管理"
|
||||||
|
|
||||||
|
[pages.login]
|
||||||
|
"hello" = "こんにちは"
|
||||||
|
"title" = "ようこそ"
|
||||||
|
"loginAgain" = "ログインセッションが切れました。再度ログインしてください。"
|
||||||
|
|
||||||
|
[pages.login.toasts]
|
||||||
|
"invalidFormData" = "データ形式エラー"
|
||||||
|
"emptyUsername" = "ユーザー名を入力してください"
|
||||||
|
"emptyPassword" = "パスワードを入力してください"
|
||||||
|
"wrongUsernameOrPassword" = "ユーザー名またはパスワードが間違っています"
|
||||||
|
"successLogin" = "ログイン成功"
|
||||||
|
|
||||||
|
[pages.index]
|
||||||
|
"title" = "システムステータス"
|
||||||
|
"memory" = "メモリ"
|
||||||
|
"hard" = "ハードディスク"
|
||||||
|
"xrayStatus" = "Xray"
|
||||||
|
"stopXray" = "停止"
|
||||||
|
"restartXray" = "再起動"
|
||||||
|
"xraySwitch" = "バージョン"
|
||||||
|
"xraySwitchClick" = "切り替えるバージョンを選択してください"
|
||||||
|
"xraySwitchClickDesk" = "慎重に選択してください。古いバージョンは現在の設定と互換性がない可能性があります。"
|
||||||
|
"operationHours" = "システム稼働時間"
|
||||||
|
"systemLoad" = "システム負荷"
|
||||||
|
"systemLoadDesc" = "過去1、5、15分間のシステム平均負荷"
|
||||||
|
"connectionTcpCountDesc" = "システム内のすべてのTCP接続数"
|
||||||
|
"connectionUdpCountDesc" = "システム内のすべてのUDP接続数"
|
||||||
|
"connectionCount" = "接続数"
|
||||||
|
"upSpeed" = "総アップロード速度"
|
||||||
|
"downSpeed" = "総ダウンロード速度"
|
||||||
|
"totalSent" = "システム起動以降の送信データ量"
|
||||||
|
"totalReceive" = "システム起動以降の受信データ量"
|
||||||
|
"xraySwitchVersionDialog" = "Xrayバージョン切り替え"
|
||||||
|
"xraySwitchVersionDialogDesc" = "Xrayのバージョンを切り替えますか?"
|
||||||
|
"dontRefresh" = "インストール中、このページをリロードしないでください"
|
||||||
|
"logs" = "ログ"
|
||||||
|
"config" = "設定"
|
||||||
|
"backup" = "バックアップと復元"
|
||||||
|
"backupTitle" = "データベースのバックアップと復元"
|
||||||
|
"backupDescription" = "データベースを復元する前にバックアップすることをお勧めします"
|
||||||
|
"exportDatabase" = "バックアップ"
|
||||||
|
"importDatabase" = "復元"
|
||||||
|
|
||||||
|
[pages.inbounds]
|
||||||
|
"title" = "インバウンド一覧"
|
||||||
|
"totalDownUp" = "総アップロード / ダウンロード"
|
||||||
|
"totalUsage" = "総使用量"
|
||||||
|
"inboundCount" = "インバウンド数"
|
||||||
|
"operate" = "メニュー"
|
||||||
|
"enable" = "有効化"
|
||||||
|
"remark" = "備考"
|
||||||
|
"protocol" = "プロトコル"
|
||||||
|
"port" = "ポート"
|
||||||
|
"traffic" = "トラフィック"
|
||||||
|
"details" = "詳細情報"
|
||||||
|
"transportConfig" = "トランスポート設定"
|
||||||
|
"expireDate" = "有効期限"
|
||||||
|
"resetTraffic" = "トラフィックリセット"
|
||||||
|
"addInbound" = "インバウンド追加"
|
||||||
|
"generalActions" = "一般操作"
|
||||||
|
"create" = "追加"
|
||||||
|
"update" = "更新"
|
||||||
|
"modifyInbound" = "インバウンド修正"
|
||||||
|
"deleteInbound" = "インバウンド削除"
|
||||||
|
"deleteInboundContent" = "インバウンドを削除してもよろしいですか?"
|
||||||
|
"deleteClient" = "クライアント削除"
|
||||||
|
"deleteClientContent" = "クライアントを削除してもよろしいですか?"
|
||||||
|
"resetTrafficContent" = "トラフィックをリセットしてもよろしいですか?"
|
||||||
|
"copyLink" = "リンクをコピー"
|
||||||
|
"address" = "アドレス"
|
||||||
|
"network" = "ネットワーク"
|
||||||
|
"destinationPort" = "宛先ポート"
|
||||||
|
"targetAddress" = "宛先アドレス"
|
||||||
|
"monitorDesc" = "空白にするとすべてのIPを監視"
|
||||||
|
"meansNoLimit" = "= 無制限(単位:GB)"
|
||||||
|
"totalFlow" = "総トラフィック"
|
||||||
|
"leaveBlankToNeverExpire" = "空白にすると期限なし"
|
||||||
|
"noRecommendKeepDefault" = "デフォルト値を保持することをお勧めします"
|
||||||
|
"certificatePath" = "ファイルパス"
|
||||||
|
"certificateContent" = "ファイル内容"
|
||||||
|
"publicKey" = "公開鍵"
|
||||||
|
"privatekey" = "秘密鍵"
|
||||||
|
"clickOnQRcode" = "QRコードをクリックしてコピー"
|
||||||
|
"client" = "クライアント"
|
||||||
|
"export" = "リンクエクスポート"
|
||||||
|
"clone" = "複製"
|
||||||
|
"cloneInbound" = "複製"
|
||||||
|
"cloneInboundContent" = "このインバウンドルールは、ポート(Port)、リスニングIP(Listening IP)、クライアント(Clients)を除くすべての設定がクローンされます"
|
||||||
|
"cloneInboundOk" = "クローン作成"
|
||||||
|
"resetAllTraffic" = "すべてのインバウンドトラフィックをリセット"
|
||||||
|
"resetAllTrafficTitle" = "すべてのインバウンドトラフィックをリセット"
|
||||||
|
"resetAllTrafficContent" = "すべてのインバウンドトラフィックをリセットしてもよろしいですか?"
|
||||||
|
"resetInboundClientTraffics" = "クライアントトラフィックをリセット"
|
||||||
|
"resetInboundClientTrafficTitle" = "すべてのクライアントトラフィックをリセット"
|
||||||
|
"resetInboundClientTrafficContent" = "このインバウンドクライアントのすべてのトラフィックをリセットしてもよろしいですか?"
|
||||||
|
"resetAllClientTraffics" = "すべてのクライアントトラフィックをリセット"
|
||||||
|
"resetAllClientTrafficTitle" = "すべてのクライアントトラフィックをリセット"
|
||||||
|
"resetAllClientTrafficContent" = "すべてのクライアントのトラフィックをリセットしてもよろしいですか?"
|
||||||
|
"delDepletedClients" = "トラフィックが尽きたクライアントを削除"
|
||||||
|
"delDepletedClientsTitle" = "トラフィックが尽きたクライアントを削除"
|
||||||
|
"delDepletedClientsContent" = "トラフィックが尽きたすべてのクライアントを削除してもよろしいですか?"
|
||||||
|
"email" = "メールアドレス"
|
||||||
|
"emailDesc" = "メールアドレスは一意でなければなりません"
|
||||||
|
"IPLimit" = "IP制限"
|
||||||
|
"IPLimitDesc" = "設定値を超えるとインバウンドトラフィックが無効になります。(0 = 無効)"
|
||||||
|
"IPLimitlog" = "IPログ"
|
||||||
|
"IPLimitlogDesc" = "IP履歴ログ(無効なインバウンドトラフィックを有効にするには、ログをクリアしてください)"
|
||||||
|
"IPLimitlogclear" = "ログをクリア"
|
||||||
|
"setDefaultCert" = "パネル設定から証明書を設定"
|
||||||
|
"telegramDesc" = "TelegramチャットIDを提供してください。(ボットで'/id'コマンドを使用)または(@userinfobot)"
|
||||||
|
"subscriptionDesc" = "サブスクリプションURLを見つけるには、“詳細情報”に移動してください。また、複数のクライアントに同じ名前を使用することができます。"
|
||||||
|
"info" = "情報"
|
||||||
|
"same" = "同じ"
|
||||||
|
"inboundData" = "インバウンドデータ"
|
||||||
|
"exportInbound" = "インバウンドルールをエクスポート"
|
||||||
|
"import" = "インポート"
|
||||||
|
"importInbound" = "インバウンドルールをインポート"
|
||||||
|
|
||||||
|
[pages.client]
|
||||||
|
"add" = "クライアント追加"
|
||||||
|
"edit" = "クライアント編集"
|
||||||
|
"submitAdd" = "クライアント追加"
|
||||||
|
"submitEdit" = "変更を保存"
|
||||||
|
"clientCount" = "クライアント数"
|
||||||
|
"bulk" = "一括作成"
|
||||||
|
"method" = "方法"
|
||||||
|
"first" = "最初"
|
||||||
|
"last" = "最後"
|
||||||
|
"prefix" = "プレフィックス"
|
||||||
|
"postfix" = "サフィックス"
|
||||||
|
"delayedStart" = "初回使用後に開始"
|
||||||
|
"expireDays" = "期間"
|
||||||
|
"days" = "日"
|
||||||
|
"renew" = "自動更新"
|
||||||
|
"renewDesc" = "期限が切れた後に自動更新。(0 = 無効)(単位:日)"
|
||||||
|
|
||||||
|
[pages.inbounds.toasts]
|
||||||
|
"obtain" = "取得"
|
||||||
|
|
||||||
|
[pages.inbounds.stream.general]
|
||||||
|
"request" = "リクエスト"
|
||||||
|
"response" = "レスポンス"
|
||||||
|
"name" = "名前"
|
||||||
|
"value" = "値"
|
||||||
|
|
||||||
|
[pages.inbounds.stream.tcp]
|
||||||
|
"version" = "バージョン"
|
||||||
|
"method" = "方法"
|
||||||
|
"path" = "パス"
|
||||||
|
"status" = "ステータス"
|
||||||
|
"statusDescription" = "ステータス説明"
|
||||||
|
"requestHeader" = "リクエストヘッダー"
|
||||||
|
"responseHeader" = "レスポンスヘッダー"
|
||||||
|
|
||||||
|
[pages.settings]
|
||||||
|
"title" = "パネル設定"
|
||||||
|
"save" = "保存"
|
||||||
|
"infoDesc" = "ここでのすべての変更は、保存してパネルを再起動する必要があります"
|
||||||
|
"restartPanel" = "パネル再起動"
|
||||||
|
"restartPanelDesc" = "パネルを再起動してもよろしいですか?再起動後にパネルにアクセスできない場合は、サーバーでパネルログを確認してください"
|
||||||
|
"actions" = "操作"
|
||||||
|
"resetDefaultConfig" = "デフォルト設定にリセット"
|
||||||
|
"panelSettings" = "一般"
|
||||||
|
"securitySettings" = "セキュリティ設定"
|
||||||
|
"TGBotSettings" = "Telegramボット設定"
|
||||||
|
"panelListeningIP" = "パネル監視IP"
|
||||||
|
"panelListeningIPDesc" = "デフォルトではすべてのIPを監視する"
|
||||||
|
"panelListeningDomain" = "パネル監視ドメイン"
|
||||||
|
"panelListeningDomainDesc" = "デフォルトで空白の場合、すべてのドメインとIPアドレスを監視する"
|
||||||
|
"panelPort" = "パネル監視ポート"
|
||||||
|
"panelPortDesc" = "再起動で有効"
|
||||||
|
"publicKeyPath" = "パネル証明書公開鍵ファイルパス"
|
||||||
|
"publicKeyPathDesc" = "'/'で始まる絶対パスを入力"
|
||||||
|
"privateKeyPath" = "パネル証明書秘密鍵ファイルパス"
|
||||||
|
"privateKeyPathDesc" = "'/'で始まる絶対パスを入力"
|
||||||
|
"panelUrlPath" = "パネルURLルートパス"
|
||||||
|
"panelUrlPathDesc" = "'/'で始まり、'/'で終わる必要があります"
|
||||||
|
"pageSize" = "ページサイズ"
|
||||||
|
"pageSizeDesc" = "インバウンドテーブルのページサイズを定義します。0を設定すると無効化されます"
|
||||||
|
"remarkModel" = "備考モデルと区切り記号"
|
||||||
|
"datepicker" = "日付ピッカー"
|
||||||
|
"datepickerPlaceholder" = "日付を選択"
|
||||||
|
"datepickerDescription" = "日付選択カレンダーで有効期限を指定する"
|
||||||
|
"sampleRemark" = "備考の例"
|
||||||
|
"oldUsername" = "旧ユーザー名"
|
||||||
|
"currentPassword" = "旧パスワード"
|
||||||
|
"newUsername" = "新しいユーザー名"
|
||||||
|
"newPassword" = "新しいパスワード"
|
||||||
|
"telegramBotEnable" = "Telegramボットを有効にする"
|
||||||
|
"telegramBotEnableDesc" = "Telegramボット機能を有効にする"
|
||||||
|
"telegramToken" = "Telegramボットトークン"
|
||||||
|
"telegramTokenDesc" = "'@BotFather'から取得したTelegramボットトークン"
|
||||||
|
"telegramProxy" = "SOCKS5プロキシ"
|
||||||
|
"telegramProxyDesc" = "SOCKS5プロキシを有効にしてTelegramに接続する(ガイドに従って設定を調整)"
|
||||||
|
"telegramAPIServer" = "Telegram APIサーバー"
|
||||||
|
"telegramAPIServerDesc" = "使用するTelegram APIサーバー。空白の場合はデフォルトサーバーを使用する"
|
||||||
|
"telegramChatId" = "管理者チャットID"
|
||||||
|
"telegramChatIdDesc" = "Telegram管理者チャットID(複数の場合はカンマで区切る)@userinfobotで取得するか、ボットで'/id'コマンドを使用して取得する"
|
||||||
|
"telegramNotifyTime" = "通知時間"
|
||||||
|
"telegramNotifyTimeDesc" = "定期的なTelegramボット通知時間を設定する(crontab時間形式を使用)"
|
||||||
|
"tgNotifyBackup" = "データベースバックアップ"
|
||||||
|
"tgNotifyBackupDesc" = "レポート付きのデータベースバックアップファイルを送信"
|
||||||
|
"tgNotifyLogin" = "ログイン通知"
|
||||||
|
"tgNotifyLoginDesc" = "誰かがパネルにログインしようとしたときに、ユーザー名、IPアドレス、時間を表示する"
|
||||||
|
"sessionMaxAge" = "セッション期間"
|
||||||
|
"sessionMaxAgeDesc" = "ログイン状態を保持する期間(単位:分)"
|
||||||
|
"expireTimeDiff" = "有効期限通知のしきい値"
|
||||||
|
"expireTimeDiffDesc" = "このしきい値に達した場合、有効期限に関する通知を受け取る(単位:日)"
|
||||||
|
"trafficDiff" = "トラフィック消耗しきい値"
|
||||||
|
"trafficDiffDesc" = "このしきい値に達した場合、トラフィック消耗に関する通知を受け取る(単位:GB)"
|
||||||
|
"tgNotifyCpu" = "CPU負荷通知しきい値"
|
||||||
|
"tgNotifyCpuDesc" = "CPU負荷がこのしきい値を超えた場合、通知を受け取る(単位:%)"
|
||||||
|
"timeZone" = "タイムゾーン"
|
||||||
|
"timeZoneDesc" = "定時タスクはこのタイムゾーンの時間に従って実行される"
|
||||||
|
"subSettings" = "サブスクリプション設定"
|
||||||
|
"subEnable" = "サブスクリプションサービスを有効にする"
|
||||||
|
"subEnableDesc" = "サブスクリプションサービス機能を有効にする"
|
||||||
|
"subListen" = "監視IP"
|
||||||
|
"subListenDesc" = "サブスクリプションサービスが監視するIPアドレス(空白にするとすべてのIPを監視)"
|
||||||
|
"subPort" = "監視ポート"
|
||||||
|
"subPortDesc" = "サブスクリプションサービスが監視するポート番号(使用されていないポートである必要があります)"
|
||||||
|
"subCertPath" = "公開鍵パス"
|
||||||
|
"subCertPathDesc" = "サブスクリプションサービスで使用する公開鍵ファイルのパス('/'で始まる)"
|
||||||
|
"subKeyPath" = "秘密鍵パス"
|
||||||
|
"subKeyPathDesc" = "サブスクリプションサービスで使用する秘密鍵ファイルのパス('/'で始まる)"
|
||||||
|
"subPath" = "URIパス"
|
||||||
|
"subPathDesc" = "サブスクリプションサービスで使用するURIパス('/'で始まり、'/'で終わる)"
|
||||||
|
"subDomain" = "監視ドメイン"
|
||||||
|
"subDomainDesc" = "サブスクリプションサービスが監視するドメイン(空白にするとすべてのドメインとIPを監視)"
|
||||||
|
"subUpdates" = "更新間隔"
|
||||||
|
"subUpdatesDesc" = "クライアントアプリケーションでサブスクリプションURLの更新間隔(単位:時間)"
|
||||||
|
"subEncrypt" = "エンコード"
|
||||||
|
"subEncryptDesc" = "サブスクリプションサービスが返す内容をBase64エンコードする"
|
||||||
|
"subShowInfo" = "利用情報を表示"
|
||||||
|
"subShowInfoDesc" = "クライアントアプリで残りのトラフィックと日付情報を表示する"
|
||||||
|
"subURI" = "リバースプロキシURI"
|
||||||
|
"subURIDesc" = "プロキシ後ろのサブスクリプションURLのURIパスに使用する"
|
||||||
|
"fragment" = "フラグメント"
|
||||||
|
"fragmentDesc" = "TLS helloパケットのフラグメントを有効にする"
|
||||||
|
"fragmentSett" = "設定"
|
||||||
|
"noisesDesc" = "Noisesを有効にする"
|
||||||
|
"noisesSett" = "Noises設定"
|
||||||
|
"mux" = "マルチプレクサ"
|
||||||
|
"muxDesc" = "確立されたストリーム内で複数の独立したストリームを伝送する"
|
||||||
|
"muxSett" = "マルチプレクサ設定"
|
||||||
|
"direct" = "直接接続"
|
||||||
|
"directDesc" = "特定の国のドメインまたはIP範囲に直接接続する"
|
||||||
|
|
||||||
|
|
||||||
|
[pages.xray]
|
||||||
|
"title" = "Xray 設定"
|
||||||
|
"save" = "保存"
|
||||||
|
"restart" = "Xray 再起動"
|
||||||
|
"basicTemplate" = "基本設定"
|
||||||
|
"advancedTemplate" = "高度な設定"
|
||||||
|
"generalConfigs" = "一般設定"
|
||||||
|
"generalConfigsDesc" = "これらのオプションは一般設定を決定します"
|
||||||
|
"logConfigs" = "ログ"
|
||||||
|
"logConfigsDesc" = "ログはサーバーのパフォーマンスに影響を与える可能性があるため、必要な場合にのみ有効にすることをお勧めします"
|
||||||
|
"blockConfigs" = "防御フィルター"
|
||||||
|
"blockConfigsDesc" = "これらのオプションは、特定のプロトコルやウェブサイトへのユーザー接続をブロックします"
|
||||||
|
"basicRouting" = "基本ルーティング"
|
||||||
|
"blockConnectionsConfigsDesc" = "これらのオプションにより、特定のリクエスト元の国に基づいてトラフィックをブロックします。"
|
||||||
|
"directConnectionsConfigsDesc" = "直接接続により、特定のトラフィックが他のサーバーを経由しないようにします。"
|
||||||
|
"blockips" = "IPをブロック"
|
||||||
|
"blockdomains" = "ドメインをブロック"
|
||||||
|
"directips" = "直接IP"
|
||||||
|
"directdomains" = "直接ドメイン"
|
||||||
|
"ipv4Routing" = "IPv4 ルーティング"
|
||||||
|
"ipv4RoutingDesc" = "このオプションはIPv4のみを介してターゲットドメインへルーティングします"
|
||||||
|
"warpRouting" = "WARP ルーティング"
|
||||||
|
"warpRoutingDesc" = "注意:これらのオプションを使用する前に、パネルのGitHubの手順に従って、サーバーにsocks5プロキシモードでWARPをインストールしてください。WARPはCloudflareサーバー経由でトラフィックをウェブサイトにルーティングします。"
|
||||||
|
"Template" = "高度なXray設定テンプレート"
|
||||||
|
"TemplateDesc" = "最終的なXray設定ファイルはこのテンプレートに基づいて生成されます"
|
||||||
|
"FreedomStrategy" = "Freedom プロトコル戦略"
|
||||||
|
"FreedomStrategyDesc" = "Freedomプロトコル内のネットワークの出力戦略を設定する"
|
||||||
|
"RoutingStrategy" = "ルーティングドメイン戦略設定"
|
||||||
|
"RoutingStrategyDesc" = "DNS解決の全体的なルーティング戦略を設定する"
|
||||||
|
"Torrent" = "BitTorrent プロトコルをブロック"
|
||||||
|
"TorrentDesc" = "BitTorrentの使用を禁止する"
|
||||||
|
"Family" = "ファミリー保護"
|
||||||
|
"FamilyDesc" = "アダルトコンテンツや悪意のあるサイトをブロックする"
|
||||||
|
"Inbounds" = "インバウンドルール"
|
||||||
|
"InboundsDesc" = "特定のクライアントからのトラフィックを受け入れる"
|
||||||
|
"Outbounds" = "アウトバウンドルール"
|
||||||
|
"Balancers" = "負荷分散"
|
||||||
|
"OutboundsDesc" = "アウトバウンドトラフィックの送信方法を設定する"
|
||||||
|
"Routings" = "ルーティングルール"
|
||||||
|
"RoutingsDesc" = "各ルールの優先順位が重要です"
|
||||||
|
"completeTemplate" = "すべて"
|
||||||
|
"logLevel" = "ログレベル"
|
||||||
|
"logLevelDesc" = "エラーログのレベルを指定し、記録する情報を示します"
|
||||||
|
"accessLog" = "アクセスログ"
|
||||||
|
"accessLogDesc" = "アクセスログのファイルパス。特殊値 'none' はアクセスログを無効にします"
|
||||||
|
"errorLog" = "エラーログ"
|
||||||
|
"errorLogDesc" = "エラーログのファイルパス。特殊値 'none' はエラーログを無効にします"
|
||||||
|
"dnsLog" = "DNS ログ"
|
||||||
|
"dnsLogDesc" = "DNSクエリのログを有効にするかどうか"
|
||||||
|
"maskAddress" = "アドレスをマスク"
|
||||||
|
"maskAddressDesc" = "IPアドレスをマスクし、有効にするとログに表示されるIPアドレスを自動的に置き換えます"
|
||||||
|
|
||||||
|
[pages.xray.rules]
|
||||||
|
"first" = "最初"
|
||||||
|
"last" = "最後"
|
||||||
|
"up" = "上へ"
|
||||||
|
"down" = "下へ"
|
||||||
|
"source" = "ソース"
|
||||||
|
"dest" = "宛先アドレス"
|
||||||
|
"inbound" = "インバウンド"
|
||||||
|
"outbound" = "アウトバウンド"
|
||||||
|
"balancer" = "負荷分散"
|
||||||
|
"info" = "情報"
|
||||||
|
"add" = "ルール追加"
|
||||||
|
"edit" = "ルール編集"
|
||||||
|
"useComma" = "カンマ区切りの項目"
|
||||||
|
|
||||||
|
[pages.xray.outbound]
|
||||||
|
"addOutbound" = "アウトバウンド追加"
|
||||||
|
"addReverse" = "リバース追加"
|
||||||
|
"editOutbound" = "アウトバウンド編集"
|
||||||
|
"editReverse" = "リバース編集"
|
||||||
|
"tag" = "タグ"
|
||||||
|
"tagDesc" = "一意のタグ"
|
||||||
|
"address" = "アドレス"
|
||||||
|
"reverse" = "リバース"
|
||||||
|
"domain" = "ドメイン"
|
||||||
|
"type" = "タイプ"
|
||||||
|
"bridge" = "ブリッジ"
|
||||||
|
"portal" = "ポータル"
|
||||||
|
"intercon" = "インターコネクション"
|
||||||
|
"settings" = "設定"
|
||||||
|
"accountInfo" = "アカウント情報"
|
||||||
|
"outboundStatus" = "アウトバウンドステータス"
|
||||||
|
"sendThrough" = "送信経路"
|
||||||
|
|
||||||
|
[pages.xray.balancer]
|
||||||
|
"addBalancer" = "負荷分散追加"
|
||||||
|
"editBalancer" = "負荷分散編集"
|
||||||
|
"balancerStrategy" = "戦略"
|
||||||
|
"balancerSelectors" = "セレクター"
|
||||||
|
"tag" = "タグ"
|
||||||
|
"tagDesc" = "一意のタグ"
|
||||||
|
"balancerDesc" = "balancerTagとoutboundTagは同時に使用できません。同時に使用された場合、outboundTagのみが有効になります。"
|
||||||
|
|
||||||
|
[pages.xray.wireguard]
|
||||||
|
"secretKey" = "シークレットキー"
|
||||||
|
"publicKey" = "公開鍵"
|
||||||
|
"allowedIPs" = "許可されたIP"
|
||||||
|
"endpoint" = "エンドポイント"
|
||||||
|
"psk" = "共有キー"
|
||||||
|
"domainStrategy" = "ドメイン戦略"
|
||||||
|
|
||||||
|
[pages.xray.dns]
|
||||||
|
"enable" = "DNSを有効にする"
|
||||||
|
"enableDesc" = "組み込みDNSサーバーを有効にする"
|
||||||
|
"tag" = "DNSインバウンドタグ"
|
||||||
|
"tagDesc" = "このタグはルーティングルールでインバウンドタグとして使用できます"
|
||||||
|
"strategy" = "クエリ戦略"
|
||||||
|
"strategyDesc" = "ドメイン名解決の全体的な戦略"
|
||||||
|
"add" = "サーバー追加"
|
||||||
|
"edit" = "サーバー編集"
|
||||||
|
"domains" = "ドメイン"
|
||||||
|
"expectIPs" = "期待されるIP"
|
||||||
|
|
||||||
|
[pages.xray.fakedns]
|
||||||
|
"add" = "フェイクDNS追加"
|
||||||
|
"edit" = "フェイクDNS編集"
|
||||||
|
"ipPool" = "IPプールサブネット"
|
||||||
|
"poolSize" = "プールサイズ"
|
||||||
|
|
||||||
|
[pages.settings.security]
|
||||||
|
"admin" = "管理者"
|
||||||
|
"secret" = "セキュリティトークン"
|
||||||
|
"loginSecurity" = "ログインセキュリティ"
|
||||||
|
"loginSecurityDesc" = "追加の認証を追加してセキュリティを向上させる"
|
||||||
|
"secretToken" = "セキュリティトークン"
|
||||||
|
"secretTokenDesc" = "このトークンを安全な場所に保管してください。このトークンはログインに使用され、紛失すると回復できません。"
|
||||||
|
|
||||||
|
[pages.settings.toasts]
|
||||||
|
"modifySettings" = "設定を変更"
|
||||||
|
"getSettings" = "設定を取得"
|
||||||
|
"modifyUser" = "管理者を変更"
|
||||||
|
"originalUserPassIncorrect" = "旧ユーザー名または旧パスワードが間違っています"
|
||||||
|
"userPassMustBeNotEmpty" = "新しいユーザー名と新しいパスワードは空にできません"
|
||||||
|
|
||||||
|
[tgbot]
|
||||||
|
"keyboardClosed" = "❌ カスタムキーボードが閉じられました!"
|
||||||
|
"noResult" = "❗ 結果がありません!"
|
||||||
|
"noQuery" = "❌ クエリが見つかりませんでした!もう一度コマンドを使用してください!"
|
||||||
|
"wentWrong" = "❌ 問題が発生しました!"
|
||||||
|
"noIpRecord" = "❗ IP記録がありません!"
|
||||||
|
"noInbounds" = "❗ インバウンド接続が見つかりません!"
|
||||||
|
"unlimited" = "♾ 無制限"
|
||||||
|
"add" = "追加"
|
||||||
|
"month" = "月"
|
||||||
|
"months" = "月"
|
||||||
|
"day" = "日"
|
||||||
|
"days" = "日"
|
||||||
|
"hours" = "時間"
|
||||||
|
"unknown" = "不明"
|
||||||
|
"inbounds" = "インバウンド接続"
|
||||||
|
"clients" = "クライアント"
|
||||||
|
"offline" = "🔴 オフライン"
|
||||||
|
"online" = "🟢 オンライン"
|
||||||
|
|
||||||
|
[tgbot.commands]
|
||||||
|
"unknown" = "❗ 不明なコマンド"
|
||||||
|
"pleaseChoose" = "👇 選択してください:\r\n"
|
||||||
|
"help" = "🤖 このボットをご利用いただきありがとうございます!サーバーから特定のデータを提供し、必要な変更を行うことができます。\r\n\r\n"
|
||||||
|
"start" = "👋 こんにちは、<i>{{ .Firstname }}</i>。\r\n"
|
||||||
|
"welcome" = "🤖 <b>{{ .Hostname }}</b> 管理ボットへようこそ。\r\n"
|
||||||
|
"status" = "✅ ボットは正常に動作しています!"
|
||||||
|
"usage" = "❗ 検索するテキストを入力してください!"
|
||||||
|
"getID" = "🆔 あなたのIDは:<code>{{ .ID }}</code>"
|
||||||
|
"helpAdminCommands" = "Xray Coreを再起動するには:\r\n<code>/restart force</code>\r\n\r\nクライアントの電子メールを検索するには:\r\n<code>/usage [電子メール]</code>\r\n\r\nインバウンド(クライアントの統計情報を含む)を検索するには:\r\n<code>/inbound [備考]</code>\r\n\r\nTelegramチャットID:\r\n<code>/id</code>"
|
||||||
|
"helpClientCommands" = "統計情報を検索するには、次のコマンドを使用してください:\r\n<code>/usage [電子メール]</code>\r\n\r\nTelegramチャットID:\r\n<code>/id</code>"
|
||||||
|
"restartUsage" = "\r\n\r\n<code>/restart force</code>"
|
||||||
|
"restartSuccess" = "✅ 操作成功!"
|
||||||
|
"restartFailed" = "❗ 操作エラー。\r\n\r\n<code>エラー: {{ .Error }}</code>"
|
||||||
|
"xrayNotRunning" = "❗ Xray Core は動作していません。"
|
||||||
|
|
||||||
|
[tgbot.messages]
|
||||||
|
"cpuThreshold" = "🔴 CPU使用率は{{ .Percent }}%、しきい値{{ .Threshold }}%を超えました"
|
||||||
|
"selectUserFailed" = "❌ ユーザーの選択に失敗しました!"
|
||||||
|
"userSaved" = "✅ Telegramユーザーが保存されました。"
|
||||||
|
"loginSuccess" = "✅ パネルに正常にログインしました。\r\n"
|
||||||
|
"loginFailed" = "❗️ パネルのログインに失敗しました。\r\n"
|
||||||
|
"report" = "🕰 定期報告:{{ .RunTime }}\r\n"
|
||||||
|
"datetime" = "⏰ 日時:{{ .DateTime }}\r\n"
|
||||||
|
"hostname" = "💻 ホスト名:{{ .Hostname }}\r\n"
|
||||||
|
"version" = "🚀 X-UI バージョン:{{ .Version }}\r\n"
|
||||||
|
"xrayVersion" = "📡 Xray バージョン: {{ .XrayVersion }}\r\n"
|
||||||
|
"ipv6" = "🌐 IPv6:{{ .IPv6 }}\r\n"
|
||||||
|
"ipv4" = "🌐 IPv4:{{ .IPv4 }}\r\n"
|
||||||
|
"ip" = "🌐 IP:{{ .IP }}\r\n"
|
||||||
|
"ips" = "🔢 IPアドレス:\r\n{{ .IPs }}\r\n"
|
||||||
|
"serverUpTime" = "⏳ サーバー稼働時間:{{ .UpTime }} {{ .Unit }}\r\n"
|
||||||
|
"serverLoad" = "📈 サーバー負荷:{{ .Load1 }}, {{ .Load2 }}, {{ .Load3 }}\r\n"
|
||||||
|
"serverMemory" = "📋 サーバーメモリ:{{ .Current }}/{{ .Total }}\r\n"
|
||||||
|
"tcpCount" = "🔹 TCP接続数:{{ .Count }}\r\n"
|
||||||
|
"udpCount" = "🔸 UDP接続数:{{ .Count }}\r\n"
|
||||||
|
"traffic" = "🚦 トラフィック:{{ .Total }} (↑{{ .Upload }},↓{{ .Download }})\r\n"
|
||||||
|
"xrayStatus" = "ℹ️ Xrayステータス:{{ .State }}\r\n"
|
||||||
|
"username" = "👤 ユーザー名:{{ .Username }}\r\n"
|
||||||
|
"password" = "👤 パスワード: {{ .Password }}\r\n"
|
||||||
|
"time" = "⏰ 時間:{{ .Time }}\r\n"
|
||||||
|
"inbound" = "📍 インバウンド:{{ .Remark }}\r\n"
|
||||||
|
"port" = "🔌 ポート:{{ .Port }}\r\n"
|
||||||
|
"expire" = "📅 有効期限:{{ .Time }}\r\n"
|
||||||
|
"expireIn" = "📅 残り時間:{{ .Time }}\r\n"
|
||||||
|
"active" = "💡 有効:{{ .Enable }}\r\n"
|
||||||
|
"enabled" = "🚨 有効化済み:{{ .Enable }}\r\n"
|
||||||
|
"online" = "🌐 接続ステータス:{{ .Status }}\r\n"
|
||||||
|
"email" = "📧 メール:{{ .Email }}\r\n"
|
||||||
|
"upload" = "🔼 アップロード↑:{{ .Upload }}\r\n"
|
||||||
|
"download" = "🔽 ダウンロード↓:{{ .Download }}\r\n"
|
||||||
|
"total" = "📊 合計:{{ .UpDown }} / {{ .Total }}\r\n"
|
||||||
|
"TGUser" = "👤 Telegramユーザー:{{ .TelegramID }}\r\n"
|
||||||
|
"exhaustedMsg" = "🚨 消耗済みの {{ .Type }}:\r\n"
|
||||||
|
"exhaustedCount" = "🚨 消耗済みの {{ .Type }} 数量:\r\n"
|
||||||
|
"onlinesCount" = "🌐 オンラインクライアント:{{ .Count }}\r\n"
|
||||||
|
"disabled" = "🛑 無効化:{{ .Disabled }}\r\n"
|
||||||
|
"depleteSoon" = "🔜 間もなく消耗:{{ .Deplete }}\r\n\r\n"
|
||||||
|
"backupTime" = "🗄 バックアップ時間:{{ .Time }}\r\n"
|
||||||
|
"refreshedOn" = "\r\n📋🔄 更新時間:{{ .Time }}\r\n\r\n"
|
||||||
|
"yes" = "✅ はい"
|
||||||
|
"no" = "❌ いいえ"
|
||||||
|
|
||||||
|
[tgbot.buttons]
|
||||||
|
"closeKeyboard" = "❌ キーボードを閉じる"
|
||||||
|
"cancel" = "❌ キャンセル"
|
||||||
|
"cancelReset" = "❌ リセットをキャンセル"
|
||||||
|
"cancelIpLimit" = "❌ IP制限をキャンセル"
|
||||||
|
"confirmResetTraffic" = "✅ トラフィックをリセットしますか?"
|
||||||
|
"confirmClearIps" = "✅ IPをクリアしますか?"
|
||||||
|
"confirmRemoveTGUser" = "✅ Telegramユーザーを削除しますか?"
|
||||||
|
"confirmToggle" = "✅ ユーザーを有効/無効にしますか?"
|
||||||
|
"dbBackup" = "データベースバックアップを取得"
|
||||||
|
"serverUsage" = "サーバーの使用状況"
|
||||||
|
"getInbounds" = "インバウンド情報を取得"
|
||||||
|
"depleteSoon" = "間もなく消耗"
|
||||||
|
"clientUsage" = "使用状況を取得"
|
||||||
|
"onlines" = "オンラインクライアント"
|
||||||
|
"commands" = "コマンド"
|
||||||
|
"refresh" = "🔄 更新"
|
||||||
|
"clearIPs" = "❌ IPをクリア"
|
||||||
|
"removeTGUser" = "❌ Telegramユーザーを削除"
|
||||||
|
"selectTGUser" = "👤 Telegramユーザーを選択"
|
||||||
|
"selectOneTGUser" = "👤 1人のTelegramユーザーを選択:"
|
||||||
|
"resetTraffic" = "📈 トラフィックをリセット"
|
||||||
|
"resetExpire" = "📅 有効期限を変更"
|
||||||
|
"ipLog" = "🔢 IPログ"
|
||||||
|
"ipLimit" = "🔢 IP制限"
|
||||||
|
"setTGUser" = "👤 Telegramユーザーを設定"
|
||||||
|
"toggle" = "🔘 有効/無効"
|
||||||
|
"custom" = "🔢 カスタム"
|
||||||
|
"confirmNumber" = "✅ 確認: {{ .Num }}"
|
||||||
|
"confirmNumberAdd" = "✅ 追加を確認:{{ .Num }}"
|
||||||
|
"limitTraffic" = "🚧 トラフィック制限"
|
||||||
|
"getBanLogs" = "禁止ログ"
|
||||||
|
"allClients" = "すべてのクライアント"
|
||||||
|
|
||||||
|
[tgbot.answers]
|
||||||
|
"successfulOperation" = "✅ 成功!"
|
||||||
|
"errorOperation" = "❗ 操作エラー。"
|
||||||
|
"getInboundsFailed" = "❌ インバウンド情報の取得に失敗しました。"
|
||||||
|
"getClientsFailed" = "❌ クライアントの取得に失敗しました。"
|
||||||
|
"canceled" = "❌ {{ .Email }}:操作がキャンセルされました。"
|
||||||
|
"clientRefreshSuccess" = "✅ {{ .Email }}:クライアントが正常に更新されました。"
|
||||||
|
"IpRefreshSuccess" = "✅ {{ .Email }}:IPが正常に更新されました。"
|
||||||
|
"TGIdRefreshSuccess" = "✅ {{ .Email }}:クライアントのTelegramユーザーが正常に更新されました。"
|
||||||
|
"resetTrafficSuccess" = "✅ {{ .Email }}:トラフィックが正常にリセットされました。"
|
||||||
|
"setTrafficLimitSuccess" = "✅ {{ .Email }}:トラフィック制限が正常に保存されました。"
|
||||||
|
"expireResetSuccess" = "✅ {{ .Email }}:有効期限の日数が正常にリセットされました。"
|
||||||
|
"resetIpSuccess" = "✅ {{ .Email }}:IP制限数が正常に保存されました:{{ .Count }}。"
|
||||||
|
"clearIpSuccess" = "✅ {{ .Email }}:IPが正常にクリアされました。"
|
||||||
|
"getIpLog" = "✅ {{ .Email }}:IPログの取得。"
|
||||||
|
"getUserInfo" = "✅ {{ .Email }}:Telegramユーザー情報の取得。"
|
||||||
|
"removedTGUserSuccess" = "✅ {{ .Email }}:Telegramユーザーが正常に削除されました。"
|
||||||
|
"enableSuccess" = "✅ {{ .Email }}:正常に有効化されました。"
|
||||||
|
"disableSuccess" = "✅ {{ .Email }}:正常に無効化されました。"
|
||||||
|
"askToAddUserId" = "設定が見つかりませんでした!\r\n管理者に問い合わせて、設定にTelegramユーザーのChatIDを使用してください。\r\n\r\nあなたのユーザーChatID:<code>{{ .TgUserID }}</code>"
|
||||||
|
"chooseClient" = "インバウンド {{ .Inbound }} のクライアントを選択"
|
||||||
|
"chooseInbound" = "インバウンドを選択"
|
245
x-ui.sh
|
@ -164,7 +164,7 @@ update() {
|
||||||
bash <(curl -Ls https://raw.githubusercontent.com/MHSanaei/3x-ui/main/install.sh)
|
bash <(curl -Ls https://raw.githubusercontent.com/MHSanaei/3x-ui/main/install.sh)
|
||||||
if [[ $? == 0 ]]; then
|
if [[ $? == 0 ]]; then
|
||||||
LOGI "Update is complete, Panel has automatically restarted "
|
LOGI "Update is complete, Panel has automatically restarted "
|
||||||
exit 0
|
before_show_menu
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,7 +185,7 @@ update_menu() {
|
||||||
|
|
||||||
if [[ $? == 0 ]]; then
|
if [[ $? == 0 ]]; then
|
||||||
echo -e "${green}Update successful. The panel has automatically restarted.${plain}"
|
echo -e "${green}Update successful. The panel has automatically restarted.${plain}"
|
||||||
exit 0
|
before_show_menu
|
||||||
else
|
else
|
||||||
echo -e "${red}Failed to update the menu.${plain}"
|
echo -e "${red}Failed to update the menu.${plain}"
|
||||||
return 1
|
return 1
|
||||||
|
@ -294,8 +294,8 @@ reset_config() {
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
/usr/local/x-ui/x-ui setting -reset
|
/usr/local/x-ui/x-ui setting -reset
|
||||||
echo -e "All panel settings have been reset to default, Please restart the panel now, and use the default ${green}2053${plain} Port to Access the web Panel"
|
echo -e "All panel settings have been reset to default."
|
||||||
confirm_restart
|
restart
|
||||||
}
|
}
|
||||||
|
|
||||||
check_config() {
|
check_config() {
|
||||||
|
@ -309,9 +309,20 @@ check_config() {
|
||||||
|
|
||||||
local existing_webBasePath=$(echo "$info" | grep -Eo 'webBasePath: .+' | awk '{print $2}')
|
local existing_webBasePath=$(echo "$info" | grep -Eo 'webBasePath: .+' | awk '{print $2}')
|
||||||
local existing_port=$(echo "$info" | grep -Eo 'port: .+' | awk '{print $2}')
|
local existing_port=$(echo "$info" | grep -Eo 'port: .+' | awk '{print $2}')
|
||||||
|
local existing_cert=$(/usr/local/x-ui/x-ui setting -getCert true | grep -Eo 'cert: .+' | awk '{print $2}')
|
||||||
local server_ip=$(curl -s https://api.ipify.org)
|
local server_ip=$(curl -s https://api.ipify.org)
|
||||||
|
|
||||||
|
if [[ -n "$existing_cert" ]]; then
|
||||||
|
local domain=$(basename "$(dirname "$existing_cert")")
|
||||||
|
|
||||||
|
if [[ "$domain" =~ ^[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
|
||||||
|
echo -e "${green}Access URL: https://${domain}:${existing_port}${existing_webBasePath}${plain}"
|
||||||
|
else
|
||||||
|
echo -e "${green}Access URL: https://${server_ip}:${existing_port}${existing_webBasePath}${plain}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
echo -e "${green}Access URL: http://${server_ip}:${existing_port}${existing_webBasePath}${plain}"
|
echo -e "${green}Access URL: http://${server_ip}:${existing_port}${existing_webBasePath}${plain}"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
set_port() {
|
set_port() {
|
||||||
|
@ -423,7 +434,7 @@ show_log() {
|
||||||
|
|
||||||
case "$choice" in
|
case "$choice" in
|
||||||
0)
|
0)
|
||||||
return
|
show_menu
|
||||||
;;
|
;;
|
||||||
1)
|
1)
|
||||||
journalctl -u x-ui -e --no-pager -f -p debug
|
journalctl -u x-ui -e --no-pager -f -p debug
|
||||||
|
@ -438,21 +449,41 @@ show_log() {
|
||||||
restart
|
restart
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "Invalid choice"
|
echo -e "${red}Invalid option. Please select a valid number.${plain}\n"
|
||||||
|
show_log
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
show_banlog() {
|
show_banlog() {
|
||||||
if test -f "${iplimit_banned_log_path}"; then
|
local system_log="/var/log/fail2ban.log"
|
||||||
|
|
||||||
|
echo -e "${green}Checking ban logs...${plain}\n"
|
||||||
|
|
||||||
|
if ! systemctl is-active --quiet fail2ban; then
|
||||||
|
echo -e "${red}Fail2ban service is not running!${plain}\n"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -f "$system_log" ]]; then
|
||||||
|
echo -e "${green}Recent system ban activities from fail2ban.log:${plain}"
|
||||||
|
grep "3x-ipl" "$system_log" | grep -E "Ban|Unban" | tail -n 10 || echo -e "${yellow}No recent system ban activities found${plain}"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -f "${iplimit_banned_log_path}" ]]; then
|
||||||
|
echo -e "${green}3X-IPL ban log entries:${plain}"
|
||||||
if [[ -s "${iplimit_banned_log_path}" ]]; then
|
if [[ -s "${iplimit_banned_log_path}" ]]; then
|
||||||
cat ${iplimit_banned_log_path}
|
grep -v "INIT" "${iplimit_banned_log_path}" | tail -n 10 || echo -e "${yellow}No ban entries found${plain}"
|
||||||
else
|
else
|
||||||
echo -e "${red}Log file is empty.${plain}\n"
|
echo -e "${yellow}Ban log file is empty${plain}"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo -e "${red}Log file not found. Please Install Fail2ban and IP Limit first.${plain}\n"
|
echo -e "${red}Ban log file not found at: ${iplimit_banned_log_path}${plain}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
echo -e "\n${green}Current jail status:${plain}"
|
||||||
|
fail2ban-client status 3x-ipl || echo -e "${yellow}Unable to get jail status${plain}"
|
||||||
}
|
}
|
||||||
|
|
||||||
bbr_menu() {
|
bbr_menu() {
|
||||||
|
@ -466,11 +497,16 @@ bbr_menu() {
|
||||||
;;
|
;;
|
||||||
1)
|
1)
|
||||||
enable_bbr
|
enable_bbr
|
||||||
|
bbr_menu
|
||||||
;;
|
;;
|
||||||
2)
|
2)
|
||||||
disable_bbr
|
disable_bbr
|
||||||
|
bbr_menu
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo -e "${red}Invalid option. Please select a valid number.${plain}\n"
|
||||||
|
bbr_menu
|
||||||
;;
|
;;
|
||||||
*) echo "Invalid choice" ;;
|
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -478,7 +514,7 @@ disable_bbr() {
|
||||||
|
|
||||||
if ! grep -q "net.core.default_qdisc=fq" /etc/sysctl.conf || ! grep -q "net.ipv4.tcp_congestion_control=bbr" /etc/sysctl.conf; then
|
if ! grep -q "net.core.default_qdisc=fq" /etc/sysctl.conf || ! grep -q "net.ipv4.tcp_congestion_control=bbr" /etc/sysctl.conf; then
|
||||||
echo -e "${yellow}BBR is not currently enabled.${plain}"
|
echo -e "${yellow}BBR is not currently enabled.${plain}"
|
||||||
exit 0
|
before_show_menu
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Replace BBR with CUBIC configurations
|
# Replace BBR with CUBIC configurations
|
||||||
|
@ -499,7 +535,7 @@ disable_bbr() {
|
||||||
enable_bbr() {
|
enable_bbr() {
|
||||||
if grep -q "net.core.default_qdisc=fq" /etc/sysctl.conf && grep -q "net.ipv4.tcp_congestion_control=bbr" /etc/sysctl.conf; then
|
if grep -q "net.core.default_qdisc=fq" /etc/sysctl.conf && grep -q "net.ipv4.tcp_congestion_control=bbr" /etc/sysctl.conf; then
|
||||||
echo -e "${green}BBR is already enabled!${plain}"
|
echo -e "${green}BBR is already enabled!${plain}"
|
||||||
exit 0
|
before_show_menu
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check the OS and install necessary packages
|
# Check the OS and install necessary packages
|
||||||
|
@ -545,7 +581,8 @@ update_shell() {
|
||||||
before_show_menu
|
before_show_menu
|
||||||
else
|
else
|
||||||
chmod +x /usr/bin/x-ui
|
chmod +x /usr/bin/x-ui
|
||||||
LOGI "Upgrade script succeeded, Please rerun the script" && exit 0
|
LOGI "Upgrade script succeeded, Please rerun the script"
|
||||||
|
before_show_menu
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -657,17 +694,24 @@ firewall_menu() {
|
||||||
;;
|
;;
|
||||||
1)
|
1)
|
||||||
open_ports
|
open_ports
|
||||||
|
firewall_menu
|
||||||
;;
|
;;
|
||||||
2)
|
2)
|
||||||
sudo ufw status
|
sudo ufw status
|
||||||
|
firewall_menu
|
||||||
;;
|
;;
|
||||||
3)
|
3)
|
||||||
delete_ports
|
delete_ports
|
||||||
|
firewall_menu
|
||||||
;;
|
;;
|
||||||
4)
|
4)
|
||||||
sudo ufw disable
|
sudo ufw disable
|
||||||
|
firewall_menu
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo -e "${red}Invalid option. Please select a valid number.${plain}\n"
|
||||||
|
firewall_menu
|
||||||
;;
|
;;
|
||||||
*) echo "Invalid choice" ;;
|
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -774,7 +818,6 @@ update_geo() {
|
||||||
echo -e "${green}\t0.${plain} Back to Main Menu"
|
echo -e "${green}\t0.${plain} Back to Main Menu"
|
||||||
read -p "Choose an option: " choice
|
read -p "Choose an option: " choice
|
||||||
|
|
||||||
systemctl stop x-ui
|
|
||||||
cd /usr/local/x-ui/bin
|
cd /usr/local/x-ui/bin
|
||||||
|
|
||||||
case "$choice" in
|
case "$choice" in
|
||||||
|
@ -782,29 +825,35 @@ update_geo() {
|
||||||
show_menu
|
show_menu
|
||||||
;;
|
;;
|
||||||
1)
|
1)
|
||||||
|
systemctl stop x-ui
|
||||||
rm -f geoip.dat geosite.dat
|
rm -f geoip.dat geosite.dat
|
||||||
wget -N https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat
|
wget -N https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat
|
||||||
wget -N https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat
|
wget -N https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat
|
||||||
echo -e "${green}Loyalsoldier datasets have been updated successfully!${plain}"
|
echo -e "${green}Loyalsoldier datasets have been updated successfully!${plain}"
|
||||||
|
restart
|
||||||
;;
|
;;
|
||||||
2)
|
2)
|
||||||
|
systemctl stop x-ui
|
||||||
rm -f geoip_IR.dat geosite_IR.dat
|
rm -f geoip_IR.dat geosite_IR.dat
|
||||||
wget -O geoip_IR.dat -N https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geoip.dat
|
wget -O geoip_IR.dat -N https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geoip.dat
|
||||||
wget -O geosite_IR.dat -N https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geosite.dat
|
wget -O geosite_IR.dat -N https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geosite.dat
|
||||||
echo -e "${green}chocolate4u datasets have been updated successfully!${plain}"
|
echo -e "${green}chocolate4u datasets have been updated successfully!${plain}"
|
||||||
|
restart
|
||||||
;;
|
;;
|
||||||
3)
|
3)
|
||||||
|
systemctl stop x-ui
|
||||||
rm -f geoip_VN.dat geosite_VN.dat
|
rm -f geoip_VN.dat geosite_VN.dat
|
||||||
wget -O geoip_VN.dat -N https://github.com/vuong2023/vn-v2ray-rules/releases/latest/download/geoip.dat
|
wget -O geoip_VN.dat -N https://github.com/vuong2023/vn-v2ray-rules/releases/latest/download/geoip.dat
|
||||||
wget -O geosite_VN.dat -N https://github.com/vuong2023/vn-v2ray-rules/releases/latest/download/geosite.dat
|
wget -O geosite_VN.dat -N https://github.com/vuong2023/vn-v2ray-rules/releases/latest/download/geosite.dat
|
||||||
echo -e "${green}vuong2023 datasets have been updated successfully!${plain}"
|
echo -e "${green}vuong2023 datasets have been updated successfully!${plain}"
|
||||||
|
restart
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "Invalid option selected! No updates made."
|
echo -e "${red}Invalid option. Please select a valid number.${plain}\n"
|
||||||
|
update_geo
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
systemctl start x-ui
|
|
||||||
before_show_menu
|
before_show_menu
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -844,6 +893,7 @@ ssl_cert_issue_main() {
|
||||||
;;
|
;;
|
||||||
1)
|
1)
|
||||||
ssl_cert_issue
|
ssl_cert_issue
|
||||||
|
ssl_cert_issue_main
|
||||||
;;
|
;;
|
||||||
2)
|
2)
|
||||||
local domains=$(find /root/cert/ -mindepth 1 -maxdepth 1 -type d -exec basename {} \;)
|
local domains=$(find /root/cert/ -mindepth 1 -maxdepth 1 -type d -exec basename {} \;)
|
||||||
|
@ -860,6 +910,7 @@ ssl_cert_issue_main() {
|
||||||
echo "Invalid domain entered."
|
echo "Invalid domain entered."
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
ssl_cert_issue_main
|
||||||
;;
|
;;
|
||||||
3)
|
3)
|
||||||
local domains=$(find /root/cert/ -mindepth 1 -maxdepth 1 -type d -exec basename {} \;)
|
local domains=$(find /root/cert/ -mindepth 1 -maxdepth 1 -type d -exec basename {} \;)
|
||||||
|
@ -876,6 +927,7 @@ ssl_cert_issue_main() {
|
||||||
echo "Invalid domain entered."
|
echo "Invalid domain entered."
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
ssl_cert_issue_main
|
||||||
;;
|
;;
|
||||||
4)
|
4)
|
||||||
local domains=$(find /root/cert/ -mindepth 1 -maxdepth 1 -type d -exec basename {} \;)
|
local domains=$(find /root/cert/ -mindepth 1 -maxdepth 1 -type d -exec basename {} \;)
|
||||||
|
@ -895,6 +947,7 @@ ssl_cert_issue_main() {
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
ssl_cert_issue_main
|
||||||
;;
|
;;
|
||||||
5)
|
5)
|
||||||
local domains=$(find /root/cert/ -mindepth 1 -maxdepth 1 -type d -exec basename {} \;)
|
local domains=$(find /root/cert/ -mindepth 1 -maxdepth 1 -type d -exec basename {} \;)
|
||||||
|
@ -922,10 +975,12 @@ ssl_cert_issue_main() {
|
||||||
echo "Invalid domain entered."
|
echo "Invalid domain entered."
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
ssl_cert_issue_main
|
||||||
;;
|
;;
|
||||||
|
|
||||||
*)
|
*)
|
||||||
echo "Invalid choice"
|
echo -e "${red}Invalid option. Please select a valid number.${plain}\n"
|
||||||
|
ssl_cert_issue_main
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
@ -1062,76 +1117,119 @@ ssl_cert_issue() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ssl_cert_issue_CF() {
|
ssl_cert_issue_CF() {
|
||||||
echo -E ""
|
local existing_webBasePath=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'webBasePath: .+' | awk '{print $2}')
|
||||||
LOGD "******Instructions for use******"
|
local existing_port=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'port: .+' | awk '{print $2}')
|
||||||
LOGI "This Acme script requires the following data:"
|
LOGI "****** Instructions for Use ******"
|
||||||
LOGI "1.Cloudflare Registered e-mail"
|
LOGI "Follow the steps below to complete the process:"
|
||||||
LOGI "2.Cloudflare Global API Key"
|
LOGI "1. Cloudflare Registered E-mail."
|
||||||
LOGI "3.The domain name that has been resolved dns to the current server by Cloudflare"
|
LOGI "2. Cloudflare Global API Key."
|
||||||
LOGI "4.The script applies for a certificate. The default installation path is /root/cert "
|
LOGI "3. The Domain Name."
|
||||||
confirm "Confirmed?[y/n]" "y"
|
LOGI "4. Once the certificate is issued, you will be prompted to set the certificate for the panel (optional)."
|
||||||
|
LOGI "5. The script also supports automatic renewal of the SSL certificate after installation."
|
||||||
|
|
||||||
|
confirm "Do you confirm the information and wish to proceed? [y/n]" "y"
|
||||||
|
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
# check for acme.sh first
|
# 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"
|
echo "acme.sh could not be found. We will install it."
|
||||||
install_acme
|
install_acme
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
LOGE "install acme failed, please check logs"
|
LOGE "Install acme failed, please check logs."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
CF_Domain=""
|
CF_Domain=""
|
||||||
CF_GlobalKey=""
|
certPath="/root/cert-CF"
|
||||||
CF_AccountEmail=""
|
|
||||||
certPath=/root/cert
|
|
||||||
if [ ! -d "$certPath" ]; then
|
if [ ! -d "$certPath" ]; then
|
||||||
mkdir $certPath
|
mkdir -p $certPath
|
||||||
else
|
else
|
||||||
rm -rf $certPath
|
rm -rf $certPath
|
||||||
mkdir $certPath
|
mkdir -p $certPath
|
||||||
fi
|
fi
|
||||||
|
|
||||||
LOGD "Please set a domain name:"
|
LOGD "Please set a domain name:"
|
||||||
read -p "Input your domain here:" CF_Domain
|
read -p "Input your domain here: " CF_Domain
|
||||||
LOGD "Your domain name is set to:${CF_Domain}"
|
LOGD "Your domain name is set to: ${CF_Domain}"
|
||||||
|
|
||||||
|
# Set up Cloudflare API details
|
||||||
|
CF_GlobalKey=""
|
||||||
|
CF_AccountEmail=""
|
||||||
LOGD "Please set the API key:"
|
LOGD "Please set the API key:"
|
||||||
read -p "Input your key here:" CF_GlobalKey
|
read -p "Input your key here: " CF_GlobalKey
|
||||||
LOGD "Your API key is:${CF_GlobalKey}"
|
LOGD "Your API key is: ${CF_GlobalKey}"
|
||||||
|
|
||||||
LOGD "Please set up registered email:"
|
LOGD "Please set up registered email:"
|
||||||
read -p "Input your email here:" CF_AccountEmail
|
read -p "Input your email here: " CF_AccountEmail
|
||||||
LOGD "Your registered email address is:${CF_AccountEmail}"
|
LOGD "Your registered email address is: ${CF_AccountEmail}"
|
||||||
|
|
||||||
|
# Set the default CA to Let's Encrypt
|
||||||
~/.acme.sh/acme.sh --set-default-ca --server letsencrypt
|
~/.acme.sh/acme.sh --set-default-ca --server letsencrypt
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
LOGE "Default CA, Lets'Encrypt fail, script exiting..."
|
LOGE "Default CA, Let'sEncrypt fail, script exiting..."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
export CF_Key="${CF_GlobalKey}"
|
export CF_Key="${CF_GlobalKey}"
|
||||||
export CF_Email=${CF_AccountEmail}
|
export CF_Email="${CF_AccountEmail}"
|
||||||
|
|
||||||
|
# Issue the certificate using Cloudflare DNS
|
||||||
~/.acme.sh/acme.sh --issue --dns dns_cf -d ${CF_Domain} -d *.${CF_Domain} --log
|
~/.acme.sh/acme.sh --issue --dns dns_cf -d ${CF_Domain} -d *.${CF_Domain} --log
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
LOGE "Certificate issuance failed, script exiting..."
|
LOGE "Certificate issuance failed, script exiting..."
|
||||||
exit 1
|
exit 1
|
||||||
else
|
else
|
||||||
LOGI "Certificate issued Successfully, Installing..."
|
LOGI "Certificate issued successfully, Installing..."
|
||||||
fi
|
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 \
|
# Install the certificate
|
||||||
--fullchain-file /root/cert/fullchain.cer
|
mkdir -p ${certPath}/${CF_Domain}
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
LOGE "Failed to create directory: ${certPath}/${CF_Domain}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
~/.acme.sh/acme.sh --installcert -d ${CF_Domain} -d *.${CF_Domain} \
|
||||||
|
--fullchain-file ${certPath}/${CF_Domain}/fullchain.pem \
|
||||||
|
--key-file ${certPath}/${CF_Domain}/privkey.pem
|
||||||
|
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
LOGE "Certificate installation failed, script exiting..."
|
LOGE "Certificate installation failed, script exiting..."
|
||||||
exit 1
|
exit 1
|
||||||
else
|
else
|
||||||
LOGI "Certificate installed Successfully,Turning on automatic updates..."
|
LOGI "Certificate installed successfully, Turning on automatic updates..."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Enable auto-update
|
||||||
~/.acme.sh/acme.sh --upgrade --auto-upgrade
|
~/.acme.sh/acme.sh --upgrade --auto-upgrade
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
LOGE "Auto update setup Failed, script exiting..."
|
LOGE "Auto update setup failed, script exiting..."
|
||||||
ls -lah cert
|
|
||||||
chmod 755 $certPath
|
|
||||||
exit 1
|
exit 1
|
||||||
else
|
else
|
||||||
LOGI "The certificate is installed and auto-renewal is turned on, Specific information is as follows"
|
LOGI "The certificate is installed and auto-renewal is turned on. Specific information is as follows:"
|
||||||
ls -lah cert
|
ls -lah ${certPath}/${CF_Domain}
|
||||||
chmod 755 $certPath
|
chmod 755 ${certPath}/${CF_Domain}
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Prompt user to set panel paths after successful certificate installation
|
||||||
|
read -p "Would you like to set this certificate for the panel? (y/n): " setPanel
|
||||||
|
if [[ "$setPanel" == "y" || "$setPanel" == "Y" ]]; then
|
||||||
|
local webCertFile="${certPath}/${CF_Domain}/fullchain.pem"
|
||||||
|
local webKeyFile="${certPath}/${CF_Domain}/privkey.pem"
|
||||||
|
|
||||||
|
if [[ -f "$webCertFile" && -f "$webKeyFile" ]]; then
|
||||||
|
/usr/local/x-ui/x-ui cert -webCert "$webCertFile" -webCertKey "$webKeyFile"
|
||||||
|
LOGI "Panel paths set for domain: $CF_Domain"
|
||||||
|
LOGI " - Certificate File: $webCertFile"
|
||||||
|
LOGI " - Private Key File: $webKeyFile"
|
||||||
|
echo -e "${green}Access URL: https://${CF_Domain}:${existing_port}${existing_webBasePath}${plain}"
|
||||||
|
restart
|
||||||
|
else
|
||||||
|
LOGE "Error: Certificate or private key file not found for domain: $CF_Domain."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
LOGI "Skipping panel path setting."
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
show_menu
|
show_menu
|
||||||
|
@ -1141,7 +1239,13 @@ ssl_cert_issue_CF() {
|
||||||
run_speedtest() {
|
run_speedtest() {
|
||||||
# Check if Speedtest is already installed
|
# 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
|
# If not installed, determine installation method
|
||||||
|
if command -v snap &>/dev/null; then
|
||||||
|
# Use snap to install Speedtest
|
||||||
|
echo "Installing Speedtest using snap..."
|
||||||
|
snap install speedtest
|
||||||
|
else
|
||||||
|
# Fallback to using package managers
|
||||||
local pkg_manager=""
|
local pkg_manager=""
|
||||||
local speedtest_install_script=""
|
local speedtest_install_script=""
|
||||||
|
|
||||||
|
@ -1163,12 +1267,13 @@ run_speedtest() {
|
||||||
echo "Error: Package manager not found. You may need to install Speedtest manually."
|
echo "Error: Package manager not found. You may need to install Speedtest manually."
|
||||||
return 1
|
return 1
|
||||||
else
|
else
|
||||||
|
echo "Installing Speedtest using $pkg_manager..."
|
||||||
curl -s $speedtest_install_script | bash
|
curl -s $speedtest_install_script | bash
|
||||||
$pkg_manager install -y speedtest
|
$pkg_manager install -y speedtest
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# Run Speedtest
|
|
||||||
speedtest
|
speedtest
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1189,7 +1294,7 @@ create_iplimit_jails() {
|
||||||
enabled=true
|
enabled=true
|
||||||
backend=auto
|
backend=auto
|
||||||
filter=3x-ipl
|
filter=3x-ipl
|
||||||
action = %(known/action)s[name=%(__name__)s, protocol="%(protocol)s", chain="%(chain)s"]
|
action=3x-ipl
|
||||||
logpath=${iplimit_log_path}
|
logpath=${iplimit_log_path}
|
||||||
maxretry=2
|
maxretry=2
|
||||||
findtime=32
|
findtime=32
|
||||||
|
@ -1225,8 +1330,6 @@ actionunban = <iptables> -D f2b-<name> -s <ip> -j <blocktype>
|
||||||
echo "\$(date +"%%Y/%%m/%%d %%H:%%M:%%S") UNBAN [Email] = <F-USER> [IP] = <ip> unbanned." >> ${iplimit_banned_log_path}
|
echo "\$(date +"%%Y/%%m/%%d %%H:%%M:%%S") UNBAN [Email] = <F-USER> [IP] = <ip> unbanned." >> ${iplimit_banned_log_path}
|
||||||
|
|
||||||
[Init]
|
[Init]
|
||||||
# Use default settings from iptables-common.conf
|
|
||||||
# This will automatically handle both IPv4 and IPv6
|
|
||||||
name = default
|
name = default
|
||||||
protocol = tcp
|
protocol = tcp
|
||||||
chain = INPUT
|
chain = INPUT
|
||||||
|
@ -1297,20 +1400,28 @@ iplimit_main() {
|
||||||
;;
|
;;
|
||||||
4)
|
4)
|
||||||
show_banlog
|
show_banlog
|
||||||
|
iplimit_main
|
||||||
;;
|
;;
|
||||||
5)
|
5)
|
||||||
tail -f /var/log/fail2ban.log
|
tail -f /var/log/fail2ban.log
|
||||||
|
iplimit_main
|
||||||
;;
|
;;
|
||||||
6)
|
6)
|
||||||
service fail2ban status
|
service fail2ban status
|
||||||
|
iplimit_main
|
||||||
;;
|
;;
|
||||||
7)
|
7)
|
||||||
systemctl restart fail2ban
|
systemctl restart fail2ban
|
||||||
|
iplimit_main
|
||||||
;;
|
;;
|
||||||
8)
|
8)
|
||||||
remove_iplimit
|
remove_iplimit
|
||||||
|
iplimit_main
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo -e "${red}Invalid option. Please select a valid number.${plain}\n"
|
||||||
|
iplimit_main
|
||||||
;;
|
;;
|
||||||
*) echo "Invalid choice" ;;
|
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1391,7 +1502,7 @@ install_iplimit() {
|
||||||
remove_iplimit() {
|
remove_iplimit() {
|
||||||
echo -e "${green}\t1.${plain} Only remove IP Limit configurations"
|
echo -e "${green}\t1.${plain} Only remove IP Limit configurations"
|
||||||
echo -e "${green}\t2.${plain} Uninstall Fail2ban and IP Limit"
|
echo -e "${green}\t2.${plain} Uninstall Fail2ban and IP Limit"
|
||||||
echo -e "${green}\t0.${plain} Abort"
|
echo -e "${green}\t0.${plain} Back to Main Menu"
|
||||||
read -p "Choose an option: " num
|
read -p "Choose an option: " num
|
||||||
case "$num" in
|
case "$num" in
|
||||||
1)
|
1)
|
||||||
|
@ -1431,8 +1542,7 @@ remove_iplimit() {
|
||||||
before_show_menu
|
before_show_menu
|
||||||
;;
|
;;
|
||||||
0)
|
0)
|
||||||
echo -e "${yellow}Cancelled.${plain}\n"
|
show_menu
|
||||||
iplimit_main
|
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo -e "${red}Invalid option. Please select a valid number.${plain}\n"
|
echo -e "${red}Invalid option. Please select a valid number.${plain}\n"
|
||||||
|
@ -1454,7 +1564,7 @@ SSH_port_forwarding() {
|
||||||
|
|
||||||
if [[ -n "$existing_cert" && -n "$existing_key" ]]; then
|
if [[ -n "$existing_cert" && -n "$existing_key" ]]; then
|
||||||
echo -e "${green}Panel is secure with SSL.${plain}"
|
echo -e "${green}Panel is secure with SSL.${plain}"
|
||||||
return 0
|
before_show_menu
|
||||||
fi
|
fi
|
||||||
if [[ -z "$existing_cert" && -z "$existing_key" && (-z "$existing_listenIP" || "$existing_listenIP" == "0.0.0.0") ]]; then
|
if [[ -z "$existing_cert" && -z "$existing_key" && (-z "$existing_listenIP" || "$existing_listenIP" == "0.0.0.0") ]]; then
|
||||||
echo -e "\n${red}Warning: No Cert and Key found! The panel is not secure.${plain}"
|
echo -e "\n${red}Warning: No Cert and Key found! The panel is not secure.${plain}"
|
||||||
|
@ -1474,7 +1584,7 @@ SSH_port_forwarding() {
|
||||||
echo -e "\nChoose an option:"
|
echo -e "\nChoose an option:"
|
||||||
echo -e "${green}1.${plain} Set listen IP"
|
echo -e "${green}1.${plain} Set listen IP"
|
||||||
echo -e "${green}2.${plain} Clear listen IP"
|
echo -e "${green}2.${plain} Clear listen IP"
|
||||||
echo -e "${green}0.${plain} Abort"
|
echo -e "${green}0.${plain} Back to Main Menu"
|
||||||
read -p "Choose an option: " num
|
read -p "Choose an option: " num
|
||||||
|
|
||||||
case "$num" in
|
case "$num" in
|
||||||
|
@ -1509,10 +1619,11 @@ SSH_port_forwarding() {
|
||||||
restart
|
restart
|
||||||
;;
|
;;
|
||||||
0)
|
0)
|
||||||
echo "Operation aborted."
|
show_menu
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "Invalid option. Exiting."
|
echo -e "${red}Invalid option. Please select a valid number.${plain}\n"
|
||||||
|
SSH_port_forwarding
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,7 +129,7 @@ func (x *XrayAPI) AddUser(Protocol string, inboundTag string, user map[string]in
|
||||||
CipherType: ssCipherType,
|
CipherType: ssCipherType,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
account = serial.ToTypedMessage(&shadowsocks_2022.User{
|
account = serial.ToTypedMessage(&shadowsocks_2022.ServerConfig{
|
||||||
Key: user["password"].(string),
|
Key: user["password"].(string),
|
||||||
Email: user["email"].(string),
|
Email: user["email"].(string),
|
||||||
})
|
})
|
||||||
|
|
|
@ -226,6 +226,7 @@ func (p *process) Start() (err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("Failure in running xray-core:", err)
|
logger.Error("Failure in running xray-core:", err)
|
||||||
p.exitErr = err
|
p.exitErr = err
|
||||||
|
p.witeCrachReport(err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -241,3 +242,8 @@ func (p *process) Stop() error {
|
||||||
}
|
}
|
||||||
return p.cmd.Process.Signal(syscall.SIGTERM)
|
return p.cmd.Process.Signal(syscall.SIGTERM)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *process) witeCrachReport(err error) error {
|
||||||
|
crashReportPath := config.GetBinFolderPath() + "/core_crash_" + time.Now().Format("20060102_150405") + ".log"
|
||||||
|
return os.WriteFile(crashReportPath, []byte(err.Error()), os.ModePerm)
|
||||||
|
}
|
||||||
|
|