Merge branch 'main' into 3x-ui
4
.github/FUNDING.yml
vendored
@ -1,6 +1,6 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: MHSanaei
|
||||
github: xeefei
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
@ -10,5 +10,5 @@ liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
|
||||
polar: # Replace with a single Polar username
|
||||
buy_me_a_coffee: mhsanaei
|
||||
buy_me_a_coffee: xeefeiz
|
||||
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
||||
|
||||
6
.github/workflows/docker.yml
vendored
@ -19,8 +19,8 @@ jobs:
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: |
|
||||
hsanaeii/3x-ui
|
||||
ghcr.io/mhsanaei/3x-ui
|
||||
xeefei/3x-ui
|
||||
ghcr.io/xeefei/3x-ui
|
||||
tags: |
|
||||
type=ref,event=branch
|
||||
type=ref,event=tag
|
||||
@ -54,4 +54,4 @@ jobs:
|
||||
push: true
|
||||
platforms: linux/amd64, linux/arm64/v8, linux/arm/v7, linux/arm/v6, linux/386
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
|
||||
124
.github/workflows/release.yml
vendored
@ -19,7 +19,11 @@ on:
|
||||
- 'x-ui.service'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
# ===============================================================
|
||||
# Linux 平台的构建任务 (这是原有的任务,保持不变)
|
||||
# ===============================================================
|
||||
build-linux:
|
||||
name: Build for Linux
|
||||
permissions:
|
||||
contents: write
|
||||
strategy:
|
||||
@ -43,7 +47,7 @@ jobs:
|
||||
go-version-file: go.mod
|
||||
check-latest: true
|
||||
|
||||
- name: Build 3X-UI
|
||||
- name: Build 3X-UI for Linux
|
||||
run: |
|
||||
export CGO_ENABLED=1
|
||||
export GOOS=linux
|
||||
@ -123,7 +127,7 @@ jobs:
|
||||
wget -q -O geosite_RU.dat https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download/geosite.dat
|
||||
mv xray xray-linux-${{ matrix.platform }}
|
||||
cd ../..
|
||||
|
||||
|
||||
- name: Package
|
||||
run: tar -zcvf x-ui-linux-${{ matrix.platform }}.tar.gz x-ui
|
||||
|
||||
@ -141,4 +145,118 @@ jobs:
|
||||
tag: ${{ github.ref }}
|
||||
file: x-ui-linux-${{ matrix.platform }}.tar.gz
|
||||
asset_name: x-ui-linux-${{ matrix.platform }}.tar.gz
|
||||
# 如果你希望这是预发布版本,可以此行注释
|
||||
prerelease: true
|
||||
|
||||
# ===============================================================
|
||||
# 【新增】Windows 平台的构建任务
|
||||
# ===============================================================
|
||||
build-windows:
|
||||
name: Build for Windows
|
||||
permissions:
|
||||
contents: write
|
||||
strategy:
|
||||
matrix:
|
||||
# 〔中文注释〕: 定义需要构建的 Windows CPU 架构,一般 amd64 就够了
|
||||
platform:
|
||||
- amd64
|
||||
- 386
|
||||
# 〔中文注释〕: 指定使用 Windows 最新版的虚拟环境
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
check-latest: true
|
||||
|
||||
- name: Build 3X-UI for Windows
|
||||
# 〔中文注释〕: 使用 PowerShell 执行脚本,更符合 Windows 环境
|
||||
shell: pwsh
|
||||
run: |
|
||||
# 〔中文注释〕: 设置环境变量,GOOS=windows 指定编译目标为 Windows
|
||||
$env:GOOS = "windows"
|
||||
$env:GOARCH = "${{ matrix.platform }}"
|
||||
# 〔中文注释〕: CGO 在 Windows 下通常不需要,设置为 0
|
||||
$env:CGO_ENABLED = "0"
|
||||
|
||||
# 〔中文注释〕: 执行 Go 编译命令。-o 指定输出文件为 .exe 可执行文件
|
||||
go build -ldflags "-w -s" -o x-ui-release.exe -v main.go
|
||||
|
||||
# 〔中文注释〕: 创建用于打包的文件夹
|
||||
mkdir x-ui
|
||||
|
||||
# 〔中文注释〕: 移动编译好的主程序到文件夹,并重命名为 x-ui.exe
|
||||
Move-Item -Path .\x-ui-release.exe -Destination .\x-ui\x-ui.exe
|
||||
|
||||
# 〔中文注释〕: 创建 bin 目录存放依赖文件
|
||||
mkdir x-ui\bin
|
||||
cd x-ui\bin
|
||||
|
||||
# 〔中文注释〕: 下载 Windows 版本的 Xray-core 依赖
|
||||
# 注意:这里的 Xray 版本号 (v25.8.29) 我沿用了你 Linux 脚本中的版本,你可以根据需要修改
|
||||
$Xray_URL="https://github.com/XTLS/Xray-core/releases/download/v25.8.29/"
|
||||
if ("${{ matrix.platform }}" -eq "amd64") {
|
||||
# Invoke-WebRequest 是 PowerShell 的下载命令,等同于 wget
|
||||
Invoke-WebRequest -Uri "${Xray_URL}Xray-windows-64.zip" -OutFile "xray.zip"
|
||||
} elseif ("${{ matrix.platform }}" -eq "386") {
|
||||
Invoke-WebRequest -Uri "${Xray_URL}Xray-windows-32.zip" -OutFile "xray.zip"
|
||||
}
|
||||
|
||||
# 〔中文注释〕: 解压 xray.zip
|
||||
Expand-Archive -Path .\xray.zip -DestinationPath .
|
||||
# 〔中文注释〕: 删除下载的压缩包
|
||||
Remove-Item -Path .\xray.zip
|
||||
|
||||
# 〔中文注释〕: 下载公用的 geo 数据文件,这些文件与平台无关
|
||||
Remove-Item -Path "geoip.dat", "geosite.dat" -ErrorAction SilentlyContinue
|
||||
Invoke-WebRequest -Uri "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat" -OutFile "geoip.dat"
|
||||
Invoke-WebRequest -Uri "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat" -OutFile "geosite.dat"
|
||||
Invoke-WebRequest -Uri "https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geoip.dat" -OutFile "geoip_IR.dat"
|
||||
Invoke-WebRequest -Uri "https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geosite.dat" -OutFile "geosite_IR.dat"
|
||||
Invoke-WebRequest -Uri "https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download/geoip.dat" -OutFile "geoip_RU.dat"
|
||||
Invoke-WebRequest -Uri "https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download/geosite.dat" -OutFile "geosite_RU.dat"
|
||||
|
||||
# 〔中文注释〕: 将解压出的 xray.exe 重命名,以便区分
|
||||
Move-Item -Path .\xray.exe -Destination "xray-windows-${{ matrix.platform }}.exe"
|
||||
|
||||
# 〔中文注释〕: 返回到 x-ui 文件夹的根目录
|
||||
cd ..
|
||||
|
||||
# ===============================================================
|
||||
# 【新增部分】从仓库复制辅助文件到待打包的 x-ui 目录中
|
||||
# 辅助文件都放在了项目根目录的 windows_files 文件夹下
|
||||
# ===============================================================
|
||||
Copy-Item -Path ..\windows_files\* -Destination . -Recurse
|
||||
|
||||
# 〔中文注释〕: 返回项目根目录
|
||||
cd ..
|
||||
|
||||
- name: Package to Zip
|
||||
# 〔中文注释〕: 使用 PowerShell 命令将 x-ui 文件夹打包成 zip 压缩包
|
||||
shell: pwsh
|
||||
run: |
|
||||
Compress-Archive -Path .\x-ui -DestinationPath "x-ui-windows-${{ matrix.platform }}.zip"
|
||||
|
||||
- name: Upload files to Artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
# 〔中文注释〕: 上传的构建产物名称,明确标识为 windows
|
||||
name: x-ui-windows-${{ matrix.platform }}
|
||||
# 〔中文注释〕: 上传的压缩包路径
|
||||
path: ./x-ui-windows-${{ matrix.platform }}.zip
|
||||
|
||||
- name: Upload files to GH release
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
if: github.event_name == 'release' && github.event.action == 'published'
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
tag: ${{ github.ref }}
|
||||
# 〔中文注释〕: 指定要上传的文件为 windows 的 zip 包
|
||||
file: x-ui-windows-${{ matrix.platform }}.zip
|
||||
# 〔中文注释〕: 在 Release 页面显示的资产名称
|
||||
asset_name: x-ui-windows-${{ matrix.platform }}.zip
|
||||
prerelease: true
|
||||
|
||||
520
README.es_ES.md
@ -1,56 +1,498 @@
|
||||
[English](/README.md) | [فارسی](/README.fa_IR.md) | [العربية](/README.ar_EG.md) | [中文](/README.zh_CN.md) | [Español](/README.es_ES.md) | [Русский](/README.ru_RU.md)
|
||||
[English](/README.md) | [Chinese](/README.zh.md) | [Español](/README.es_ES.md)
|
||||
|
||||
<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 align="center"><a href="#"><img src="./media/3X-UI.png" alt="Image"></a></p>
|
||||
|
||||
**Un Panel Web Avanzado • Construido sobre Xray Core**
|
||||
|
||||
[](https://github.com/xeefei/3x-ui/releases)
|
||||
[](#)
|
||||
[](#)
|
||||
[](#)
|
||||
[](https://www.gnu.org/licenses/gpl-3.0.en.html)
|
||||
|
||||
> **Descargo de responsabilidad:** Este proyecto es solo para aprendizaje personal y comunicación, por favor no lo uses con fines ilegales, por favor no lo uses en un entorno de producción
|
||||
|
||||
**Si este proyecto te es útil, podrías considerar darle una**:star2:
|
||||
|
||||
<p align="left">
|
||||
<a href="https://buymeacoffee.com/xeefeiz" target="_blank">
|
||||
<img src="./media/buymeacoffe.png" alt="Image">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
[](https://github.com/MHSanaei/3x-ui/releases)
|
||||
[](https://github.com/MHSanaei/3x-ui/actions)
|
||||
[](#)
|
||||
[](https://github.com/MHSanaei/3x-ui/releases/latest)
|
||||
[](https://www.gnu.org/licenses/gpl-3.0.en.html)
|
||||
- USDT (TRC20): `TYQEmQp1P65u9bG7KPehgJdvuokfb72YkZ`
|
||||
|
||||
**3X-UI** — panel de control avanzado basado en web de código abierto diseñado para gestionar el servidor Xray-core. Ofrece una interfaz fácil de usar para configurar y monitorear varios protocolos VPN y proxy.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Este proyecto es solo para uso personal y comunicación, por favor no lo use para fines ilegales, por favor no lo use en un entorno de producción.
|
||||
|
||||
Como una versión mejorada del proyecto X-UI original, 3X-UI proporciona mayor estabilidad, soporte más amplio de protocolos y características adicionales.
|
||||
|
||||
## Inicio Rápido
|
||||
## Instalar y Actualizar
|
||||
|
||||
```
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/xeefei/3x-ui/master/install.sh)
|
||||
```
|
||||
|
||||
Para documentación completa, visita la [Wiki del proyecto](https://github.com/MHSanaei/3x-ui/wiki).
|
||||
## Instalar una Versión Personalizada
|
||||
|
||||
## Un Agradecimiento Especial a
|
||||
Para instalar la versión deseada, agrega la versión al final del comando de instalación. Por ejemplo, ver `v2.4.1`:
|
||||
|
||||
```
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/xeefei/3x-ui/master/install.sh) v2.4.1
|
||||
```
|
||||
|
||||
## Certificado SSL
|
||||
|
||||
<details>
|
||||
<summary>Haz clic para el Certificado SSL</summary>
|
||||
|
||||
### Cloudflare
|
||||
|
||||
El script de gestión tiene una aplicación de certificado SSL incorporada para Cloudflare. Para usar este script para colocar un certificado, necesitas lo siguiente:
|
||||
|
||||
- Correo electrónico registrado en Cloudflare
|
||||
- Clave Global de API de Cloudflare
|
||||
- El nombre de dominio se ha resuelto en el servidor actual a través de Cloudflare
|
||||
|
||||
**1:** Ejecuta el comando`x-ui`en la terminal, luego elige `Certificado SSL de Cloudflare`.
|
||||
|
||||
|
||||
### Certbot
|
||||
```
|
||||
apt-get install certbot -y
|
||||
certbot certonly --standalone --agree-tos --register-unsafely-without-email -d yourdomain.com
|
||||
certbot renew --dry-run
|
||||
```
|
||||
|
||||
***Consejo:*** *Certbot también está integrado en el script de gestión. Puedes ejecutar el comando `x-ui` , luego elegir `Gestión de Certificados SSL`.*
|
||||
|
||||
</details>
|
||||
|
||||
## Instalación y Actualización Manual
|
||||
|
||||
<details>
|
||||
<summary>Haz clic para más detalles de la instalación manual</summary>
|
||||
|
||||
#### Uso
|
||||
|
||||
1. Para descargar la última versión del paquete comprimido directamente en tu servidor, ejecuta el siguiente comando:
|
||||
|
||||
```sh
|
||||
ARCH=$(uname -m)
|
||||
case "${ARCH}" in
|
||||
x86_64 | x64 | amd64) XUI_ARCH="amd64" ;;
|
||||
i*86 | x86) XUI_ARCH="386" ;;
|
||||
armv8* | armv8 | arm64 | aarch64) XUI_ARCH="arm64" ;;
|
||||
armv7* | armv7) XUI_ARCH="armv7" ;;
|
||||
armv6* | armv6) XUI_ARCH="armv6" ;;
|
||||
armv5* | armv5) XUI_ARCH="armv5" ;;
|
||||
*) XUI_ARCH="amd64" ;;
|
||||
esac
|
||||
|
||||
|
||||
wget https://github.com/xeefei/3x-ui/releases/latest/download/x-ui-linux-${XUI_ARCH}.tar.gz
|
||||
```
|
||||
|
||||
2. Una vez que se haya descargado el paquete comprimido, ejecuta los siguientes comandos para instalar o actualizar x-ui:
|
||||
|
||||
```sh
|
||||
ARCH=$(uname -m)
|
||||
case "${ARCH}" in
|
||||
x86_64 | x64 | amd64) XUI_ARCH="amd64" ;;
|
||||
i*86 | x86) XUI_ARCH="386" ;;
|
||||
armv8* | armv8 | arm64 | aarch64) XUI_ARCH="arm64" ;;
|
||||
armv7* | armv7) XUI_ARCH="armv7" ;;
|
||||
armv6* | armv6) XUI_ARCH="armv6" ;;
|
||||
armv5* | armv5) XUI_ARCH="armv5" ;;
|
||||
*) XUI_ARCH="amd64" ;;
|
||||
esac
|
||||
|
||||
cd /root/
|
||||
rm -rf x-ui/ /usr/local/x-ui/ /usr/bin/x-ui
|
||||
tar zxvf x-ui-linux-${XUI_ARCH}.tar.gz
|
||||
chmod +x x-ui/x-ui x-ui/bin/xray-linux-* x-ui/x-ui.sh
|
||||
cp x-ui/x-ui.sh /usr/bin/x-ui
|
||||
cp -f x-ui/x-ui.service /etc/systemd/system/
|
||||
mv x-ui/ /usr/local/
|
||||
systemctl daemon-reload
|
||||
systemctl enable x-ui
|
||||
systemctl restart x-ui
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## Instalar con Docker
|
||||
|
||||
<details>
|
||||
<summary>Haz clic para más detalles del Docker</summary>
|
||||
|
||||
#### Uso
|
||||
|
||||
1. Instala Docker:
|
||||
|
||||
```sh
|
||||
bash <(curl -sSL https://get.docker.com)
|
||||
```
|
||||
|
||||
2. Clona el Repositorio del Proyecto:
|
||||
|
||||
```sh
|
||||
git clone https://github.com/xeefei/3x-ui.git
|
||||
cd 3x-ui
|
||||
```
|
||||
|
||||
3. Inicia el Servicio
|
||||
|
||||
```sh
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
O tambien
|
||||
|
||||
```sh
|
||||
docker run -itd \
|
||||
-e XRAY_VMESS_AEAD_FORCED=false \
|
||||
-v $PWD/db/:/etc/x-ui/ \
|
||||
-v $PWD/cert/:/root/cert/ \
|
||||
--network=host \
|
||||
--restart=unless-stopped \
|
||||
--name 3x-ui \
|
||||
ghcr.io/xeefei/3x-ui:latest
|
||||
```
|
||||
|
||||
actualizar a la última versión
|
||||
|
||||
```sh
|
||||
cd 3x-ui
|
||||
docker compose down
|
||||
docker compose pull 3x-ui
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
eliminar 3x-ui de docker
|
||||
|
||||
```sh
|
||||
docker stop 3x-ui
|
||||
docker rm 3x-ui
|
||||
cd --
|
||||
rm -r 3x-ui
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
## SO Recomendados
|
||||
|
||||
- Ubuntu 20.04+
|
||||
- Debian 11+
|
||||
- CentOS 8+
|
||||
- Fedora 36+
|
||||
- Arch Linux
|
||||
- Manjaro
|
||||
- Armbian
|
||||
- AlmaLinux 9+
|
||||
- Rockylinux 9+
|
||||
- OpenSUSE Tubleweed
|
||||
|
||||
## Arquitecturas y Dispositivos Compatibles
|
||||
|
||||
<details>
|
||||
<summary>Haz clic para detalles de arquitecturas y dispositivos compatibles</summary>
|
||||
|
||||
Nuestra plataforma ofrece compatibilidad con una amplia gama de arquitecturas y dispositivos, garantizando flexibilidad en diversos entornos informáticos. A continuación se presentan las principales arquitecturas que admitimos:
|
||||
|
||||
- **amd64**: Esta arquitectura predominante es la estándar para computadoras personales y servidores, y admite la mayoría de los sistemas operativos modernos sin problemas.
|
||||
|
||||
- **x86 / i386**: Ampliamente adoptada en computadoras de escritorio y portátiles, esta arquitectura cuenta con un amplio soporte de numerosos sistemas operativos y aplicaciones, incluidos, entre otros, Windows, macOS y sistemas Linux.
|
||||
|
||||
- **armv8 / arm64 / aarch64**: Diseñada para dispositivos móviles y embebidos contemporáneos, como teléfonos inteligentes y tabletas, esta arquitectura está ejemplificada por dispositivos como Raspberry Pi 4, Raspberry Pi 3, Raspberry Pi Zero 2/Zero 2 W, Orange Pi 3 LTS, entre otros.
|
||||
|
||||
- **armv7 / arm / arm32**: Sirve como arquitectura para dispositivos móviles y embebidos más antiguos, y sigue siendo ampliamente utilizada en dispositivos como Orange Pi Zero LTS, Orange Pi PC Plus, Raspberry Pi 2, entre otros.
|
||||
|
||||
- **armv6 / arm / arm32**: Orientada a dispositivos embebidos muy antiguos, esta arquitectura, aunque menos común, todavía se utiliza. Dispositivos como Raspberry Pi 1, Raspberry Pi Zero/Zero W, dependen de esta arquitectura.
|
||||
|
||||
- **armv5 / arm / arm32**: Una arquitectura más antigua asociada principalmente con sistemas embebidos tempranos, es menos común hoy en día pero aún puede encontrarse en dispositivos heredados como versiones antiguas de Raspberry Pi y algunos teléfonos inteligentes más antiguos.
|
||||
</details>
|
||||
|
||||
## Idiomas
|
||||
|
||||
- Inglés
|
||||
- Farsi
|
||||
- Chino
|
||||
- Ruso
|
||||
- Vietnamita
|
||||
- Español
|
||||
- Indonesio
|
||||
- Ucraniano
|
||||
|
||||
|
||||
## Características
|
||||
|
||||
- Monitoreo del Estado del Sistema
|
||||
- Búsqueda dentro de todas las reglas de entrada y clientes
|
||||
- Tema Oscuro/Claro
|
||||
- Soporta multiusuario y multiprotocolo
|
||||
- Soporta protocolos, incluyendo VMess, VLESS, Trojan, Shadowsocks, Dokodemo-door, Socks, HTTP, wireguard
|
||||
- Soporta Protocolos nativos XTLS, incluyendo RPRX-Direct, Visión, REALITY
|
||||
- Estadísticas de tráfico, límite de tráfico, límite de tiempo de vencimiento
|
||||
- Plantillas de configuración de Xray personalizables
|
||||
- Soporta acceso HTTPS al panel (dominio proporcionado por uno mismo + certificado SSL)
|
||||
- Soporta la solicitud y renovación automática de certificados SSL con un clic
|
||||
- Para elementos de configuración más avanzados, consulta el panel
|
||||
- Corrige rutas de API (la configuración del usuario se creará con la API)
|
||||
- Soporta cambiar las configuraciones por diferentes elementos proporcionados en el panel.
|
||||
- Soporta exportar/importar base de datos desde el panel
|
||||
|
||||
|
||||
## Configuración Predeterminada del Panel
|
||||
|
||||
<details>
|
||||
<summary>Haz clic para ver los detalles de la configuración predeterminada</summary>
|
||||
|
||||
### Nombre de Usuario & Contraseña & Ruta Base Web:
|
||||
|
||||
Estos se generarán aleatoriamente si no los modificas.
|
||||
|
||||
- **Puerto:** el puerto predeterminado para el panel es `2053`
|
||||
|
||||
### Gestión de la Base de Datos:
|
||||
|
||||
Puedes realizar copias de seguridad y restauraciones de la base de datos directamente desde el panel.
|
||||
|
||||
### Ruta Base Web
|
||||
- /etc/x-ui/x-ui.db
|
||||
- **Ruta de Configuración de Xray:**
|
||||
- /usr/local/x-ui/bin/config.json
|
||||
- **Ruta del Panel Web sin Implementar SSL:**
|
||||
- http://ip:2053/panel
|
||||
- http://domain:2053/panel
|
||||
- **Ruta del Panel Web con Implementación de SSL:**
|
||||
- https://domain:2053/panel
|
||||
|
||||
</details>
|
||||
|
||||
1. **Restablecer la Ruta Base Web:**
|
||||
- Abre tu terminal.
|
||||
- Ejecuta el comando `x-ui`.
|
||||
- Selecciona la opción `Restablecer la Ruta Base Web`.
|
||||
|
||||
2. **Generar o Personalizar la Ruta:**
|
||||
- La ruta se generará aleatoriamente, o puedes ingresar una ruta personalizada.
|
||||
|
||||
3. **Ver Configuración Actual:**
|
||||
- Para ver tu configuración actual, utiliza el comando `x-ui settings` en el terminal o selecciona `Ver Configuración Actual` en `x-ui`.
|
||||
|
||||
### Recomendación de Seguridad:
|
||||
- Para mayor seguridad, utiliza una palabra larga y aleatoria en la estructura de tu URL.
|
||||
|
||||
**Ejemplos:**
|
||||
- `http://ip:port/*webbasepath*/panel`
|
||||
- `http://domain:port/*webbasepath*/panel`
|
||||
|
||||
</details>
|
||||
|
||||
## Configuración de WARP
|
||||
|
||||
<details>
|
||||
<summary>Haz clic para ver los detalles de la configuración de WARP</summary>
|
||||
|
||||
#### Uso
|
||||
|
||||
**Para versiones `v2.1.0` y posteriores:**
|
||||
|
||||
WARP está integrado, no se requiere instalación adicional. Simplemente habilita la configuración necesaria en el panel.
|
||||
|
||||
</details>
|
||||
|
||||
## Límite de IP
|
||||
|
||||
<details>
|
||||
<summary>Haz clic para ver los detalles del límite de IP</summary>
|
||||
|
||||
#### Uso
|
||||
|
||||
**Nota:** El Límite de IP no funcionará correctamente cuando uses Túnel IP.
|
||||
|
||||
- **Para versiones hasta `v1.6.1`:**
|
||||
- El límite de IP está integrado en el panel.
|
||||
|
||||
**Para versiones `v1.7.0` y posteriores:**
|
||||
|
||||
Para habilitar la funcionalidad de límite de IP, necesitas instalar `fail2ban` y los archivos requeridos siguiendo estos pasos:
|
||||
|
||||
1. Ejecuta el comando `x-ui` en el terminal, luego elige `Gestión de Límite de IP`.
|
||||
2. Verás las siguientes opciones:
|
||||
|
||||
- **Cambiar la Duración del Bloqueo:** Ajustar la duración de los bloqueos.
|
||||
- **Desbloquear a Todos:** Levantar todos los bloqueos actuales.
|
||||
- **Revisar los Registros:** Revisar los registros.
|
||||
- **Estado de Fail2ban:** Verificar el estado de `fail2ban`.
|
||||
- **Reiniciar Fail2ban:** Reiniciar el servicio `fail2ban`.
|
||||
- **Desinstalar Fail2ban:** Desinstalar Fail2ban con la configuración.
|
||||
|
||||
3. Agrega una ruta para el registro de acceso en el panel configurando `Xray Configs/log/Access log` a `./access.log`, luego guarda y reinicia Xray.
|
||||
|
||||
- **Para versiones anteriores a `v2.1.3`:**
|
||||
- Necesitas configurar manualmente la ruta del registro de acceso en tu configuración de Xray:
|
||||
|
||||
```sh
|
||||
"log": {
|
||||
"access": "./access.log",
|
||||
"dnsLog": false,
|
||||
"loglevel": "warning"
|
||||
},
|
||||
```
|
||||
|
||||
- **Para versiones `v2.1.3` y posteriores:**
|
||||
- Hay una opción para configurar `access.log` directamente desde el panel.
|
||||
|
||||
</details>
|
||||
|
||||
## Bot de Telegram
|
||||
|
||||
<details>
|
||||
<summary>Haz clic para más detalles del bot de Telegram</summary>
|
||||
|
||||
#### Uso
|
||||
|
||||
El panel web admite tráfico diario, inicio de sesión en el panel, copia de seguridad de la base de datos, estado del sistema, información del cliente y otras notificaciones y funciones a través del Bot de Telegram. Para usar el bot, debes establecer los parámetros relacionados con el bot en el panel, que incluyen:
|
||||
|
||||
- Token de Telegram
|
||||
- ID de chat de administrador(es)
|
||||
- Hora de Notificación (en sintaxis cron)
|
||||
- Notificación de Fecha de Caducidad
|
||||
- Notificación de Capacidad de Tráfico
|
||||
- Copia de seguridad de la base de datos
|
||||
- Notificación de Carga de CPU
|
||||
|
||||
|
||||
**Sintaxis de referencia:**
|
||||
|
||||
- `30 \* \* \* \* \*` - Notifica a los 30s de cada punto
|
||||
- `0 \*/10 \* \* \* \*` - Notifica en el primer segundo de cada 10 minutos
|
||||
- `@hourly` - Notificación por hora
|
||||
- `@daily` - Notificación diaria (00:00 de la mañana)
|
||||
- `@weekly` - Notificación semanal
|
||||
- `@every 8h` - Notifica cada 8 horas
|
||||
|
||||
### Funcionalidades del Bot de Telegram
|
||||
|
||||
- Reporte periódico
|
||||
- Notificación de inicio de sesión
|
||||
- Notificación de umbral de CPU
|
||||
- Umbral de Notificación para Fecha de Caducidad y Tráfico para informar con anticipación
|
||||
- Soporte para menú de reporte de cliente si el nombre de usuario de Telegram del cliente se agrega a las configuraciones de usuario
|
||||
- Soporte para reporte de tráfico de Telegram buscado con UUID (VMESS/VLESS) o Contraseña (TROJAN) - anónimamente
|
||||
- Bot basado en menú
|
||||
- Buscar cliente por correo electrónico (solo administrador)
|
||||
- Ver todas las Entradas
|
||||
- Ver estado del servidor
|
||||
- Ver clientes agotados
|
||||
- Recibir copia de seguridad bajo demanda y en informes periódicos
|
||||
- Bot multilingüe
|
||||
|
||||
### Configuración del Bot de Telegram
|
||||
|
||||
- Inicia [Botfather](https://t.me/BotFather) en tu cuenta de Telegram:
|
||||

|
||||
|
||||
- Crea un nuevo bot usando el comando /newbot: Te hará 2 preguntas, Un nombre y un nombre de usuario para tu bot. Ten en cuenta que el nombre de usuario debe terminar con la palabra "bot".
|
||||

|
||||
|
||||
- Inicia el bot que acabas de crear. Puedes encontrar el enlace a tu bot aquí.
|
||||

|
||||
|
||||
- Ingresa a tu panel y configura los ajustes del bot de Telegram como se muestra a continuación:
|
||||

|
||||
|
||||
Ingresa el token de tu bot en el campo de entrada número 3.
|
||||
Ingresa el ID de chat de usuario en el campo de entrada número 4. Las cuentas de Telegram con esta ID serán los administradores del bot. (Puedes ingresar más de uno, solo sepáralos con ,)
|
||||
|
||||
- ¿Cómo obtener el ID de chat de Telegram? Usa este [bot](https://t.me/useridinfobot), Inicia el bot y te dará el ID de chat del usuario de Telegram.
|
||||

|
||||
|
||||
</details>
|
||||
|
||||
## Rutas de API
|
||||
|
||||
<details>
|
||||
<summary>Haz clic para más detalles de las rutas de API</summary>
|
||||
|
||||
#### Uso
|
||||
|
||||
- `/login` con `POST` datos de usuario: `{username: '', password: ''}` para iniciar sesión
|
||||
- `/panel/api/inbounds` base para las siguientes acciones:
|
||||
|
||||
| Método | Ruta | Acción |
|
||||
| :----: | ---------------------------------- | --------------------------------------------------------- |
|
||||
| `GET` | `"/list"` | Obtener todas los Entradas |
|
||||
| `GET` | `"/get/:id"` | Obtener Entrada con inbound.id |
|
||||
| `GET` | `"/getClientTraffics/:email"` | Obtener Tráficos del Cliente con email |
|
||||
| `GET` | `"/createbackup"` | El bot de Telegram envía copia de seguridad a los admins |
|
||||
| `POST` | `"/add"` | Agregar Entrada |
|
||||
| `POST` | `"/del/:id"` | Eliminar Entrada |
|
||||
| `POST` | `"/update/:id"` | Actualizar Entrada |
|
||||
| `POST` | `"/clientIps/:email"` | Dirección IP del Cliente |
|
||||
| `POST` | `"/clearClientIps/:email"` | Borrar Dirección IP del Cliente |
|
||||
| `POST` | `"/addClient"` | Agregar Cliente a la Entrada |
|
||||
| `POST` | `"/:id/delClient/:clientId"` | Eliminar Cliente por clientId\* |
|
||||
| `POST` | `"/updateClient/:clientId"` | Actualizar Cliente por clientId\* |
|
||||
| `POST` | `"/:id/resetClientTraffic/:email"` | Restablecer Tráfico del Cliente |
|
||||
| `POST` | `"/resetAllTraffics"` | Restablecer tráfico de todos las Entradas |
|
||||
| `POST` | `"/resetAllClientTraffics/:id"` | Restablecer tráfico de todos los clientes en una Entrada |
|
||||
| `POST` | `"/delDepletedClients/:id"` | Eliminar clientes agotados de la entrada (-1: todos) |
|
||||
| `POST` | `"/onlines"` | Obtener usuarios en línea (lista de correos electrónicos) |
|
||||
|
||||
\*- El campo `clientId` debe llenarse por:
|
||||
|
||||
- `client.id` para VMESS y VLESS
|
||||
- `client.password` para TROJAN
|
||||
- `client.email` para Shadowsocks
|
||||
|
||||
|
||||
- [Documentación de API](https://documenter.getpostman.com/view/16802678/2s9YkgD5jm)
|
||||
- [<img src="https://run.pstmn.io/button.svg" alt="Run In Postman" style="width: 128px; height: 32px;">](https://app.getpostman.com/run-collection/16802678-1a4c9270-ac77-40ed-959a-7aa56dc4a415?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D16802678-1a4c9270-ac77-40ed-959a-7aa56dc4a415%26entityType%3Dcollection%26workspaceId%3D2cd38c01-c851-4a15-a972-f181c23359d9)
|
||||
</details>
|
||||
|
||||
## Variables de Entorno
|
||||
|
||||
<details>
|
||||
<summary>Haz clic para más detalles de las variables de entorno</summary>
|
||||
|
||||
#### Uso
|
||||
|
||||
| Variable | Tipo | Predeterminado |
|
||||
| -------------- | :--------------------------------------------: | :------------- |
|
||||
| XUI_LOG_LEVEL | `"debug"` \| `"info"` \| `"warn"` \| `"error"` | `"info"` |
|
||||
| XUI_DEBUG | `boolean` | `false` |
|
||||
| XUI_BIN_FOLDER | `string` | `"bin"` |
|
||||
| XUI_DB_FOLDER | `string` | `"/etc/x-ui"` |
|
||||
| XUI_LOG_FOLDER | `string` | `"/var/log"` |
|
||||
|
||||
Ejemplo:
|
||||
|
||||
```sh
|
||||
XUI_BIN_FOLDER="bin" XUI_DB_FOLDER="/etc/x-ui" go build main.go
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## Vista previa
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
## Un agradecimiento especial a
|
||||
|
||||
- [alireza0](https://github.com/alireza0/)
|
||||
|
||||
## Reconocimientos
|
||||
|
||||
- [Iran v2ray rules](https://github.com/chocolate4u/Iran-v2ray-rules) (Licencia: **GPL-3.0**): _Reglas de enrutamiento mejoradas para v2ray/xray y v2ray/xray-clients con dominios iraníes incorporados y un enfoque en seguridad y bloqueo de anuncios._
|
||||
- [Russia v2ray rules](https://github.com/runetfreedom/russia-v2ray-rules-dat) (Licencia: **GPL-3.0**): _Este repositorio contiene reglas de enrutamiento V2Ray actualizadas automáticamente basadas en datos de dominios y direcciones bloqueadas en Rusia._
|
||||
赞助地址(USDT/TRC20):TYQEmQp1P65u9bG7KPehgJdvuokfb72YkZ
|
||||
|
||||
## Apoyar el Proyecto
|
||||
- [Iran v2ray rules](https://github.com/chocolate4u/Iran-v2ray-rules) (Licencia: **GPL-3.0**): _Reglas de enrutamiento mejoradas de v2ray/xray y v2ray/xray-clients con dominios iraníes integrados y un enfoque en seguridad y bloqueo de anuncios._
|
||||
- [Vietnam Adblock rules](https://github.com/vuong2023/vn-v2ray-rules) (License: **GPL-3.0**): _Un dominio alojado en Vietnam y una lista de bloqueo con la máxima eficiencia para vietnamitas._
|
||||
|
||||
**Si este proyecto te es útil, puedes darle una**:star2:
|
||||
## Estrellas a lo largo del tiempo
|
||||
|
||||
<p align="left">
|
||||
<a href="https://buymeacoffee.com/mhsanaei" target="_blank">
|
||||
<img src="./media/buymeacoffe.png" alt="Image">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
- USDT (TRC20): `TXncxkvhkDWGts487Pjqq1qT9JmwRUz8CC`
|
||||
- POL (polygon): `0x41C9548675D044c6Bfb425786C765bc37427256A`
|
||||
- LTC (Litecoin): `ltc1q2ach7x6d2zq0n4l0t4zl7d7xe2s6fs7a3vspwv`
|
||||
|
||||
## Estrellas a lo Largo del Tiempo
|
||||
|
||||
[](https://starchart.cc/MHSanaei/3x-ui)
|
||||
[](https://starchart.cc/xeefei/3x-ui)
|
||||
|
||||
@ -1,16 +1,12 @@
|
||||
[English](/README.md) | [فارسی](/README.fa_IR.md) | [العربية](/README.ar_EG.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构建------------------------------**
|
||||
|
||||
[](https://github.com/MHSanaei/3x-ui/releases)
|
||||
[](https://github.com/MHSanaei/3x-ui/actions)
|
||||
[](#)
|
||||
[](https://github.com/MHSanaei/3x-ui/releases/latest)
|
||||
|
||||
[](https://github.com/xeefei/3x-ui/releases)
|
||||
[](https://github.com/xeefei/3x-ui/actions)
|
||||
[](#)
|
||||
[](https://github.com/xeefei/3x-ui/releases/latest)
|
||||
[](https://www.gnu.org/licenses/gpl-3.0.en.html)
|
||||
|
||||
**3X-UI** — یک پنل کنترل پیشرفته مبتنی بر وب با کد باز که برای مدیریت سرور Xray-core طراحی شده است. این پنل یک رابط کاربری آسان برای پیکربندی و نظارت بر پروتکلهای مختلف VPN و پراکسی ارائه میدهد.
|
||||
|
||||
836
README.md
@ -1,56 +1,808 @@
|
||||
[English](/README.md) | [فارسی](/README.fa_IR.md) | [العربية](/README.ar_EG.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构建------------------------------**
|
||||
|
||||
[](https://github.com/MHSanaei/3x-ui/releases)
|
||||
[](https://github.com/MHSanaei/3x-ui/actions)
|
||||
[](#)
|
||||
[](https://github.com/MHSanaei/3x-ui/releases/latest)
|
||||
|
||||
[](https://github.com/xeefei/3x-ui/releases)
|
||||
[](https://github.com/xeefei/3x-ui/actions)
|
||||
[](#)
|
||||
[](https://github.com/xeefei/3x-ui/releases/latest)
|
||||
[](https://www.gnu.org/licenses/gpl-3.0.en.html)
|
||||
|
||||
**3X-UI** — advanced, open-source web-based control panel designed for managing Xray-core server. It offers a user-friendly interface for configuring and monitoring various VPN and proxy protocols.
|
||||
> **声明:** 此项目仅供个人学习、交流使用,请遵守当地法律法规,勿用于非法用途;请勿用于生产环境。
|
||||
|
||||
> [!IMPORTANT]
|
||||
> This project is only for personal using, please do not use it for illegal purposes, please do not use it in a production environment.
|
||||
> **注意:** 在使用此项目和〔教程〕过程中,若因违反以上声明使用规则而产生的一切后果由使用者自负。
|
||||
|
||||
As an enhanced fork of the original X-UI project, 3X-UI provides improved stability, broader protocol support, and additional features.
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)
|
||||
```
|
||||
|
||||
For full documentation, please visit the [project Wiki](https://github.com/MHSanaei/3x-ui/wiki).
|
||||
|
||||
## A Special Thanks to
|
||||
|
||||
- [alireza0](https://github.com/alireza0/)
|
||||
|
||||
## Acknowledgment
|
||||
|
||||
- [Iran v2ray rules](https://github.com/chocolate4u/Iran-v2ray-rules) (License: **GPL-3.0**): _Enhanced v2ray/xray and v2ray/xray-clients routing rules with built-in Iranian domains and a focus on security and adblocking._
|
||||
- [Russia v2ray rules](https://github.com/runetfreedom/russia-v2ray-rules-dat) (License: **GPL-3.0**): _This repository contains automatically updated V2Ray routing rules based on data on blocked domains and addresses in Russia._
|
||||
|
||||
## Support project
|
||||
|
||||
**If this project is helpful to you, you may wish to give it a**:star2:
|
||||
**如果此项目对你有用,请给一个**:star2:
|
||||
|
||||
<p align="left">
|
||||
<a href="https://buymeacoffee.com/mhsanaei" target="_blank">
|
||||
<a href="https://buymeacoffee.com/xeefeiz" target="_blank">
|
||||
<img src="./media/buymeacoffe.png" alt="Image">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
- USDT (TRC20): `TXncxkvhkDWGts487Pjqq1qT9JmwRUz8CC`
|
||||
- POL (polygon): `0x41C9548675D044c6Bfb425786C765bc37427256A`
|
||||
- LTC (Litecoin): `ltc1q2ach7x6d2zq0n4l0t4zl7d7xe2s6fs7a3vspwv`
|
||||
- 赞助地址(USDT/TRC20):`TYQEmQp1P65u9bG7KPehgJdvuokfb72YkZ`
|
||||
|
||||
## Stargazers over Time
|
||||
## [【3X-UI】中文交流群:https://t.me/XUI_CN](https://t.me/XUI_CN)
|
||||
## [【3X-UI】详细安装流程步骤:https://xeefei.blogspot.com/2025/07/3x-ui.html](https://xeefei.blogspot.com/2025/07/3x-ui.html)
|
||||
|
||||
[](https://starchart.cc/MHSanaei/3x-ui)
|
||||
------------
|
||||
## ✰〔3X-UI优化版〕跟原版3X-UI的区别?✰
|
||||
### 大部分功能基于原版3X-UI进行汉化优化,主要的优化内容如下:
|
||||
#### 1、最大限度地汉化了面板项目,更适合中文宝宝体质,包括:
|
||||
##### ①优化在VPS中进行〔脚本安装过程〕的汉化提示,增加相应的安装中文提示,让中文用户能明白清楚自己安装到了哪个环节?在细节方面,增加了安装成功之后的〔用户设置信息〕提示,在脚本中加入〔面板登录地址〕显示,
|
||||
##### ②管理后台进行了相应的〔图标和按钮〕汉化,让中文宝宝能够看得懂,
|
||||
##### ③安装成功后〔自动更改〕后台管理界面和电报机器人界面默认为〔中文〕,
|
||||
##### ④在管理后台中〔设置证书处〕,增加了acme方式填入路径的提示;
|
||||
#### 2、为了保证登录面板的安全性,脚本强制〔ssh转发〕,
|
||||
#### 3、新增〔设备限制〕功能,可配合脚本中的〔IPlimit〕使用,
|
||||
#### 4、新增〔订阅转换〕功能,进入脚本用选项【25】去安装使用,
|
||||
#### 5、创建了〔3X-UI〕中文交流群,各位中文宝宝可以一起讨论交流;
|
||||
#### 6、管理后台中增加了〔实用导航〕页面,里面包含实用内容;
|
||||
#### 7、优化了后台〔二维码〕显示模式,点击打开会更加丝滑美观;
|
||||
#### 8、在创建reality协议时,更改uTLS指纹默认使用chrome;更改默认目标网站为tesla.com;
|
||||
#### 9、更新README内容添加备份&恢复操作说明,以及更多其他图文介绍;
|
||||
#### 10、管理后台中增加〔端口检测〕和〔网络测速〕,点击可以跳转直达;
|
||||
#### 11、增加了详细的项目〔安装配置教程〕,解决小白用户不懂配置的烦恼。
|
||||
|
||||
------------
|
||||
## ✰你必须要看的【重要安全提示/警告】✰
|
||||
#### 1、请勿使用【http明文模式】登录管理面板,因为明文会造成信息泄露;这个安全问题社区讨论过,
|
||||
#### 2、可使用设置【SSH端口转发功能】去登录面板或安装证书之后用https加密方式登录;两种方式选择其一,
|
||||

|
||||
#### 3、若无域名那就按照脚本提示去做【ssh转发】;有域名则可选择更加安全的【申请安装证书】方式,
|
||||
#### 4、Windows电脑首先通过快捷键【Win + R】调出运行窗口,在里面输入【cmd】打开本地终端服务,
|
||||

|
||||

|
||||

|
||||

|
||||
#### 5、若在搭建之前没有翻墙加密,则【http明文模式】登录面板有很大的信息泄露安全风险,那建议你第一次搭建成功之后,去修改用户/密码,和访问路径,后期则通过搭建好的代理加密访问,
|
||||

|
||||
#### 6、在做【ssh转发】过程中,本地电脑的终端不能关闭,保持打开不能断开;且每一次要登录3X-UI管理后台都要做【ssh转发】,因为关闭之后就失效了。
|
||||

|
||||
#### PS:上述两种方法:【ssh端口转发】或申请安装证书的目的都是为了更安全地登录面板,而至于搭建的其他流程和步骤,都是一样的;如果你已经【申请安装证书】了,并不会受到其他什么额外影响,就不用去折腾【ssh转发】了,直接用 【https://你的域名:端口/路径】 去登录你的面板管理后台就行了。
|
||||
|
||||
------------
|
||||
## ✰如何从其他x-ui版本迁移到〔3X-UI优化版〕?✰
|
||||
#### 1、若你用的是伊朗老哥的原版3X-UI,是可以直接〔覆盖安装〕的,因为〔3X-UI优化版〕是fork了原版3X-UI的项目,基于原有的功能进行优化的,大功能是没有变化的,主要是进行了脚本的〔汉化处理〕,其他诸如数据库文件等位置是没有改变的,所以直接覆盖安装,并不会影响你〔原有节点及配置〕等数据;安装命令如下:
|
||||
```
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/xeefei/3x-ui/master/install.sh)
|
||||
```
|
||||
#### 2、若你之前用的是Docker方式安装,那先进入容器里面/命令:docker exec -it 容器id /bin/sh,再执行以上脚本命令直接【覆盖安装】即可,
|
||||
#### 3、若你用的是之前F佬的x-ui或者其他分支版本,那直接覆盖安装的话,并不能确保一定就能够兼容?建议你先去备份〔数据库〕配置文件,再进行安装〔3X-UI优化版〕。
|
||||
|
||||
|
||||
------------
|
||||
## 安装之前的准备
|
||||
- 购买一台性能还不错的VPS,可通过本页底部链接购买,
|
||||
- PS:若你不想升级系统,则可以跳过此步骤。
|
||||
- 若你需要更新/升级系统,Debian系统可用如下命令:
|
||||
```
|
||||
apt update
|
||||
apt upgrade -y
|
||||
apt dist-upgrade -y
|
||||
apt autoclean
|
||||
apt autoremove -y
|
||||
```
|
||||
- 查看系统当前版本:
|
||||
```
|
||||
cat /etc/debian_version
|
||||
```
|
||||
- 查看内核版本:
|
||||
```
|
||||
uname -r
|
||||
```
|
||||
- 列出所有内核:
|
||||
```
|
||||
dpkg --list | grep linux-image
|
||||
```
|
||||
- 更新完成后执行重新引导:
|
||||
```
|
||||
update-grub
|
||||
```
|
||||
- 完成以上步骤之后输入reboot重启系统
|
||||
|
||||
------------
|
||||
## 【搬瓦工】重装/升级系统之后SSH连不上如何解决?
|
||||
- 【搬瓦工】重装/升级系统会恢复默认22端口,如果需要修改SSH的端口号,您需要进行以下步骤:
|
||||
- 以管理员身份使用默认22端口登录到SSH服务器
|
||||
- 打开SSH服务器的配置文件进行编辑,SSH配置文件通常位于/etc/ssh/sshd_config
|
||||
- 找到"Port"选项,并将其更改为您想要的端口号
|
||||
- Port <新端口号>,请将<新端口号>替换为您想要使用的端口号
|
||||
- 保存文件并退出编辑器
|
||||
- 重启服务器以使更改生效
|
||||
|
||||
------------
|
||||
## 安装 & 升级
|
||||
- 使用3x-ui脚本一般情况下,安装完成创建入站之后,端口是默认关闭的,所以必须进入脚本选择【22】去放行端口
|
||||
- 要使用【自动续签】证书功能,也必须放行【80】端口,保持80端口是打开的,才会每3个月自动续签一次
|
||||
|
||||
- 【全新安装】请执行以下脚本:
|
||||
```
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/xeefei/3x-ui/master/install.sh)
|
||||
```
|
||||
#### 如果执行了上面的代码但是报错,证明你的系统里面没有curl这个软件,请执行以下命令先安装curl软件,安装curl之后再去执行上面代码,
|
||||
```
|
||||
apt update -y&&apt install -y curl&&apt install -y socat
|
||||
```
|
||||
|
||||
- 若要对版本进行升级,可直接通过脚本选择【2】,如下图:
|
||||

|
||||

|
||||
- 在到这一步必须要注意:要保留旧设置的话,需要输入【n】
|
||||

|
||||
|
||||
|
||||
## 安装指定版本
|
||||
|
||||
若要安装指定的版本,请使用以下安装命令。 e.g., ver `v2.4.5`:
|
||||
|
||||
```
|
||||
VERSION=v2.4.5 && bash <(curl -Ls "https://raw.githubusercontent.com/xeefei/3x-ui/$VERSION/install.sh") $VERSION
|
||||
```
|
||||
------------
|
||||
## 若你的VPS默认有防火墙,请在安装完成之后放行指定端口
|
||||
- 放行【面板登录端口】
|
||||
- 放行出入站管理协议端口
|
||||
- 如果要申请安装证书并每3个月【自动续签】证书,请确保80和443端口是放行打开的
|
||||
- 可通过此脚本的第【22】选项去安装防火墙进行管理,如下图:
|
||||

|
||||
- 若要一次性放行多个端口或一整个段的端口,用英文逗号隔开。
|
||||
#### PS:若你的VPS没有防火墙,则所有端口都是能够ping通的,可自行选择是否进入脚本安装防火墙保证安全,但安装了防火墙必须放行相应端口。
|
||||
|
||||
------------
|
||||
## 安装证书开启https方式实现域名登录访问管理面板/----->>偷自己
|
||||
#### PS:如果不需要以上功能或无域名,可以跳过这步;建议申请证书,
|
||||
##### 1、把自己的域名托管到CF,并解析到自己VPS的IP,不要开启【小云朵】,
|
||||
##### 2、如果要申请安装证书并每3个月【自动续签】证书,请确保80和443端口是放行打开的,
|
||||
##### 3、输入x-ui命令进入面板管理脚本,通过选择第【18】选项去进行安装,
|
||||
##### 4、在安装证书的最后一步,请输入【y】设置面板证书路径,如下图所示:
|
||||

|
||||
##### 5、进入后台【面板设置】—–>【常规】中,会看到脚本已经自动填好了证书公钥、私钥路径,
|
||||
##### 6、点击左上角的【保存】和【重启面板】,即可用自己域名进行登录管理;也可按照后续方法实现【自己偷自己】。
|
||||
|
||||
------------
|
||||
## 登录面板进行【常规】设置
|
||||
### 特别是如果在安装过程中,全部都是默认【回车键】安装的话,用户名/密码/访问路径是随机的,而面板监听端口默认是2053,最好进入面板更改,
|
||||
##### 1、填写自己想要设置的【面板监听端口】,并去登录SSH放行,
|
||||
##### 2、更改自己想要设置的【面板登录访问路径】,后续加上路径登录访问,
|
||||

|
||||
##### 3、其他:安全设定和电报机器人等配置,可自行根据需求去进行设置,
|
||||
##### 4、建议申请证书保护并在【脚本中】设置路径,建议配置电报机器人方便管理,
|
||||

|
||||
##### 5、面板设置【改动保存】之后,都需要点击左上角【重启面板】,才能生效。
|
||||
#### PS:若你在正确完成了上述步骤之后,你没有安装证书的情况下,去用【ssh转发】的方式却不能访问面板,那请检查一下是不是你的浏览器自动默认开启了https模式,需要手动调整一下改成http方式,把“s”去掉,即可访问成功;或查看一下是不是对应的端口被占用?
|
||||
|
||||
------------
|
||||
## 创建【入站协议】和添加【客户端】,并测试上网
|
||||
##### 1、点击左边【入站列表】,然后【添加入站】,传输方式保持【TCP】不变,尽量选择主流的vless+reality+vision协议组合,
|
||||

|
||||
##### 2、在选择reality安全选项时,偷的域名可以使用默认的,要使用其他的,请替换尽量保持一致就行,比如Apple、Yahoo,VPS所在地区的旅游、学校网站等;如果要实现【偷自己】,请参看后续【如何偷自己】的说明部分;而私钥/公钥部分,可以直接点击下方的【Get New Cert】获取一个随机的,
|
||||
##### 3、在创建reality安全选项过程中,至于其他诸如:PROXY Protocol,HTTP 伪装,TPROXY,External Proxy等等选项,若无特殊要求,保持默认设置即可,不用去动它们,
|
||||

|
||||
##### 4、创建好入站协议之后,默认只有一个客户端,可根据自己需求继续添加;重点:并编辑客户端,选择【Flow流控】为xtls-rprx-vision-udp443,
|
||||

|
||||
##### 5、其他:流量限制,到期时间,客户TG的ID等选项根据自己需求填写,
|
||||

|
||||
##### 6、一定要放行端口之后,确保端口能够ping通,再导入软件,
|
||||
##### 7、点击二维码或者复制链接导入到v2rayN等软件中进行测试。
|
||||
|
||||
------------
|
||||
## 备份与恢复/迁移数据库(以Debian系统为例)
|
||||
#### 一、备份:通过配置好电报管理机器人,并去设置开启【自动备份】,每天凌晨12点会通过VPS管理机器人获取【备份配置】文件,有x-ui.db和config.json两个文件,可自行下载保存到自己电脑里面,
|
||||

|
||||
#### 二、搭建:在新的VPS中全新安装好3x-ui面板,通过脚本放行之前配置的所有端口,一次性放行多个端口请用【英文逗号】分隔,
|
||||
#### 三、若需要安装证书,则提前把域名解析到新的VPS对应的IP,并且去输入x-ui选择第【18】选项去安装,并记录公钥/私钥的路径,无域名则跳过这一步,
|
||||
#### 四、恢复:SSH登录服务器找到/etc/x-ui/x-ui.db和/usr/local/x-ui/bin/config.json文件位置,上传之前的两个备份文件,进行覆盖,
|
||||

|
||||
##### PS:把之前通过自动备份下载得到的两个文件上传覆盖掉旧文件,重启3x-ui面板即可【迁移成功】;即使迁移过程中出现问题,你是有备份文件的,不用担心,多试几次。
|
||||

|
||||
#### 五、若安装了证书,去核对/更改一下证书的路径,一般是同一个域名的话,位置在:/root/cert/域名/fullchain.pem,路径是相同的就不用更改,
|
||||
#### 六、重启面板/重启服务器,让上述步骤生效即可,这时可以看到所有配置都是之前自己常用的,包括面板用户名、密码,入站、客户端,电报机器人配置等。
|
||||
|
||||
------------
|
||||
## 安装完成后如何设置调整成【中文界面】?
|
||||
- 方法一:通过管理后台【登录页面】调整,登录时可以选择,如下图:
|
||||

|
||||
- 方法二:通过在管理后台-->【面板设置】中去选择设置,如下图:
|
||||

|
||||
- 【TG机器人】设置中文:通过在管理后台-->【面板设置】-->【机器人配置】中去选择设置,并建议打开数据库备份和登录通知,如下图:
|
||||

|
||||
|
||||
------------
|
||||
## 用3x-ui如何实现【自己偷自己】?
|
||||
- 其实很简单,只要你为面板设置了证书,
|
||||
- 开启了HTTPS登录,就可以将3x-ui自身作为Web Server,
|
||||
- 无需Nginx等,这里给一个示例:
|
||||
- 其中目标网站(Dest)请填写面板监听端口,
|
||||
- 可选域名(SNI)填写面板登录域名,
|
||||
- 如果您使用其他web server(如nginx)等,
|
||||
- 将目标网站改为对应监听端口也可。
|
||||
- 需要说明的是,如果您处于白名单地区,自己“偷”自己并不适合你;
|
||||
- 其次,可选域名一项实际上可以填写任意SNI,只要客户端保持一致即可,不过并不推荐这样做。
|
||||
- 配置方法如下图所示:
|
||||

|
||||
|
||||
------------
|
||||
## 〔子域名〕被墙针对特征
|
||||
#### 网络表现:
|
||||
##### 1、可以Ping通域名和IP地址,
|
||||
##### 2、子域名无法打开3X-UI管理界面,
|
||||
##### 3、什么都正常就是不能上网;
|
||||
|
||||
#### 问题:
|
||||
##### 你的子域名被墙针对了:无法上网!
|
||||
|
||||
#### 解决方案:
|
||||
##### 1、更换为新的子域名,
|
||||
##### 2、解析新的子域名到VPS的IP,
|
||||
##### 3、重新去安装新证书,
|
||||
##### 4、重启3X-UI和服务器,
|
||||
##### 5、重新去获取链接并测试上网。
|
||||
#### PS:若通过以上步骤还是不能正常上网,则重装VPS服务器OS系统,以及3X-UI面板全部重新安装,之后就正常了!
|
||||
|
||||
------------
|
||||
## 用3x-ui中文版如何开启【设备限制】功能?
|
||||
##### 1、进入后台在【添加入站】的时候,弹出来的页面就能有【设备数量】输入框,
|
||||

|
||||
##### 2、通过步骤1设置完成后,在后台的【入站列表】页面也有对应的同步数据显示。
|
||||

|
||||
##### 3、具体要查看【设备限制】功能的封禁情况,就进入〔3X-UI中文版〕后台用日志查看。
|
||||

|
||||
##### 4、以下图片里面,详细阐述了我们的〔设备限制〕功能,跟3X-UI原本就有的〔IP Limit〕之间的区别对比。
|
||||

|
||||
|
||||
------------
|
||||
## 用3x-ui如何开启【每月流量自动重置】?
|
||||
##### 1、进入后台的【入站列表】,选择需要设置的【客户端】,
|
||||

|
||||
##### 2、要注意是编辑【入站】下面的【客户端】,才会有效果,
|
||||
##### 2、并不是编辑【入站】,所以不要弄错对象,如下图所示:
|
||||

|
||||
|
||||
|
||||
------------
|
||||
## 在自己的VPS服务器部署【订阅转换】功能
|
||||
### 如何把vless/vmess等协议转换成Clash/Surge等软件支持的格式?
|
||||
##### 1、进入脚本输入x-ui命令调取面板,选择第【25】选项安装订阅转换模块,
|
||||
##### 2、等待安装【订阅转换】成功之后,访问地址:https://你的域名:15268 ,
|
||||

|
||||
##### 3、因为在转换过程中需要调取后端API,所以请确保端口 8000 和 15268 是打开放行的,
|
||||
##### 4、直接复制脚本中提供的【登录地址】,进入后台,点击【节点列表】,如下图:
|
||||

|
||||
##### 5、接下来点击左边侧边栏的【订阅列表】去【添加订阅】,按照下图中去操作,
|
||||

|
||||
##### 6、最后一步,点击【客户端】,即可导入Clash等软件中使用。
|
||||

|
||||

|
||||
|
||||
------------
|
||||
## 常见的翻墙软件/工具:
|
||||
- [1、Windows系统v2rayN:https://github.com/2dust/v2rayN](https://github.com/2dust/v2rayN)
|
||||
- [2、安卓手机版【v2rayNG】:https://github.com/2dust/v2rayNG](https://github.com/2dust/v2rayNG)
|
||||
- [3、苹果手机IOS【小火箭】:https://apple02.com/(自己购买)](https://apple02.com/)
|
||||
- [4、苹果MacOS电脑【Clash Verge】:https://github.com/clash-verge-rev/clash-verge-rev/releases](https://github.com/clash-verge-rev/clash-verge-rev/releases)
|
||||
[或v2rayN:https://github.com/2dust/v2rayN](https://github.com/2dust/v2rayN)
|
||||
|
||||
------------
|
||||
## 如何保护自己的IP不被墙被封?
|
||||
##### 1、使用的代理协议要安全,加密是必备,推荐使用vless+reality+vision协议组合,
|
||||
##### 2、因为有时节点会共享,在不同的地区,多个省份之间不要共同连接同一个IP,
|
||||
##### 3、连接同一个IP就算了,不要同一个端口,不要同IP+同端口到处漫游,要分开,
|
||||
##### 4、同一台VPS,不要在一天内一直大流量去下载东西使用,不要流量过高要切换,
|
||||
##### 5、创建【入站协议】的时候,尽量用【高位端口】,比如40000--65000之间的端口号。
|
||||
#### 提醒:为什么在特殊时期,比如:两会,春节等被封得最严重最惨?
|
||||
##### 尼玛同一个IP+同一个端口号,多个省份去漫游,跟开飞机场一样!不封你,封谁的IP和端口?
|
||||
#### 总结:不要多终端/多省份/多个朋友/共同使用同一个IP和端口号!使用3x-ui多创建几个【入站】,
|
||||
#### 多做几条备用,各用各的!各行其道才比较安全!GFW的思维模式是干掉机场,机场的特征个人用户不要去沾染,自然IP就保护好了。
|
||||
|
||||
------------
|
||||
## SSL 认证
|
||||
|
||||
<details>
|
||||
<summary>点击查看 SSL 认证</summary>
|
||||
|
||||
### ACME
|
||||
|
||||
要使用 ACME 管理 SSL 证书:
|
||||
|
||||
1. 确保您的域名已正确解析到服务器,
|
||||
2. 输入“x-ui”命令并选择“SSL 证书管理”,
|
||||
3. 您将看到以下选项:
|
||||
|
||||
- **获取证书** ----获取SSL证书
|
||||
- **吊销证书** ----吊销现有的SSL证书
|
||||
- **续签证书** ----强制续签SSL证书
|
||||
- **显示所有证书** ----显示服务器中所有能用的证书
|
||||
- **设置面板证书路径** ----指定面板要使用的证书
|
||||
|
||||
|
||||
### Certbot
|
||||
|
||||
安装和使用 Certbot:
|
||||
|
||||
```sh
|
||||
apt-get install certbot -y
|
||||
certbot certonly --standalone --agree-tos --register-unsafely-without-email -d yourdomain.com
|
||||
certbot renew --dry-run
|
||||
```
|
||||
|
||||
### Cloudflare
|
||||
|
||||
管理脚本具有用于 Cloudflare 的内置 SSL 证书应用程序。若要使用此脚本申请证书,需要满足以下条件:
|
||||
|
||||
- Cloudflare 邮箱地址
|
||||
- Cloudflare Global API Key
|
||||
- 域名已通过 cloudflare 解析到当前服务器
|
||||
|
||||
**如何获取 Cloudflare全局API密钥:**
|
||||
|
||||
1. 在终端中输入“x-ui”命令,然后选择“CF SSL 证书”。
|
||||
2. 访问链接: [Cloudflare API Tokens](https://dash.cloudflare.com/profile/api-tokens).
|
||||
3. 点击“查看全局 API 密钥”(如下图所示):
|
||||

|
||||
4. 您可能需要重新验证您的帐户。之后,将显示 API 密钥(请参见下面的屏幕截图):
|
||||

|
||||
|
||||
使用时,只需输入您的“域名”、“电子邮件”和“API KEY”即可。示意图如下:
|
||||

|
||||
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## 手动安装 & 升级
|
||||
|
||||
<details>
|
||||
<summary>点击查看 手动安装 & 升级</summary>
|
||||
|
||||
#### 使用
|
||||
|
||||
1. 若要将最新版本的压缩包直接下载到服务器,请运行以下命令:
|
||||
|
||||
```sh
|
||||
ARCH=$(uname -m)
|
||||
case "${ARCH}" in
|
||||
x86_64 | x64 | amd64) XUI_ARCH="amd64" ;;
|
||||
i*86 | x86) XUI_ARCH="386" ;;
|
||||
armv8* | armv8 | arm64 | aarch64) XUI_ARCH="arm64" ;;
|
||||
armv7* | armv7) XUI_ARCH="armv7" ;;
|
||||
armv6* | armv6) XUI_ARCH="armv6" ;;
|
||||
armv5* | armv5) XUI_ARCH="armv5" ;;
|
||||
s390x) echo 's390x' ;;
|
||||
*) XUI_ARCH="amd64" ;;
|
||||
esac
|
||||
|
||||
|
||||
wget https://github.com/xeefei/3x-ui/releases/latest/download/x-ui-linux-${XUI_ARCH}.tar.gz
|
||||
```
|
||||
|
||||
2. 下载压缩包后,执行以下命令安装或升级 x-ui:
|
||||
|
||||
```sh
|
||||
ARCH=$(uname -m)
|
||||
case "${ARCH}" in
|
||||
x86_64 | x64 | amd64) XUI_ARCH="amd64" ;;
|
||||
i*86 | x86) XUI_ARCH="386" ;;
|
||||
armv8* | armv8 | arm64 | aarch64) XUI_ARCH="arm64" ;;
|
||||
armv7* | armv7) XUI_ARCH="armv7" ;;
|
||||
armv6* | armv6) XUI_ARCH="armv6" ;;
|
||||
armv5* | armv5) XUI_ARCH="armv5" ;;
|
||||
s390x) echo 's390x' ;;
|
||||
*) XUI_ARCH="amd64" ;;
|
||||
esac
|
||||
|
||||
cd /root/
|
||||
rm -rf x-ui/ /usr/local/x-ui/ /usr/bin/x-ui
|
||||
tar zxvf x-ui-linux-${XUI_ARCH}.tar.gz
|
||||
chmod +x x-ui/x-ui x-ui/bin/xray-linux-* x-ui/x-ui.sh
|
||||
cp x-ui/x-ui.sh /usr/bin/x-ui
|
||||
cp -f x-ui/x-ui.service /etc/systemd/system/
|
||||
mv x-ui/ /usr/local/
|
||||
systemctl daemon-reload
|
||||
systemctl enable x-ui
|
||||
systemctl restart x-ui
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## 通过Docker安装
|
||||
|
||||
<details>
|
||||
<summary>点击查看 通过Docker安装</summary>
|
||||
|
||||
#### 使用
|
||||
|
||||
|
||||
1. **安装Docker**
|
||||
|
||||
```sh
|
||||
bash <(curl -sSL https://get.docker.com)
|
||||
```
|
||||
|
||||
|
||||
2. **克隆项目仓库**
|
||||
|
||||
```sh
|
||||
git clone https://github.com/xeefei/3x-ui.git
|
||||
cd 3x-ui
|
||||
```
|
||||
|
||||
3. **启动服务**:
|
||||
|
||||
```sh
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
添加 ```--pull always``` 标志使 docker 在拉取更新的镜像时自动重新创建容器。有关更多信息,请参阅:https://docs.docker.com/reference/cli/docker/container/run/#pull
|
||||
|
||||
**或**
|
||||
|
||||
```sh
|
||||
docker run -itd \
|
||||
-e XRAY_VMESS_AEAD_FORCED=false \
|
||||
-v $PWD/db/:/etc/x-ui/ \
|
||||
-v $PWD/cert/:/root/cert/ \
|
||||
--network=host \
|
||||
--restart=unless-stopped \
|
||||
--name 3x-ui \
|
||||
ghcr.io/xeefei/3x-ui:latest
|
||||
```
|
||||
|
||||
4. **更新至最新版本**
|
||||
|
||||
```sh
|
||||
cd 3x-ui
|
||||
docker compose down
|
||||
docker compose pull 3x-ui
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
5. **从Docker中删除3x-ui **
|
||||
|
||||
```sh
|
||||
docker stop 3x-ui
|
||||
docker rm 3x-ui
|
||||
cd --
|
||||
rm -r 3x-ui
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## 建议使用的操作系统
|
||||
|
||||
- Ubuntu 20.04+
|
||||
- Debian 11+
|
||||
- CentOS 8+
|
||||
- OpenEuler 22.03+
|
||||
- Fedora 36+
|
||||
- Arch Linux
|
||||
- Manjaro
|
||||
- Armbian
|
||||
- AlmaLinux 8.0+
|
||||
- Rocky Linux 8+
|
||||
- Oracle Linux 8+
|
||||
- OpenSUSE Tubleweed
|
||||
- Amazon Linux 2023
|
||||
|
||||
------------
|
||||
## 支持的架构和设备
|
||||
<details>
|
||||
<summary>点击查看 支持的架构和设备</summary>
|
||||
|
||||
我们的平台提供与各种架构和设备的兼容性,确保在各种计算环境中的灵活性。以下是我们支持的关键架构:
|
||||
|
||||
- **amd64**: 这种流行的架构是个人计算机和服务器的标准,可以无缝地适应大多数现代操作系统。
|
||||
|
||||
- **x86 / i386**: 这种架构在台式机和笔记本电脑中被广泛采用,得到了众多操作系统和应用程序的广泛支持,包括但不限于 Windows、macOS 和 Linux 系统。
|
||||
|
||||
- **armv8 / arm64 / aarch64**: 这种架构专为智能手机和平板电脑等当代移动和嵌入式设备量身定制,以 Raspberry Pi 4、Raspberry Pi 3、Raspberry Pi Zero 2/Zero 2 W、Orange Pi 3 LTS 等设备为例。
|
||||
|
||||
- **armv7 / arm / arm32**: 作为较旧的移动和嵌入式设备的架构,它仍然广泛用于Orange Pi Zero LTS、Orange Pi PC Plus、Raspberry Pi 2等设备。
|
||||
|
||||
- **armv6 / arm / arm32**: 这种架构面向非常老旧的嵌入式设备,虽然不太普遍,但仍在使用中。Raspberry Pi 1、Raspberry Pi Zero/Zero W 等设备都依赖于这种架构。
|
||||
|
||||
- **armv5 / arm / arm32**: 它是一种主要与早期嵌入式系统相关的旧架构,目前不太常见,但仍可能出现在早期 Raspberry Pi 版本和一些旧智能手机等传统设备中。
|
||||
</details>
|
||||
|
||||
------------
|
||||
## Languages
|
||||
|
||||
- English(英语)
|
||||
- Farsi(伊朗语)
|
||||
- Simplified Chinese(简体中文)
|
||||
- Traditional Chinese(繁体中文)
|
||||
- Russian(俄语)
|
||||
- Vietnamese(越南语)
|
||||
- Spanish(西班牙语)
|
||||
- Indonesian (印度尼西亚语)
|
||||
- Ukrainian(乌克兰语)
|
||||
- Turkish(土耳其语)
|
||||
- Português (葡萄牙语)
|
||||
|
||||
------------
|
||||
## 项目特点
|
||||
|
||||
- 系统状态查看与监控
|
||||
- 可搜索所有入站和客户端信息
|
||||
- 深色/浅色主题随意切换
|
||||
- 支持多用户和多协议
|
||||
- 支持多种协议,包括 VMess、VLESS、Trojan、Shadowsocks、Dokodemo-door、Socks、HTTP、wireguard
|
||||
- 支持 XTLS 原生协议,包括 RPRX-Direct、Vision、REALITY
|
||||
- 流量统计、流量限制、过期时间限制
|
||||
- 可自定义的 Xray配置模板
|
||||
- 支持HTTPS访问面板(自备域名+SSL证书)
|
||||
- 支持一键式SSL证书申请和自动续签证书
|
||||
- 更多高级配置项目请参考面板去进行设定
|
||||
- 修复了 API 路由(用户设置将使用 API 创建)
|
||||
- 支持通过面板中提供的不同项目更改配置。
|
||||
- 支持从面板导出/导入数据库
|
||||
|
||||
## 默认面板设置
|
||||
|
||||
<details>
|
||||
|
||||
<summary>点击查看 默认设置</summary>
|
||||
|
||||
### 默认信息
|
||||
|
||||
- **端口**
|
||||
- 2053
|
||||
- **用户名 & 密码 & 访问路径**
|
||||
- 当您跳过设置时,这些信息会随机生成,
|
||||
- 您也可以在安装的时候自定义访问路径。
|
||||
- **数据库路径:**
|
||||
- /etc/x-ui/x-ui.db
|
||||
- **Xray 配置路径:**
|
||||
- /usr/local/x-ui/bin/config.json
|
||||
- **面板链接(无SSL):**
|
||||
- http://ip:2053/访问路径/panel
|
||||
- **面板链接(有SSL):**
|
||||
- https://你的域名:2053/访问路径/panel
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## [WARP 配置](https://gitlab.com/fscarmen/warp)
|
||||
|
||||
<details>
|
||||
<summary>点击查看 WARP 配置</summary>
|
||||
|
||||
#### 使用
|
||||
|
||||
**对于版本 `v2.1.0` 及更高版本:**
|
||||
|
||||
WARP 是内置的,无需额外安装;只需在面板中打开必要的配置即可。
|
||||
|
||||
**如果要在 v2.1.0 之前使用 WARP 路由**,请按照以下步骤操作:
|
||||
|
||||
**1.** 在 **SOCKS Proxy Mode** 模式中安装Wrap
|
||||
|
||||
- **Account Type (free, plus, team):** Choose the appropriate account type.
|
||||
- **Enable/Disable WireProxy:** Toggle WireProxy on or off.
|
||||
- **Uninstall WARP:** Remove the WARP application.
|
||||
|
||||
**2.** 如果您已经安装了 warp,您可以使用以下命令卸载:
|
||||
|
||||
```sh
|
||||
warp u
|
||||
```
|
||||
|
||||
**3.** 在面板中打开您需要的配置
|
||||
|
||||
配置:
|
||||
|
||||
- Block Ads
|
||||
- Route Google, Netflix, Spotify, and OpenAI (ChatGPT) traffic to WARP
|
||||
- Fix Google 403 error
|
||||
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## IP 限制
|
||||
|
||||
<details>
|
||||
<summary>点击查看 IP 限制</summary>
|
||||
|
||||
#### 使用
|
||||
|
||||
**注意:** 使用 IP 隧道时,IP 限制无法正常工作。
|
||||
|
||||
- 对于 `v1.6.1`之前的版本 :
|
||||
|
||||
- IP 限制 已被集成在面板中。
|
||||
|
||||
- 对于 `v1.7.0` 以及更新的版本:
|
||||
|
||||
- 要使 IP 限制正常工作,您需要按照以下步骤安装 fail2ban 及其所需的文件:
|
||||
|
||||
1. 使用面板内置的 `x-ui` 指令
|
||||
2. 选择 `IP Limit Management`.
|
||||
3. 根据您的需要选择合适的选项。
|
||||
|
||||
- 确保您的 Xray 配置上有 ./access.log 。在 v2.1.3 之后,我们有一个选项。
|
||||
|
||||
```sh
|
||||
"log": {
|
||||
"access": "./access.log",
|
||||
"dnsLog": false,
|
||||
"loglevel": "warning"
|
||||
},
|
||||
```
|
||||
- 您需要在Xray配置中手动设置〔访问日志〕的路径。
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## Telegram 机器人
|
||||
|
||||
<details>
|
||||
<summary>点击查看 Telegram 机器人</summary>
|
||||
|
||||
#### 使用
|
||||
|
||||
Web 面板通过 Telegram Bot 支持每日流量、面板登录、数据库备份、系统状态、客户端信息等通知和功能。要使用机器人,您需要在面板中设置机器人相关参数,包括:
|
||||
|
||||
- 电报令牌
|
||||
- 管理员聊天 ID
|
||||
- 通知时间(cron 语法)
|
||||
- 到期日期通知
|
||||
- 流量上限通知
|
||||
- 数据库备份
|
||||
- CPU 负载通知
|
||||
|
||||
|
||||
**参考:**
|
||||
|
||||
- `30 \* \* \* \* \*` - 在每个点的 30 秒处通知
|
||||
- `0 \*/10 \* \* \* \*` - 每 10 分钟的第一秒通知
|
||||
- `@hourly` - 每小时通知
|
||||
- `@daily` - 每天通知 (00:00)
|
||||
- `@weekly` - 每周通知
|
||||
- `@every 8h` - 每8小时通知
|
||||
|
||||
### Telegram Bot 功能
|
||||
|
||||
- 定期报告
|
||||
- 登录通知
|
||||
- CPU 阈值通知
|
||||
- 提前报告的过期时间和流量阈值
|
||||
- 如果将客户的电报用户名添加到用户的配置中,则支持客户端报告菜单
|
||||
- 支持使用UUID(VMESS/VLESS)或密码(TROJAN)搜索报文流量报告 - 匿名
|
||||
- 基于菜单的机器人
|
||||
- 通过电子邮件搜索客户端(仅限管理员)
|
||||
- 检查所有入库
|
||||
- 检查服务器状态
|
||||
- 检查耗尽的用户
|
||||
- 根据请求和定期报告接收备份
|
||||
- 多语言机器人
|
||||
|
||||
### 注册 Telegram bot
|
||||
|
||||
- 与 [Botfather](https://t.me/BotFather) 对话:
|
||||

|
||||
|
||||
- 使用 /newbot 创建新机器人:你需要提供机器人名称以及用户名,注意名称中末尾要包含“bot”
|
||||

|
||||
|
||||
- 启动您刚刚创建的机器人。可以在此处找到机器人的链接。
|
||||

|
||||
|
||||
- 输入您的面板并配置 Telegram 机器人设置,如下所示:
|
||||

|
||||
|
||||
在输入字段编号 3 中输入机器人令牌。
|
||||
在输入字段编号 4 中输入用户 ID。具有此 id 的 Telegram 帐户将是机器人管理员。 (您可以输入多个,只需将它们用“ ,”分开即可)
|
||||
|
||||
- 如何获取TG ID? 使用 [bot](https://t.me/useridinfobot), 启动机器人,它会给你 Telegram 用户 ID。
|
||||

|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## API 路由
|
||||
|
||||
<details>
|
||||
<summary>点击查看 API 路由</summary>
|
||||
|
||||
#### 使用
|
||||
|
||||
- `/login` 使用 `POST` 用户名称 & 密码: `{username: '', password: ''}` 登录
|
||||
- `/panel/api/inbounds` 以下操作的基础:
|
||||
|
||||
| 方法 | 路径 | 操作 |
|
||||
| :----: | ---------------------------------- | ------------------------------------------- |
|
||||
| `GET` | `"/list"` | 获取所有入站 |
|
||||
| `GET` | `"/get/:id"` | 获取所有入站以及inbound.id |
|
||||
| `GET` | `"/getClientTraffics/:email"` | 通过电子邮件获取客户端流量 |
|
||||
| `GET` | `"/getClientTrafficsById/:id"` | 通过用户ID获取客户端流量 |
|
||||
| `GET` | `"/createbackup"` | Telegram 机器人向管理员发送备份 |
|
||||
| `POST` | `"/add"` | 添加入站 |
|
||||
| `POST` | `"/del/:id"` | 删除入站 |
|
||||
| `POST` | `"/update/:id"` | 更新入站 |
|
||||
| `POST` | `"/clientIps/:email"` | 客户端 IP 地址 |
|
||||
| `POST` | `"/clearClientIps/:email"` | 清除客户端 IP 地址 |
|
||||
| `POST` | `"/addClient"` | 将客户端添加到入站 |
|
||||
| `POST` | `"/:id/delClient/:clientId"` | 通过 clientId\* 删除客户端 |
|
||||
| `POST` | `"/updateClient/:clientId"` | 通过 clientId\* 更新客户端 |
|
||||
| `POST` | `"/:id/resetClientTraffic/:email"` | 重置客户端的流量 |
|
||||
| `POST` | `"/resetAllTraffics"` | 重置所有入站的流量 |
|
||||
| `POST` | `"/resetAllClientTraffics/:id"` | 重置入站中所有客户端的流量 |
|
||||
| `POST` | `"/delDepletedClients/:id"` | 删除入站耗尽的客户端 (-1: all) |
|
||||
| `POST` | `"/onlines"` | 获取在线用户 ( 电子邮件列表 ) |
|
||||
|
||||
- 使用`clientId` 项应该填写下列数据:
|
||||
|
||||
- `client.id` for VMESS and VLESS
|
||||
- `client.password` for TROJAN
|
||||
- `client.email` for Shadowsocks
|
||||
|
||||
|
||||
|
||||
- [API 文档](https://documenter.getpostman.com/view/16802678/2s9YkgD5jm)
|
||||
|
||||
- [<img src="https://run.pstmn.io/button.svg" alt="Run In Postman" style="width: 128px; height: 32px;">](https://app.getpostman.com/run-collection/16802678-1a4c9270-ac77-40ed-959a-7aa56dc4a415?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D16802678-1a4c9270-ac77-40ed-959a-7aa56dc4a415%26entityType%3Dcollection%26workspaceId%3D2cd38c01-c851-4a15-a972-f181c23359d9)
|
||||
</details>
|
||||
|
||||
------------
|
||||
## 环境变量
|
||||
|
||||
<details>
|
||||
<summary>点击查看 环境变量</summary>
|
||||
|
||||
#### Usage
|
||||
|
||||
| 变量 | Type | 默认 |
|
||||
| -------------- | :--------------------------------------------: | :------------ |
|
||||
| XUI_LOG_LEVEL | `"debug"` \| `"info"` \| `"warn"` \| `"error"` | `"info"` |
|
||||
| XUI_DEBUG | `boolean` | `false` |
|
||||
| XUI_BIN_FOLDER | `string` | `"bin"` |
|
||||
| XUI_DB_FOLDER | `string` | `"/etc/x-ui"` |
|
||||
| XUI_LOG_FOLDER | `string` | `"/var/log"` |
|
||||
|
||||
例子:
|
||||
|
||||
```sh
|
||||
XUI_BIN_FOLDER="bin" XUI_DB_FOLDER="/etc/x-ui" go build main.go
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## 预览
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
------------
|
||||
## 广告赞助
|
||||
- 如果你觉得本项目对你有用,而且你也恰巧有这方面的需求,你也可以选择通过我的购买链接赞助我。
|
||||
- [1、搬瓦工GIA高端线路,仅推荐购买GIA套餐:https://bandwagonhost.com/aff.php?aff=75015](https://bandwagonhost.com/aff.php?aff=75015)
|
||||
- [2、Dmit高端GIA线路:https://www.dmit.io/aff.php?aff=9326](https://www.dmit.io/aff.php?aff=9326)
|
||||
- [3、白丝云【4837线路】实惠量大管饱:https://cloudsilk.io/aff.php?aff=706](https://cloudsilk.io/aff.php?aff=706)
|
||||
|
||||
------------
|
||||
## 特别感谢
|
||||
|
||||
- [MHSanaei](https://github.com/MHSanaei/)
|
||||
- [alireza0](https://github.com/alireza0/)
|
||||
- [FranzKafkaYu](https://github.com/FranzKafkaYu/)
|
||||
- [vaxilu](https://github.com/vaxilu/)
|
||||
|
||||
------------
|
||||
## 致谢
|
||||
|
||||
- [Iran v2ray rules](https://github.com/chocolate4u/Iran-v2ray-rules) (License: **GPL-3.0**): _Enhanced v2ray/xray and v2ray/xray-clients routing rules with built-in Iranian domains and a focus on security and adblocking._
|
||||
- [Vietnam Adblock rules](https://github.com/vuong2023/vn-v2ray-rules) (License: **GPL-3.0**): _A hosted domain hosted in Vietnam and blocklist with the most efficiency for Vietnamese._
|
||||
|
||||
------------
|
||||
## Star 趋势
|
||||
|
||||
[](https://starchart.cc/xeefei/3x-ui)
|
||||
|
||||
808
README.zh.md
Normal file
@ -0,0 +1,808 @@
|
||||
<p align="center"><a href="#"><img src="./media/3X-UI.png" alt="Image"></a></p>
|
||||
|
||||
**---------------------------------------一个更好的面板 • 基于Xray Core构建------------------------------**
|
||||
|
||||
|
||||
[](https://github.com/xeefei/3x-ui/releases)
|
||||
[](https://github.com/xeefei/3x-ui/actions)
|
||||
[](#)
|
||||
[](https://github.com/xeefei/3x-ui/releases/latest)
|
||||
[](https://www.gnu.org/licenses/gpl-3.0.en.html)
|
||||
|
||||
> **声明:** 此项目仅供个人学习、交流使用,请遵守当地法律法规,勿用于非法用途;请勿用于生产环境。
|
||||
|
||||
> **注意:** 在使用此项目和〔教程〕过程中,若因违反以上声明使用规则而产生的一切后果由使用者自负。
|
||||
|
||||
**如果此项目对你有用,请给一个**:star2:
|
||||
|
||||
<p align="left">
|
||||
<a href="https://buymeacoffee.com/xeefeiz" target="_blank">
|
||||
<img src="./media/buymeacoffe.png" alt="Image">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
- 赞助地址(USDT/TRC20):`TYQEmQp1P65u9bG7KPehgJdvuokfb72YkZ`
|
||||
|
||||
## [【3X-UI】中文交流群:https://t.me/XUI_CN](https://t.me/XUI_CN)
|
||||
## [【3X-UI】详细安装流程步骤:https://xeefei.blogspot.com/2025/07/3x-ui.html](https://xeefei.blogspot.com/2025/07/3x-ui.html)
|
||||
|
||||
------------
|
||||
## ✰〔3X-UI优化版〕跟原版3X-UI的区别?✰
|
||||
### 大部分功能基于原版3X-UI进行汉化优化,主要的优化内容如下:
|
||||
#### 1、最大限度地汉化了面板项目,更适合中文宝宝体质,包括:
|
||||
##### ①优化在VPS中进行〔脚本安装过程〕的汉化提示,增加相应的安装中文提示,让中文用户能明白清楚自己安装到了哪个环节?在细节方面,增加了安装成功之后的〔用户设置信息〕提示,在脚本中加入〔面板登录地址〕显示,
|
||||
##### ②管理后台进行了相应的〔图标和按钮〕汉化,让中文宝宝能够看得懂,
|
||||
##### ③安装成功后〔自动更改〕后台管理界面和电报机器人界面默认为〔中文〕,
|
||||
##### ④在管理后台中〔设置证书处〕,增加了acme方式填入路径的提示;
|
||||
#### 2、为了保证登录面板的安全性,脚本强制〔ssh转发〕,
|
||||
#### 3、新增〔设备限制〕功能,可配合脚本中的〔IPlimit〕使用,
|
||||
#### 4、新增〔订阅转换〕功能,进入脚本用选项【25】去安装使用,
|
||||
#### 5、创建了〔3X-UI〕中文交流群,各位中文宝宝可以一起讨论交流;
|
||||
#### 6、管理后台中增加了〔实用导航〕页面,里面包含实用内容;
|
||||
#### 7、优化了后台〔二维码〕显示模式,点击打开会更加丝滑美观;
|
||||
#### 8、在创建reality协议时,更改uTLS指纹默认使用chrome;更改默认目标网站为tesla.com;
|
||||
#### 9、更新README内容添加备份&恢复操作说明,以及更多其他图文介绍;
|
||||
#### 10、管理后台中增加〔端口检测〕和〔网络测速〕,点击可以跳转直达;
|
||||
#### 11、增加了详细的项目〔安装配置教程〕,解决小白用户不懂配置的烦恼。
|
||||
|
||||
------------
|
||||
## ✰你必须要看的【重要安全提示/警告】✰
|
||||
#### 1、请勿使用【http明文模式】登录管理面板,因为明文会造成信息泄露;这个安全问题社区讨论过,
|
||||
#### 2、可使用设置【SSH端口转发功能】去登录面板或安装证书之后用https加密方式登录;两种方式选择其一,
|
||||

|
||||
#### 3、若无域名那就按照脚本提示去做【ssh转发】;有域名则可选择更加安全的【申请安装证书】方式,
|
||||
#### 4、Windows电脑首先通过快捷键【Win + R】调出运行窗口,在里面输入【cmd】打开本地终端服务,
|
||||

|
||||

|
||||

|
||||

|
||||
#### 5、若在搭建之前没有翻墙加密,则【http明文模式】登录面板有很大的信息泄露安全风险,那建议你第一次搭建成功之后,去修改用户/密码,和访问路径,后期则通过搭建好的代理加密访问,
|
||||

|
||||
#### 6、在做【ssh转发】过程中,本地电脑的终端不能关闭,保持打开不能断开;且每一次要登录3X-UI管理后台都要做【ssh转发】,因为关闭之后就失效了。
|
||||

|
||||
#### PS:上述两种方法:【ssh端口转发】或申请安装证书的目的都是为了更安全地登录面板,而至于搭建的其他流程和步骤,都是一样的;如果你已经【申请安装证书】了,并不会受到其他什么额外影响,就不用去折腾【ssh转发】了,直接用 【https://你的域名:端口/路径】 去登录你的面板管理后台就行了。
|
||||
|
||||
------------
|
||||
## ✰如何从其他x-ui版本迁移到〔3X-UI优化版〕?✰
|
||||
#### 1、若你用的是伊朗老哥的原版3X-UI,是可以直接〔覆盖安装〕的,因为〔3X-UI优化版〕是fork了原版3X-UI的项目,基于原有的功能进行优化的,大功能是没有变化的,主要是进行了脚本的〔汉化处理〕,其他诸如数据库文件等位置是没有改变的,所以直接覆盖安装,并不会影响你〔原有节点及配置〕等数据;安装命令如下:
|
||||
```
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/xeefei/3x-ui/master/install.sh)
|
||||
```
|
||||
#### 2、若你之前用的是Docker方式安装,那先进入容器里面/命令:docker exec -it 容器id /bin/sh,再执行以上脚本命令直接【覆盖安装】即可,
|
||||
#### 3、若你用的是之前F佬的x-ui或者其他分支版本,那直接覆盖安装的话,并不能确保一定就能够兼容?建议你先去备份〔数据库〕配置文件,再进行安装〔3X-UI优化版〕。
|
||||
|
||||
|
||||
------------
|
||||
## 安装之前的准备
|
||||
- 购买一台性能还不错的VPS,可通过本页底部链接购买,
|
||||
- PS:若你不想升级系统,则可以跳过此步骤。
|
||||
- 若你需要更新/升级系统,Debian系统可用如下命令:
|
||||
```
|
||||
apt update
|
||||
apt upgrade -y
|
||||
apt dist-upgrade -y
|
||||
apt autoclean
|
||||
apt autoremove -y
|
||||
```
|
||||
- 查看系统当前版本:
|
||||
```
|
||||
cat /etc/debian_version
|
||||
```
|
||||
- 查看内核版本:
|
||||
```
|
||||
uname -r
|
||||
```
|
||||
- 列出所有内核:
|
||||
```
|
||||
dpkg --list | grep linux-image
|
||||
```
|
||||
- 更新完成后执行重新引导:
|
||||
```
|
||||
update-grub
|
||||
```
|
||||
- 完成以上步骤之后输入reboot重启系统
|
||||
|
||||
------------
|
||||
## 【搬瓦工】重装/升级系统之后SSH连不上如何解决?
|
||||
- 【搬瓦工】重装/升级系统会恢复默认22端口,如果需要修改SSH的端口号,您需要进行以下步骤:
|
||||
- 以管理员身份使用默认22端口登录到SSH服务器
|
||||
- 打开SSH服务器的配置文件进行编辑,SSH配置文件通常位于/etc/ssh/sshd_config
|
||||
- 找到"Port"选项,并将其更改为您想要的端口号
|
||||
- Port <新端口号>,请将<新端口号>替换为您想要使用的端口号
|
||||
- 保存文件并退出编辑器
|
||||
- 重启服务器以使更改生效
|
||||
|
||||
------------
|
||||
## 安装 & 升级
|
||||
- 使用3x-ui脚本一般情况下,安装完成创建入站之后,端口是默认关闭的,所以必须进入脚本选择【22】去放行端口
|
||||
- 要使用【自动续签】证书功能,也必须放行【80】端口,保持80端口是打开的,才会每3个月自动续签一次
|
||||
|
||||
- 【全新安装】请执行以下脚本:
|
||||
```
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/xeefei/3x-ui/master/install.sh)
|
||||
```
|
||||
#### 如果执行了上面的代码但是报错,证明你的系统里面没有curl这个软件,请执行以下命令先安装curl软件,安装curl之后再去执行上面代码,
|
||||
```
|
||||
apt update -y&&apt install -y curl&&apt install -y socat
|
||||
```
|
||||
|
||||
- 若要对版本进行升级,可直接通过脚本选择【2】,如下图:
|
||||

|
||||

|
||||
- 在到这一步必须要注意:要保留旧设置的话,需要输入【n】
|
||||

|
||||
|
||||
|
||||
## 安装指定版本
|
||||
|
||||
若要安装指定的版本,请使用以下安装命令。 e.g., ver `v2.4.5`:
|
||||
|
||||
```
|
||||
VERSION=v2.4.5 && bash <(curl -Ls "https://raw.githubusercontent.com/xeefei/3x-ui/$VERSION/install.sh") $VERSION
|
||||
```
|
||||
------------
|
||||
## 若你的VPS默认有防火墙,请在安装完成之后放行指定端口
|
||||
- 放行【面板登录端口】
|
||||
- 放行出入站管理协议端口
|
||||
- 如果要申请安装证书并每3个月【自动续签】证书,请确保80和443端口是放行打开的
|
||||
- 可通过此脚本的第【22】选项去安装防火墙进行管理,如下图:
|
||||

|
||||
- 若要一次性放行多个端口或一整个段的端口,用英文逗号隔开。
|
||||
#### PS:若你的VPS没有防火墙,则所有端口都是能够ping通的,可自行选择是否进入脚本安装防火墙保证安全,但安装了防火墙必须放行相应端口。
|
||||
|
||||
------------
|
||||
## 安装证书开启https方式实现域名登录访问管理面板/----->>偷自己
|
||||
#### PS:如果不需要以上功能或无域名,可以跳过这步;建议申请证书,
|
||||
##### 1、把自己的域名托管到CF,并解析到自己VPS的IP,不要开启【小云朵】,
|
||||
##### 2、如果要申请安装证书并每3个月【自动续签】证书,请确保80和443端口是放行打开的,
|
||||
##### 3、输入x-ui命令进入面板管理脚本,通过选择第【18】选项去进行安装,
|
||||
##### 4、在安装证书的最后一步,请输入【y】设置面板证书路径,如下图所示:
|
||||

|
||||
##### 5、进入后台【面板设置】—–>【常规】中,会看到脚本已经自动填好了证书公钥、私钥路径,
|
||||
##### 6、点击左上角的【保存】和【重启面板】,即可用自己域名进行登录管理;也可按照后续方法实现【自己偷自己】。
|
||||
|
||||
------------
|
||||
## 登录面板进行【常规】设置
|
||||
### 特别是如果在安装过程中,全部都是默认【回车键】安装的话,用户名/密码/访问路径是随机的,而面板监听端口默认是2053,最好进入面板更改,
|
||||
##### 1、填写自己想要设置的【面板监听端口】,并去登录SSH放行,
|
||||
##### 2、更改自己想要设置的【面板登录访问路径】,后续加上路径登录访问,
|
||||

|
||||
##### 3、其他:安全设定和电报机器人等配置,可自行根据需求去进行设置,
|
||||
##### 4、建议申请证书保护并在【脚本中】设置路径,建议配置电报机器人方便管理,
|
||||

|
||||
##### 5、面板设置【改动保存】之后,都需要点击左上角【重启面板】,才能生效。
|
||||
#### PS:若你在正确完成了上述步骤之后,你没有安装证书的情况下,去用【ssh转发】的方式却不能访问面板,那请检查一下是不是你的浏览器自动默认开启了https模式,需要手动调整一下改成http方式,把“s”去掉,即可访问成功;或查看一下是不是对应的端口被占用?
|
||||
|
||||
------------
|
||||
## 创建【入站协议】和添加【客户端】,并测试上网
|
||||
##### 1、点击左边【入站列表】,然后【添加入站】,传输方式保持【TCP】不变,尽量选择主流的vless+reality+vision协议组合,
|
||||

|
||||
##### 2、在选择reality安全选项时,偷的域名可以使用默认的,要使用其他的,请替换尽量保持一致就行,比如Apple、Yahoo,VPS所在地区的旅游、学校网站等;如果要实现【偷自己】,请参看后续【如何偷自己】的说明部分;而私钥/公钥部分,可以直接点击下方的【Get New Cert】获取一个随机的,
|
||||
##### 3、在创建reality安全选项过程中,至于其他诸如:PROXY Protocol,HTTP 伪装,TPROXY,External Proxy等等选项,若无特殊要求,保持默认设置即可,不用去动它们,
|
||||

|
||||
##### 4、创建好入站协议之后,默认只有一个客户端,可根据自己需求继续添加;重点:并编辑客户端,选择【Flow流控】为xtls-rprx-vision-udp443,
|
||||

|
||||
##### 5、其他:流量限制,到期时间,客户TG的ID等选项根据自己需求填写,
|
||||

|
||||
##### 6、一定要放行端口之后,确保端口能够ping通,再导入软件,
|
||||
##### 7、点击二维码或者复制链接导入到v2rayN等软件中进行测试。
|
||||
|
||||
------------
|
||||
## 备份与恢复/迁移数据库(以Debian系统为例)
|
||||
#### 一、备份:通过配置好电报管理机器人,并去设置开启【自动备份】,每天凌晨12点会通过VPS管理机器人获取【备份配置】文件,有x-ui.db和config.json两个文件,可自行下载保存到自己电脑里面,
|
||||

|
||||
#### 二、搭建:在新的VPS中全新安装好3x-ui面板,通过脚本放行之前配置的所有端口,一次性放行多个端口请用【英文逗号】分隔,
|
||||
#### 三、若需要安装证书,则提前把域名解析到新的VPS对应的IP,并且去输入x-ui选择第【18】选项去安装,并记录公钥/私钥的路径,无域名则跳过这一步,
|
||||
#### 四、恢复:SSH登录服务器找到/etc/x-ui/x-ui.db和/usr/local/x-ui/bin/config.json文件位置,上传之前的两个备份文件,进行覆盖,
|
||||

|
||||
##### PS:把之前通过自动备份下载得到的两个文件上传覆盖掉旧文件,重启3x-ui面板即可【迁移成功】;即使迁移过程中出现问题,你是有备份文件的,不用担心,多试几次。
|
||||

|
||||
#### 五、若安装了证书,去核对/更改一下证书的路径,一般是同一个域名的话,位置在:/root/cert/域名/fullchain.pem,路径是相同的就不用更改,
|
||||
#### 六、重启面板/重启服务器,让上述步骤生效即可,这时可以看到所有配置都是之前自己常用的,包括面板用户名、密码,入站、客户端,电报机器人配置等。
|
||||
|
||||
------------
|
||||
## 安装完成后如何设置调整成【中文界面】?
|
||||
- 方法一:通过管理后台【登录页面】调整,登录时可以选择,如下图:
|
||||

|
||||
- 方法二:通过在管理后台-->【面板设置】中去选择设置,如下图:
|
||||

|
||||
- 【TG机器人】设置中文:通过在管理后台-->【面板设置】-->【机器人配置】中去选择设置,并建议打开数据库备份和登录通知,如下图:
|
||||

|
||||
|
||||
------------
|
||||
## 用3x-ui如何实现【自己偷自己】?
|
||||
- 其实很简单,只要你为面板设置了证书,
|
||||
- 开启了HTTPS登录,就可以将3x-ui自身作为Web Server,
|
||||
- 无需Nginx等,这里给一个示例:
|
||||
- 其中目标网站(Dest)请填写面板监听端口,
|
||||
- 可选域名(SNI)填写面板登录域名,
|
||||
- 如果您使用其他web server(如nginx)等,
|
||||
- 将目标网站改为对应监听端口也可。
|
||||
- 需要说明的是,如果您处于白名单地区,自己“偷”自己并不适合你;
|
||||
- 其次,可选域名一项实际上可以填写任意SNI,只要客户端保持一致即可,不过并不推荐这样做。
|
||||
- 配置方法如下图所示:
|
||||

|
||||
|
||||
------------
|
||||
## 〔子域名〕被墙针对特征
|
||||
#### 网络表现:
|
||||
##### 1、可以Ping通域名和IP地址,
|
||||
##### 2、子域名无法打开3X-UI管理界面,
|
||||
##### 3、什么都正常就是不能上网;
|
||||
|
||||
#### 问题:
|
||||
##### 你的子域名被墙针对了:无法上网!
|
||||
|
||||
#### 解决方案:
|
||||
##### 1、更换为新的子域名,
|
||||
##### 2、解析新的子域名到VPS的IP,
|
||||
##### 3、重新去安装新证书,
|
||||
##### 4、重启3X-UI和服务器,
|
||||
##### 5、重新去获取链接并测试上网。
|
||||
#### PS:若通过以上步骤还是不能正常上网,则重装VPS服务器OS系统,以及3X-UI面板全部重新安装,之后就正常了!
|
||||
|
||||
------------
|
||||
## 用3x-ui中文版如何开启【设备限制】功能?
|
||||
##### 1、进入后台在【添加入站】的时候,弹出来的页面就能有【设备数量】输入框,
|
||||

|
||||
##### 2、通过步骤1设置完成后,在后台的【入站列表】页面也有对应的同步数据显示。
|
||||

|
||||
##### 3、具体要查看【设备限制】功能的封禁情况,就进入〔3X-UI中文版〕后台用日志查看。
|
||||

|
||||
##### 4、以下图片里面,详细阐述了我们的〔设备限制〕功能,跟3X-UI原本就有的〔IP Limit〕之间的区别对比。
|
||||

|
||||
|
||||
------------
|
||||
## 用3x-ui如何开启【每月流量自动重置】?
|
||||
##### 1、进入后台的【入站列表】,选择需要设置的【客户端】,
|
||||

|
||||
##### 2、要注意是编辑【入站】下面的【客户端】,才会有效果,
|
||||
##### 2、并不是编辑【入站】,所以不要弄错对象,如下图所示:
|
||||

|
||||
|
||||
|
||||
------------
|
||||
## 在自己的VPS服务器部署【订阅转换】功能
|
||||
### 如何把vless/vmess等协议转换成Clash/Surge等软件支持的格式?
|
||||
##### 1、进入脚本输入x-ui命令调取面板,选择第【25】选项安装订阅转换模块,
|
||||
##### 2、等待安装【订阅转换】成功之后,访问地址:https://你的域名:15268 ,
|
||||

|
||||
##### 3、因为在转换过程中需要调取后端API,所以请确保端口 8000 和 15268 是打开放行的,
|
||||
##### 4、直接复制脚本中提供的【登录地址】,进入后台,点击【节点列表】,如下图:
|
||||

|
||||
##### 5、接下来点击左边侧边栏的【订阅列表】去【添加订阅】,按照下图中去操作,
|
||||

|
||||
##### 6、最后一步,点击【客户端】,即可导入Clash等软件中使用。
|
||||

|
||||

|
||||
|
||||
------------
|
||||
## 常见的翻墙软件/工具:
|
||||
- [1、Windows系统v2rayN:https://github.com/2dust/v2rayN](https://github.com/2dust/v2rayN)
|
||||
- [2、安卓手机版【v2rayNG】:https://github.com/2dust/v2rayNG](https://github.com/2dust/v2rayNG)
|
||||
- [3、苹果手机IOS【小火箭】:https://apple02.com/(自己购买)](https://apple02.com/)
|
||||
- [4、苹果MacOS电脑【Clash Verge】:https://github.com/clash-verge-rev/clash-verge-rev/releases](https://github.com/clash-verge-rev/clash-verge-rev/releases)
|
||||
[或v2rayN:https://github.com/2dust/v2rayN](https://github.com/2dust/v2rayN)
|
||||
|
||||
------------
|
||||
## 如何保护自己的IP不被墙被封?
|
||||
##### 1、使用的代理协议要安全,加密是必备,推荐使用vless+reality+vision协议组合,
|
||||
##### 2、因为有时节点会共享,在不同的地区,多个省份之间不要共同连接同一个IP,
|
||||
##### 3、连接同一个IP就算了,不要同一个端口,不要同IP+同端口到处漫游,要分开,
|
||||
##### 4、同一台VPS,不要在一天内一直大流量去下载东西使用,不要流量过高要切换,
|
||||
##### 5、创建【入站协议】的时候,尽量用【高位端口】,比如40000--65000之间的端口号。
|
||||
#### 提醒:为什么在特殊时期,比如:两会,春节等被封得最严重最惨?
|
||||
##### 尼玛同一个IP+同一个端口号,多个省份去漫游,跟开飞机场一样!不封你,封谁的IP和端口?
|
||||
#### 总结:不要多终端/多省份/多个朋友/共同使用同一个IP和端口号!使用3x-ui多创建几个【入站】,
|
||||
#### 多做几条备用,各用各的!各行其道才比较安全!GFW的思维模式是干掉机场,机场的特征个人用户不要去沾染,自然IP就保护好了。
|
||||
|
||||
------------
|
||||
## SSL 认证
|
||||
|
||||
<details>
|
||||
<summary>点击查看 SSL 认证</summary>
|
||||
|
||||
### ACME
|
||||
|
||||
要使用 ACME 管理 SSL 证书:
|
||||
|
||||
1. 确保您的域名已正确解析到服务器,
|
||||
2. 输入“x-ui”命令并选择“SSL 证书管理”,
|
||||
3. 您将看到以下选项:
|
||||
|
||||
- **获取证书** ----获取SSL证书
|
||||
- **吊销证书** ----吊销现有的SSL证书
|
||||
- **续签证书** ----强制续签SSL证书
|
||||
- **显示所有证书** ----显示服务器中所有能用的证书
|
||||
- **设置面板证书路径** ----指定面板要使用的证书
|
||||
|
||||
|
||||
### Certbot
|
||||
|
||||
安装和使用 Certbot:
|
||||
|
||||
```sh
|
||||
apt-get install certbot -y
|
||||
certbot certonly --standalone --agree-tos --register-unsafely-without-email -d yourdomain.com
|
||||
certbot renew --dry-run
|
||||
```
|
||||
|
||||
### Cloudflare
|
||||
|
||||
管理脚本具有用于 Cloudflare 的内置 SSL 证书应用程序。若要使用此脚本申请证书,需要满足以下条件:
|
||||
|
||||
- Cloudflare 邮箱地址
|
||||
- Cloudflare Global API Key
|
||||
- 域名已通过 cloudflare 解析到当前服务器
|
||||
|
||||
**如何获取 Cloudflare全局API密钥:**
|
||||
|
||||
1. 在终端中输入“x-ui”命令,然后选择“CF SSL 证书”。
|
||||
2. 访问链接: [Cloudflare API Tokens](https://dash.cloudflare.com/profile/api-tokens).
|
||||
3. 点击“查看全局 API 密钥”(如下图所示):
|
||||

|
||||
4. 您可能需要重新验证您的帐户。之后,将显示 API 密钥(请参见下面的屏幕截图):
|
||||

|
||||
|
||||
使用时,只需输入您的“域名”、“电子邮件”和“API KEY”即可。示意图如下:
|
||||

|
||||
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## 手动安装 & 升级
|
||||
|
||||
<details>
|
||||
<summary>点击查看 手动安装 & 升级</summary>
|
||||
|
||||
#### 使用
|
||||
|
||||
1. 若要将最新版本的压缩包直接下载到服务器,请运行以下命令:
|
||||
|
||||
```sh
|
||||
ARCH=$(uname -m)
|
||||
case "${ARCH}" in
|
||||
x86_64 | x64 | amd64) XUI_ARCH="amd64" ;;
|
||||
i*86 | x86) XUI_ARCH="386" ;;
|
||||
armv8* | armv8 | arm64 | aarch64) XUI_ARCH="arm64" ;;
|
||||
armv7* | armv7) XUI_ARCH="armv7" ;;
|
||||
armv6* | armv6) XUI_ARCH="armv6" ;;
|
||||
armv5* | armv5) XUI_ARCH="armv5" ;;
|
||||
s390x) echo 's390x' ;;
|
||||
*) XUI_ARCH="amd64" ;;
|
||||
esac
|
||||
|
||||
|
||||
wget https://github.com/xeefei/3x-ui/releases/latest/download/x-ui-linux-${XUI_ARCH}.tar.gz
|
||||
```
|
||||
|
||||
2. 下载压缩包后,执行以下命令安装或升级 x-ui:
|
||||
|
||||
```sh
|
||||
ARCH=$(uname -m)
|
||||
case "${ARCH}" in
|
||||
x86_64 | x64 | amd64) XUI_ARCH="amd64" ;;
|
||||
i*86 | x86) XUI_ARCH="386" ;;
|
||||
armv8* | armv8 | arm64 | aarch64) XUI_ARCH="arm64" ;;
|
||||
armv7* | armv7) XUI_ARCH="armv7" ;;
|
||||
armv6* | armv6) XUI_ARCH="armv6" ;;
|
||||
armv5* | armv5) XUI_ARCH="armv5" ;;
|
||||
s390x) echo 's390x' ;;
|
||||
*) XUI_ARCH="amd64" ;;
|
||||
esac
|
||||
|
||||
cd /root/
|
||||
rm -rf x-ui/ /usr/local/x-ui/ /usr/bin/x-ui
|
||||
tar zxvf x-ui-linux-${XUI_ARCH}.tar.gz
|
||||
chmod +x x-ui/x-ui x-ui/bin/xray-linux-* x-ui/x-ui.sh
|
||||
cp x-ui/x-ui.sh /usr/bin/x-ui
|
||||
cp -f x-ui/x-ui.service /etc/systemd/system/
|
||||
mv x-ui/ /usr/local/
|
||||
systemctl daemon-reload
|
||||
systemctl enable x-ui
|
||||
systemctl restart x-ui
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## 通过Docker安装
|
||||
|
||||
<details>
|
||||
<summary>点击查看 通过Docker安装</summary>
|
||||
|
||||
#### 使用
|
||||
|
||||
|
||||
1. **安装Docker**
|
||||
|
||||
```sh
|
||||
bash <(curl -sSL https://get.docker.com)
|
||||
```
|
||||
|
||||
|
||||
2. **克隆项目仓库**
|
||||
|
||||
```sh
|
||||
git clone https://github.com/xeefei/3x-ui.git
|
||||
cd 3x-ui
|
||||
```
|
||||
|
||||
3. **启动服务**:
|
||||
|
||||
```sh
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
添加 ```--pull always``` 标志使 docker 在拉取更新的镜像时自动重新创建容器。有关更多信息,请参阅:https://docs.docker.com/reference/cli/docker/container/run/#pull
|
||||
|
||||
**或**
|
||||
|
||||
```sh
|
||||
docker run -itd \
|
||||
-e XRAY_VMESS_AEAD_FORCED=false \
|
||||
-v $PWD/db/:/etc/x-ui/ \
|
||||
-v $PWD/cert/:/root/cert/ \
|
||||
--network=host \
|
||||
--restart=unless-stopped \
|
||||
--name 3x-ui \
|
||||
ghcr.io/xeefei/3x-ui:latest
|
||||
```
|
||||
|
||||
4. **更新至最新版本**
|
||||
|
||||
```sh
|
||||
cd 3x-ui
|
||||
docker compose down
|
||||
docker compose pull 3x-ui
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
5. **从Docker中删除3x-ui **
|
||||
|
||||
```sh
|
||||
docker stop 3x-ui
|
||||
docker rm 3x-ui
|
||||
cd --
|
||||
rm -r 3x-ui
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## 建议使用的操作系统
|
||||
|
||||
- Ubuntu 20.04+
|
||||
- Debian 11+
|
||||
- CentOS 8+
|
||||
- OpenEuler 22.03+
|
||||
- Fedora 36+
|
||||
- Arch Linux
|
||||
- Manjaro
|
||||
- Armbian
|
||||
- AlmaLinux 8.0+
|
||||
- Rocky Linux 8+
|
||||
- Oracle Linux 8+
|
||||
- OpenSUSE Tubleweed
|
||||
- Amazon Linux 2023
|
||||
|
||||
------------
|
||||
## 支持的架构和设备
|
||||
<details>
|
||||
<summary>点击查看 支持的架构和设备</summary>
|
||||
|
||||
我们的平台提供与各种架构和设备的兼容性,确保在各种计算环境中的灵活性。以下是我们支持的关键架构:
|
||||
|
||||
- **amd64**: 这种流行的架构是个人计算机和服务器的标准,可以无缝地适应大多数现代操作系统。
|
||||
|
||||
- **x86 / i386**: 这种架构在台式机和笔记本电脑中被广泛采用,得到了众多操作系统和应用程序的广泛支持,包括但不限于 Windows、macOS 和 Linux 系统。
|
||||
|
||||
- **armv8 / arm64 / aarch64**: 这种架构专为智能手机和平板电脑等当代移动和嵌入式设备量身定制,以 Raspberry Pi 4、Raspberry Pi 3、Raspberry Pi Zero 2/Zero 2 W、Orange Pi 3 LTS 等设备为例。
|
||||
|
||||
- **armv7 / arm / arm32**: 作为较旧的移动和嵌入式设备的架构,它仍然广泛用于Orange Pi Zero LTS、Orange Pi PC Plus、Raspberry Pi 2等设备。
|
||||
|
||||
- **armv6 / arm / arm32**: 这种架构面向非常老旧的嵌入式设备,虽然不太普遍,但仍在使用中。Raspberry Pi 1、Raspberry Pi Zero/Zero W 等设备都依赖于这种架构。
|
||||
|
||||
- **armv5 / arm / arm32**: 它是一种主要与早期嵌入式系统相关的旧架构,目前不太常见,但仍可能出现在早期 Raspberry Pi 版本和一些旧智能手机等传统设备中。
|
||||
</details>
|
||||
|
||||
------------
|
||||
## Languages
|
||||
|
||||
- English(英语)
|
||||
- Farsi(伊朗语)
|
||||
- Simplified Chinese(简体中文)
|
||||
- Traditional Chinese(繁体中文)
|
||||
- Russian(俄语)
|
||||
- Vietnamese(越南语)
|
||||
- Spanish(西班牙语)
|
||||
- Indonesian (印度尼西亚语)
|
||||
- Ukrainian(乌克兰语)
|
||||
- Turkish(土耳其语)
|
||||
- Português (葡萄牙语)
|
||||
|
||||
------------
|
||||
## 项目特点
|
||||
|
||||
- 系统状态查看与监控
|
||||
- 可搜索所有入站和客户端信息
|
||||
- 深色/浅色主题随意切换
|
||||
- 支持多用户和多协议
|
||||
- 支持多种协议,包括 VMess、VLESS、Trojan、Shadowsocks、Dokodemo-door、Socks、HTTP、wireguard
|
||||
- 支持 XTLS 原生协议,包括 RPRX-Direct、Vision、REALITY
|
||||
- 流量统计、流量限制、过期时间限制
|
||||
- 可自定义的 Xray配置模板
|
||||
- 支持HTTPS访问面板(自备域名+SSL证书)
|
||||
- 支持一键式SSL证书申请和自动续签证书
|
||||
- 更多高级配置项目请参考面板去进行设定
|
||||
- 修复了 API 路由(用户设置将使用 API 创建)
|
||||
- 支持通过面板中提供的不同项目更改配置。
|
||||
- 支持从面板导出/导入数据库
|
||||
|
||||
## 默认面板设置
|
||||
|
||||
<details>
|
||||
|
||||
<summary>点击查看 默认设置</summary>
|
||||
|
||||
### 默认信息
|
||||
|
||||
- **端口**
|
||||
- 2053
|
||||
- **用户名 & 密码 & 访问路径**
|
||||
- 当您跳过设置时,这些信息会随机生成,
|
||||
- 您也可以在安装的时候自定义访问路径。
|
||||
- **数据库路径:**
|
||||
- /etc/x-ui/x-ui.db
|
||||
- **Xray 配置路径:**
|
||||
- /usr/local/x-ui/bin/config.json
|
||||
- **面板链接(无SSL):**
|
||||
- http://ip:2053/访问路径/panel
|
||||
- **面板链接(有SSL):**
|
||||
- https://你的域名:2053/访问路径/panel
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## [WARP 配置](https://gitlab.com/fscarmen/warp)
|
||||
|
||||
<details>
|
||||
<summary>点击查看 WARP 配置</summary>
|
||||
|
||||
#### 使用
|
||||
|
||||
**对于版本 `v2.1.0` 及更高版本:**
|
||||
|
||||
WARP 是内置的,无需额外安装;只需在面板中打开必要的配置即可。
|
||||
|
||||
**如果要在 v2.1.0 之前使用 WARP 路由**,请按照以下步骤操作:
|
||||
|
||||
**1.** 在 **SOCKS Proxy Mode** 模式中安装Wrap
|
||||
|
||||
- **Account Type (free, plus, team):** Choose the appropriate account type.
|
||||
- **Enable/Disable WireProxy:** Toggle WireProxy on or off.
|
||||
- **Uninstall WARP:** Remove the WARP application.
|
||||
|
||||
**2.** 如果您已经安装了 warp,您可以使用以下命令卸载:
|
||||
|
||||
```sh
|
||||
warp u
|
||||
```
|
||||
|
||||
**3.** 在面板中打开您需要的配置
|
||||
|
||||
配置:
|
||||
|
||||
- Block Ads
|
||||
- Route Google, Netflix, Spotify, and OpenAI (ChatGPT) traffic to WARP
|
||||
- Fix Google 403 error
|
||||
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## IP 限制
|
||||
|
||||
<details>
|
||||
<summary>点击查看 IP 限制</summary>
|
||||
|
||||
#### 使用
|
||||
|
||||
**注意:** 使用 IP 隧道时,IP 限制无法正常工作。
|
||||
|
||||
- 对于 `v1.6.1`之前的版本 :
|
||||
|
||||
- IP 限制 已被集成在面板中。
|
||||
|
||||
- 对于 `v1.7.0` 以及更新的版本:
|
||||
|
||||
- 要使 IP 限制正常工作,您需要按照以下步骤安装 fail2ban 及其所需的文件:
|
||||
|
||||
1. 使用面板内置的 `x-ui` 指令
|
||||
2. 选择 `IP Limit Management`.
|
||||
3. 根据您的需要选择合适的选项。
|
||||
|
||||
- 确保您的 Xray 配置上有 ./access.log 。在 v2.1.3 之后,我们有一个选项。
|
||||
|
||||
```sh
|
||||
"log": {
|
||||
"access": "./access.log",
|
||||
"dnsLog": false,
|
||||
"loglevel": "warning"
|
||||
},
|
||||
```
|
||||
- 您需要在Xray配置中手动设置〔访问日志〕的路径。
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## Telegram 机器人
|
||||
|
||||
<details>
|
||||
<summary>点击查看 Telegram 机器人</summary>
|
||||
|
||||
#### 使用
|
||||
|
||||
Web 面板通过 Telegram Bot 支持每日流量、面板登录、数据库备份、系统状态、客户端信息等通知和功能。要使用机器人,您需要在面板中设置机器人相关参数,包括:
|
||||
|
||||
- 电报令牌
|
||||
- 管理员聊天 ID
|
||||
- 通知时间(cron 语法)
|
||||
- 到期日期通知
|
||||
- 流量上限通知
|
||||
- 数据库备份
|
||||
- CPU 负载通知
|
||||
|
||||
|
||||
**参考:**
|
||||
|
||||
- `30 \* \* \* \* \*` - 在每个点的 30 秒处通知
|
||||
- `0 \*/10 \* \* \* \*` - 每 10 分钟的第一秒通知
|
||||
- `@hourly` - 每小时通知
|
||||
- `@daily` - 每天通知 (00:00)
|
||||
- `@weekly` - 每周通知
|
||||
- `@every 8h` - 每8小时通知
|
||||
|
||||
### Telegram Bot 功能
|
||||
|
||||
- 定期报告
|
||||
- 登录通知
|
||||
- CPU 阈值通知
|
||||
- 提前报告的过期时间和流量阈值
|
||||
- 如果将客户的电报用户名添加到用户的配置中,则支持客户端报告菜单
|
||||
- 支持使用UUID(VMESS/VLESS)或密码(TROJAN)搜索报文流量报告 - 匿名
|
||||
- 基于菜单的机器人
|
||||
- 通过电子邮件搜索客户端(仅限管理员)
|
||||
- 检查所有入库
|
||||
- 检查服务器状态
|
||||
- 检查耗尽的用户
|
||||
- 根据请求和定期报告接收备份
|
||||
- 多语言机器人
|
||||
|
||||
### 注册 Telegram bot
|
||||
|
||||
- 与 [Botfather](https://t.me/BotFather) 对话:
|
||||

|
||||
|
||||
- 使用 /newbot 创建新机器人:你需要提供机器人名称以及用户名,注意名称中末尾要包含“bot”
|
||||

|
||||
|
||||
- 启动您刚刚创建的机器人。可以在此处找到机器人的链接。
|
||||

|
||||
|
||||
- 输入您的面板并配置 Telegram 机器人设置,如下所示:
|
||||

|
||||
|
||||
在输入字段编号 3 中输入机器人令牌。
|
||||
在输入字段编号 4 中输入用户 ID。具有此 id 的 Telegram 帐户将是机器人管理员。 (您可以输入多个,只需将它们用“ ,”分开即可)
|
||||
|
||||
- 如何获取TG ID? 使用 [bot](https://t.me/useridinfobot), 启动机器人,它会给你 Telegram 用户 ID。
|
||||

|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## API 路由
|
||||
|
||||
<details>
|
||||
<summary>点击查看 API 路由</summary>
|
||||
|
||||
#### 使用
|
||||
|
||||
- `/login` 使用 `POST` 用户名称 & 密码: `{username: '', password: ''}` 登录
|
||||
- `/panel/api/inbounds` 以下操作的基础:
|
||||
|
||||
| 方法 | 路径 | 操作 |
|
||||
| :----: | ---------------------------------- | ------------------------------------------- |
|
||||
| `GET` | `"/list"` | 获取所有入站 |
|
||||
| `GET` | `"/get/:id"` | 获取所有入站以及inbound.id |
|
||||
| `GET` | `"/getClientTraffics/:email"` | 通过电子邮件获取客户端流量 |
|
||||
| `GET` | `"/getClientTrafficsById/:id"` | 通过用户ID获取客户端流量 |
|
||||
| `GET` | `"/createbackup"` | Telegram 机器人向管理员发送备份 |
|
||||
| `POST` | `"/add"` | 添加入站 |
|
||||
| `POST` | `"/del/:id"` | 删除入站 |
|
||||
| `POST` | `"/update/:id"` | 更新入站 |
|
||||
| `POST` | `"/clientIps/:email"` | 客户端 IP 地址 |
|
||||
| `POST` | `"/clearClientIps/:email"` | 清除客户端 IP 地址 |
|
||||
| `POST` | `"/addClient"` | 将客户端添加到入站 |
|
||||
| `POST` | `"/:id/delClient/:clientId"` | 通过 clientId\* 删除客户端 |
|
||||
| `POST` | `"/updateClient/:clientId"` | 通过 clientId\* 更新客户端 |
|
||||
| `POST` | `"/:id/resetClientTraffic/:email"` | 重置客户端的流量 |
|
||||
| `POST` | `"/resetAllTraffics"` | 重置所有入站的流量 |
|
||||
| `POST` | `"/resetAllClientTraffics/:id"` | 重置入站中所有客户端的流量 |
|
||||
| `POST` | `"/delDepletedClients/:id"` | 删除入站耗尽的客户端 (-1: all) |
|
||||
| `POST` | `"/onlines"` | 获取在线用户 ( 电子邮件列表 ) |
|
||||
|
||||
- 使用`clientId` 项应该填写下列数据:
|
||||
|
||||
- `client.id` for VMESS and VLESS
|
||||
- `client.password` for TROJAN
|
||||
- `client.email` for Shadowsocks
|
||||
|
||||
|
||||
|
||||
- [API 文档](https://documenter.getpostman.com/view/16802678/2s9YkgD5jm)
|
||||
|
||||
- [<img src="https://run.pstmn.io/button.svg" alt="Run In Postman" style="width: 128px; height: 32px;">](https://app.getpostman.com/run-collection/16802678-1a4c9270-ac77-40ed-959a-7aa56dc4a415?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D16802678-1a4c9270-ac77-40ed-959a-7aa56dc4a415%26entityType%3Dcollection%26workspaceId%3D2cd38c01-c851-4a15-a972-f181c23359d9)
|
||||
</details>
|
||||
|
||||
------------
|
||||
## 环境变量
|
||||
|
||||
<details>
|
||||
<summary>点击查看 环境变量</summary>
|
||||
|
||||
#### Usage
|
||||
|
||||
| 变量 | Type | 默认 |
|
||||
| -------------- | :--------------------------------------------: | :------------ |
|
||||
| XUI_LOG_LEVEL | `"debug"` \| `"info"` \| `"warn"` \| `"error"` | `"info"` |
|
||||
| XUI_DEBUG | `boolean` | `false` |
|
||||
| XUI_BIN_FOLDER | `string` | `"bin"` |
|
||||
| XUI_DB_FOLDER | `string` | `"/etc/x-ui"` |
|
||||
| XUI_LOG_FOLDER | `string` | `"/var/log"` |
|
||||
|
||||
例子:
|
||||
|
||||
```sh
|
||||
XUI_BIN_FOLDER="bin" XUI_DB_FOLDER="/etc/x-ui" go build main.go
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## 预览
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
------------
|
||||
## 广告赞助
|
||||
- 如果你觉得本项目对你有用,而且你也恰巧有这方面的需求,你也可以选择通过我的购买链接赞助我。
|
||||
- [1、搬瓦工GIA高端线路,仅推荐购买GIA套餐:https://bandwagonhost.com/aff.php?aff=75015](https://bandwagonhost.com/aff.php?aff=75015)
|
||||
- [2、Dmit高端GIA线路:https://www.dmit.io/aff.php?aff=9326](https://www.dmit.io/aff.php?aff=9326)
|
||||
- [3、白丝云【4837线路】实惠量大管饱:https://cloudsilk.io/aff.php?aff=706](https://cloudsilk.io/aff.php?aff=706)
|
||||
|
||||
------------
|
||||
## 特别感谢
|
||||
|
||||
- [MHSanaei](https://github.com/MHSanaei/)
|
||||
- [alireza0](https://github.com/alireza0/)
|
||||
- [FranzKafkaYu](https://github.com/FranzKafkaYu/)
|
||||
- [vaxilu](https://github.com/vaxilu/)
|
||||
|
||||
------------
|
||||
## 致谢
|
||||
|
||||
- [Iran v2ray rules](https://github.com/chocolate4u/Iran-v2ray-rules) (License: **GPL-3.0**): _Enhanced v2ray/xray and v2ray/xray-clients routing rules with built-in Iranian domains and a focus on security and adblocking._
|
||||
- [Vietnam Adblock rules](https://github.com/vuong2023/vn-v2ray-rules) (License: **GPL-3.0**): _A hosted domain hosted in Vietnam and blocklist with the most efficiency for Vietnamese._
|
||||
|
||||
------------
|
||||
## Star 趋势
|
||||
|
||||
[](https://starchart.cc/xeefei/3x-ui)
|
||||
836
README.zh_CN.md
@ -1,56 +1,808 @@
|
||||
[English](/README.md) | [فارسی](/README.fa_IR.md) | [العربية](/README.ar_EG.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构建------------------------------**
|
||||
|
||||
[](https://github.com/MHSanaei/3x-ui/releases)
|
||||
[](https://github.com/MHSanaei/3x-ui/actions)
|
||||
[](#)
|
||||
[](https://github.com/MHSanaei/3x-ui/releases/latest)
|
||||
|
||||
[](https://github.com/xeefei/3x-ui/releases)
|
||||
[](https://github.com/xeefei/3x-ui/actions)
|
||||
[](#)
|
||||
[](https://github.com/xeefei/3x-ui/releases/latest)
|
||||
[](https://www.gnu.org/licenses/gpl-3.0.en.html)
|
||||
|
||||
**3X-UI** — 一个基于网页的高级开源控制面板,专为管理 Xray-core 服务器而设计。它提供了用户友好的界面,用于配置和监控各种 VPN 和代理协议。
|
||||
> **声明:** 此项目仅供个人学习、交流使用,请遵守当地法律法规,勿用于非法用途;请勿用于生产环境。
|
||||
|
||||
> [!IMPORTANT]
|
||||
> 本项目仅用于个人使用和通信,请勿将其用于非法目的,请勿在生产环境中使用。
|
||||
> **注意:** 在使用此项目和〔教程〕过程中,若因违反以上声明使用规则而产生的一切后果由使用者自负。
|
||||
|
||||
作为原始 X-UI 项目的增强版本,3X-UI 提供了更好的稳定性、更广泛的协议支持和额外的功能。
|
||||
|
||||
## 快速开始
|
||||
|
||||
```
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)
|
||||
```
|
||||
|
||||
完整文档请参阅 [项目Wiki](https://github.com/MHSanaei/3x-ui/wiki)。
|
||||
|
||||
## 特别感谢
|
||||
|
||||
- [alireza0](https://github.com/alireza0/)
|
||||
|
||||
## 致谢
|
||||
|
||||
- [Iran v2ray rules](https://github.com/chocolate4u/Iran-v2ray-rules) (许可证: **GPL-3.0**): _增强的 v2ray/xray 和 v2ray/xray-clients 路由规则,内置伊朗域名,专注于安全性和广告拦截。_
|
||||
- [Russia v2ray rules](https://github.com/runetfreedom/russia-v2ray-rules-dat) (许可证: **GPL-3.0**): _此仓库包含基于俄罗斯被阻止域名和地址数据自动更新的 V2Ray 路由规则。_
|
||||
|
||||
## 支持项目
|
||||
|
||||
**如果这个项目对您有帮助,您可以给它一个**:star2:
|
||||
**如果此项目对你有用,请给一个**:star2:
|
||||
|
||||
<p align="left">
|
||||
<a href="https://buymeacoffee.com/mhsanaei" target="_blank">
|
||||
<a href="https://buymeacoffee.com/xeefeiz" target="_blank">
|
||||
<img src="./media/buymeacoffe.png" alt="Image">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
- USDT (TRC20): `TXncxkvhkDWGts487Pjqq1qT9JmwRUz8CC`
|
||||
- POL (polygon): `0x41C9548675D044c6Bfb425786C765bc37427256A`
|
||||
- LTC (Litecoin): `ltc1q2ach7x6d2zq0n4l0t4zl7d7xe2s6fs7a3vspwv`
|
||||
- 赞助地址(USDT/TRC20):`TYQEmQp1P65u9bG7KPehgJdvuokfb72YkZ`
|
||||
|
||||
## 随时间变化的星标数
|
||||
## [【3X-UI】中文交流群:https://t.me/XUI_CN](https://t.me/XUI_CN)
|
||||
## [【3X-UI】详细安装流程步骤:https://xeefei.blogspot.com/2025/07/3x-ui.html](https://xeefei.blogspot.com/2025/07/3x-ui.html)
|
||||
|
||||
[](https://starchart.cc/MHSanaei/3x-ui)
|
||||
------------
|
||||
## ✰〔3X-UI优化版〕跟原版3X-UI的区别?✰
|
||||
### 大部分功能基于原版3X-UI进行汉化优化,主要的优化内容如下:
|
||||
#### 1、最大限度地汉化了面板项目,更适合中文宝宝体质,包括:
|
||||
##### ①优化在VPS中进行〔脚本安装过程〕的汉化提示,增加相应的安装中文提示,让中文用户能明白清楚自己安装到了哪个环节?在细节方面,增加了安装成功之后的〔用户设置信息〕提示,在脚本中加入〔面板登录地址〕显示,
|
||||
##### ②管理后台进行了相应的〔图标和按钮〕汉化,让中文宝宝能够看得懂,
|
||||
##### ③安装成功后〔自动更改〕后台管理界面和电报机器人界面默认为〔中文〕,
|
||||
##### ④在管理后台中〔设置证书处〕,增加了acme方式填入路径的提示;
|
||||
#### 2、为了保证登录面板的安全性,脚本强制〔ssh转发〕,
|
||||
#### 3、新增〔设备限制〕功能,可配合脚本中的〔IPlimit〕使用,
|
||||
#### 4、新增〔订阅转换〕功能,进入脚本用选项【25】去安装使用,
|
||||
#### 5、创建了〔3X-UI〕中文交流群,各位中文宝宝可以一起讨论交流;
|
||||
#### 6、管理后台中增加了〔实用导航〕页面,里面包含实用内容;
|
||||
#### 7、优化了后台〔二维码〕显示模式,点击打开会更加丝滑美观;
|
||||
#### 8、在创建reality协议时,更改uTLS指纹默认使用chrome;更改默认目标网站为tesla.com;
|
||||
#### 9、更新README内容添加备份&恢复操作说明,以及更多其他图文介绍;
|
||||
#### 10、管理后台中增加〔端口检测〕和〔网络测速〕,点击可以跳转直达;
|
||||
#### 11、增加了详细的项目〔安装配置教程〕,解决小白用户不懂配置的烦恼。
|
||||
|
||||
------------
|
||||
## ✰你必须要看的【重要安全提示/警告】✰
|
||||
#### 1、请勿使用【http明文模式】登录管理面板,因为明文会造成信息泄露;这个安全问题社区讨论过,
|
||||
#### 2、可使用设置【SSH端口转发功能】去登录面板或安装证书之后用https加密方式登录;两种方式选择其一,
|
||||

|
||||
#### 3、若无域名那就按照脚本提示去做【ssh转发】;有域名则可选择更加安全的【申请安装证书】方式,
|
||||
#### 4、Windows电脑首先通过快捷键【Win + R】调出运行窗口,在里面输入【cmd】打开本地终端服务,
|
||||

|
||||

|
||||

|
||||

|
||||
#### 5、若在搭建之前没有翻墙加密,则【http明文模式】登录面板有很大的信息泄露安全风险,那建议你第一次搭建成功之后,去修改用户/密码,和访问路径,后期则通过搭建好的代理加密访问,
|
||||

|
||||
#### 6、在做【ssh转发】过程中,本地电脑的终端不能关闭,保持打开不能断开;且每一次要登录3X-UI管理后台都要做【ssh转发】,因为关闭之后就失效了。
|
||||

|
||||
#### PS:上述两种方法:【ssh端口转发】或申请安装证书的目的都是为了更安全地登录面板,而至于搭建的其他流程和步骤,都是一样的;如果你已经【申请安装证书】了,并不会受到其他什么额外影响,就不用去折腾【ssh转发】了,直接用 【https://你的域名:端口/路径】 去登录你的面板管理后台就行了。
|
||||
|
||||
------------
|
||||
## ✰如何从其他x-ui版本迁移到〔3X-UI优化版〕?✰
|
||||
#### 1、若你用的是伊朗老哥的原版3X-UI,是可以直接〔覆盖安装〕的,因为〔3X-UI优化版〕是fork了原版3X-UI的项目,基于原有的功能进行优化的,大功能是没有变化的,主要是进行了脚本的〔汉化处理〕,其他诸如数据库文件等位置是没有改变的,所以直接覆盖安装,并不会影响你〔原有节点及配置〕等数据;安装命令如下:
|
||||
```
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/xeefei/3x-ui/master/install.sh)
|
||||
```
|
||||
#### 2、若你之前用的是Docker方式安装,那先进入容器里面/命令:docker exec -it 容器id /bin/sh,再执行以上脚本命令直接【覆盖安装】即可,
|
||||
#### 3、若你用的是之前F佬的x-ui或者其他分支版本,那直接覆盖安装的话,并不能确保一定就能够兼容?建议你先去备份〔数据库〕配置文件,再进行安装〔3X-UI优化版〕。
|
||||
|
||||
|
||||
------------
|
||||
## 安装之前的准备
|
||||
- 购买一台性能还不错的VPS,可通过本页底部链接购买,
|
||||
- PS:若你不想升级系统,则可以跳过此步骤。
|
||||
- 若你需要更新/升级系统,Debian系统可用如下命令:
|
||||
```
|
||||
apt update
|
||||
apt upgrade -y
|
||||
apt dist-upgrade -y
|
||||
apt autoclean
|
||||
apt autoremove -y
|
||||
```
|
||||
- 查看系统当前版本:
|
||||
```
|
||||
cat /etc/debian_version
|
||||
```
|
||||
- 查看内核版本:
|
||||
```
|
||||
uname -r
|
||||
```
|
||||
- 列出所有内核:
|
||||
```
|
||||
dpkg --list | grep linux-image
|
||||
```
|
||||
- 更新完成后执行重新引导:
|
||||
```
|
||||
update-grub
|
||||
```
|
||||
- 完成以上步骤之后输入reboot重启系统
|
||||
|
||||
------------
|
||||
## 【搬瓦工】重装/升级系统之后SSH连不上如何解决?
|
||||
- 【搬瓦工】重装/升级系统会恢复默认22端口,如果需要修改SSH的端口号,您需要进行以下步骤:
|
||||
- 以管理员身份使用默认22端口登录到SSH服务器
|
||||
- 打开SSH服务器的配置文件进行编辑,SSH配置文件通常位于/etc/ssh/sshd_config
|
||||
- 找到"Port"选项,并将其更改为您想要的端口号
|
||||
- Port <新端口号>,请将<新端口号>替换为您想要使用的端口号
|
||||
- 保存文件并退出编辑器
|
||||
- 重启服务器以使更改生效
|
||||
|
||||
------------
|
||||
## 安装 & 升级
|
||||
- 使用3x-ui脚本一般情况下,安装完成创建入站之后,端口是默认关闭的,所以必须进入脚本选择【22】去放行端口
|
||||
- 要使用【自动续签】证书功能,也必须放行【80】端口,保持80端口是打开的,才会每3个月自动续签一次
|
||||
|
||||
- 【全新安装】请执行以下脚本:
|
||||
```
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/xeefei/3x-ui/master/install.sh)
|
||||
```
|
||||
#### 如果执行了上面的代码但是报错,证明你的系统里面没有curl这个软件,请执行以下命令先安装curl软件,安装curl之后再去执行上面代码,
|
||||
```
|
||||
apt update -y&&apt install -y curl&&apt install -y socat
|
||||
```
|
||||
|
||||
- 若要对版本进行升级,可直接通过脚本选择【2】,如下图:
|
||||

|
||||

|
||||
- 在到这一步必须要注意:要保留旧设置的话,需要输入【n】
|
||||

|
||||
|
||||
|
||||
## 安装指定版本
|
||||
|
||||
若要安装指定的版本,请使用以下安装命令。 e.g., ver `v2.4.5`:
|
||||
|
||||
```
|
||||
VERSION=v2.4.5 && bash <(curl -Ls "https://raw.githubusercontent.com/xeefei/3x-ui/$VERSION/install.sh") $VERSION
|
||||
```
|
||||
------------
|
||||
## 若你的VPS默认有防火墙,请在安装完成之后放行指定端口
|
||||
- 放行【面板登录端口】
|
||||
- 放行出入站管理协议端口
|
||||
- 如果要申请安装证书并每3个月【自动续签】证书,请确保80和443端口是放行打开的
|
||||
- 可通过此脚本的第【22】选项去安装防火墙进行管理,如下图:
|
||||

|
||||
- 若要一次性放行多个端口或一整个段的端口,用英文逗号隔开。
|
||||
#### PS:若你的VPS没有防火墙,则所有端口都是能够ping通的,可自行选择是否进入脚本安装防火墙保证安全,但安装了防火墙必须放行相应端口。
|
||||
|
||||
------------
|
||||
## 安装证书开启https方式实现域名登录访问管理面板/----->>偷自己
|
||||
#### PS:如果不需要以上功能或无域名,可以跳过这步;建议申请证书,
|
||||
##### 1、把自己的域名托管到CF,并解析到自己VPS的IP,不要开启【小云朵】,
|
||||
##### 2、如果要申请安装证书并每3个月【自动续签】证书,请确保80和443端口是放行打开的,
|
||||
##### 3、输入x-ui命令进入面板管理脚本,通过选择第【18】选项去进行安装,
|
||||
##### 4、在安装证书的最后一步,请输入【y】设置面板证书路径,如下图所示:
|
||||

|
||||
##### 5、进入后台【面板设置】—–>【常规】中,会看到脚本已经自动填好了证书公钥、私钥路径,
|
||||
##### 6、点击左上角的【保存】和【重启面板】,即可用自己域名进行登录管理;也可按照后续方法实现【自己偷自己】。
|
||||
|
||||
------------
|
||||
## 登录面板进行【常规】设置
|
||||
### 特别是如果在安装过程中,全部都是默认【回车键】安装的话,用户名/密码/访问路径是随机的,而面板监听端口默认是2053,最好进入面板更改,
|
||||
##### 1、填写自己想要设置的【面板监听端口】,并去登录SSH放行,
|
||||
##### 2、更改自己想要设置的【面板登录访问路径】,后续加上路径登录访问,
|
||||

|
||||
##### 3、其他:安全设定和电报机器人等配置,可自行根据需求去进行设置,
|
||||
##### 4、建议申请证书保护并在【脚本中】设置路径,建议配置电报机器人方便管理,
|
||||

|
||||
##### 5、面板设置【改动保存】之后,都需要点击左上角【重启面板】,才能生效。
|
||||
#### PS:若你在正确完成了上述步骤之后,你没有安装证书的情况下,去用【ssh转发】的方式却不能访问面板,那请检查一下是不是你的浏览器自动默认开启了https模式,需要手动调整一下改成http方式,把“s”去掉,即可访问成功;或查看一下是不是对应的端口被占用?
|
||||
|
||||
------------
|
||||
## 创建【入站协议】和添加【客户端】,并测试上网
|
||||
##### 1、点击左边【入站列表】,然后【添加入站】,传输方式保持【TCP】不变,尽量选择主流的vless+reality+vision协议组合,
|
||||

|
||||
##### 2、在选择reality安全选项时,偷的域名可以使用默认的,要使用其他的,请替换尽量保持一致就行,比如Apple、Yahoo,VPS所在地区的旅游、学校网站等;如果要实现【偷自己】,请参看后续【如何偷自己】的说明部分;而私钥/公钥部分,可以直接点击下方的【Get New Cert】获取一个随机的,
|
||||
##### 3、在创建reality安全选项过程中,至于其他诸如:PROXY Protocol,HTTP 伪装,TPROXY,External Proxy等等选项,若无特殊要求,保持默认设置即可,不用去动它们,
|
||||

|
||||
##### 4、创建好入站协议之后,默认只有一个客户端,可根据自己需求继续添加;重点:并编辑客户端,选择【Flow流控】为xtls-rprx-vision-udp443,
|
||||

|
||||
##### 5、其他:流量限制,到期时间,客户TG的ID等选项根据自己需求填写,
|
||||

|
||||
##### 6、一定要放行端口之后,确保端口能够ping通,再导入软件,
|
||||
##### 7、点击二维码或者复制链接导入到v2rayN等软件中进行测试。
|
||||
|
||||
------------
|
||||
## 备份与恢复/迁移数据库(以Debian系统为例)
|
||||
#### 一、备份:通过配置好电报管理机器人,并去设置开启【自动备份】,每天凌晨12点会通过VPS管理机器人获取【备份配置】文件,有x-ui.db和config.json两个文件,可自行下载保存到自己电脑里面,
|
||||

|
||||
#### 二、搭建:在新的VPS中全新安装好3x-ui面板,通过脚本放行之前配置的所有端口,一次性放行多个端口请用【英文逗号】分隔,
|
||||
#### 三、若需要安装证书,则提前把域名解析到新的VPS对应的IP,并且去输入x-ui选择第【18】选项去安装,并记录公钥/私钥的路径,无域名则跳过这一步,
|
||||
#### 四、恢复:SSH登录服务器找到/etc/x-ui/x-ui.db和/usr/local/x-ui/bin/config.json文件位置,上传之前的两个备份文件,进行覆盖,
|
||||

|
||||
##### PS:把之前通过自动备份下载得到的两个文件上传覆盖掉旧文件,重启3x-ui面板即可【迁移成功】;即使迁移过程中出现问题,你是有备份文件的,不用担心,多试几次。
|
||||

|
||||
#### 五、若安装了证书,去核对/更改一下证书的路径,一般是同一个域名的话,位置在:/root/cert/域名/fullchain.pem,路径是相同的就不用更改,
|
||||
#### 六、重启面板/重启服务器,让上述步骤生效即可,这时可以看到所有配置都是之前自己常用的,包括面板用户名、密码,入站、客户端,电报机器人配置等。
|
||||
|
||||
------------
|
||||
## 安装完成后如何设置调整成【中文界面】?
|
||||
- 方法一:通过管理后台【登录页面】调整,登录时可以选择,如下图:
|
||||

|
||||
- 方法二:通过在管理后台-->【面板设置】中去选择设置,如下图:
|
||||

|
||||
- 【TG机器人】设置中文:通过在管理后台-->【面板设置】-->【机器人配置】中去选择设置,并建议打开数据库备份和登录通知,如下图:
|
||||

|
||||
|
||||
------------
|
||||
## 用3x-ui如何实现【自己偷自己】?
|
||||
- 其实很简单,只要你为面板设置了证书,
|
||||
- 开启了HTTPS登录,就可以将3x-ui自身作为Web Server,
|
||||
- 无需Nginx等,这里给一个示例:
|
||||
- 其中目标网站(Dest)请填写面板监听端口,
|
||||
- 可选域名(SNI)填写面板登录域名,
|
||||
- 如果您使用其他web server(如nginx)等,
|
||||
- 将目标网站改为对应监听端口也可。
|
||||
- 需要说明的是,如果您处于白名单地区,自己“偷”自己并不适合你;
|
||||
- 其次,可选域名一项实际上可以填写任意SNI,只要客户端保持一致即可,不过并不推荐这样做。
|
||||
- 配置方法如下图所示:
|
||||

|
||||
|
||||
------------
|
||||
## 〔子域名〕被墙针对特征
|
||||
#### 网络表现:
|
||||
##### 1、可以Ping通域名和IP地址,
|
||||
##### 2、子域名无法打开3X-UI管理界面,
|
||||
##### 3、什么都正常就是不能上网;
|
||||
|
||||
#### 问题:
|
||||
##### 你的子域名被墙针对了:无法上网!
|
||||
|
||||
#### 解决方案:
|
||||
##### 1、更换为新的子域名,
|
||||
##### 2、解析新的子域名到VPS的IP,
|
||||
##### 3、重新去安装新证书,
|
||||
##### 4、重启3X-UI和服务器,
|
||||
##### 5、重新去获取链接并测试上网。
|
||||
#### PS:若通过以上步骤还是不能正常上网,则重装VPS服务器OS系统,以及3X-UI面板全部重新安装,之后就正常了!
|
||||
|
||||
------------
|
||||
## 用3x-ui中文版如何开启【设备限制】功能?
|
||||
##### 1、进入后台在【添加入站】的时候,弹出来的页面就能有【设备数量】输入框,
|
||||

|
||||
##### 2、通过步骤1设置完成后,在后台的【入站列表】页面也有对应的同步数据显示。
|
||||

|
||||
##### 3、具体要查看【设备限制】功能的封禁情况,就进入〔3X-UI中文版〕后台用日志查看。
|
||||

|
||||
##### 4、以下图片里面,详细阐述了我们的〔设备限制〕功能,跟3X-UI原本就有的〔IP Limit〕之间的区别对比。
|
||||

|
||||
|
||||
------------
|
||||
## 用3x-ui如何开启【每月流量自动重置】?
|
||||
##### 1、进入后台的【入站列表】,选择需要设置的【客户端】,
|
||||

|
||||
##### 2、要注意是编辑【入站】下面的【客户端】,才会有效果,
|
||||
##### 2、并不是编辑【入站】,所以不要弄错对象,如下图所示:
|
||||

|
||||
|
||||
|
||||
------------
|
||||
## 在自己的VPS服务器部署【订阅转换】功能
|
||||
### 如何把vless/vmess等协议转换成Clash/Surge等软件支持的格式?
|
||||
##### 1、进入脚本输入x-ui命令调取面板,选择第【25】选项安装订阅转换模块,
|
||||
##### 2、等待安装【订阅转换】成功之后,访问地址:https://你的域名:15268 ,
|
||||

|
||||
##### 3、因为在转换过程中需要调取后端API,所以请确保端口 8000 和 15268 是打开放行的,
|
||||
##### 4、直接复制脚本中提供的【登录地址】,进入后台,点击【节点列表】,如下图:
|
||||

|
||||
##### 5、接下来点击左边侧边栏的【订阅列表】去【添加订阅】,按照下图中去操作,
|
||||

|
||||
##### 6、最后一步,点击【客户端】,即可导入Clash等软件中使用。
|
||||

|
||||

|
||||
|
||||
------------
|
||||
## 常见的翻墙软件/工具:
|
||||
- [1、Windows系统v2rayN:https://github.com/2dust/v2rayN](https://github.com/2dust/v2rayN)
|
||||
- [2、安卓手机版【v2rayNG】:https://github.com/2dust/v2rayNG](https://github.com/2dust/v2rayNG)
|
||||
- [3、苹果手机IOS【小火箭】:https://apple02.com/(自己购买)](https://apple02.com/)
|
||||
- [4、苹果MacOS电脑【Clash Verge】:https://github.com/clash-verge-rev/clash-verge-rev/releases](https://github.com/clash-verge-rev/clash-verge-rev/releases)
|
||||
[或v2rayN:https://github.com/2dust/v2rayN](https://github.com/2dust/v2rayN)
|
||||
|
||||
------------
|
||||
## 如何保护自己的IP不被墙被封?
|
||||
##### 1、使用的代理协议要安全,加密是必备,推荐使用vless+reality+vision协议组合,
|
||||
##### 2、因为有时节点会共享,在不同的地区,多个省份之间不要共同连接同一个IP,
|
||||
##### 3、连接同一个IP就算了,不要同一个端口,不要同IP+同端口到处漫游,要分开,
|
||||
##### 4、同一台VPS,不要在一天内一直大流量去下载东西使用,不要流量过高要切换,
|
||||
##### 5、创建【入站协议】的时候,尽量用【高位端口】,比如40000--65000之间的端口号。
|
||||
#### 提醒:为什么在特殊时期,比如:两会,春节等被封得最严重最惨?
|
||||
##### 尼玛同一个IP+同一个端口号,多个省份去漫游,跟开飞机场一样!不封你,封谁的IP和端口?
|
||||
#### 总结:不要多终端/多省份/多个朋友/共同使用同一个IP和端口号!使用3x-ui多创建几个【入站】,
|
||||
#### 多做几条备用,各用各的!各行其道才比较安全!GFW的思维模式是干掉机场,机场的特征个人用户不要去沾染,自然IP就保护好了。
|
||||
|
||||
------------
|
||||
## SSL 认证
|
||||
|
||||
<details>
|
||||
<summary>点击查看 SSL 认证</summary>
|
||||
|
||||
### ACME
|
||||
|
||||
要使用 ACME 管理 SSL 证书:
|
||||
|
||||
1. 确保您的域名已正确解析到服务器,
|
||||
2. 输入“x-ui”命令并选择“SSL 证书管理”,
|
||||
3. 您将看到以下选项:
|
||||
|
||||
- **获取证书** ----获取SSL证书
|
||||
- **吊销证书** ----吊销现有的SSL证书
|
||||
- **续签证书** ----强制续签SSL证书
|
||||
- **显示所有证书** ----显示服务器中所有能用的证书
|
||||
- **设置面板证书路径** ----指定面板要使用的证书
|
||||
|
||||
|
||||
### Certbot
|
||||
|
||||
安装和使用 Certbot:
|
||||
|
||||
```sh
|
||||
apt-get install certbot -y
|
||||
certbot certonly --standalone --agree-tos --register-unsafely-without-email -d yourdomain.com
|
||||
certbot renew --dry-run
|
||||
```
|
||||
|
||||
### Cloudflare
|
||||
|
||||
管理脚本具有用于 Cloudflare 的内置 SSL 证书应用程序。若要使用此脚本申请证书,需要满足以下条件:
|
||||
|
||||
- Cloudflare 邮箱地址
|
||||
- Cloudflare Global API Key
|
||||
- 域名已通过 cloudflare 解析到当前服务器
|
||||
|
||||
**如何获取 Cloudflare全局API密钥:**
|
||||
|
||||
1. 在终端中输入“x-ui”命令,然后选择“CF SSL 证书”。
|
||||
2. 访问链接: [Cloudflare API Tokens](https://dash.cloudflare.com/profile/api-tokens).
|
||||
3. 点击“查看全局 API 密钥”(如下图所示):
|
||||

|
||||
4. 您可能需要重新验证您的帐户。之后,将显示 API 密钥(请参见下面的屏幕截图):
|
||||

|
||||
|
||||
使用时,只需输入您的“域名”、“电子邮件”和“API KEY”即可。示意图如下:
|
||||

|
||||
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## 手动安装 & 升级
|
||||
|
||||
<details>
|
||||
<summary>点击查看 手动安装 & 升级</summary>
|
||||
|
||||
#### 使用
|
||||
|
||||
1. 若要将最新版本的压缩包直接下载到服务器,请运行以下命令:
|
||||
|
||||
```sh
|
||||
ARCH=$(uname -m)
|
||||
case "${ARCH}" in
|
||||
x86_64 | x64 | amd64) XUI_ARCH="amd64" ;;
|
||||
i*86 | x86) XUI_ARCH="386" ;;
|
||||
armv8* | armv8 | arm64 | aarch64) XUI_ARCH="arm64" ;;
|
||||
armv7* | armv7) XUI_ARCH="armv7" ;;
|
||||
armv6* | armv6) XUI_ARCH="armv6" ;;
|
||||
armv5* | armv5) XUI_ARCH="armv5" ;;
|
||||
s390x) echo 's390x' ;;
|
||||
*) XUI_ARCH="amd64" ;;
|
||||
esac
|
||||
|
||||
|
||||
wget https://github.com/xeefei/3x-ui/releases/latest/download/x-ui-linux-${XUI_ARCH}.tar.gz
|
||||
```
|
||||
|
||||
2. 下载压缩包后,执行以下命令安装或升级 x-ui:
|
||||
|
||||
```sh
|
||||
ARCH=$(uname -m)
|
||||
case "${ARCH}" in
|
||||
x86_64 | x64 | amd64) XUI_ARCH="amd64" ;;
|
||||
i*86 | x86) XUI_ARCH="386" ;;
|
||||
armv8* | armv8 | arm64 | aarch64) XUI_ARCH="arm64" ;;
|
||||
armv7* | armv7) XUI_ARCH="armv7" ;;
|
||||
armv6* | armv6) XUI_ARCH="armv6" ;;
|
||||
armv5* | armv5) XUI_ARCH="armv5" ;;
|
||||
s390x) echo 's390x' ;;
|
||||
*) XUI_ARCH="amd64" ;;
|
||||
esac
|
||||
|
||||
cd /root/
|
||||
rm -rf x-ui/ /usr/local/x-ui/ /usr/bin/x-ui
|
||||
tar zxvf x-ui-linux-${XUI_ARCH}.tar.gz
|
||||
chmod +x x-ui/x-ui x-ui/bin/xray-linux-* x-ui/x-ui.sh
|
||||
cp x-ui/x-ui.sh /usr/bin/x-ui
|
||||
cp -f x-ui/x-ui.service /etc/systemd/system/
|
||||
mv x-ui/ /usr/local/
|
||||
systemctl daemon-reload
|
||||
systemctl enable x-ui
|
||||
systemctl restart x-ui
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## 通过Docker安装
|
||||
|
||||
<details>
|
||||
<summary>点击查看 通过Docker安装</summary>
|
||||
|
||||
#### 使用
|
||||
|
||||
|
||||
1. **安装Docker**
|
||||
|
||||
```sh
|
||||
bash <(curl -sSL https://get.docker.com)
|
||||
```
|
||||
|
||||
|
||||
2. **克隆项目仓库**
|
||||
|
||||
```sh
|
||||
git clone https://github.com/xeefei/3x-ui.git
|
||||
cd 3x-ui
|
||||
```
|
||||
|
||||
3. **启动服务**:
|
||||
|
||||
```sh
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
添加 ```--pull always``` 标志使 docker 在拉取更新的镜像时自动重新创建容器。有关更多信息,请参阅:https://docs.docker.com/reference/cli/docker/container/run/#pull
|
||||
|
||||
**或**
|
||||
|
||||
```sh
|
||||
docker run -itd \
|
||||
-e XRAY_VMESS_AEAD_FORCED=false \
|
||||
-v $PWD/db/:/etc/x-ui/ \
|
||||
-v $PWD/cert/:/root/cert/ \
|
||||
--network=host \
|
||||
--restart=unless-stopped \
|
||||
--name 3x-ui \
|
||||
ghcr.io/xeefei/3x-ui:latest
|
||||
```
|
||||
|
||||
4. **更新至最新版本**
|
||||
|
||||
```sh
|
||||
cd 3x-ui
|
||||
docker compose down
|
||||
docker compose pull 3x-ui
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
5. **从Docker中删除3x-ui **
|
||||
|
||||
```sh
|
||||
docker stop 3x-ui
|
||||
docker rm 3x-ui
|
||||
cd --
|
||||
rm -r 3x-ui
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## 建议使用的操作系统
|
||||
|
||||
- Ubuntu 20.04+
|
||||
- Debian 11+
|
||||
- CentOS 8+
|
||||
- OpenEuler 22.03+
|
||||
- Fedora 36+
|
||||
- Arch Linux
|
||||
- Manjaro
|
||||
- Armbian
|
||||
- AlmaLinux 8.0+
|
||||
- Rocky Linux 8+
|
||||
- Oracle Linux 8+
|
||||
- OpenSUSE Tubleweed
|
||||
- Amazon Linux 2023
|
||||
|
||||
------------
|
||||
## 支持的架构和设备
|
||||
<details>
|
||||
<summary>点击查看 支持的架构和设备</summary>
|
||||
|
||||
我们的平台提供与各种架构和设备的兼容性,确保在各种计算环境中的灵活性。以下是我们支持的关键架构:
|
||||
|
||||
- **amd64**: 这种流行的架构是个人计算机和服务器的标准,可以无缝地适应大多数现代操作系统。
|
||||
|
||||
- **x86 / i386**: 这种架构在台式机和笔记本电脑中被广泛采用,得到了众多操作系统和应用程序的广泛支持,包括但不限于 Windows、macOS 和 Linux 系统。
|
||||
|
||||
- **armv8 / arm64 / aarch64**: 这种架构专为智能手机和平板电脑等当代移动和嵌入式设备量身定制,以 Raspberry Pi 4、Raspberry Pi 3、Raspberry Pi Zero 2/Zero 2 W、Orange Pi 3 LTS 等设备为例。
|
||||
|
||||
- **armv7 / arm / arm32**: 作为较旧的移动和嵌入式设备的架构,它仍然广泛用于Orange Pi Zero LTS、Orange Pi PC Plus、Raspberry Pi 2等设备。
|
||||
|
||||
- **armv6 / arm / arm32**: 这种架构面向非常老旧的嵌入式设备,虽然不太普遍,但仍在使用中。Raspberry Pi 1、Raspberry Pi Zero/Zero W 等设备都依赖于这种架构。
|
||||
|
||||
- **armv5 / arm / arm32**: 它是一种主要与早期嵌入式系统相关的旧架构,目前不太常见,但仍可能出现在早期 Raspberry Pi 版本和一些旧智能手机等传统设备中。
|
||||
</details>
|
||||
|
||||
------------
|
||||
## Languages
|
||||
|
||||
- English(英语)
|
||||
- Farsi(伊朗语)
|
||||
- Simplified Chinese(简体中文)
|
||||
- Traditional Chinese(繁体中文)
|
||||
- Russian(俄语)
|
||||
- Vietnamese(越南语)
|
||||
- Spanish(西班牙语)
|
||||
- Indonesian (印度尼西亚语)
|
||||
- Ukrainian(乌克兰语)
|
||||
- Turkish(土耳其语)
|
||||
- Português (葡萄牙语)
|
||||
|
||||
------------
|
||||
## 项目特点
|
||||
|
||||
- 系统状态查看与监控
|
||||
- 可搜索所有入站和客户端信息
|
||||
- 深色/浅色主题随意切换
|
||||
- 支持多用户和多协议
|
||||
- 支持多种协议,包括 VMess、VLESS、Trojan、Shadowsocks、Dokodemo-door、Socks、HTTP、wireguard
|
||||
- 支持 XTLS 原生协议,包括 RPRX-Direct、Vision、REALITY
|
||||
- 流量统计、流量限制、过期时间限制
|
||||
- 可自定义的 Xray配置模板
|
||||
- 支持HTTPS访问面板(自备域名+SSL证书)
|
||||
- 支持一键式SSL证书申请和自动续签证书
|
||||
- 更多高级配置项目请参考面板去进行设定
|
||||
- 修复了 API 路由(用户设置将使用 API 创建)
|
||||
- 支持通过面板中提供的不同项目更改配置。
|
||||
- 支持从面板导出/导入数据库
|
||||
|
||||
## 默认面板设置
|
||||
|
||||
<details>
|
||||
|
||||
<summary>点击查看 默认设置</summary>
|
||||
|
||||
### 默认信息
|
||||
|
||||
- **端口**
|
||||
- 2053
|
||||
- **用户名 & 密码 & 访问路径**
|
||||
- 当您跳过设置时,这些信息会随机生成,
|
||||
- 您也可以在安装的时候自定义访问路径。
|
||||
- **数据库路径:**
|
||||
- /etc/x-ui/x-ui.db
|
||||
- **Xray 配置路径:**
|
||||
- /usr/local/x-ui/bin/config.json
|
||||
- **面板链接(无SSL):**
|
||||
- http://ip:2053/访问路径/panel
|
||||
- **面板链接(有SSL):**
|
||||
- https://你的域名:2053/访问路径/panel
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## [WARP 配置](https://gitlab.com/fscarmen/warp)
|
||||
|
||||
<details>
|
||||
<summary>点击查看 WARP 配置</summary>
|
||||
|
||||
#### 使用
|
||||
|
||||
**对于版本 `v2.1.0` 及更高版本:**
|
||||
|
||||
WARP 是内置的,无需额外安装;只需在面板中打开必要的配置即可。
|
||||
|
||||
**如果要在 v2.1.0 之前使用 WARP 路由**,请按照以下步骤操作:
|
||||
|
||||
**1.** 在 **SOCKS Proxy Mode** 模式中安装Wrap
|
||||
|
||||
- **Account Type (free, plus, team):** Choose the appropriate account type.
|
||||
- **Enable/Disable WireProxy:** Toggle WireProxy on or off.
|
||||
- **Uninstall WARP:** Remove the WARP application.
|
||||
|
||||
**2.** 如果您已经安装了 warp,您可以使用以下命令卸载:
|
||||
|
||||
```sh
|
||||
warp u
|
||||
```
|
||||
|
||||
**3.** 在面板中打开您需要的配置
|
||||
|
||||
配置:
|
||||
|
||||
- Block Ads
|
||||
- Route Google, Netflix, Spotify, and OpenAI (ChatGPT) traffic to WARP
|
||||
- Fix Google 403 error
|
||||
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## IP 限制
|
||||
|
||||
<details>
|
||||
<summary>点击查看 IP 限制</summary>
|
||||
|
||||
#### 使用
|
||||
|
||||
**注意:** 使用 IP 隧道时,IP 限制无法正常工作。
|
||||
|
||||
- 对于 `v1.6.1`之前的版本 :
|
||||
|
||||
- IP 限制 已被集成在面板中。
|
||||
|
||||
- 对于 `v1.7.0` 以及更新的版本:
|
||||
|
||||
- 要使 IP 限制正常工作,您需要按照以下步骤安装 fail2ban 及其所需的文件:
|
||||
|
||||
1. 使用面板内置的 `x-ui` 指令
|
||||
2. 选择 `IP Limit Management`.
|
||||
3. 根据您的需要选择合适的选项。
|
||||
|
||||
- 确保您的 Xray 配置上有 ./access.log 。在 v2.1.3 之后,我们有一个选项。
|
||||
|
||||
```sh
|
||||
"log": {
|
||||
"access": "./access.log",
|
||||
"dnsLog": false,
|
||||
"loglevel": "warning"
|
||||
},
|
||||
```
|
||||
- 您需要在Xray配置中手动设置〔访问日志〕的路径。
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## Telegram 机器人
|
||||
|
||||
<details>
|
||||
<summary>点击查看 Telegram 机器人</summary>
|
||||
|
||||
#### 使用
|
||||
|
||||
Web 面板通过 Telegram Bot 支持每日流量、面板登录、数据库备份、系统状态、客户端信息等通知和功能。要使用机器人,您需要在面板中设置机器人相关参数,包括:
|
||||
|
||||
- 电报令牌
|
||||
- 管理员聊天 ID
|
||||
- 通知时间(cron 语法)
|
||||
- 到期日期通知
|
||||
- 流量上限通知
|
||||
- 数据库备份
|
||||
- CPU 负载通知
|
||||
|
||||
|
||||
**参考:**
|
||||
|
||||
- `30 \* \* \* \* \*` - 在每个点的 30 秒处通知
|
||||
- `0 \*/10 \* \* \* \*` - 每 10 分钟的第一秒通知
|
||||
- `@hourly` - 每小时通知
|
||||
- `@daily` - 每天通知 (00:00)
|
||||
- `@weekly` - 每周通知
|
||||
- `@every 8h` - 每8小时通知
|
||||
|
||||
### Telegram Bot 功能
|
||||
|
||||
- 定期报告
|
||||
- 登录通知
|
||||
- CPU 阈值通知
|
||||
- 提前报告的过期时间和流量阈值
|
||||
- 如果将客户的电报用户名添加到用户的配置中,则支持客户端报告菜单
|
||||
- 支持使用UUID(VMESS/VLESS)或密码(TROJAN)搜索报文流量报告 - 匿名
|
||||
- 基于菜单的机器人
|
||||
- 通过电子邮件搜索客户端(仅限管理员)
|
||||
- 检查所有入库
|
||||
- 检查服务器状态
|
||||
- 检查耗尽的用户
|
||||
- 根据请求和定期报告接收备份
|
||||
- 多语言机器人
|
||||
|
||||
### 注册 Telegram bot
|
||||
|
||||
- 与 [Botfather](https://t.me/BotFather) 对话:
|
||||

|
||||
|
||||
- 使用 /newbot 创建新机器人:你需要提供机器人名称以及用户名,注意名称中末尾要包含“bot”
|
||||

|
||||
|
||||
- 启动您刚刚创建的机器人。可以在此处找到机器人的链接。
|
||||

|
||||
|
||||
- 输入您的面板并配置 Telegram 机器人设置,如下所示:
|
||||

|
||||
|
||||
在输入字段编号 3 中输入机器人令牌。
|
||||
在输入字段编号 4 中输入用户 ID。具有此 id 的 Telegram 帐户将是机器人管理员。 (您可以输入多个,只需将它们用“ ,”分开即可)
|
||||
|
||||
- 如何获取TG ID? 使用 [bot](https://t.me/useridinfobot), 启动机器人,它会给你 Telegram 用户 ID。
|
||||

|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## API 路由
|
||||
|
||||
<details>
|
||||
<summary>点击查看 API 路由</summary>
|
||||
|
||||
#### 使用
|
||||
|
||||
- `/login` 使用 `POST` 用户名称 & 密码: `{username: '', password: ''}` 登录
|
||||
- `/panel/api/inbounds` 以下操作的基础:
|
||||
|
||||
| 方法 | 路径 | 操作 |
|
||||
| :----: | ---------------------------------- | ------------------------------------------- |
|
||||
| `GET` | `"/list"` | 获取所有入站 |
|
||||
| `GET` | `"/get/:id"` | 获取所有入站以及inbound.id |
|
||||
| `GET` | `"/getClientTraffics/:email"` | 通过电子邮件获取客户端流量 |
|
||||
| `GET` | `"/getClientTrafficsById/:id"` | 通过用户ID获取客户端流量 |
|
||||
| `GET` | `"/createbackup"` | Telegram 机器人向管理员发送备份 |
|
||||
| `POST` | `"/add"` | 添加入站 |
|
||||
| `POST` | `"/del/:id"` | 删除入站 |
|
||||
| `POST` | `"/update/:id"` | 更新入站 |
|
||||
| `POST` | `"/clientIps/:email"` | 客户端 IP 地址 |
|
||||
| `POST` | `"/clearClientIps/:email"` | 清除客户端 IP 地址 |
|
||||
| `POST` | `"/addClient"` | 将客户端添加到入站 |
|
||||
| `POST` | `"/:id/delClient/:clientId"` | 通过 clientId\* 删除客户端 |
|
||||
| `POST` | `"/updateClient/:clientId"` | 通过 clientId\* 更新客户端 |
|
||||
| `POST` | `"/:id/resetClientTraffic/:email"` | 重置客户端的流量 |
|
||||
| `POST` | `"/resetAllTraffics"` | 重置所有入站的流量 |
|
||||
| `POST` | `"/resetAllClientTraffics/:id"` | 重置入站中所有客户端的流量 |
|
||||
| `POST` | `"/delDepletedClients/:id"` | 删除入站耗尽的客户端 (-1: all) |
|
||||
| `POST` | `"/onlines"` | 获取在线用户 ( 电子邮件列表 ) |
|
||||
|
||||
- 使用`clientId` 项应该填写下列数据:
|
||||
|
||||
- `client.id` for VMESS and VLESS
|
||||
- `client.password` for TROJAN
|
||||
- `client.email` for Shadowsocks
|
||||
|
||||
|
||||
|
||||
- [API 文档](https://documenter.getpostman.com/view/16802678/2s9YkgD5jm)
|
||||
|
||||
- [<img src="https://run.pstmn.io/button.svg" alt="Run In Postman" style="width: 128px; height: 32px;">](https://app.getpostman.com/run-collection/16802678-1a4c9270-ac77-40ed-959a-7aa56dc4a415?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D16802678-1a4c9270-ac77-40ed-959a-7aa56dc4a415%26entityType%3Dcollection%26workspaceId%3D2cd38c01-c851-4a15-a972-f181c23359d9)
|
||||
</details>
|
||||
|
||||
------------
|
||||
## 环境变量
|
||||
|
||||
<details>
|
||||
<summary>点击查看 环境变量</summary>
|
||||
|
||||
#### Usage
|
||||
|
||||
| 变量 | Type | 默认 |
|
||||
| -------------- | :--------------------------------------------: | :------------ |
|
||||
| XUI_LOG_LEVEL | `"debug"` \| `"info"` \| `"warn"` \| `"error"` | `"info"` |
|
||||
| XUI_DEBUG | `boolean` | `false` |
|
||||
| XUI_BIN_FOLDER | `string` | `"bin"` |
|
||||
| XUI_DB_FOLDER | `string` | `"/etc/x-ui"` |
|
||||
| XUI_LOG_FOLDER | `string` | `"/var/log"` |
|
||||
|
||||
例子:
|
||||
|
||||
```sh
|
||||
XUI_BIN_FOLDER="bin" XUI_DB_FOLDER="/etc/x-ui" go build main.go
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
------------
|
||||
## 预览
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
------------
|
||||
## 广告赞助
|
||||
- 如果你觉得本项目对你有用,而且你也恰巧有这方面的需求,你也可以选择通过我的购买链接赞助我。
|
||||
- [1、搬瓦工GIA高端线路,仅推荐购买GIA套餐:https://bandwagonhost.com/aff.php?aff=75015](https://bandwagonhost.com/aff.php?aff=75015)
|
||||
- [2、Dmit高端GIA线路:https://www.dmit.io/aff.php?aff=9326](https://www.dmit.io/aff.php?aff=9326)
|
||||
- [3、白丝云【4837线路】实惠量大管饱:https://cloudsilk.io/aff.php?aff=706](https://cloudsilk.io/aff.php?aff=706)
|
||||
|
||||
------------
|
||||
## 特别感谢
|
||||
|
||||
- [MHSanaei](https://github.com/MHSanaei/)
|
||||
- [alireza0](https://github.com/alireza0/)
|
||||
- [FranzKafkaYu](https://github.com/FranzKafkaYu/)
|
||||
- [vaxilu](https://github.com/vaxilu/)
|
||||
|
||||
------------
|
||||
## 致谢
|
||||
|
||||
- [Iran v2ray rules](https://github.com/chocolate4u/Iran-v2ray-rules) (License: **GPL-3.0**): _Enhanced v2ray/xray and v2ray/xray-clients routing rules with built-in Iranian domains and a focus on security and adblocking._
|
||||
- [Vietnam Adblock rules](https://github.com/vuong2023/vn-v2ray-rules) (License: **GPL-3.0**): _A hosted domain hosted in Vietnam and blocklist with the most efficiency for Vietnamese._
|
||||
|
||||
------------
|
||||
## Star 趋势
|
||||
|
||||
[](https://starchart.cc/xeefei/3x-ui)
|
||||
|
||||
@ -36,6 +36,9 @@ type Inbound struct {
|
||||
Remark string `json:"remark" form:"remark"`
|
||||
Enable bool `json:"enable" form:"enable"`
|
||||
ExpiryTime int64 `json:"expiryTime" form:"expiryTime"`
|
||||
// 中文注释: 新增设备限制字段,用于存储每个入站的设备数限制。
|
||||
// gorm:"column:device_limit;default:0" 定义了数据库中的字段名和默认值。
|
||||
DeviceLimit int `json:"deviceLimit" form:"deviceLimit" gorm:"column:device_limit;default:0"`
|
||||
ClientStats []xray.ClientTraffic `gorm:"foreignKey:InboundId;references:Id" json:"clientStats" form:"clientStats"`
|
||||
|
||||
// config part
|
||||
|
||||
470
install.sh
@ -9,7 +9,7 @@ plain='\033[0m'
|
||||
cur_dir=$(pwd)
|
||||
|
||||
# check root
|
||||
[[ $EUID -ne 0 ]] && echo -e "${red}Fatal error: ${plain} Please run this script with root privilege \n " && exit 1
|
||||
[[ $EUID -ne 0 ]] && echo -e "${red}致命错误: ${plain} 请使用 root 权限运行此脚本\n" && exit 1
|
||||
|
||||
# Check OS and set release variable
|
||||
if [[ -f /etc/os-release ]]; then
|
||||
@ -19,45 +19,148 @@ elif [[ -f /usr/lib/os-release ]]; then
|
||||
source /usr/lib/os-release
|
||||
release=$ID
|
||||
else
|
||||
echo "Failed to check the system OS, please contact the author!" >&2
|
||||
echo ""
|
||||
echo -e "${red}检查服务器操作系统失败,请联系作者!${plain}" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "The OS release is: $release"
|
||||
echo ""
|
||||
echo -e "${green}---------->>>>>目前服务器的操作系统为: $release${plain}"
|
||||
|
||||
arch() {
|
||||
case "$(uname -m)" in
|
||||
x86_64 | x64 | amd64) echo 'amd64' ;;
|
||||
i*86 | x86) echo '386' ;;
|
||||
armv8* | armv8 | arm64 | aarch64) echo 'arm64' ;;
|
||||
armv7* | armv7 | arm) echo 'armv7' ;;
|
||||
armv6* | armv6) echo 'armv6' ;;
|
||||
armv5* | armv5) echo 'armv5' ;;
|
||||
s390x) echo 's390x' ;;
|
||||
*) echo -e "${green}Unsupported CPU architecture! ${plain}" && rm -f install.sh && exit 1 ;;
|
||||
x86_64 | x64 | amd64 ) echo 'amd64' ;;
|
||||
i*86 | x86 ) echo '386' ;;
|
||||
armv8* | armv8 | arm64 | aarch64 ) echo 'arm64' ;;
|
||||
armv7* | armv7 | arm ) echo 'armv7' ;;
|
||||
armv6* | armv6 ) echo 'armv6' ;;
|
||||
armv5* | armv5 ) echo 'armv5' ;;
|
||||
s390x) echo 's390x' ;;
|
||||
*) echo -e "${green}不支持的CPU架构! ${plain}" && rm -f install.sh && exit 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
echo "Arch: $(arch)"
|
||||
echo ""
|
||||
# check_glibc_version() {
|
||||
# glibc_version=$(ldd --version | head -n1 | awk '{print $NF}')
|
||||
|
||||
# required_version="2.32"
|
||||
# if [[ "$(printf '%s\n' "$required_version" "$glibc_version" | sort -V | head -n1)" != "$required_version" ]]; then
|
||||
# echo -e "${red}------>>>GLIBC版本 $glibc_version 太旧了! 要求2.32或以上版本${plain}"
|
||||
# echo -e "${green}-------->>>>请升级到较新版本的操作系统以便获取更高版本的GLIBC${plain}"
|
||||
# exit 1
|
||||
# fi
|
||||
# echo -e "${green}-------->>>>GLIBC版本: $glibc_version(符合高于2.32的要求)${plain}"
|
||||
# }
|
||||
# check_glibc_version
|
||||
|
||||
# echo ""
|
||||
echo -e "${yellow}---------->>>>>当前系统的架构为: $(arch)${plain}"
|
||||
echo ""
|
||||
last_version=$(curl -Ls "https://api.github.com/repos/xeefei/3x-ui/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
|
||||
# 获取 x-ui 版本
|
||||
xui_version=$(/usr/local/x-ui/x-ui -v)
|
||||
|
||||
# 检查 xui_version 是否为空
|
||||
if [[ -z "$xui_version" ]]; then
|
||||
echo ""
|
||||
echo -e "${red}------>>>当前服务器没有安装任何 x-ui 系列代理面板${plain}"
|
||||
echo ""
|
||||
echo -e "${green}-------->>>>片刻之后脚本将会自动引导安装〔3X-UI优化版〕${plain}"
|
||||
else
|
||||
# 检查版本号中是否包含冒号
|
||||
if [[ "$xui_version" == *:* ]]; then
|
||||
echo -e "${green}---------->>>>>当前代理面板的版本为: ${red}其他 x-ui 分支版本${plain}"
|
||||
echo ""
|
||||
echo -e "${green}-------->>>>片刻之后脚本将会自动引导安装〔3X-UI优化版〕${plain}"
|
||||
else
|
||||
echo -e "${green}---------->>>>>当前代理面板的版本为: ${red}〔3X-UI优化版〕v${xui_version}${plain}"
|
||||
fi
|
||||
fi
|
||||
echo ""
|
||||
echo -e "${yellow}---------------------->>>>>〔3X-UI优化版〕最新版为:${last_version}${plain}"
|
||||
sleep 4
|
||||
|
||||
os_version=$(grep -i version_id /etc/os-release | cut -d \" -f2 | cut -d . -f1)
|
||||
|
||||
if [[ "${release}" == "arch" ]]; then
|
||||
echo "您的操作系统是 ArchLinux"
|
||||
elif [[ "${release}" == "manjaro" ]]; then
|
||||
echo "您的操作系统是 Manjaro"
|
||||
elif [[ "${release}" == "armbian" ]]; then
|
||||
echo "您的操作系统是 Armbian"
|
||||
elif [[ "${release}" == "alpine" ]]; then
|
||||
echo "您的操作系统是 Alpine Linux"
|
||||
elif [[ "${release}" == "opensuse-tumbleweed" ]]; then
|
||||
echo "您的操作系统是 OpenSUSE Tumbleweed"
|
||||
elif [[ "${release}" == "centos" ]]; then
|
||||
if [[ ${os_version} -lt 8 ]]; then
|
||||
echo -e "${red} 请使用 CentOS 8 或更高版本 ${plain}\n" && exit 1
|
||||
fi
|
||||
elif [[ "${release}" == "ubuntu" ]]; then
|
||||
if [[ ${os_version} -lt 20 ]]; then
|
||||
echo -e "${red} 请使用 Ubuntu 20 或更高版本!${plain}\n" && exit 1
|
||||
fi
|
||||
elif [[ "${release}" == "fedora" ]]; then
|
||||
if [[ ${os_version} -lt 36 ]]; then
|
||||
echo -e "${red} 请使用 Fedora 36 或更高版本!${plain}\n" && exit 1
|
||||
fi
|
||||
elif [[ "${release}" == "debian" ]]; then
|
||||
if [[ ${os_version} -lt 11 ]]; then
|
||||
echo -e "${red} 请使用 Debian 11 或更高版本 ${plain}\n" && exit 1
|
||||
fi
|
||||
elif [[ "${release}" == "almalinux" ]]; then
|
||||
if [[ ${os_version} -lt 9 ]]; then
|
||||
echo -e "${red} 请使用 AlmaLinux 9 或更高版本 ${plain}\n" && exit 1
|
||||
fi
|
||||
elif [[ "${release}" == "rocky" ]]; then
|
||||
if [[ ${os_version} -lt 9 ]]; then
|
||||
echo -e "${red} 请使用 RockyLinux 9 或更高版本 ${plain}\n" && exit 1
|
||||
fi
|
||||
elif [[ "${release}" == "oracle" ]]; then
|
||||
if [[ ${os_version} -lt 8 ]]; then
|
||||
echo -e "${red} 请使用 Oracle Linux 8 或更高版本 ${plain}\n" && exit 1
|
||||
fi
|
||||
else
|
||||
echo -e "${red}此脚本不支持您的操作系统。${plain}\n"
|
||||
echo "请确保您使用的是以下受支持的操作系统之一:"
|
||||
echo "- Ubuntu 20.04+"
|
||||
echo "- Debian 11+"
|
||||
echo "- CentOS 8+"
|
||||
echo "- Fedora 36+"
|
||||
echo "- Arch Linux"
|
||||
echo "- Manjaro"
|
||||
echo "- Armbian"
|
||||
echo "- Alpine Linux"
|
||||
echo "- AlmaLinux 9+"
|
||||
echo "- Rocky Linux 9+"
|
||||
echo "- Oracle Linux 8+"
|
||||
echo "- OpenSUSE Tumbleweed"
|
||||
exit 1
|
||||
|
||||
fi
|
||||
|
||||
install_base() {
|
||||
case "${release}" in
|
||||
ubuntu | debian | armbian)
|
||||
apt-get update && apt-get install -y -q wget curl tar tzdata
|
||||
apt-get update && apt-get install -y -q wget curl sudo tar tzdata
|
||||
;;
|
||||
centos | rhel | almalinux | rocky | ol)
|
||||
yum -y update && yum install -y -q wget curl tar tzdata
|
||||
yum -y update && yum install -y -q wget curl sudo tar tzdata
|
||||
;;
|
||||
fedora | amzn | virtuozzo)
|
||||
dnf -y update && dnf install -y -q wget curl tar tzdata
|
||||
dnf -y update && dnf install -y -q wget curl sudo tar tzdata
|
||||
;;
|
||||
arch | manjaro | parch)
|
||||
pacman -Syu && pacman -Syu --noconfirm wget curl tar tzdata
|
||||
pacman -Syu && pacman -Syu --noconfirm wget curl sudo tar tzdata
|
||||
;;
|
||||
alpine)
|
||||
apk update && apk add --no-cache wget curl sudo tar tzdata
|
||||
;;
|
||||
opensuse-tumbleweed)
|
||||
zypper refresh && zypper -q install -y wget curl tar timezone
|
||||
zypper refresh && zypper -q install -y wget curl sudo tar timezone
|
||||
;;
|
||||
*)
|
||||
apt-get update && apt-get install -y -q wget curl tar tzdata
|
||||
apt-get update && apt-get install -y -q wget curl sudo tar tzdata
|
||||
;;
|
||||
esac
|
||||
}
|
||||
@ -68,120 +171,120 @@ gen_random_string() {
|
||||
echo "$random_string"
|
||||
}
|
||||
|
||||
# This function will be called when user installed x-ui out of security
|
||||
config_after_install() {
|
||||
local existing_hasDefaultCredential=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'hasDefaultCredential: .+' | awk '{print $2}')
|
||||
local existing_webBasePath=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'webBasePath: .+' | awk '{print $2}')
|
||||
local existing_port=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'port: .+' | awk '{print $2}')
|
||||
local URL_lists=(
|
||||
"https://api4.ipify.org"
|
||||
"https://ipv4.icanhazip.com"
|
||||
"https://v4.api.ipinfo.io/ip"
|
||||
"https://ipv4.myexternalip.com/raw"
|
||||
"https://4.ident.me"
|
||||
"https://check-host.net/ip"
|
||||
)
|
||||
local server_ip=""
|
||||
for ip_address in "${URL_lists[@]}"; do
|
||||
server_ip=$(curl -s --max-time 3 "${ip_address}" 2>/dev/null | tr -d '[:space:]')
|
||||
if [[ -n "${server_ip}" ]]; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ ${#existing_webBasePath} -lt 4 ]]; then
|
||||
if [[ "$existing_hasDefaultCredential" == "true" ]]; then
|
||||
local config_webBasePath=$(gen_random_string 18)
|
||||
local config_username=$(gen_random_string 10)
|
||||
local config_password=$(gen_random_string 10)
|
||||
|
||||
read -rp "Would you like to customize the Panel Port settings? (If not, a random port will be applied) [y/n]: " config_confirm
|
||||
if [[ "${config_confirm}" == "y" || "${config_confirm}" == "Y" ]]; then
|
||||
read -rp "Please set up the panel port: " config_port
|
||||
echo -e "${yellow}Your Panel Port is: ${config_port}${plain}"
|
||||
else
|
||||
local config_port=$(shuf -i 1024-62000 -n 1)
|
||||
echo -e "${yellow}Generated random port: ${config_port}${plain}"
|
||||
fi
|
||||
|
||||
/usr/local/x-ui/x-ui setting -username "${config_username}" -password "${config_password}" -port "${config_port}" -webBasePath "${config_webBasePath}"
|
||||
echo -e "This is a fresh installation, generating random login info for security concerns:"
|
||||
echo -e "###############################################"
|
||||
echo -e "${green}Username: ${config_username}${plain}"
|
||||
echo -e "${green}Password: ${config_password}${plain}"
|
||||
echo -e "${green}Port: ${config_port}${plain}"
|
||||
echo -e "${green}WebBasePath: ${config_webBasePath}${plain}"
|
||||
echo -e "${green}Access URL: http://${server_ip}:${config_port}/${config_webBasePath}${plain}"
|
||||
echo -e "###############################################"
|
||||
else
|
||||
local config_webBasePath=$(gen_random_string 18)
|
||||
echo -e "${yellow}WebBasePath is missing or too short. Generating a new one...${plain}"
|
||||
/usr/local/x-ui/x-ui setting -webBasePath "${config_webBasePath}"
|
||||
echo -e "${green}New WebBasePath: ${config_webBasePath}${plain}"
|
||||
echo -e "${green}Access URL: http://${server_ip}:${existing_port}/${config_webBasePath}${plain}"
|
||||
fi
|
||||
echo -e "${yellow}安装/更新完成! 为了您的面板安全,建议修改面板设置 ${plain}"
|
||||
echo ""
|
||||
read -p "$(echo -e "${green}想继续修改吗?${red}选择“n”以保留旧设置${plain} [y/n]?--->>请输入:")" config_confirm
|
||||
if [[ "${config_confirm}" == "y" || "${config_confirm}" == "Y" ]]; then
|
||||
read -p "请设置您的用户名: " config_account
|
||||
echo -e "${yellow}您的用户名将是: ${config_account}${plain}"
|
||||
read -p "请设置您的密码: " config_password
|
||||
echo -e "${yellow}您的密码将是: ${config_password}${plain}"
|
||||
read -p "请设置面板端口: " config_port
|
||||
echo -e "${yellow}您的面板端口号为: ${config_port}${plain}"
|
||||
read -p "请设置面板登录访问路径: " config_webBasePath
|
||||
echo -e "${yellow}您的面板访问路径为: ${config_webBasePath}${plain}"
|
||||
echo -e "${yellow}正在初始化,请稍候...${plain}"
|
||||
/usr/local/x-ui/x-ui setting -username ${config_account} -password ${config_password}
|
||||
echo -e "${yellow}用户名和密码设置成功!${plain}"
|
||||
/usr/local/x-ui/x-ui setting -port ${config_port}
|
||||
echo -e "${yellow}面板端口号设置成功!${plain}"
|
||||
/usr/local/x-ui/x-ui setting -webBasePath ${config_webBasePath}
|
||||
echo -e "${yellow}面板登录访问路径设置成功!${plain}"
|
||||
echo ""
|
||||
else
|
||||
if [[ "$existing_hasDefaultCredential" == "true" ]]; then
|
||||
local config_username=$(gen_random_string 10)
|
||||
local config_password=$(gen_random_string 10)
|
||||
|
||||
echo -e "${yellow}Default credentials detected. Security update required...${plain}"
|
||||
/usr/local/x-ui/x-ui setting -username "${config_username}" -password "${config_password}"
|
||||
echo -e "Generated new random login credentials:"
|
||||
echo ""
|
||||
sleep 1
|
||||
echo -e "${red}--------------->>>>Cancel...--------------->>>>>>>取消修改...${plain}"
|
||||
echo ""
|
||||
if [[ ! -f "/etc/x-ui/x-ui.db" ]]; then
|
||||
local usernameTemp=$(head -c 10 /dev/urandom | base64)
|
||||
local passwordTemp=$(head -c 10 /dev/urandom | base64)
|
||||
local webBasePathTemp=$(gen_random_string 15)
|
||||
/usr/local/x-ui/x-ui setting -username ${usernameTemp} -password ${passwordTemp} -webBasePath ${webBasePathTemp}
|
||||
echo ""
|
||||
echo -e "${yellow}检测到为全新安装,出于安全考虑将生成随机登录信息:${plain}"
|
||||
echo -e "###############################################"
|
||||
echo -e "${green}Username: ${config_username}${plain}"
|
||||
echo -e "${green}Password: ${config_password}${plain}"
|
||||
echo -e "${green}用户名: ${usernameTemp}${plain}"
|
||||
echo -e "${green}密 码: ${passwordTemp}${plain}"
|
||||
echo -e "${green}访问路径: ${webBasePathTemp}${plain}"
|
||||
echo -e "###############################################"
|
||||
echo -e "${green}如果您忘记了登录信息,可以在安装后通过 x-ui 命令然后输入${red}数字 10 选项${green}进行查看${plain}"
|
||||
else
|
||||
echo -e "${green}Username, Password, and WebBasePath are properly set. Exiting...${plain}"
|
||||
echo -e "${green}此次操作属于版本升级,保留之前旧设置项,登录方式保持不变${plain}"
|
||||
echo ""
|
||||
echo -e "${green}如果您忘记了登录信息,您可以通过 x-ui 命令然后输入${red}数字 10 选项${green}进行查看${plain}"
|
||||
echo ""
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
echo -e ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
|
||||
echo ""
|
||||
/usr/local/x-ui/x-ui migrate
|
||||
}
|
||||
|
||||
echo ""
|
||||
install_x-ui() {
|
||||
cd /usr/local/
|
||||
|
||||
# Download resources
|
||||
if [ $# == 0 ]; then
|
||||
tag_version=$(curl -Ls "https://api.github.com/repos/MHSanaei/3x-ui/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
|
||||
if [[ ! -n "$tag_version" ]]; then
|
||||
echo -e "${red}Failed to fetch x-ui version, it may be due to GitHub API restrictions, please try it later${plain}"
|
||||
last_version=$(curl -Ls "https://api.github.com/repos/xeefei/3x-ui/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
|
||||
if [[ ! -n "$last_version" ]]; then
|
||||
echo -e "${red}获取 3x-ui 版本失败,可能是 Github API 限制,请稍后再试${plain}"
|
||||
exit 1
|
||||
fi
|
||||
echo -e "Got x-ui latest version: ${tag_version}, beginning the installation..."
|
||||
wget -N -O /usr/local/x-ui-linux-$(arch).tar.gz https://github.com/MHSanaei/3x-ui/releases/download/${tag_version}/x-ui-linux-$(arch).tar.gz
|
||||
echo ""
|
||||
echo -e "-----------------------------------------------------"
|
||||
echo -e "${green}--------->>获取 3x-ui 最新版本:${yellow}${last_version}${plain}${green},开始安装...${plain}"
|
||||
echo -e "-----------------------------------------------------"
|
||||
echo ""
|
||||
sleep 2
|
||||
echo -e "${green}---------------->>>>>>>>>安装进度50%${plain}"
|
||||
sleep 3
|
||||
echo ""
|
||||
echo -e "${green}---------------->>>>>>>>>>>>>>>>>>>>>安装进度100%${plain}"
|
||||
echo ""
|
||||
sleep 2
|
||||
wget -N --no-check-certificate -O /usr/local/x-ui-linux-$(arch).tar.gz https://github.com/xeefei/3x-ui/releases/download/${last_version}/x-ui-linux-$(arch).tar.gz
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo -e "${red}Downloading x-ui failed, please be sure that your server can access GitHub ${plain}"
|
||||
echo -e "${red}下载 3x-ui 失败, 请检查服务器是否可以连接至 GitHub? ${plain}"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
tag_version=$1
|
||||
tag_version_numeric=${tag_version#v}
|
||||
min_version="2.3.5"
|
||||
|
||||
if [[ "$(printf '%s\n' "$min_version" "$tag_version_numeric" | sort -V | head -n1)" != "$min_version" ]]; then
|
||||
echo -e "${red}Please use a newer version (at least v2.3.5). Exiting installation.${plain}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
url="https://github.com/MHSanaei/3x-ui/releases/download/${tag_version}/x-ui-linux-$(arch).tar.gz"
|
||||
echo -e "Beginning to install x-ui $1"
|
||||
wget -N -O /usr/local/x-ui-linux-$(arch).tar.gz ${url}
|
||||
last_version=$1
|
||||
url="https://github.com/xeefei/3x-ui/releases/download/${last_version}/x-ui-linux-$(arch).tar.gz"
|
||||
echo ""
|
||||
echo -e "--------------------------------------------"
|
||||
echo -e "${green}---------------->>>>开始安装 3x-ui $1${plain}"
|
||||
echo -e "--------------------------------------------"
|
||||
echo ""
|
||||
sleep 2
|
||||
echo -e "${green}---------------->>>>>>>>>安装进度50%${plain}"
|
||||
sleep 3
|
||||
echo ""
|
||||
echo -e "${green}---------------->>>>>>>>>>>>>>>>>>>>>安装进度100%${plain}"
|
||||
echo ""
|
||||
sleep 2
|
||||
wget -N --no-check-certificate -O /usr/local/x-ui-linux-$(arch).tar.gz ${url}
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo -e "${red}Download x-ui $1 failed, please check if the version exists ${plain}"
|
||||
echo -e "${red}下载 3x-ui $1 失败, 请检查此版本是否存在 ${plain}"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
wget -O /usr/bin/x-ui-temp https://raw.githubusercontent.com/MHSanaei/3x-ui/main/x-ui.sh
|
||||
wget -O /usr/bin/x-ui-temp https://raw.githubusercontent.com/xeefei/3x-ui/main/x-ui.sh
|
||||
|
||||
# Stop x-ui service and remove old resources
|
||||
if [[ -e /usr/local/x-ui/ ]]; then
|
||||
systemctl stop x-ui
|
||||
rm /usr/local/x-ui/ -rf
|
||||
fi
|
||||
|
||||
# Extract resources and set permissions
|
||||
|
||||
sleep 3
|
||||
echo -e "${green}------->>>>>>>>>>>检查并保存安装目录${plain}"
|
||||
echo ""
|
||||
tar zxvf x-ui-linux-$(arch).tar.gz
|
||||
rm x-ui-linux-$(arch).tar.gz -f
|
||||
|
||||
@ -199,34 +302,155 @@ install_x-ui() {
|
||||
# Update x-ui cli and se set permission
|
||||
mv -f /usr/bin/x-ui-temp /usr/bin/x-ui
|
||||
chmod +x /usr/bin/x-ui
|
||||
sleep 2
|
||||
echo -e "${green}------->>>>>>>>>>>保存成功${plain}"
|
||||
sleep 2
|
||||
echo ""
|
||||
config_after_install
|
||||
|
||||
ssh_forwarding() {
|
||||
# 获取 IPv4 和 IPv6 地址
|
||||
v4=$(curl -s4m8 http://ip.sb -k)
|
||||
v6=$(curl -s6m8 http://ip.sb -k)
|
||||
local existing_webBasePath=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'webBasePath(访问路径): .+' | awk '{print $2}')
|
||||
local existing_port=$(/usr/local/x-ui/x-ui setting -show true | 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 existing_key=$(/usr/local/x-ui/x-ui setting -getCert true | grep -Eo 'key: .+' | awk '{print $2}')
|
||||
|
||||
if [[ -n "$existing_cert" && -n "$existing_key" ]]; then
|
||||
echo -e "${green}面板已安装证书采用SSL保护${plain}"
|
||||
echo ""
|
||||
local existing_cert=$(/usr/local/x-ui/x-ui setting -getCert true | grep -Eo 'cert: .+' | awk '{print $2}')
|
||||
domain=$(basename "$(dirname "$existing_cert")")
|
||||
echo -e "${green}登录访问面板URL: https://${domain}:${existing_port}${green}${existing_webBasePath}${plain}"
|
||||
fi
|
||||
echo ""
|
||||
if [[ -z "$existing_cert" && -z "$existing_key" ]]; then
|
||||
echo -e "${red}警告:未找到证书和密钥,面板不安全!${plain}"
|
||||
echo ""
|
||||
echo -e "${green}------->>>>请按照下述方法设置〔ssh转发〕<<<<-------${plain}"
|
||||
echo ""
|
||||
|
||||
# 检查 IP 并输出相应的 SSH 和浏览器访问信息
|
||||
if [[ -z $v4 ]]; then
|
||||
echo -e "${green}1、本地电脑客户端转发命令:${plain} ${blue}ssh -L [::]:15208:127.0.0.1:${existing_port}${blue} root@[$v6]${plain}"
|
||||
echo ""
|
||||
echo -e "${green}2、请通过快捷键【Win + R】调出运行窗口,在里面输入【cmd】打开本地终端服务${plain}"
|
||||
echo ""
|
||||
echo -e "${green}3、请在终端中成功输入服务器的〔root密码〕,注意区分大小写,用以上命令进行转发${plain}"
|
||||
echo ""
|
||||
echo -e "${green}4、请在浏览器地址栏复制${plain} ${blue}[::1]:15208${existing_webBasePath}${plain} ${green}进入〔3X-UI〕登录界面"
|
||||
echo ""
|
||||
echo -e "${red}注意:若不使用〔ssh转发〕请为3X-UI面板配置安装证书再行登录管理后台${plain}"
|
||||
elif [[ -n $v4 && -n $v6 ]]; then
|
||||
echo -e "${green}1、本地电脑客户端转发命令:${plain} ${blue}ssh -L 15208:127.0.0.1:${existing_port}${blue} root@$v4${plain} ${yellow}或者 ${blue}ssh -L [::]:15208:127.0.0.1:${existing_port}${blue} root@[$v6]${plain}"
|
||||
echo ""
|
||||
echo -e "${green}2、请通过快捷键【Win + R】调出运行窗口,在里面输入【cmd】打开本地终端服务${plain}"
|
||||
echo ""
|
||||
echo -e "${green}3、请在终端中成功输入服务器的〔root密码〕,注意区分大小写,用以上命令进行转发${plain}"
|
||||
echo ""
|
||||
echo -e "${green}4、请在浏览器地址栏复制${plain} ${blue}127.0.0.1:15208${existing_webBasePath}${plain} ${yellow}或者${plain} ${blue}[::1]:15208${existing_webBasePath}${plain} ${green}进入〔3X-UI〕登录界面"
|
||||
echo ""
|
||||
echo -e "${red}注意:若不使用〔ssh转发〕请为3X-UI面板配置安装证书再行登录管理后台${plain}"
|
||||
else
|
||||
echo -e "${green}1、本地电脑客户端转发命令:${plain} ${blue}ssh -L 15208:127.0.0.1:${existing_port}${blue} root@$v4${plain}"
|
||||
echo ""
|
||||
echo -e "${green}2、请通过快捷键【Win + R】调出运行窗口,在里面输入【cmd】打开本地终端服务${plain}"
|
||||
echo ""
|
||||
echo -e "${green}3、请在终端中成功输入服务器的〔root密码〕,注意区分大小写,用以上命令进行转发${plain}"
|
||||
echo ""
|
||||
echo -e "${green}4、请在浏览器地址栏复制${plain} ${blue}127.0.0.1:15208${existing_webBasePath}${plain} ${green}进入〔3X-UI〕登录界面"
|
||||
echo ""
|
||||
echo -e "${red}注意:若不使用〔ssh转发〕请为3X-UI面板配置安装证书再行登录管理后台${plain}"
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
}
|
||||
# 执行ssh端口转发
|
||||
ssh_forwarding
|
||||
|
||||
cp -f x-ui.service /etc/systemd/system/
|
||||
systemctl daemon-reload
|
||||
systemctl enable x-ui
|
||||
systemctl start x-ui
|
||||
echo -e "${green}x-ui ${tag_version}${plain} installation finished, it is running now..."
|
||||
echo -e ""
|
||||
echo -e "┌───────────────────────────────────────────────────────┐
|
||||
│ ${blue}x-ui control menu usages (subcommands):${plain} │
|
||||
│ │
|
||||
│ ${blue}x-ui${plain} - Admin Management Script │
|
||||
│ ${blue}x-ui start${plain} - Start │
|
||||
│ ${blue}x-ui stop${plain} - Stop │
|
||||
│ ${blue}x-ui restart${plain} - Restart │
|
||||
│ ${blue}x-ui status${plain} - Current Status │
|
||||
│ ${blue}x-ui settings${plain} - Current Settings │
|
||||
│ ${blue}x-ui enable${plain} - Enable Autostart on OS Startup │
|
||||
│ ${blue}x-ui disable${plain} - Disable Autostart on OS Startup │
|
||||
│ ${blue}x-ui log${plain} - Check logs │
|
||||
│ ${blue}x-ui banlog${plain} - Check Fail2ban ban logs │
|
||||
│ ${blue}x-ui update${plain} - Update │
|
||||
│ ${blue}x-ui legacy${plain} - legacy version │
|
||||
│ ${blue}x-ui install${plain} - Install │
|
||||
│ ${blue}x-ui uninstall${plain} - Uninstall │
|
||||
└───────────────────────────────────────────────────────┘"
|
||||
}
|
||||
systemctl stop warp-go >/dev/null 2>&1
|
||||
wg-quick down wgcf >/dev/null 2>&1
|
||||
ipv4=$(curl -s4m8 ip.p3terx.com -k | sed -n 1p)
|
||||
ipv6=$(curl -s6m8 ip.p3terx.com -k | sed -n 1p)
|
||||
systemctl start warp-go >/dev/null 2>&1
|
||||
wg-quick up wgcf >/dev/null 2>&1
|
||||
|
||||
echo -e "${green}Running...${plain}"
|
||||
echo ""
|
||||
echo -e "------->>>>${green}3x-ui ${last_version}${plain}<<<<安装成功,正在启动..."
|
||||
sleep 1
|
||||
echo ""
|
||||
echo -e " ---------------------"
|
||||
echo -e " |${green}3X-UI 控制菜单用法 ${plain}|${plain}"
|
||||
echo -e " | ${yellow}一个更好的面板 ${plain}|${plain}"
|
||||
echo -e " | ${yellow}基于Xray Core构建 ${plain}|${plain}"
|
||||
echo -e "--------------------------------------------"
|
||||
echo -e "x-ui - 进入管理脚本"
|
||||
echo -e "x-ui start - 启动 3x-ui 面板"
|
||||
echo -e "x-ui stop - 关闭 3x-ui 面板"
|
||||
echo -e "x-ui restart - 重启 3x-ui 面板"
|
||||
echo -e "x-ui status - 查看 3x-ui 状态"
|
||||
echo -e "x-ui settings - 查看当前设置信息"
|
||||
echo -e "x-ui enable - 启用 3x-ui 开机启动"
|
||||
echo -e "x-ui disable - 禁用 3x-ui 开机启动"
|
||||
echo -e "x-ui log - 查看 3x-ui 运行日志"
|
||||
echo -e "x-ui banlog - 检查 Fail2ban 禁止日志"
|
||||
echo -e "x-ui update - 更新 3x-ui 面板"
|
||||
echo -e "x-ui custom - 自定义 3x-ui 版本"
|
||||
echo -e "x-ui install - 安装 3x-ui 面板"
|
||||
echo -e "x-ui uninstall - 卸载 3x-ui 面板"
|
||||
echo -e "--------------------------------------------"
|
||||
echo ""
|
||||
# if [[ -n $ipv4 ]]; then
|
||||
# echo -e "${yellow}面板 IPv4 访问地址为:${green}http://$ipv4:${config_port}/${config_webBasePath}${plain}"
|
||||
# fi
|
||||
# if [[ -n $ipv6 ]]; then
|
||||
# echo -e "${yellow}面板 IPv6 访问地址为:${green}http://[$ipv6]:${config_port}/${config_webBasePath}${plain}"
|
||||
# fi
|
||||
# echo -e "请自行确保此端口没有被其他程序占用,${yellow}并且确保${red} ${config_port} ${yellow}端口已放行${plain}"
|
||||
sleep 3
|
||||
echo -e ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
|
||||
echo ""
|
||||
echo -e "${yellow}----->>>3X-UI面板和Xray启动成功<<<-----${plain}"
|
||||
}
|
||||
install_base
|
||||
install_x-ui $1
|
||||
echo ""
|
||||
echo -e "----------------------------------------------"
|
||||
sleep 4
|
||||
info=$(/usr/local/x-ui/x-ui setting -show true)
|
||||
echo -e "${info}${plain}"
|
||||
echo ""
|
||||
echo -e "若您忘记了上述面板信息,后期可通过x-ui命令进入脚本${red}输入数字〔10〕选项获取${plain}"
|
||||
echo ""
|
||||
echo -e "----------------------------------------------"
|
||||
echo ""
|
||||
sleep 2
|
||||
echo -e "${green}安装/更新完成,若在使用过程中有任何问题${plain}"
|
||||
echo -e "${yellow}请先描述清楚所遇问题加〔3X-UI〕中文交流群${plain}"
|
||||
echo -e "${yellow}在TG群中${red} https://t.me/XUI_CN ${yellow}截图进行反馈${plain}"
|
||||
echo ""
|
||||
echo -e "----------------------------------------------"
|
||||
echo ""
|
||||
echo -e "${green}〔3X-UI〕优化版项目地址:${yellow}https://github.com/xeefei/3x-ui${plain}"
|
||||
echo ""
|
||||
echo -e "${green} 详细安装教程:${yellow}https://xeefei.blogspot.com/2025/07/3x-ui.html${plain}"
|
||||
echo ""
|
||||
echo -e "----------------------------------------------"
|
||||
echo ""
|
||||
echo -e "-------------->>>>>>>赞 助 推 广 区<<<<<<<<-------------------"
|
||||
echo ""
|
||||
echo -e "${green}1、搬瓦工GIA高端线路:${yellow}https://bandwagonhost.com/aff.php?aff=75015${plain}"
|
||||
echo ""
|
||||
echo -e "${green}2、Dmit高端GIA线路:${yellow}https://www.dmit.io/aff.php?aff=9326${plain}"
|
||||
echo ""
|
||||
echo -e "${green}3、白丝云〔4837线路〕实惠量大管饱:${yellow}https://cloudsilk.io/aff.php?aff=706${plain}"
|
||||
echo ""
|
||||
echo -e "${green}4、RackNerd性价比机器:${yellow}https://my.racknerd.com/aff.php?aff=15268&pid=912${plain}"
|
||||
echo ""
|
||||
echo -e "----------------------------------------------"
|
||||
echo ""
|
||||
|
||||
184
main.go
@ -6,9 +6,14 @@ import (
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
// "os/exec"
|
||||
// "strings"
|
||||
"syscall"
|
||||
_ "unsafe"
|
||||
// 中文注释: 新增了 time 和 x-ui/job 的导入,这是运行定时任务所必需的
|
||||
"time"
|
||||
|
||||
"x-ui/web/job"
|
||||
"x-ui/config"
|
||||
"x-ui/database"
|
||||
"x-ui/logger"
|
||||
@ -22,6 +27,7 @@ import (
|
||||
"github.com/op/go-logging"
|
||||
)
|
||||
|
||||
// runWebServer 是【设备限制】项目的主执行函数
|
||||
func runWebServer() {
|
||||
log.Printf("Starting %v %v", config.GetName(), config.GetVersion())
|
||||
|
||||
@ -47,6 +53,9 @@ func runWebServer() {
|
||||
log.Fatalf("Error initializing database: %v", err)
|
||||
}
|
||||
|
||||
// 中文注释: xrayService 在这里被创建,我们需要将它传递给我们的新任务
|
||||
xrayService := service.XrayService{}
|
||||
|
||||
var server *web.Server
|
||||
server = web.NewServer()
|
||||
global.SetWebServer(server)
|
||||
@ -65,6 +74,27 @@ func runWebServer() {
|
||||
return
|
||||
}
|
||||
|
||||
// 中文注释: 在面板服务启动后,我们在这里启动设备限制的后台任务
|
||||
go func() {
|
||||
// 中文注释: 等待5秒,确保面板和Xray服务已基本稳定,避免任务启动过早
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
// 中文注释: 创建一个定时器。这里的 "10 * time.Second" 就是任务执行的间隔时间。
|
||||
// 您可以修改 10 为 2 或 1,来实现更短的延迟。
|
||||
// 例如: time.NewTicker(2 * time.Second) 就是2秒执行一次。
|
||||
ticker := time.NewTicker(10 * time.Second)
|
||||
defer ticker.Stop()
|
||||
|
||||
// 中文注释: 创建我们的任务实例, 并传入 xrayService
|
||||
checkJob := job.NewCheckDeviceLimitJob(&xrayService)
|
||||
|
||||
// 中文注释: 使用一个无限循环,每次定时器触发,就执行一次任务的 Run() 函数
|
||||
for {
|
||||
<-ticker.C
|
||||
checkJob.Run()
|
||||
}
|
||||
}()
|
||||
|
||||
sigCh := make(chan os.Signal, 1)
|
||||
// Trap shutdown signals
|
||||
signal.Notify(sigCh, syscall.SIGHUP, syscall.SIGTERM)
|
||||
@ -121,23 +151,47 @@ func resetSetting() {
|
||||
settingService := service.SettingService{}
|
||||
err = settingService.ResetSettings()
|
||||
if err != nil {
|
||||
fmt.Println("Failed to reset settings:", err)
|
||||
fmt.Println("Failed to reset settings(重置设置失败):", err)
|
||||
} else {
|
||||
fmt.Println("Settings successfully reset.")
|
||||
fmt.Println("Settings successfully reset ---->>重置设置成功")
|
||||
}
|
||||
}
|
||||
|
||||
func showSetting(show bool) {
|
||||
// 执行 shell 命令获取 IPv4 地址
|
||||
// cmdIPv4 := exec.Command("sh", "-c", "curl -s4m8 ip.p3terx.com -k | sed -n 1p")
|
||||
// outputIPv4, err := cmdIPv4.Output()
|
||||
// if err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
|
||||
// 执行 shell 命令获取 IPv6 地址
|
||||
// cmdIPv6 := exec.Command("sh", "-c", "curl -s6m8 ip.p3terx.com -k | sed -n 1p")
|
||||
// outputIPv6, err := cmdIPv6.Output()
|
||||
// if err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
|
||||
// 去除命令输出中的换行符
|
||||
// ipv4 := strings.TrimSpace(string(outputIPv4))
|
||||
// ipv6 := strings.TrimSpace(string(outputIPv6))
|
||||
// 定义转义字符,定义不同颜色的转义字符
|
||||
const (
|
||||
Reset = "\033[0m"
|
||||
Red = "\033[31m"
|
||||
Green = "\033[32m"
|
||||
Yellow = "\033[33m"
|
||||
)
|
||||
if show {
|
||||
settingService := service.SettingService{}
|
||||
port, err := settingService.GetPort()
|
||||
if err != nil {
|
||||
fmt.Println("get current port failed, error info:", err)
|
||||
fmt.Println("get current port failed, error info(获取当前端口失败,错误信息):", err)
|
||||
}
|
||||
|
||||
webBasePath, err := settingService.GetBasePath()
|
||||
if err != nil {
|
||||
fmt.Println("get webBasePath failed, error info:", err)
|
||||
fmt.Println("get webBasePath failed, error info(获取访问路径失败,错误信息):", err)
|
||||
}
|
||||
|
||||
certFile, err := settingService.GetCertFile()
|
||||
@ -152,28 +206,78 @@ func showSetting(show bool) {
|
||||
userService := service.UserService{}
|
||||
userModel, err := userService.GetFirstUser()
|
||||
if err != nil {
|
||||
fmt.Println("get current user info failed, error info:", err)
|
||||
fmt.Println("get current user info failed, error info(获取当前用户信息失败,错误信息):", err)
|
||||
}
|
||||
|
||||
if userModel.Username == "" || userModel.Password == "" {
|
||||
fmt.Println("current username or password is empty")
|
||||
fmt.Println("current username or password is empty --->>当前用户名或密码为空")
|
||||
}
|
||||
|
||||
fmt.Println("current panel settings as follows:")
|
||||
fmt.Println("")
|
||||
fmt.Println(Yellow + "----->>>以下为面板重要信息,请自行记录保存<<<-----" + Reset)
|
||||
fmt.Println(Green + "Current panel settings as follows (当前面板设置如下):" + Reset)
|
||||
fmt.Println("")
|
||||
if certFile == "" || keyFile == "" {
|
||||
fmt.Println("Warning: Panel is not secure with SSL")
|
||||
fmt.Println(Red + "------>> 警告:面板未安装证书进行SSL保护" + Reset)
|
||||
} else {
|
||||
fmt.Println("Panel is secure with SSL")
|
||||
fmt.Println(Green + "------>> 面板已安装证书采用SSL保护" + Reset)
|
||||
}
|
||||
|
||||
fmt.Println("")
|
||||
hasDefaultCredential := func() bool {
|
||||
return userModel.Username == "admin" && crypto.CheckPasswordHash(userModel.Password, "admin")
|
||||
}()
|
||||
if hasDefaultCredential == true {
|
||||
fmt.Println(Red + "------>> 警告:使用了默认的admin账号/密码,容易被扫描" + Reset)
|
||||
} else {
|
||||
fmt.Println(Green + "------>> 为非默认admin账号/密码,请牢记" + Reset)
|
||||
}
|
||||
fmt.Println("")
|
||||
fmt.Println(Green + fmt.Sprintf("port(端口号): %d", port) + Reset)
|
||||
fmt.Println(Green + fmt.Sprintf("webBasePath(访问路径): %s", webBasePath) + Reset)
|
||||
fmt.Println(Green + "PS:为安全起见,不显示账号和密码" + Reset)
|
||||
fmt.Println(Green + "若您已经忘记账号/密码,请用脚本选项〔6〕重新设置" + Reset)
|
||||
|
||||
fmt.Println("hasDefaultCredential:", hasDefaultCredential)
|
||||
fmt.Println("port:", port)
|
||||
fmt.Println("webBasePath:", webBasePath)
|
||||
}
|
||||
fmt.Println("")
|
||||
fmt.Println("--------------------------------------------------")
|
||||
// 根据条件打印带颜色的字符串
|
||||
// if ipv4 != "" {
|
||||
// fmt.Println("")
|
||||
// formattedIPv4 := fmt.Sprintf("%s %s%s:%d%s" + Reset,
|
||||
// Green+"面板 IPv4 访问地址------>>",
|
||||
// Yellow+"http://",
|
||||
// ipv4,
|
||||
// port,
|
||||
// Yellow+webBasePath + Reset)
|
||||
// fmt.Println(formattedIPv4)
|
||||
// fmt.Println("")
|
||||
// }
|
||||
|
||||
// if ipv6 != "" {
|
||||
// fmt.Println("")
|
||||
// formattedIPv6 := fmt.Sprintf("%s %s[%s%s%s]:%d%s%s",
|
||||
// Green+"面板 IPv6 访问地址------>>", // 绿色的提示信息
|
||||
// Yellow+"http://", // 黄色的 http:// 部分
|
||||
// Yellow, // 黄色的[ 左方括号
|
||||
// ipv6, // IPv6 地址
|
||||
// Yellow, // 黄色的] 右方括号
|
||||
// port, // 端口号
|
||||
// Yellow+webBasePath, // 黄色的 Web 基础路径
|
||||
// Reset) // 重置颜色
|
||||
// fmt.Println(formattedIPv6)
|
||||
// fmt.Println("")
|
||||
// }
|
||||
fmt.Println(Green + ">>>>>>>>注:若您安装了〔证书〕,请使用您的域名用https方式登录" + Reset)
|
||||
fmt.Println("")
|
||||
fmt.Println("--------------------------------------------------")
|
||||
fmt.Println("")
|
||||
// fmt.Println("↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑")
|
||||
fmt.Println(fmt.Sprintf("%s请确保 %s%d%s 端口已打开放行%s",Green, Red, port, Green, Reset))
|
||||
fmt.Println(Yellow + "请自行确保此端口没有被其他程序占用" + Reset)
|
||||
// fmt.Println(Green + "若要登录访问面板,请复制上面的地址到浏览器" + Reset)
|
||||
fmt.Println("")
|
||||
fmt.Println("--------------------------------------------------")
|
||||
fmt.Println("")
|
||||
}
|
||||
}
|
||||
|
||||
func updateTgbotEnableSts(status bool) {
|
||||
@ -198,7 +302,7 @@ func updateTgbotEnableSts(status bool) {
|
||||
func updateTgbotSetting(tgBotToken string, tgBotChatid string, tgBotRuntime string) {
|
||||
err := database.InitDB(config.GetDBPath())
|
||||
if err != nil {
|
||||
fmt.Println("Error initializing database:", err)
|
||||
fmt.Println("Error initializing database(初始化数据库出错):", err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -207,35 +311,35 @@ func updateTgbotSetting(tgBotToken string, tgBotChatid string, tgBotRuntime stri
|
||||
if tgBotToken != "" {
|
||||
err := settingService.SetTgBotToken(tgBotToken)
|
||||
if err != nil {
|
||||
fmt.Printf("Error setting Telegram bot token: %v\n", err)
|
||||
fmt.Printf("Error setting Telegram bot token(设置TG电报机器人令牌出错): %v\n", err)
|
||||
return
|
||||
}
|
||||
logger.Info("Successfully updated Telegram bot token.")
|
||||
logger.Info("Successfully updated Telegram bot token ----->>已成功更新TG电报机器人令牌")
|
||||
}
|
||||
|
||||
if tgBotRuntime != "" {
|
||||
err := settingService.SetTgbotRuntime(tgBotRuntime)
|
||||
if err != nil {
|
||||
fmt.Printf("Error setting Telegram bot runtime: %v\n", err)
|
||||
fmt.Printf("Error setting Telegram bot runtime(设置TG电报机器人通知周期出错): %v\n", err)
|
||||
return
|
||||
}
|
||||
logger.Infof("Successfully updated Telegram bot runtime to [%s].", tgBotRuntime)
|
||||
logger.Infof("Successfully updated Telegram bot runtime to (已成功将TG电报机器人通知周期设置为) [%s].", tgBotRuntime)
|
||||
}
|
||||
|
||||
if tgBotChatid != "" {
|
||||
err := settingService.SetTgBotChatId(tgBotChatid)
|
||||
if err != nil {
|
||||
fmt.Printf("Error setting Telegram bot chat ID: %v\n", err)
|
||||
fmt.Printf("Error setting Telegram bot chat ID(设置TG电报机器人管理者聊天ID出错): %v\n", err)
|
||||
return
|
||||
}
|
||||
logger.Info("Successfully updated Telegram bot chat ID.")
|
||||
logger.Info("Successfully updated Telegram bot chat ID ----->>已成功更新TG电报机器人管理者聊天ID")
|
||||
}
|
||||
}
|
||||
|
||||
func updateSetting(port int, username string, password string, webBasePath string, listenIP string, resetTwoFactor bool) {
|
||||
err := database.InitDB(config.GetDBPath())
|
||||
if err != nil {
|
||||
fmt.Println("Database initialization failed:", err)
|
||||
fmt.Println("Database initialization failed(初始化数据库失败):", err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -245,27 +349,27 @@ func updateSetting(port int, username string, password string, webBasePath strin
|
||||
if port > 0 {
|
||||
err := settingService.SetPort(port)
|
||||
if err != nil {
|
||||
fmt.Println("Failed to set port:", err)
|
||||
fmt.Println("Failed to set port(设置端口失败):", err)
|
||||
} else {
|
||||
fmt.Printf("Port set successfully: %v\n", port)
|
||||
fmt.Printf("Port set successfully(端口设置成功): %v\n", port)
|
||||
}
|
||||
}
|
||||
|
||||
if username != "" || password != "" {
|
||||
err := userService.UpdateFirstUser(username, password)
|
||||
if err != nil {
|
||||
fmt.Println("Failed to update username and password:", err)
|
||||
fmt.Println("Failed to update username and password(更新用户名和密码失败):", err)
|
||||
} else {
|
||||
fmt.Println("Username and password updated successfully")
|
||||
fmt.Println("Username and password updated successfully ------>>用户名和密码更新成功")
|
||||
}
|
||||
}
|
||||
|
||||
if webBasePath != "" {
|
||||
err := settingService.SetBasePath(webBasePath)
|
||||
if err != nil {
|
||||
fmt.Println("Failed to set base URI path:", err)
|
||||
fmt.Println("Failed to set base URI path(设置访问路径失败):", err)
|
||||
} else {
|
||||
fmt.Println("Base URI path set successfully")
|
||||
fmt.Println("Base URI path set successfully ------>>设置访问路径成功")
|
||||
}
|
||||
}
|
||||
|
||||
@ -273,19 +377,19 @@ func updateSetting(port int, username string, password string, webBasePath strin
|
||||
err := settingService.SetTwoFactorEnable(false)
|
||||
|
||||
if err != nil {
|
||||
fmt.Println("Failed to reset two-factor authentication:", err)
|
||||
fmt.Println("Failed to reset two-factor authentication(设置两步验证失败):", err)
|
||||
} else {
|
||||
settingService.SetTwoFactorToken("")
|
||||
fmt.Println("Two-factor authentication reset successfully")
|
||||
fmt.Println("Two-factor authentication reset successfully --------->>设置两步验证成功")
|
||||
}
|
||||
}
|
||||
|
||||
if listenIP != "" {
|
||||
err := settingService.SetListen(listenIP)
|
||||
if err != nil {
|
||||
fmt.Println("Failed to set listen IP:", err)
|
||||
fmt.Println("Failed to set listen IP(设置监听IP失败):", err)
|
||||
} else {
|
||||
fmt.Printf("listen %v set successfully", listenIP)
|
||||
fmt.Printf("listen %v set successfully --------->>设置监听IP成功", listenIP)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -301,19 +405,19 @@ func updateCert(publicKey string, privateKey string) {
|
||||
settingService := service.SettingService{}
|
||||
err = settingService.SetCertFile(publicKey)
|
||||
if err != nil {
|
||||
fmt.Println("set certificate public key failed:", err)
|
||||
fmt.Println("set certificate public key failed(设置证书公钥失败):", err)
|
||||
} else {
|
||||
fmt.Println("set certificate public key success")
|
||||
fmt.Println("set certificate public key success --------->>设置证书公钥成功")
|
||||
}
|
||||
|
||||
err = settingService.SetKeyFile(privateKey)
|
||||
if err != nil {
|
||||
fmt.Println("set certificate private key failed:", err)
|
||||
fmt.Println("set certificate private key failed(设置证书私钥失败):", err)
|
||||
} else {
|
||||
fmt.Println("set certificate private key success")
|
||||
fmt.Println("set certificate private key success --------->>设置证书私钥成功")
|
||||
}
|
||||
} else {
|
||||
fmt.Println("both public and private key should be entered.")
|
||||
fmt.Println("both public and private key should be entered ------>>必须同时输入证书公钥和私钥")
|
||||
}
|
||||
}
|
||||
|
||||
@ -355,9 +459,9 @@ func migrateDb() {
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Println("Start migrating database...")
|
||||
fmt.Println("Start migrating database... ---->>开始迁移数据库...")
|
||||
inboundService.MigrateDB()
|
||||
fmt.Println("Migration done!")
|
||||
fmt.Println("Migration done! ------------>>迁移完成!")
|
||||
}
|
||||
|
||||
func main() {
|
||||
@ -469,7 +573,7 @@ func main() {
|
||||
updateCert(webCertFile, webKeyFile)
|
||||
}
|
||||
default:
|
||||
fmt.Println("Invalid subcommands")
|
||||
fmt.Println("Invalid subcommands ----->>无效命令")
|
||||
fmt.Println()
|
||||
runCmd.Usage()
|
||||
fmt.Println()
|
||||
|
||||
BIN
media/1.png
Normal file
|
After Width: | Height: | Size: 321 KiB |
BIN
media/10.png
Normal file
|
After Width: | Height: | Size: 681 KiB |
BIN
media/11.png
Normal file
|
After Width: | Height: | Size: 636 KiB |
BIN
media/12.png
Normal file
|
After Width: | Height: | Size: 990 KiB |
BIN
media/13.png
Normal file
|
After Width: | Height: | Size: 965 KiB |
BIN
media/14.png
Normal file
|
After Width: | Height: | Size: 94 KiB |
BIN
media/15.png
Normal file
|
After Width: | Height: | Size: 88 KiB |
BIN
media/16.png
Normal file
|
After Width: | Height: | Size: 122 KiB |
BIN
media/17.png
Normal file
|
After Width: | Height: | Size: 153 KiB |
BIN
media/18.png
Normal file
|
After Width: | Height: | Size: 101 KiB |
BIN
media/19.png
Normal file
|
After Width: | Height: | Size: 78 KiB |
BIN
media/2.png
Normal file
|
After Width: | Height: | Size: 385 KiB |
BIN
media/20.png
Normal file
|
After Width: | Height: | Size: 288 KiB |
BIN
media/21.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
media/22.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
media/23.png
Normal file
|
After Width: | Height: | Size: 85 KiB |
BIN
media/24.png
Normal file
|
After Width: | Height: | Size: 128 KiB |
BIN
media/25.png
Normal file
|
After Width: | Height: | Size: 404 KiB |
BIN
media/26.png
Normal file
|
After Width: | Height: | Size: 245 KiB |
BIN
media/27.png
Normal file
|
After Width: | Height: | Size: 385 KiB |
BIN
media/28.png
Normal file
|
After Width: | Height: | Size: 256 KiB |
BIN
media/29.png
Normal file
|
After Width: | Height: | Size: 221 KiB |
BIN
media/3.png
Normal file
|
After Width: | Height: | Size: 63 KiB |
BIN
media/30.png
Normal file
|
After Width: | Height: | Size: 722 KiB |
BIN
media/31.png
Normal file
|
After Width: | Height: | Size: 172 KiB |
BIN
media/32.png
Normal file
|
After Width: | Height: | Size: 261 KiB |
BIN
media/33.png
Normal file
|
After Width: | Height: | Size: 401 KiB |
BIN
media/34.png
Normal file
|
After Width: | Height: | Size: 304 KiB |
BIN
media/35.png
Normal file
|
After Width: | Height: | Size: 210 KiB |
BIN
media/36.png
Normal file
|
After Width: | Height: | Size: 375 KiB |
BIN
media/37.png
Normal file
|
After Width: | Height: | Size: 97 KiB |
BIN
media/38.png
Normal file
|
After Width: | Height: | Size: 163 KiB |
BIN
media/39.png
Normal file
|
After Width: | Height: | Size: 2.1 MiB |
BIN
media/3X-UI.png
Normal file
|
After Width: | Height: | Size: 223 KiB |
BIN
media/4.png
Normal file
|
After Width: | Height: | Size: 92 KiB |
BIN
media/40.png
Normal file
|
After Width: | Height: | Size: 137 KiB |
BIN
media/41.png
Normal file
|
After Width: | Height: | Size: 150 KiB |
BIN
media/42.png
Normal file
|
After Width: | Height: | Size: 122 KiB |
BIN
media/43.png
Normal file
|
After Width: | Height: | Size: 139 KiB |
BIN
media/44.png
Normal file
|
After Width: | Height: | Size: 99 KiB |
BIN
media/45.png
Normal file
|
After Width: | Height: | Size: 85 KiB |
BIN
media/5.png
Normal file
|
After Width: | Height: | Size: 346 KiB |
BIN
media/6.png
Normal file
|
After Width: | Height: | Size: 244 KiB |
BIN
media/7.png
Normal file
|
After Width: | Height: | Size: 249 KiB |
BIN
media/8.png
Normal file
|
After Width: | Height: | Size: 591 KiB |
BIN
media/9.png
Normal file
|
After Width: | Height: | Size: 555 KiB |
@ -10,6 +10,9 @@ class DBInbound {
|
||||
this.remark = "";
|
||||
this.enable = true;
|
||||
this.expiryTime = 0;
|
||||
|
||||
// 新增:入站级设备限制(0 表示不限制)
|
||||
this.deviceLimit = 0;
|
||||
|
||||
this.listen = "";
|
||||
this.port = 0;
|
||||
@ -146,4 +149,4 @@ class DBInbound {
|
||||
const inbound = this.toInbound();
|
||||
return inbound.genInboundLinks(this.remark, remarkModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -731,8 +731,8 @@ class RealityStreamSettings extends XrayCommonClass {
|
||||
constructor(
|
||||
show = false,
|
||||
xver = 0,
|
||||
dest = 'google.com:443',
|
||||
serverNames = 'google.com,www.google.com',
|
||||
dest = 'tesla.com:443',
|
||||
serverNames = 'tesla.com,www.tesla.com',
|
||||
privateKey = '',
|
||||
minClientVer = '',
|
||||
maxClientVer = '',
|
||||
|
||||
@ -22,7 +22,7 @@ class AllSetting {
|
||||
this.tgBotBackup = false;
|
||||
this.tgBotLoginNotify = true;
|
||||
this.tgCpu = 80;
|
||||
this.tgLang = "en-US";
|
||||
this.tgLang = "zh-CN";
|
||||
this.twoFactorEnable = false;
|
||||
this.twoFactorToken = "";
|
||||
this.xrayTemplateConfig = "";
|
||||
@ -58,4 +58,4 @@ class AllSetting {
|
||||
equals(other) {
|
||||
return ObjectUtil.equals(this, other);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -817,11 +817,11 @@ class LanguageManager {
|
||||
if (LanguageManager.isSupportLanguage(lang)) {
|
||||
CookieManager.setCookie("lang", lang, 150);
|
||||
} else {
|
||||
CookieManager.setCookie("lang", "en-US", 150);
|
||||
CookieManager.setCookie("lang", "zh-CN", 150);
|
||||
window.location.reload();
|
||||
}
|
||||
} else {
|
||||
CookieManager.setCookie("lang", "en-US", 150);
|
||||
CookieManager.setCookie("lang", "zh-CN", 150);
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
@ -831,7 +831,7 @@ class LanguageManager {
|
||||
|
||||
static setLanguage(language) {
|
||||
if (!LanguageManager.isSupportLanguage(language)) {
|
||||
language = "en-US";
|
||||
language = "zh-CN";
|
||||
}
|
||||
|
||||
CookieManager.setCookie("lang", language, 150);
|
||||
@ -884,4 +884,4 @@ class FileManager {
|
||||
|
||||
link.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,6 +26,7 @@ func (a *XUIController) initRouter(g *gin.RouterGroup) {
|
||||
g.GET("/inbounds", a.inbounds)
|
||||
g.GET("/settings", a.settings)
|
||||
g.GET("/xray", a.xraySettings)
|
||||
g.GET("/navigation", a.navigation)
|
||||
|
||||
a.inboundController = NewInboundController(g)
|
||||
a.settingController = NewSettingController(g)
|
||||
@ -47,3 +48,7 @@ func (a *XUIController) settings(c *gin.Context) {
|
||||
func (a *XUIController) xraySettings(c *gin.Context) {
|
||||
html(c, "xray.html", "pages.xray.title", nil)
|
||||
}
|
||||
|
||||
func (a *XUIController) navigation(c *gin.Context) {
|
||||
html(c, "navigation.html", "pages.navigation.title", nil)
|
||||
}
|
||||
|
||||
@ -64,6 +64,11 @@
|
||||
icon: 'tool',
|
||||
title: '{{ i18n "menu.xray"}}'
|
||||
},
|
||||
{
|
||||
key: '{{ .base_path }}panel/navigation',
|
||||
icon: 'link',
|
||||
title: '{{ i18n "menu.navigation"}}'
|
||||
},
|
||||
{
|
||||
key: '{{ .base_path }}logout/',
|
||||
icon: 'logout',
|
||||
@ -100,4 +105,4 @@
|
||||
template: `{{template "component/sidebar/content"}}`,
|
||||
});
|
||||
</script>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
@ -1,19 +1,24 @@
|
||||
{{define "form/inbound"}}
|
||||
<!-- base -->
|
||||
<a-form :colon="false" :label-col="{ md: {span:8} }" :wrapper-col="{ md: {span:14} }">
|
||||
<!-- 开关:启用/禁用 -->
|
||||
<a-form-item label='{{ i18n "enable" }}'>
|
||||
<a-switch v-model="dbInbound.enable"></a-switch>
|
||||
</a-form-item>
|
||||
|
||||
<!-- 备注 -->
|
||||
<a-form-item label='{{ i18n "remark" }}'>
|
||||
<a-input v-model.trim="dbInbound.remark"></a-input>
|
||||
</a-form-item>
|
||||
|
||||
<!-- 协议选择 -->
|
||||
<a-form-item label='{{ i18n "protocol" }}'>
|
||||
<a-select v-model="inbound.protocol" :disabled="isEdit" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||
<a-select-option v-for="p in Protocols" :key="p" :value="p">[[ p ]]</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
|
||||
<!-- 监听地址 -->
|
||||
<a-form-item>
|
||||
<template slot="label">
|
||||
<a-tooltip>
|
||||
@ -27,23 +32,60 @@
|
||||
<a-input v-model.trim="inbound.listen"></a-input>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label='{{ i18n "pages.inbounds.port" }}'>
|
||||
<a-input-number v-model.number="inbound.port" :min="1" :max="65531"></a-input-number>
|
||||
</a-form-item>
|
||||
<!-- 端口 + 总流量 在同一行 -->
|
||||
<a-row :gutter="16">
|
||||
<!-- 左侧:端口 -->
|
||||
<a-col :span="12">
|
||||
<a-form-item>
|
||||
<template slot="label">
|
||||
<a-tooltip>
|
||||
<template slot="title">
|
||||
端口范围:1 - 65531(请尽量使用高位端口)
|
||||
</template>
|
||||
{{ i18n "pages.inbounds.port" }}
|
||||
<a-icon type="question-circle"></a-icon>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<a-input-number v-model.number="inbound.port" :min="1" :max="65531" style="width: 100%" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<!-- 右侧:总流量 -->
|
||||
<a-col :span="12">
|
||||
<a-form-item>
|
||||
<template slot="label">
|
||||
<a-tooltip>
|
||||
<template slot="title">
|
||||
0 <span>{{ i18n "pages.inbounds.meansNoLimit" }}</span>
|
||||
</template>
|
||||
{{ i18n "pages.inbounds.totalFlow" }}
|
||||
<a-icon type="question-circle"></a-icon>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<a-input-number v-model.number="dbInbound.totalGB" :min="0" style="width: 100%" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<!-- 设备限制 单独占一行 -->
|
||||
<a-form-item>
|
||||
<template slot="label">
|
||||
<a-tooltip>
|
||||
<template slot="title">
|
||||
0 <span>{{ i18n "pages.inbounds.meansNoLimit" }}</span>
|
||||
0 表示不限制(留空也表示不限制)
|
||||
</template>
|
||||
{{ i18n "pages.inbounds.totalFlow" }}
|
||||
设备限制
|
||||
<a-icon type="question-circle"></a-icon>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<a-input-number v-model.number="dbInbound.totalGB" :min="0"></a-input-number>
|
||||
<a-input-number
|
||||
v-model.number="dbInbound.deviceLimit"
|
||||
:min="0"
|
||||
style="width: 100%"
|
||||
placeholder="0 = 不限制" />
|
||||
</a-form-item>
|
||||
|
||||
<!-- 到期时间 -->
|
||||
<a-form-item>
|
||||
<template slot="label">
|
||||
<a-tooltip>
|
||||
|
||||
@ -48,7 +48,7 @@
|
||||
<a-textarea v-model="inbound.stream.reality.privateKey"></a-textarea>
|
||||
</a-form-item>
|
||||
<a-form-item label=" ">
|
||||
<a-button type="primary" icon="import" @click="getNewX25519Cert">Get New Cert</a-button>
|
||||
<a-button type="primary" icon="import" @click="getNewX25519Cert">Get New Cert(随机获取新证书)</a-button>
|
||||
</a-form-item>
|
||||
<a-form-item label="mldsa65 Seed">
|
||||
<a-textarea v-model="inbound.stream.reality.mldsa65Seed"></a-textarea>
|
||||
@ -57,7 +57,7 @@
|
||||
<a-textarea v-model="inbound.stream.reality.settings.mldsa65Verify"></a-textarea>
|
||||
</a-form-item>
|
||||
<a-form-item label=" ">
|
||||
<a-button type="primary" icon="import" @click="getNewmldsa65">Get New Seed</a-button>
|
||||
<a-button type="primary" icon="import" @click="getNewmldsa65">Get New Seed(获取Mldsa65数值)</a-button>
|
||||
</a-form-item>
|
||||
</template>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
@ -701,7 +701,7 @@
|
||||
}, {
|
||||
title: '{{ i18n "pages.inbounds.operate" }}',
|
||||
align: 'center',
|
||||
width: 30,
|
||||
width: 20,
|
||||
scopedSlots: { customRender: 'action' },
|
||||
}, {
|
||||
title: '{{ i18n "pages.inbounds.enable" }}',
|
||||
@ -711,32 +711,38 @@
|
||||
}, {
|
||||
title: '{{ i18n "pages.inbounds.remark" }}',
|
||||
align: 'center',
|
||||
width: 60,
|
||||
width: 40,
|
||||
dataIndex: "remark",
|
||||
}, {
|
||||
title: '{{ i18n "pages.inbounds.port" }}',
|
||||
align: 'center',
|
||||
dataIndex: "port",
|
||||
width: 40,
|
||||
width: 30,
|
||||
}, {
|
||||
title: '{{ i18n "pages.inbounds.protocol" }}',
|
||||
align: 'left',
|
||||
align: 'center',
|
||||
width: 70,
|
||||
scopedSlots: { customRender: 'protocol' },
|
||||
}, {
|
||||
title: '{{ i18n "clients" }}',
|
||||
align: 'left',
|
||||
width: 50,
|
||||
width: 30,
|
||||
scopedSlots: { customRender: 'clients' },
|
||||
}, {
|
||||
title: '{{ i18n "pages.inbounds.deviceLimit" }}',
|
||||
dataIndex: "deviceLimit",
|
||||
align: "center",
|
||||
width: 40,
|
||||
customRender: (text) => (text > 0 ? text : i18n("pages.inbounds.unlimited")),
|
||||
}, {
|
||||
title: '{{ i18n "pages.inbounds.traffic" }}',
|
||||
align: 'center',
|
||||
width: 90,
|
||||
width: 50,
|
||||
scopedSlots: { customRender: 'traffic' },
|
||||
}, {
|
||||
title: '{{ i18n "pages.inbounds.allTimeTraffic" }}',
|
||||
align: 'center',
|
||||
width: 70,
|
||||
width: 50,
|
||||
scopedSlots: { customRender: 'allTimeInbound' },
|
||||
}, {
|
||||
title: '{{ i18n "pages.inbounds.expireDate" }}',
|
||||
@ -1128,6 +1134,8 @@
|
||||
remark: dbInbound.remark,
|
||||
enable: dbInbound.enable,
|
||||
expiryTime: dbInbound.expiryTime,
|
||||
// 新增这一行
|
||||
deviceLimit: dbInbound.deviceLimit,
|
||||
|
||||
listen: inbound.listen,
|
||||
port: inbound.port,
|
||||
@ -1151,6 +1159,8 @@
|
||||
remark: dbInbound.remark,
|
||||
enable: dbInbound.enable,
|
||||
expiryTime: dbInbound.expiryTime,
|
||||
// 新增这一行
|
||||
deviceLimit: dbInbound.deviceLimit,
|
||||
|
||||
listen: inbound.listen,
|
||||
port: inbound.port,
|
||||
@ -1651,4 +1661,4 @@
|
||||
},
|
||||
});
|
||||
</script>
|
||||
{{ template "page/body_end" .}}
|
||||
{{ template "page/body_end" .}}
|
||||
|
||||
@ -219,20 +219,20 @@
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :sm="24" :lg="12">
|
||||
<a-card title='3X-UI' hoverable>
|
||||
<a rel="noopener" href="https://github.com/MHSanaei/3x-ui/releases" target="_blank">
|
||||
<a-card title='〔3X-UI〕中文优化版' hoverable>
|
||||
<a rel="noopener" href="https://github.com/xeefei/3x-ui/releases" target="_blank">
|
||||
<a-tag color="green">
|
||||
<span>v{{ .cur_ver }}</span>
|
||||
</a-tag>
|
||||
</a>
|
||||
<a rel="noopener" href="https://t.me/XrayUI" target="_blank">
|
||||
<a rel="noopener" href="https://t.me/is_Chat_Bot" target="_blank">
|
||||
<a-tag color="green">
|
||||
<span>@XrayUI</span>
|
||||
<span>TG私聊交流</span>
|
||||
</a-tag>
|
||||
</a>
|
||||
<a rel="noopener" href="https://github.com/MHSanaei/3x-ui/wiki" target="_blank">
|
||||
<a rel="noopener" href="https://t.me/XUI_CN" target="_blank">
|
||||
<a-tag color="purple">
|
||||
<span>{{ i18n "pages.index.documentation" }}</span>
|
||||
<span>〔3X-UI〕中文交流群</span>
|
||||
</a-tag>
|
||||
</a>
|
||||
</a-card>
|
||||
@ -253,6 +253,8 @@
|
||||
</template>
|
||||
</a-tooltip>
|
||||
</a-tag>
|
||||
<a rel="noopener" href="https://ping.pe" target="_blank"><a-tag color="green">端口检测</a-tag></a>
|
||||
<a rel="noopener" href="https://www.speedtest.net" target="_blank"><a-tag color="green">网络测速</a-tag></a>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :sm="24" :lg="12">
|
||||
@ -911,4 +913,4 @@ ${dateTime}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
{{ template "page/body_end" .}}
|
||||
{{ template "page/body_end" .}}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{{define "modals/ruleModal"}}
|
||||
<a-modal id="rule-modal" v-model="ruleModal.visible" :title="ruleModal.title" @ok="ruleModal.ok" :confirm-loading="ruleModal.confirmLoading" :closable="true" :mask-closable="false" :ok-text="ruleModal.okText" cancel-text='{{ i18n "close" }}' :class="themeSwitcher.currentTheme">
|
||||
<a-form :colon="false" :label-col="{ md: {span:8} }" :wrapper-col="{ md: {span:14} }">
|
||||
<a-form-item label='Domain Matcher'>
|
||||
<a-form-item label='{{ i18n "pages.xray.rules.DomainMatcher" }}'>
|
||||
<a-select v-model="ruleModal.rule.domainMatcher" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||
<a-select-option v-for="dm in ['','hybrid','linear']" :value="dm">[[ dm ]]</a-select-option>
|
||||
</a-select>
|
||||
@ -11,7 +11,7 @@
|
||||
<a-tooltip>
|
||||
<template slot="title">
|
||||
<span>{{ i18n "pages.xray.rules.useComma" }}</span>
|
||||
</template> Source IPs <a-icon type="question-circle"></a-icon>
|
||||
</template> {{ i18n "pages.xray.rules.SourceIPs" }} <a-icon type="question-circle"></a-icon>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<a-input v-model.trim="ruleModal.rule.source"></a-input>
|
||||
@ -21,22 +21,22 @@
|
||||
<a-tooltip>
|
||||
<template slot="title">
|
||||
<span>{{ i18n "pages.xray.rules.useComma" }}</span>
|
||||
</template> Source Port <a-icon type="question-circle"></a-icon>
|
||||
</template> {{ i18n "pages.xray.rules.SourcePort" }} <a-icon type="question-circle"></a-icon>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<a-input v-model.trim="ruleModal.rule.sourcePort"></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label='Network'>
|
||||
<a-form-item label='{{ i18n "pages.xray.rules.Network" }}'>
|
||||
<a-select v-model="ruleModal.rule.network" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||
<a-select-option v-for="x in ['','TCP','UDP','TCP,UDP']" :value="x">[[ x ]]</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label='Protocol'>
|
||||
<a-form-item label='{{ i18n "pages.xray.rules.Protocol" }}'>
|
||||
<a-select v-model="ruleModal.rule.protocol" mode="multiple" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||
<a-select-option v-for="x in ['http','tls','bittorrent','quic']" :value="x">[[ x ]]</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label='Attributes'>
|
||||
<a-form-item label='{{ i18n "pages.xray.rules.Attributes" }}'>
|
||||
<a-button icon="plus" size="small" :style="{ marginLeft: '10px' }" @click="ruleModal.rule.attrs.push(['', ''])"></a-button>
|
||||
</a-form-item>
|
||||
<a-form-item :wrapper-col="{span: 24}">
|
||||
@ -64,7 +64,7 @@
|
||||
<a-tooltip>
|
||||
<template slot="title">
|
||||
<span>{{ i18n "pages.xray.rules.useComma" }}</span>
|
||||
</template> Domain <a-icon type="question-circle"></a-icon>
|
||||
</template> {{ i18n "pages.xray.rules.Domain" }} <a-icon type="question-circle"></a-icon>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<a-input v-model.trim="ruleModal.rule.domain"></a-input>
|
||||
@ -74,7 +74,7 @@
|
||||
<a-tooltip>
|
||||
<template slot="title">
|
||||
<span>{{ i18n "pages.xray.rules.useComma" }}</span>
|
||||
</template> User <a-icon type="question-circle"></a-icon>
|
||||
</template> {{ i18n "pages.xray.rules.User" }} <a-icon type="question-circle"></a-icon>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<a-input v-model.trim="ruleModal.rule.user"></a-input>
|
||||
@ -84,17 +84,17 @@
|
||||
<a-tooltip>
|
||||
<template slot="title">
|
||||
<span>{{ i18n "pages.xray.rules.useComma" }}</span>
|
||||
</template> Port <a-icon type="question-circle"></a-icon>
|
||||
</template> {{ i18n "pages.xray.rules.Port" }} <a-icon type="question-circle"></a-icon>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<a-input v-model.trim="ruleModal.rule.port"></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label='Inbound Tags'>
|
||||
<a-form-item label='{{ i18n "pages.xray.rules.InboundTag" }}'>
|
||||
<a-select v-model="ruleModal.rule.inboundTag" mode="multiple" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||
<a-select-option v-for="tag in ruleModal.inboundTags" :value="tag">[[ tag ]]</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label='Outbound Tag'>
|
||||
<a-form-item label='{{ i18n "pages.xray.rules.OutboundTag" }}'>
|
||||
<a-select v-model="ruleModal.rule.outboundTag" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||
<a-select-option v-for="tag in ruleModal.outboundTags" :value="tag">[[ tag ]]</a-select-option>
|
||||
</a-select>
|
||||
@ -104,7 +104,7 @@
|
||||
<a-tooltip>
|
||||
<template slot="title">
|
||||
<span>{{ i18n "pages.xray.balancer.balancerDesc" }}</span>
|
||||
</template> Balancer Tag <a-icon type="question-circle"></a-icon>
|
||||
</template> {{ i18n "pages.xray.rules.BalancerTag" }} <a-icon type="question-circle"></a-icon>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<a-select v-model="ruleModal.rule.balancerTag" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||
|
||||
165
web/html/navigation.html
Normal file
@ -0,0 +1,165 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>实用导航&技巧</title>
|
||||
<style>
|
||||
body {
|
||||
background-color: #151F31;
|
||||
color: white;
|
||||
font-family: Arial, sans-serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
}
|
||||
.sidebar {
|
||||
width: 150px;
|
||||
background-color: #151F31;
|
||||
padding: 20px;
|
||||
}
|
||||
.sidebar h2 {
|
||||
color: #fff;
|
||||
margin-top: 0;
|
||||
}
|
||||
.sidebar button {
|
||||
background-color: #2C3E56;
|
||||
color: #008000; /* 绿色字体 */
|
||||
border: none;
|
||||
padding: 10px 20px;
|
||||
margin-bottom: 10px;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
width: 100%;
|
||||
border-radius: 15px; /* 增加圆角幅度 */
|
||||
font-weight: bold; /* 加粗字体 */
|
||||
}
|
||||
.sidebar button:hover {
|
||||
background-color: #4A90E2;
|
||||
}
|
||||
.sidebar .friend-links {
|
||||
margin-top: auto;
|
||||
text-align: center;
|
||||
margin-bottom: 12px; /* 调整友情链接下边距 */
|
||||
}
|
||||
.sidebar .friend-links a {
|
||||
color: #0080FF; /* 蓝色字体 */
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.separator {
|
||||
width: 15px;
|
||||
background-color: #34495e;
|
||||
}
|
||||
.content {
|
||||
flex: 1;
|
||||
padding: 20px;
|
||||
padding-top: 0; /* 移除顶部空白 */
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="sidebar">
|
||||
<button onclick="history.back()">返回上一步</button>
|
||||
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
|
||||
<div class="friend-links">
|
||||
<a href="https://chat.openai.com/">ChatGPT</a>
|
||||
<a href="https://github.com/xeefei/3x-ui">项目地址</a>
|
||||
<a href="https://t.me/XUI_CN">3X-UI交流群</a>
|
||||
<a href="https://www.youtube.com/results?search_query=4k%E6%B5%8B%E9%80%9F">油管4K测速</a>
|
||||
<a href="https://whatismyipaddress.com/">我的IP查询</a>
|
||||
<a href="https://translate.google.com/?hl=zh-CN">Google翻译</a>
|
||||
<a href="https://xtls.github.io/">Project X</a>
|
||||
<a href="https://t.me/is_Haotian_Bot">预留&占位</a>
|
||||
<a href="https://t.me/is_Chat_Bot">联系作者</a>
|
||||
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
|
||||
<button onclick="window.scrollTo(0, 0)">回滚至顶部</button>
|
||||
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
|
||||
<button onclick="history.back()">返回到面板</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="separator"></div>
|
||||
<div class="content">
|
||||
<h3>一、【3x-ui】中文交流群:<a href="https://t.me/XUI_CN">https://t.me/XUI_CN</a></h3>
|
||||
<h3> 【3x-ui】详细安装流程步骤:<a href="https://xeefei.blogspot.com/2025/07/3x-ui.html">https://xeefei.blogspot.com/2025/07/3x-ui.html</a></h3>
|
||||
|
||||
<h3>二、判断VPS服务器的IP是否【送中】?</h3>
|
||||
<p>***点击打开:<a href="https://music.youtube.com/">https://music.youtube.com/</a>,能正常打开访问,就代表【没送中】,反之就是送中了。</p>
|
||||
<p>***如果送中了如何解决去【拉回来】?</p>
|
||||
<p>1:关闭/取消登录了谷歌账户的APP定位权限/授权;2:将常用的一个谷歌账号的位置记录功能打开;3:在电脑上打开Chrome/谷歌浏览器,登录开了位置记录功能的谷歌账号,安装Location Guard拓展插件<a href="https://chrome.google.com/webstore/detail/location-guard/cfohepagpmnodfdmjliccbbigdkfcgia">https://chrome.google.com/webstore/detail/location-guard/cfohepagpmnodfdmjliccbbigdkfcgia</a>(也可在其他支持此插件的浏览器使用);4:打开Location Guard插件,选择Fixed Location,并在给出的地图上单击,即可标记上你想要IP所处的国家/地区
|
||||
Google IP定位错误,使用Location Guard修改;5:转换到Options选项,Default level默认设置为Use fixed location;6:打开谷歌地图google.com/maps,点击右下角定位授权图标,使google maps获取当前“我的GPS位置”
|
||||
Google IP定位错误,使用Location Guard修改GPS位置地址;7:谷歌搜索my ip,即可看到谷歌IP定位到了刚才地图上标记的位置;8:在此网页向谷歌报告IP问题:<a href="https://support.google.com/websearch/workflow/9308722">https://support.google.com/websearch/workflow/9308722</a></p>
|
||||
|
||||
<h3>三、在自己的VPS服务器部署【订阅转换】功能</h3>
|
||||
<p>如何把vless/vmess等协议转换成Clash/Surge等软件支持的格式?
|
||||
1、进入脚本输入x-ui命令调取面板,选择第【24】选项安装订阅转换模块,
|
||||
2、等待安装【订阅转换】成功之后,访问地址:你的IP:18080(端口号)进行转换,
|
||||
3、因为在转换过程中需要调取后端API,所以请确保端口25500是打开放行的,
|
||||
4、在得到【转换链接】之后,只要你的VPS服务器25500端口是能ping通的,就能导入Clash/Surge等软件成功下载配置,
|
||||
5、此功能集成到3x-ui面板中,是为了保证安全,通过调取24选项把【订阅转换】功能部署在自己的VPS中,不会造成链接泄露。</p>
|
||||
|
||||
<h3>四、如何保护自己的IP不被墙被封?</h3>
|
||||
<p>1、使用的代理协议要安全,加密是必备,推荐使用vless+reality+vision协议组合,
|
||||
2、因为有时节点会共享,在不同的地区,多个省份之间不要共同连接同一个IP,
|
||||
3、连接同一个IP就算了,不要同一个端口,不要同IP+同端口到处漫游,要分开,
|
||||
4、同一台VPS,不要在一天内一直大流量去下载东西使用,不要流量过高要切换,
|
||||
5、创建【入站协议】的时候,尽量用【高位端口】,比如40000--65000之间的端口号。
|
||||
提醒:为什么在特殊时期,比如:两会,春节等被封得最严重最惨?
|
||||
尼玛同一个IP+同一个端口号,多个省份去漫游,跟开飞机场一样!不封你,封谁的IP和端口?
|
||||
总结:不要多终端/多省份/多个朋友/共同使用同一个IP和端口号!使用3x-ui多创建几个【入站】,
|
||||
多做几条备用,各用各的!各行其道才比较安全!GFW的思维模式是干掉机场,机场的特征个人用户不要去沾染,自然IP就保护好了。</p>
|
||||
|
||||
<h3>五、检测IP纯净度的方法:</h3>
|
||||
<p>网址:<a href="https://scamalytics.com/">https://scamalytics.com/</a>,输入IP进行检测,看【欺诈分数】,分数越高IP越脏。</p>
|
||||
|
||||
<h3>六、常见的翻墙软件/工具:</h3>
|
||||
<ol>
|
||||
<p>1、Windows系统v2rayN:<a href="https://github.com/2dust/v2rayN">https://github.com/2dust/v2rayN</a></p>
|
||||
<p>2、安卓手机版【v2rayNG】:<a href="https://github.com/2dust/v2rayNG">https://github.com/2dust/v2rayNG</a></p>
|
||||
<p>3、苹果手机IOS【小火箭】:<a href="https://apple02.com/">https://apple02.com/</a></p>
|
||||
<p>4、苹果MacOS电脑【Clash Verge】:<a href="https://github.com/clash-verge-rev/clash-verge-rev/releases">https://github.com/clash-verge-rev/clash-verge-rev/releases</a>或v2rayN:<a href="https://github.com/2dust/v2rayN">https://github.com/2dust/v2rayN</a></p>
|
||||
</ol>
|
||||
|
||||
<h3>七、查看节点【指定端口】的网络连接数/命令:</h3>
|
||||
<p>netstat -ntu | grep :节点端口 | grep ESTABLISHED | awk '{print $5}'</p>
|
||||
|
||||
<h3>八、用3x-ui如何实现【自己偷自己】?</h3>
|
||||
<p>其实很简单,只要你为面板设置了证书,
|
||||
开启了HTTPS登录,就可以将3x-ui自身作为web server,
|
||||
无需Nginx等,这里给一个示例:
|
||||
其中目标网站(Dest)请填写面板监听端口,
|
||||
可选域名(SNI)填写面板登录域名,
|
||||
如果您使用其他web server(如nginx)等,
|
||||
将目标网站改为对应监听端口也可。
|
||||
需要说明的是,如果您处于白名单地区,自己“偷”自己并不适合你;其次,可选域名一项实际上可以填写任意SNI,只要客户端保持一致即可,不过并不推荐这样做。</p>
|
||||
|
||||
<h3>九、【接码】网站:</h3>
|
||||
<p>网址:<a href="https://sms-activate.org/cn">https://sms-activate.org/cn</a>,直接注册账号购买。</p>
|
||||
|
||||
<h3>十、一些MJJ经常逛的网站和群组:</h3>
|
||||
<ol>
|
||||
<p>1、NodeSeek论坛:<a href="https://www.nodeseek.com/">https://www.nodeseek.com/</a></p>
|
||||
<p>2、V2EX论坛:<a href="https://www.v2ex.com/">https://www.v2ex.com/</a></p>
|
||||
<p>3、搬瓦工TG群:<a href="https://t.me/BWHOfficial">https://t.me/BWHOfficial</a></p>
|
||||
<p>4、Xray的官方群:<a href="https://t.me/projectXray">https://t.me/projectXray</a></p>
|
||||
<p>5、Dmit交流群:<a href="https://t.me/DmitChat">https://t.me/DmitChat</a></p>
|
||||
<p>6、白丝云用户群:<a href="https://t.me/+VHZLKELTQyzPNgOV">https://t.me/+VHZLKELTQyzPNgOV</a></p>
|
||||
<p>7、NameSilo域名注册:<a href="https://www.namesilo.com/">https://www.namesilo.com/</a></p>
|
||||
</ol>
|
||||
|
||||
<h3>十一、若此项目对你有帮助,你正想购买VPS的话,可以走一下我的AFF:</h3>
|
||||
<ol>
|
||||
<p>1、搬瓦工GIA线路:<a href="https://bandwagonhost.com/aff.php?aff=75015">https://bandwagonhost.com/aff.php?aff=75015</a></p>
|
||||
<p>2、Dmit高端GIA:<a href="https://www.dmit.io/aff.php?aff=9326">https://www.dmit.io/aff.php?aff=9326</a></p>
|
||||
<p>3、白丝云【4837】:<a href="https://cloudsilk.io/aff.php?aff=706">https://cloudsilk.io/aff.php?aff=706</a></p>
|
||||
</ol>
|
||||
|
||||
<h3>十二、项目〔声明和注意〕</h3>
|
||||
<ol>
|
||||
<p>1、声明: 此项目仅供个人学习、交流使用,请遵守当地法律法规,勿用于非法用途;请勿用于生产环境;</a></p>
|
||||
<p>2、注意: 在使用此项目和〔教程〕过程中,若因违反以上声明使用规则而产生的一切后果由使用者自负。</a></p>
|
||||
</ol>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@ -1,4 +1,10 @@
|
||||
{{define "settings/panel/general"}}
|
||||
<style>
|
||||
.red-placeholder input::-webkit-input-placeholder { color: red !important; }
|
||||
.red-placeholder input::-moz-placeholder { color: red !important; }
|
||||
.red-placeholder input:-ms-input-placeholder { color: red !important; }
|
||||
.red-placeholder input::placeholder { color: red !important; }
|
||||
</style>
|
||||
<a-collapse default-active-key="1">
|
||||
<a-collapse-panel key="1" header='{{ i18n "pages.xray.generalConfigs"}}'>
|
||||
<a-setting-list-item paddings="small">
|
||||
@ -97,14 +103,14 @@
|
||||
<template #title>{{ i18n "pages.settings.publicKeyPath"}}</template>
|
||||
<template #description>{{ i18n "pages.settings.publicKeyPathDesc"}}</template>
|
||||
<template #control>
|
||||
<a-input type="text" v-model="allSetting.webCertFile"></a-input>
|
||||
<a-input type="text" v-model="allSetting.webCertFile" placeholder="/root/cert/域名/fullchain.pem" class="red-placeholder"></a-input>
|
||||
</template>
|
||||
</a-setting-list-item>
|
||||
<a-setting-list-item paddings="small">
|
||||
<template #title>{{ i18n "pages.settings.privateKeyPath"}}</template>
|
||||
<template #description>{{ i18n "pages.settings.privateKeyPathDesc"}}</template>
|
||||
<template #control>
|
||||
<a-input type="text" v-model="allSetting.webKeyFile"></a-input>
|
||||
<a-input type="text" v-model="allSetting.webKeyFile" placeholder="/root/cert/域名/privkey.pem" class="red-placeholder"></a-input>
|
||||
</template>
|
||||
</a-setting-list-item>
|
||||
</a-collapse-panel>
|
||||
@ -146,4 +152,4 @@
|
||||
</a-setting-list-item>
|
||||
</a-collapse-panel>
|
||||
</a-collapse>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
@ -10,13 +10,330 @@ import (
|
||||
"regexp"
|
||||
"sort"
|
||||
"time"
|
||||
"sync"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
|
||||
"x-ui/database"
|
||||
"x-ui/database/model"
|
||||
"x-ui/logger"
|
||||
"x-ui/xray"
|
||||
"x-ui/web/service"
|
||||
)
|
||||
|
||||
// =================================================================
|
||||
// 中文注释: 以下是用于实现设备限制功能的核心代码
|
||||
// =================================================================
|
||||
|
||||
// ActiveClientIPs 中文注释: 用于在内存中跟踪每个用户的活跃IP (TTL机制)
|
||||
// 结构: map[用户email] -> map[IP地址] -> 最后活跃时间
|
||||
var ActiveClientIPs = make(map[string]map[string]time.Time)
|
||||
var activeClientsLock sync.RWMutex
|
||||
|
||||
// ClientStatus 中文注释: 用于跟踪每个用户的状态(是否因为设备超限而被禁用)
|
||||
// 结构: map[用户email] -> 是否被禁用(true/false)
|
||||
var ClientStatus = make(map[string]bool)
|
||||
var clientStatusLock sync.RWMutex
|
||||
|
||||
// CheckDeviceLimitJob 中文注释: 这是我们的设备限制任务的结构体
|
||||
type CheckDeviceLimitJob struct {
|
||||
inboundService service.InboundService
|
||||
xrayService *service.XrayService
|
||||
// 中文注释: 新增 xrayApi 字段,用于持有 Xray API 客户端实例
|
||||
xrayApi xray.XrayAPI
|
||||
// lastPosition 中文注释: 用于记录上次读取 access.log 的位置,避免重复读取
|
||||
lastPosition int64
|
||||
}
|
||||
|
||||
// RandomUUID 中文注释: 新增一个辅助函数,用于生成一个随机的 UUID
|
||||
func RandomUUID() string {
|
||||
uuid := make([]byte, 16)
|
||||
rand.Read(uuid)
|
||||
uuid[6] = (uuid[6] & 0x0f) | 0x40
|
||||
uuid[8] = (uuid[8] & 0x3f) | 0x80
|
||||
return hex.EncodeToString(uuid[0:4]) + "-" + hex.EncodeToString(uuid[4:6]) + "-" + hex.EncodeToString(uuid[6:8]) + "-" + hex.EncodeToString(uuid[8:10]) + "-" + hex.EncodeToString(uuid[10:16])
|
||||
}
|
||||
|
||||
// NewCheckDeviceLimitJob 中文注释: 创建一个新的任务实例
|
||||
func NewCheckDeviceLimitJob(xrayService *service.XrayService) *CheckDeviceLimitJob {
|
||||
return &CheckDeviceLimitJob{
|
||||
xrayService: xrayService,
|
||||
// 中文注释: 初始化 xrayApi 字段
|
||||
xrayApi: xray.XrayAPI{},
|
||||
}
|
||||
}
|
||||
|
||||
// Run 中文注释: 定时任务的主函数,每次定时器触发时执行
|
||||
func (j *CheckDeviceLimitJob) Run() {
|
||||
// 中文注释: 检查 xray 是否正在运行,如果xray没运行,则无需执行此任务
|
||||
if !j.xrayService.IsXrayRunning() {
|
||||
return
|
||||
}
|
||||
|
||||
// 1. 清理过期的IP
|
||||
j.cleanupExpiredIPs()
|
||||
|
||||
// 2. 解析新的日志并更新IP列表
|
||||
j.parseAccessLog()
|
||||
|
||||
// 3. 检查所有用户的设备限制状态
|
||||
j.checkAllClientsLimit()
|
||||
}
|
||||
|
||||
// cleanupExpiredIPs 中文注释: 清理长时间不活跃的IP
|
||||
func (j *CheckDeviceLimitJob) cleanupExpiredIPs() {
|
||||
activeClientsLock.Lock()
|
||||
defer activeClientsLock.Unlock()
|
||||
|
||||
now := time.Now()
|
||||
// 中文注释: 活跃判断窗口(TTL): 近3分钟内出现过就算“活跃”
|
||||
const activeTTL = 3 * time.Minute
|
||||
for email, ips := range ActiveClientIPs {
|
||||
for ip, lastSeen := range ips {
|
||||
// 中文注释: 如果一个IP超过3分钟没有新的连接日志,我们就认为它已经下线
|
||||
if now.Sub(lastSeen) > activeTTL {
|
||||
delete(ActiveClientIPs[email], ip)
|
||||
}
|
||||
}
|
||||
// 中文注释: 如果一个用户的所有IP都下线了,就从大Map中移除这个用户,节省内存
|
||||
if len(ActiveClientIPs[email]) == 0 {
|
||||
delete(ActiveClientIPs, email)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// parseAccessLog 中文注释: 解析 xray access log 来获取最新的用户IP信息
|
||||
func (j *CheckDeviceLimitJob) parseAccessLog() {
|
||||
logPath, err := xray.GetAccessLogPath()
|
||||
if err != nil || logPath == "none" || logPath == "" {
|
||||
return
|
||||
}
|
||||
|
||||
file, err := os.Open(logPath)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// 中文注释: 移动到上次读取结束的位置,实现增量读取
|
||||
file.Seek(j.lastPosition, 0)
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
|
||||
// 中文注释: 使用正则表达式从日志行中提取 email 和 IP
|
||||
emailRegex := regexp.MustCompile(`email: ([^ ]+)`)
|
||||
ipRegex := regexp.MustCompile(`from (?:tcp:|udp:)?\[?([0-9a-fA-F\.:]+)\]?:\d+ accepted`)
|
||||
|
||||
activeClientsLock.Lock()
|
||||
defer activeClientsLock.Unlock()
|
||||
|
||||
now := time.Now()
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
|
||||
emailMatch := emailRegex.FindStringSubmatch(line)
|
||||
ipMatch := ipRegex.FindStringSubmatch(line)
|
||||
|
||||
if len(emailMatch) > 1 && len(ipMatch) > 1 {
|
||||
email := emailMatch[1]
|
||||
ip := ipMatch[1]
|
||||
|
||||
if ip == "127.0.0.1" || ip == "::1" {
|
||||
continue
|
||||
}
|
||||
|
||||
if _, ok := ActiveClientIPs[email]; !ok {
|
||||
ActiveClientIPs[email] = make(map[string]time.Time)
|
||||
}
|
||||
ActiveClientIPs[email][ip] = now
|
||||
}
|
||||
}
|
||||
|
||||
currentPosition, err := file.Seek(0, os.SEEK_END)
|
||||
if err == nil {
|
||||
if currentPosition < j.lastPosition {
|
||||
j.lastPosition = 0
|
||||
} else {
|
||||
j.lastPosition = currentPosition
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// checkAllClientsLimit 中文注释: 核心功能,检查所有用户,对超限的执行封禁,对恢复的执行解封
|
||||
func (j *CheckDeviceLimitJob) checkAllClientsLimit() {
|
||||
db := database.GetDB()
|
||||
var inbounds []*model.Inbound
|
||||
// 中文注释: 这里仅查询启用了设备限制(device_limit > 0)并且自身是开启状态的入站规则
|
||||
db.Where("device_limit > 0 AND enable = ?", true).Find(&inbounds)
|
||||
|
||||
if len(inbounds) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// 中文注释: 获取 API 端口。如果端口为0 (说明Xray未完全启动或有问题),则直接返回
|
||||
apiPort := j.xrayService.GetApiPort()
|
||||
if apiPort == 0 {
|
||||
return
|
||||
}
|
||||
// 中文注释: 使用获取到的端口号初始化 API 客户端
|
||||
j.xrayApi.Init(apiPort)
|
||||
defer j.xrayApi.Close()
|
||||
|
||||
// 中文注释: 优化 - 在一次循环中同时获取 tag 和 protocol
|
||||
inboundInfoMap := make(map[int]struct {
|
||||
Limit int
|
||||
Tag string
|
||||
Protocol model.Protocol
|
||||
})
|
||||
for _, inbound := range inbounds {
|
||||
inboundInfoMap[inbound.Id] = struct {
|
||||
Limit int
|
||||
Tag string
|
||||
Protocol model.Protocol
|
||||
}{Limit: inbound.DeviceLimit, Tag: inbound.Tag, Protocol: inbound.Protocol}
|
||||
}
|
||||
|
||||
activeClientsLock.RLock()
|
||||
clientStatusLock.Lock()
|
||||
defer activeClientsLock.RUnlock()
|
||||
defer clientStatusLock.Unlock()
|
||||
|
||||
// 第一步: 处理当前在线的用户
|
||||
for email, ips := range ActiveClientIPs {
|
||||
traffic, err := j.inboundService.GetClientTrafficByEmail(email)
|
||||
if err != nil || traffic == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
info, ok := inboundInfoMap[traffic.InboundId]
|
||||
if !ok || info.Limit <= 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
isBanned := ClientStatus[email]
|
||||
activeIPCount := len(ips)
|
||||
|
||||
// 调用封禁函数
|
||||
if activeIPCount > info.Limit && !isBanned {
|
||||
// 中文注释: 调用封禁函数时,传入当前的IP数用于记录日志
|
||||
j.banUser(email, activeIPCount, &info)
|
||||
}
|
||||
|
||||
// 调用解封函数
|
||||
if activeIPCount <= info.Limit && isBanned {
|
||||
// 中文注释: 调用解封函数时,传入当前的IP数用于记录日志
|
||||
j.unbanUser(email, activeIPCount, &info)
|
||||
}
|
||||
}
|
||||
|
||||
// 第二步: 专门处理那些“已被封禁”但“已不在线”的用户,为他们解封
|
||||
for email, isBanned := range ClientStatus {
|
||||
if !isBanned {
|
||||
continue
|
||||
}
|
||||
if _, online := ActiveClientIPs[email]; !online {
|
||||
traffic, err := j.inboundService.GetClientTrafficByEmail(email)
|
||||
if err != nil || traffic == nil {
|
||||
continue
|
||||
}
|
||||
info, ok := inboundInfoMap[traffic.InboundId]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
logger.Infof("已封禁用户 %s 已完全下线,执行解封操作。", email)
|
||||
|
||||
// 调用解封函数,这种情况下:活跃IP数为0,我们直接传入0用于记录日志
|
||||
j.unbanUser(email, 0, &info)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// banUser 中文注释: 封装的封禁用户函数;IP数量超限,且用户当前未被封禁 -> 执行封禁 (UUID 替换)
|
||||
func (j *CheckDeviceLimitJob) banUser(email string, activeIPCount int, info *struct {
|
||||
Limit int
|
||||
Tag string
|
||||
Protocol model.Protocol
|
||||
}) {
|
||||
// =================================================================
|
||||
// 这一行代码是整个解封逻辑的灵魂!
|
||||
// GetClientByEmail 函数会去查询您的数据库 (x-ui.db),
|
||||
// 找到 `inbounds` 表,解析其中的 `settings` 字段,并从中去,
|
||||
// 读取出您最初设置的、最原始、最正确的用户信息(包括最原始的UUID),
|
||||
// 然后把它赋值给 `client` 这个变量;此时,`client` 变量就持有了那个“老链接”的正确原始 UUID。
|
||||
// =================================================================
|
||||
_, client, err := j.inboundService.GetClientByEmail(email)
|
||||
if err != nil || client == nil {
|
||||
return
|
||||
}
|
||||
logger.Infof("〔设备限制〕超限:用户 %s. 限制: %d, 当前活跃: %d. 执行封禁掐网。", email, info.Limit, activeIPCount)
|
||||
|
||||
// 中文注释: 步骤一:先从 Xray-Core 中删除该用户。
|
||||
j.xrayApi.RemoveUser(info.Tag, email)
|
||||
|
||||
// =================================================================
|
||||
// 中文注释: 增加 5000 毫秒延时,解决竞态条件问题
|
||||
time.Sleep(5000 * time.Millisecond)
|
||||
// =================================================================
|
||||
|
||||
// 中文注释: 创建一个带有随机UUID/Password的临时客户端配置用于“封禁”
|
||||
tempClient := *client
|
||||
|
||||
// 适用于 VMess/VLESS
|
||||
if tempClient.ID != "" { tempClient.ID = RandomUUID() }
|
||||
|
||||
// 适用于 Trojan/Shadowsocks/Socks
|
||||
if tempClient.Password != "" { tempClient.Password = RandomUUID() }
|
||||
|
||||
var clientMap map[string]interface{}
|
||||
clientJson, _ := json.Marshal(tempClient)
|
||||
json.Unmarshal(clientJson, &clientMap)
|
||||
|
||||
// 中文注释: 步骤二:将这个带有错误UUID/Password的临时用户添加回去。
|
||||
// 客户端持有的还是旧的UUID,自然就无法通过验证,从而达到了“封禁”的效果。
|
||||
err = j.xrayApi.AddUser(string(info.Protocol), info.Tag, clientMap)
|
||||
if err != nil {
|
||||
logger.Warningf("通过API封禁用户 %s 失败: %v", email, err)
|
||||
} else {
|
||||
// 中文注释: 封禁成功后,在内存中标记该用户为“已封禁”状态。
|
||||
ClientStatus[email] = true
|
||||
}
|
||||
}
|
||||
|
||||
// unbanUser 中文注释: 封装的解封用户函数;IP数量已恢复正常,但用户处于封禁状态 -> 执行解封 (恢复原始 UUID)
|
||||
func (j *CheckDeviceLimitJob) unbanUser(email string, activeIPCount int, info *struct {
|
||||
Limit int
|
||||
Tag string
|
||||
Protocol model.Protocol
|
||||
}) {
|
||||
_, client, err := j.inboundService.GetClientByEmail(email)
|
||||
if err != nil || client == nil {
|
||||
return
|
||||
}
|
||||
logger.Infof("〔设备数量〕已恢复:用户 %s. 限制: %d, 当前活跃: %d. 执行解封/恢复用户。", email, info.Limit, activeIPCount)
|
||||
|
||||
// 中文注释: 步骤一:先从 Xray-Core 中删除用于“封禁”的那个临时用户。
|
||||
j.xrayApi.RemoveUser(info.Tag, email)
|
||||
|
||||
// =================================================================
|
||||
// 中文注释: 同样增加 5000 毫秒延时,确保解封操作的稳定性
|
||||
time.Sleep(5000 * time.Millisecond)
|
||||
// =================================================================
|
||||
|
||||
var clientMap map[string]interface{}
|
||||
clientJson, _ := json.Marshal(client)
|
||||
json.Unmarshal(clientJson, &clientMap)
|
||||
|
||||
// 中文注释: 步骤二:将数据库中原始的、正确的用户信息重新添加回 Xray-Core,从而实现“解封”。
|
||||
err = j.xrayApi.AddUser(string(info.Protocol), info.Tag, clientMap)
|
||||
if err != nil {
|
||||
logger.Warningf("通过API恢复用户 %s 失败: %v", email, err)
|
||||
} else {
|
||||
// 中文注释: 解封成功后,从内存中移除该用户的“已封禁”状态标记。
|
||||
delete(ClientStatus, email)
|
||||
}
|
||||
}
|
||||
|
||||
type CheckClientIpJob struct {
|
||||
lastClear int64
|
||||
disAllowedIps []string
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
{
|
||||
"log": {
|
||||
"access": "none",
|
||||
"dnsLog": false,
|
||||
"error": "",
|
||||
"loglevel": "warning",
|
||||
"access": "./access.log",
|
||||
"dnsLog": true,
|
||||
"error": "./error.log",
|
||||
"loglevel": "debug",
|
||||
"maskAddress": ""
|
||||
},
|
||||
"api": {
|
||||
|
||||
@ -397,6 +397,8 @@ func (s *InboundService) UpdateInbound(inbound *model.Inbound) (*model.Inbound,
|
||||
oldInbound.Remark = inbound.Remark
|
||||
oldInbound.Enable = inbound.Enable
|
||||
oldInbound.ExpiryTime = inbound.ExpiryTime
|
||||
// 中文注释:确保在更新数据时,将前端传来的 deviceLimit 值赋给从数据库中读出的旧对象。
|
||||
oldInbound.DeviceLimit = inbound.DeviceLimit
|
||||
oldInbound.Listen = inbound.Listen
|
||||
oldInbound.Port = inbound.Port
|
||||
oldInbound.Protocol = inbound.Protocol
|
||||
|
||||
@ -47,7 +47,7 @@ var defaultValueMap = map[string]string{
|
||||
"tgBotBackup": "false",
|
||||
"tgBotLoginNotify": "true",
|
||||
"tgCpu": "80",
|
||||
"tgLang": "en-US",
|
||||
"tgLang": "zh-CN",
|
||||
"twoFactorEnable": "false",
|
||||
"twoFactorToken": "",
|
||||
"subEnable": "false",
|
||||
|
||||
@ -26,10 +26,24 @@ type XrayService struct {
|
||||
xrayAPI xray.XrayAPI
|
||||
}
|
||||
|
||||
// IsXrayRunning 检查 Xray 是否正在运行
|
||||
func (s *XrayService) IsXrayRunning() bool {
|
||||
return p != nil && p.IsRunning()
|
||||
}
|
||||
|
||||
// 中文注释:
|
||||
// 新增 GetApiPort 函数。
|
||||
// 这个函数的作用是安全地返回当前 Xray 进程正在监听的 API 端口号。
|
||||
// 如果 Xray 没有运行 (p == nil),则返回 0。
|
||||
// 我们的后台任务将调用这个函数来获取端口号。
|
||||
func (s *XrayService) GetApiPort() int {
|
||||
if p == nil {
|
||||
return 0
|
||||
}
|
||||
return p.GetAPIPort()
|
||||
}
|
||||
|
||||
|
||||
func (s *XrayService) GetXrayErr() error {
|
||||
if p == nil {
|
||||
return nil
|
||||
|
||||
@ -81,6 +81,7 @@
|
||||
"xray" = "Xray Configs"
|
||||
"logout" = "Log Out"
|
||||
"link" = "Manage"
|
||||
"navigation" = "navigation"
|
||||
|
||||
[pages.login]
|
||||
"hello" = "Hello"
|
||||
@ -453,6 +454,9 @@
|
||||
"statsOutboundDownlink" = "Outbound Download Statistics"
|
||||
"statsOutboundDownlinkDesc" = "Enables the statistics collection for downstream traffic of all outbound proxies."
|
||||
|
||||
[pages.navigation]
|
||||
"title" = "navigation"
|
||||
|
||||
[pages.xray.rules]
|
||||
"first" = "First"
|
||||
"last" = "Last"
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
"edit" = "编辑"
|
||||
"delete" = "删除"
|
||||
"reset" = "重置"
|
||||
"noData" = "无数据。"
|
||||
"noData" = "无数据"
|
||||
"copySuccess" = "复制成功"
|
||||
"sure" = "确定"
|
||||
"encryption" = "加密"
|
||||
@ -54,17 +54,18 @@
|
||||
"install" = "安装"
|
||||
"clients" = "客户端"
|
||||
"usage" = "使用情况"
|
||||
"secretToken" = "安全密钥"
|
||||
"twoFactorCode" = "代码"
|
||||
"remained" = "剩余"
|
||||
"security" = "安全"
|
||||
"secAlertTitle" = "安全警报"
|
||||
"secAlertSsl" = "此连接不安全。在激活 TLS 进行数据保护之前,请勿输入敏感信息。"
|
||||
"secAlertConf" = "某些设置易受攻击。建议加强安全协议以防止潜在漏洞。"
|
||||
"secAlertSSL" = "面板缺少安全连接。请安装 TLS 证书以保护数据安全。"
|
||||
"secAlertPanelPort" = "面板默认端口存在安全风险。请配置随机端口或特定端口。"
|
||||
"secAlertPanelURI" = "面板默认 URI 路径不安全。请配置复杂的 URI 路径。"
|
||||
"secAlertSubURI" = "订阅默认 URI 路径不安全。请配置复杂的 URI 路径。"
|
||||
"secAlertSubJsonURI" = "订阅 JSON 默认 URI 路径不安全。请配置复杂的 URI 路径。"
|
||||
"secAlertSsl" = "此连接不安全!在激活 TLS 进行数据保护之前,请勿输入敏感信息。"
|
||||
"secAlertConf" = "某些设置易受攻击!建议加强安全协议以防止潜在漏洞。"
|
||||
"secAlertSSL" = "面板缺少安全连接!请安装 TLS 证书以保护数据安全。"
|
||||
"secAlertPanelPort" = "面板默认端口存在安全风险!请配置随机端口或特定端口。"
|
||||
"secAlertPanelURI" = "面板默认 URI 路径不安全!请配置复杂的 URI 路径。"
|
||||
"secAlertSubURI" = "订阅默认 URI 路径不安全!请配置复杂的 URI 路径。"
|
||||
"secAlertSubJsonURI" = "订阅 JSON 默认 URI 路径不安全!请配置复杂的 URI 路径。"
|
||||
"emptyDnsDesc" = "未添加DNS服务器。"
|
||||
"emptyFakeDnsDesc" = "未添加Fake DNS服务器。"
|
||||
"emptyBalancersDesc" = "未添加负载均衡器。"
|
||||
@ -74,13 +75,14 @@
|
||||
[menu]
|
||||
"theme" = "主题"
|
||||
"dark" = "暗色"
|
||||
"ultraDark" = "超暗色"
|
||||
"ultraDark" = "黑色"
|
||||
"dashboard" = "系统状态"
|
||||
"inbounds" = "入站列表"
|
||||
"settings" = "面板设置"
|
||||
"xray" = "Xray 设置"
|
||||
"xray" = "Xray设置"
|
||||
"logout" = "退出登录"
|
||||
"link" = "管理"
|
||||
"navigation" = "实用导航"
|
||||
|
||||
[pages.login]
|
||||
"hello" = "你好"
|
||||
@ -102,6 +104,7 @@
|
||||
"swap" = "交换分区"
|
||||
"storage" = "存储"
|
||||
"memory" = "内存"
|
||||
"hard" = "磁盘"
|
||||
"threads" = "线程"
|
||||
"xrayStatus" = "Xray"
|
||||
"stopXray" = "停止"
|
||||
@ -138,7 +141,7 @@
|
||||
"dontRefresh" = "安装中,请勿刷新此页面"
|
||||
"logs" = "日志"
|
||||
"config" = "配置"
|
||||
"backup" = "备份"
|
||||
"backup" = "备份和恢复"
|
||||
"backupTitle" = "备份和恢复数据库"
|
||||
"exportDatabase" = "备份"
|
||||
"exportDatabaseDesc" = "点击下载包含当前数据库备份的 .db 文件到您的设备。"
|
||||
@ -174,6 +177,8 @@
|
||||
"generalActions" = "通用操作"
|
||||
"autoRefresh" = "自动刷新"
|
||||
"autoRefreshInterval" = "间隔"
|
||||
"create" = "添加"
|
||||
"update" = "修改"
|
||||
"modifyInbound" = "修改入站"
|
||||
"deleteInbound" = "删除入站"
|
||||
"deleteInboundContent" = "确定要删除入站吗?"
|
||||
@ -195,7 +200,7 @@
|
||||
"publicKey" = "公钥"
|
||||
"privatekey" = "私钥"
|
||||
"clickOnQRcode" = "点击二维码复制"
|
||||
"client" = "客户"
|
||||
"client" = "客户/用户"
|
||||
"export" = "导出链接"
|
||||
"clone" = "克隆"
|
||||
"cloneInbound" = "克隆"
|
||||
@ -214,14 +219,14 @@
|
||||
"delDepletedClientsTitle" = "删除流量耗尽的客户端"
|
||||
"delDepletedClientsContent" = "确定要删除所有流量耗尽的客户端吗?"
|
||||
"email" = "电子邮件"
|
||||
"emailDesc" = "电子邮件必须完全唯一"
|
||||
"emailDesc" = "电子邮件必须确保唯一"
|
||||
"IPLimit" = "IP 限制"
|
||||
"IPLimitDesc" = "如果数量超过设置值,则禁用入站流量。(0 = 禁用)"
|
||||
"IPLimitlog" = "IP 日志"
|
||||
"IPLimitlogDesc" = "IP 历史日志(要启用被禁用的入站流量,请清除日志)"
|
||||
"IPLimitlogclear" = "清除日志"
|
||||
"setDefaultCert" = "从面板设置证书"
|
||||
"telegramDesc" = "请提供Telegram聊天ID。(在机器人中使用'/id'命令)或(@userinfobot"
|
||||
"telegramDesc" = "请提供Telegram聊天ID。(在机器人中使用'/id'命令或跟@userinfobot机器人对话获取)"
|
||||
"subscriptionDesc" = "要找到你的订阅 URL,请导航到“详细信息”。此外,你可以为多个客户端使用相同的名称。"
|
||||
"info" = "信息"
|
||||
"same" = "相同"
|
||||
@ -229,6 +234,12 @@
|
||||
"exportInbound" = "导出入站规则"
|
||||
"import"="导入"
|
||||
"importInbound" = "导入入站规则"
|
||||
"reviewTitle"="请确认以下配置信息"
|
||||
"neverExpire"="永不过期"
|
||||
"reviewHint"="如需修改请返回上一步"
|
||||
"unlimited"="无限制"
|
||||
"deviceLimit"="设备限制"
|
||||
|
||||
|
||||
[pages.client]
|
||||
"add" = "添加客户端"
|
||||
@ -243,7 +254,7 @@
|
||||
"prefix" = "前缀"
|
||||
"postfix" = "后缀"
|
||||
"delayedStart" = "首次使用后开始"
|
||||
"expireDays" = "期间"
|
||||
"expireDays" = "到期天数/期间"
|
||||
"days" = "天"
|
||||
"renew" = "自动续订"
|
||||
"renewDesc" = "到期后自动续订。(0 = 禁用)(单位: 天)"
|
||||
@ -293,7 +304,7 @@
|
||||
"resetDefaultConfig" = "重置为默认配置"
|
||||
"panelSettings" = "常规"
|
||||
"securitySettings" = "安全设定"
|
||||
"TGBotSettings" = "Telegram 机器人配置"
|
||||
"TGBotSettings" = "Telegram机器人配置"
|
||||
"panelListeningIP" = "面板监听 IP"
|
||||
"panelListeningIPDesc" = "默认留空监听所有 IP"
|
||||
"panelListeningDomain" = "面板监听域名"
|
||||
@ -301,10 +312,12 @@
|
||||
"panelPort" = "面板监听端口"
|
||||
"panelPortDesc" = "重启面板生效"
|
||||
"publicKeyPath" = "面板证书公钥文件路径"
|
||||
"publicKeyPathDesc" = "填写一个 '/' 开头的绝对路径"
|
||||
"DefaultpublicKeyPath" = "/root/.acme.sh/域名_ecc/域名.cer"
|
||||
"publicKeyPathDesc" = "填写一个 '/' 开头的绝对路径,〔acme方式〕请自行在填入时修改域名"
|
||||
"privateKeyPath" = "面板证书密钥文件路径"
|
||||
"privateKeyPathDesc" = "填写一个 '/' 开头的绝对路径"
|
||||
"panelUrlPath" = "面板 url 根路径"
|
||||
"DefaultprivateKeyPath" = "/root/.acme.sh/域名_ecc/域名.key"
|
||||
"privateKeyPathDesc" = "填写一个 '/' 开头的绝对路径,〔acme方式〕请自行在填入时修改域名"
|
||||
"panelUrlPath" = "面板登录访问路径"
|
||||
"panelUrlPathDesc" = "必须以 '/' 开头,以 '/' 结尾"
|
||||
"pageSize" = "分页大小"
|
||||
"pageSizeDesc" = "定义入站表的页面大小。设置 0 表示禁用"
|
||||
@ -320,7 +333,7 @@
|
||||
"telegramBotEnable" = "启用 Telegram 机器人"
|
||||
"telegramBotEnableDesc" = "启用 Telegram 机器人功能"
|
||||
"telegramToken" = "Telegram 机器人令牌(token)"
|
||||
"telegramTokenDesc" = "从 '@BotFather' 获取的 Telegram 机器人令牌"
|
||||
"telegramTokenDesc" = "跟 '@BotFather' 对话获取的 Telegram 机器人令牌"
|
||||
"telegramProxy" = "SOCKS5 Proxy"
|
||||
"telegramProxyDesc" = "启用 SOCKS5 代理连接到 Telegram(根据指南调整设置)"
|
||||
"telegramAPIServer" = "Telegram API Server"
|
||||
@ -453,13 +466,16 @@
|
||||
"statsOutboundDownlink" = "出站下载统计"
|
||||
"statsOutboundDownlinkDesc" = "启用所有出站代理的下行流量统计收集。"
|
||||
|
||||
[pages.navigation]
|
||||
"title" = "实用导航"
|
||||
|
||||
[pages.xray.rules]
|
||||
"first" = "置顶"
|
||||
"last" = "置底"
|
||||
"up" = "向上"
|
||||
"down" = "向下"
|
||||
"source" = "来源"
|
||||
"dest" = "目的地址"
|
||||
"dest" = "目标地址"
|
||||
"inbound" = "入站"
|
||||
"outbound" = "出站"
|
||||
"balancer" = "负载均衡"
|
||||
@ -467,6 +483,18 @@
|
||||
"add" = "添加规则"
|
||||
"edit" = "编辑规则"
|
||||
"useComma" = "逗号分隔的项目"
|
||||
"DomainMatcher" = "域匹配类型"
|
||||
"SourceIPs" = "源IP"
|
||||
"SourcePort" = "源端口"
|
||||
"Network" = "网络类型"
|
||||
"Protocol" = "传输协议"
|
||||
"Attributes" = "属性"
|
||||
"Domain" = "域地址"
|
||||
"User" = "用户"
|
||||
"Port" = "端口"
|
||||
"InboundTag" = "入站 Tag"
|
||||
"OutboundTag" = "出站 Tag"
|
||||
"BalancerTag" = "负载均衡 Tag"
|
||||
|
||||
[pages.xray.outbound]
|
||||
"addOutbound" = "添加出站"
|
||||
@ -567,27 +595,26 @@
|
||||
[tgbot]
|
||||
"keyboardClosed" = "❌ 自定义键盘已关闭!"
|
||||
"noResult" = "❗ 没有结果!"
|
||||
"noQuery" = "❌ 未找到查询!请再次使用该命令!"
|
||||
"noQuery" = "❌ 未找到查询!请重新使用命令!"
|
||||
"wentWrong" = "❌ 出了点问题!"
|
||||
"noIpRecord" = "❗ 没有IP记录!"
|
||||
"noInbounds" = "❗ 未找到入站!"
|
||||
"unlimited" = "♾ 无限(重置)"
|
||||
"noIpRecord" = "❗ 没有 IP 记录!"
|
||||
"noInbounds" = "❗ 没有找到入站连接!"
|
||||
"unlimited" = "♾ 无限制"
|
||||
"add" = "添加"
|
||||
"month" = "月"
|
||||
"months" = "月"
|
||||
"day" = "天"
|
||||
"days" = "天"
|
||||
"hours" = "小时"
|
||||
"minutes" = "分钟"
|
||||
"unknown" = "未知"
|
||||
"inbounds" = "入站"
|
||||
"inbounds" = "入站连接"
|
||||
"clients" = "客户端"
|
||||
"offline" = "🔴 离线"
|
||||
"online" = "🟢 在线"
|
||||
|
||||
[tgbot.commands]
|
||||
"unknown" = "❗ 未知命令"
|
||||
"pleaseChoose" = "👇 请选择:\r\n"
|
||||
"pleaseChoose" = "👇请〔按照需求〕选择下方按钮 :\r\n"
|
||||
"help" = "🤖 欢迎使用本机器人!它旨在为您提供来自服务器的特定数据,并允许您进行必要的修改。\r\n\r\n"
|
||||
"start" = "👋 你好,<i>{{ .Firstname }}</i>。\r\n"
|
||||
"welcome" = "🤖 欢迎来到 <b>{{ .Hostname }}</b> 管理机器人。\r\n"
|
||||
@ -614,7 +641,7 @@
|
||||
"report" = "🕰 定时报告:{{ .RunTime }}\r\n"
|
||||
"datetime" = "⏰ 日期时间:{{ .DateTime }}\r\n"
|
||||
"hostname" = "💻 主机名:{{ .Hostname }}\r\n"
|
||||
"version" = "🚀 X-UI 版本:{{ .Version }}\r\n"
|
||||
"version" = "🚀 3X-UI 版本:{{ .Version }}\r\n"
|
||||
"xrayVersion" = "📡 Xray 版本: {{ .XrayVersion }}\r\n"
|
||||
"ipv6" = "🌐 IPv6:{{ .IPv6 }}\r\n"
|
||||
"ipv4" = "🌐 IPv4:{{ .IPv4 }}\r\n"
|
||||
@ -637,7 +664,7 @@
|
||||
"active" = "💡 激活:{{ .Enable }}\r\n"
|
||||
"enabled" = "🚨 已启用:{{ .Enable }}\r\n"
|
||||
"online" = "🌐 连接状态:{{ .Status }}\r\n"
|
||||
"email" = "📧 邮箱:{{ .Email }}\r\n"
|
||||
"email" = "📧 邮箱(用户):{{ .Email }}\r\n"
|
||||
"upload" = "🔼 上传↑:{{ .Upload }}\r\n"
|
||||
"download" = "🔽 下载↓:{{ .Download }}\r\n"
|
||||
"total" = "📊 总计:{{ .UpDown }} / {{ .Total }}\r\n"
|
||||
@ -680,12 +707,12 @@
|
||||
"confirmRemoveTGUser" = "✅ 确认移除 Telegram 用户?"
|
||||
"confirmToggle" = "✅ 确认启用/禁用用户?"
|
||||
"dbBackup" = "获取数据库备份"
|
||||
"serverUsage" = "服务器使用情况"
|
||||
"serverUsage" = "服务器状态"
|
||||
"getInbounds" = "获取入站信息"
|
||||
"depleteSoon" = "即将耗尽"
|
||||
"clientUsage" = "获取使用情况"
|
||||
"onlines" = "在线客户端"
|
||||
"commands" = "命令"
|
||||
"commands" = "常用命令"
|
||||
"refresh" = "🔄 刷新"
|
||||
"clearIPs" = "❌ 清除 IP"
|
||||
"removeTGUser" = "❌ 移除 Telegram 用户"
|
||||
@ -697,7 +724,7 @@
|
||||
"ipLimit" = "🔢 IP 限制"
|
||||
"setTGUser" = "👤 设置 Telegram 用户"
|
||||
"toggle" = "🔘 启用/禁用"
|
||||
"custom" = "🔢 风俗"
|
||||
"custom" = "🔢 自定义输入"
|
||||
"confirmNumber" = "✅ 确认: {{ .Num }}"
|
||||
"confirmNumberAdd" = "✅ 确认添加:{{ .Num }}"
|
||||
"limitTraffic" = "🚧 流量限制"
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
"username" = "使用者名稱"
|
||||
"username" = "用戶名"
|
||||
"password" = "密碼"
|
||||
"login" = "登入"
|
||||
"confirm" = "確定"
|
||||
"cancel" = "取消"
|
||||
"close" = "關閉"
|
||||
"create" = "建立"
|
||||
"create" = "創建"
|
||||
"update" = "更新"
|
||||
"copy" = "複製"
|
||||
"copied" = "已複製"
|
||||
@ -27,8 +27,8 @@
|
||||
"info" = "更多資訊"
|
||||
"edit" = "編輯"
|
||||
"delete" = "刪除"
|
||||
"reset" = "重置"
|
||||
"noData" = "無數據。"
|
||||
"reset" = "重設"
|
||||
"noData" = "無資料"
|
||||
"copySuccess" = "複製成功"
|
||||
"sure" = "確定"
|
||||
"encryption" = "加密"
|
||||
@ -43,10 +43,10 @@
|
||||
"depleted" = "耗盡"
|
||||
"depletingSoon" = "即將耗盡"
|
||||
"offline" = "離線"
|
||||
"online" = "線上"
|
||||
"domainName" = "域名"
|
||||
"online" = "在線"
|
||||
"domainName" = "網域名稱"
|
||||
"monitor" = "監聽"
|
||||
"certificate" = "憑證"
|
||||
"certificate" = "數位憑證"
|
||||
"fail" = "失敗"
|
||||
"comment" = "評論"
|
||||
"success" = "成功"
|
||||
@ -54,33 +54,35 @@
|
||||
"install" = "安裝"
|
||||
"clients" = "客戶端"
|
||||
"usage" = "使用情況"
|
||||
"secretToken" = "安全金鑰"
|
||||
"twoFactorCode" = "代碼"
|
||||
"remained" = "剩餘"
|
||||
"security" = "安全"
|
||||
"secAlertTitle" = "安全警報"
|
||||
"secAlertSsl" = "此連線不安全。在啟用 TLS 進行資料保護之前,請勿輸入敏感資訊。"
|
||||
"secAlertConf" = "某些設定易受攻擊。建議加強安全協議以防止潛在漏洞。"
|
||||
"secAlertSSL" = "面板缺少安全連線。請安裝 TLS 證書以保護資料安全。"
|
||||
"secAlertPanelPort" = "面板預設埠存在安全風險。請配置隨機埠或特定埠。"
|
||||
"secAlertPanelURI" = "面板預設 URI 路徑不安全。請配置複雜的 URI 路徑。"
|
||||
"secAlertSubURI" = "訂閱預設 URI 路徑不安全。請配置複雜的 URI 路徑。"
|
||||
"secAlertSubJsonURI" = "訂閱 JSON 預設 URI 路徑不安全。請配置複雜的 URI 路徑。"
|
||||
"emptyDnsDesc" = "未添加DNS伺服器。"
|
||||
"emptyFakeDnsDesc" = "未添加Fake DNS伺服器。"
|
||||
"emptyBalancersDesc" = "未添加負載平衡器。"
|
||||
"emptyReverseDesc" = "未添加反向代理。"
|
||||
"somethingWentWrong" = "發生錯誤"
|
||||
"secAlertSsl" = "此連線不安全!在啟用 TLS 進行資料保護之前,請勿輸入敏感資訊。"
|
||||
"secAlertConf" = "某些設定易受攻擊!建議加強安全協議以防止潛在漏洞。"
|
||||
"secAlertSSL" = "面板缺少安全連線!請安裝 TLS 憑證以保護資料安全。"
|
||||
"secAlertPanelPort" = "面板預設連接埠存在安全風險!請設定隨機連接埠或特定連接埠。"
|
||||
"secAlertPanelURI" = "面板預設 URI 路徑不安全!請設定複雜的 URI 路徑。"
|
||||
"secAlertSubURI" = "訂閱預設 URI 路徑不安全!請設定複雜的 URI 路徑。"
|
||||
"secAlertSubJsonURI" = "訂閱 JSON 預設 URI 路徑不安全!請設定複雜的 URI 路徑。"
|
||||
"emptyDnsDesc" = "未新增 DNS 伺服器。"
|
||||
"emptyFakeDnsDesc" = "未新增 Fake DNS 伺服器。"
|
||||
"emptyBalancersDesc" = "未新增負載平衡器。"
|
||||
"emptyReverseDesc" = "未新增反向代理。"
|
||||
"somethingWentWrong" = "出了一點問題"
|
||||
|
||||
[menu]
|
||||
"theme" = "主題"
|
||||
"dark" = "深色"
|
||||
"ultraDark" = "超深色"
|
||||
"dark" = "暗色"
|
||||
"ultraDark" = "黑色"
|
||||
"dashboard" = "系統狀態"
|
||||
"inbounds" = "入站列表"
|
||||
"settings" = "面板設定"
|
||||
"xray" = "Xray 設定"
|
||||
"logout" = "退出登入"
|
||||
"logout" = "登出"
|
||||
"link" = "管理"
|
||||
"navigation" = "實用導覽"
|
||||
|
||||
[pages.login]
|
||||
"hello" = "你好"
|
||||
@ -89,9 +91,9 @@
|
||||
|
||||
[pages.login.toasts]
|
||||
"invalidFormData" = "資料格式錯誤"
|
||||
"emptyUsername" = "請輸入使用者名稱"
|
||||
"emptyUsername" = "請輸入用戶名"
|
||||
"emptyPassword" = "請輸入密碼"
|
||||
"wrongUsernameOrPassword" = "用戶名、密碼或雙重驗證碼無效。"
|
||||
"wrongUsernameOrPassword" = "用戶名、密碼或雙重驗證碼無效。"
|
||||
"successLogin" = "您已成功登入您的帳戶。"
|
||||
|
||||
[pages.index]
|
||||
@ -99,56 +101,57 @@
|
||||
"cpu" = "CPU"
|
||||
"logicalProcessors" = "邏輯處理器"
|
||||
"frequency" = "頻率"
|
||||
"swap" = "交換空間"
|
||||
"swap" = "交換分區"
|
||||
"storage" = "儲存"
|
||||
"memory" = "記憶體"
|
||||
"hard" = "磁碟"
|
||||
"threads" = "執行緒"
|
||||
"xrayStatus" = "Xray"
|
||||
"stopXray" = "停止"
|
||||
"restartXray" = "重啟"
|
||||
"xraySwitch" = "版本"
|
||||
"xraySwitchClick" = "選擇你要切換到的版本"
|
||||
"xraySwitchClickDesk" = "請謹慎選擇,因為較舊版本可能與當前配置不相容"
|
||||
"xraySwitchClick" = "選擇您要切換到的版本"
|
||||
"xraySwitchClickDesk" = "請謹慎選擇,因為較舊版本可能與目前設定不相容"
|
||||
"xrayStatusUnknown" = "未知"
|
||||
"xrayStatusRunning" = "運行中"
|
||||
"xrayStatusStop" = "停止"
|
||||
"xrayStatusError" = "錯誤"
|
||||
"xrayErrorPopoverTitle" = "執行Xray時發生錯誤"
|
||||
"xrayErrorPopoverTitle" = "執行 Xray 時發生錯誤"
|
||||
"operationHours" = "系統正常執行時間"
|
||||
"systemLoad" = "系統負載"
|
||||
"systemLoadDesc" = "過去 1、5 和 15 分鐘的系統平均負載"
|
||||
"connectionCount" = "連線數"
|
||||
"ipAddresses" = "IP地址"
|
||||
"toggleIpVisibility" = "切換IP可見性"
|
||||
"ipAddresses" = "IP 位址"
|
||||
"toggleIpVisibility" = "切換 IP 可見性"
|
||||
"overallSpeed" = "整體速度"
|
||||
"upload" = "上傳"
|
||||
"download" = "下載"
|
||||
"totalData" = "總數據"
|
||||
"sent" = "已發送"
|
||||
"sent" = "已傳送"
|
||||
"received" = "已接收"
|
||||
"documentation" = "文件"
|
||||
"xraySwitchVersionDialog" = "您確定要變更Xray版本嗎?"
|
||||
"xraySwitchVersionDialogDesc" = "這將會把Xray版本變更為#version#。"
|
||||
"xraySwitchVersionDialog" = "您確定要變更 Xray 版本嗎?"
|
||||
"xraySwitchVersionDialogDesc" = "這將把 Xray 版本變更為 #version#。"
|
||||
"xraySwitchVersionPopover" = "Xray 更新成功"
|
||||
"geofileUpdateDialog" = "您確定要更新地理檔案嗎?"
|
||||
"geofileUpdateDialogDesc" = "這將更新 #filename# 檔案。"
|
||||
"geofilesUpdateDialogDesc" = "這將更新所有文件。"
|
||||
"geofilesUpdateDialogDesc" = "這將更新所有檔案。"
|
||||
"geofilesUpdateAll" = "全部更新"
|
||||
"geofileUpdatePopover" = "地理檔案更新成功"
|
||||
"dontRefresh" = "安裝中,請勿重新整理此頁面"
|
||||
"logs" = "日誌"
|
||||
"config" = "配置"
|
||||
"backup" = "備份和恢復"
|
||||
"backupTitle" = "備份和恢復資料庫"
|
||||
"config" = "設定"
|
||||
"backup" = "備份與還原"
|
||||
"backupTitle" = "備份與還原資料庫"
|
||||
"exportDatabase" = "備份"
|
||||
"exportDatabaseDesc" = "點擊下載包含當前資料庫備份的 .db 文件到您的設備。"
|
||||
"importDatabase" = "恢復"
|
||||
"importDatabaseDesc" = "點擊選擇並上傳設備中的 .db 文件以從備份恢復資料庫。"
|
||||
"exportDatabaseDesc" = "點擊下載包含目前資料庫備份的 .db 檔案到您的裝置。"
|
||||
"importDatabase" = "還原"
|
||||
"importDatabaseDesc" = "點擊選擇並上傳裝置中的 .db 檔案以從備份還原資料庫。"
|
||||
"importDatabaseSuccess" = "資料庫匯入成功"
|
||||
"importDatabaseError" = "匯入資料庫時發生錯誤"
|
||||
"readDatabaseError" = "讀取資料庫時發生錯誤"
|
||||
"getDatabaseError" = "檢索資料庫時發生錯誤"
|
||||
"getConfigError" = "檢索設定檔時發生錯誤"
|
||||
"getDatabaseError" = "擷取資料庫時發生錯誤"
|
||||
"getConfigError" = "擷取設定檔時發生錯誤"
|
||||
|
||||
[pages.inbounds]
|
||||
"allTimeTraffic" = "累計總流量"
|
||||
@ -161,30 +164,32 @@
|
||||
"enable" = "啟用"
|
||||
"remark" = "備註"
|
||||
"protocol" = "協議"
|
||||
"port" = "埠"
|
||||
"portMap" = "埠映射"
|
||||
"port" = "連接埠"
|
||||
"portMap" = "連接埠映射"
|
||||
"traffic" = "流量"
|
||||
"details" = "詳細資訊"
|
||||
"transportConfig" = "傳輸配置"
|
||||
"transportConfig" = "傳輸設定"
|
||||
"expireDate" = "到期時間"
|
||||
"createdAt" = "建立時間"
|
||||
"updatedAt" = "更新時間"
|
||||
"resetTraffic" = "重置流量"
|
||||
"addInbound" = "新增入站"
|
||||
"generalActions" = "通用操作"
|
||||
"autoRefresh" = "自動刷新"
|
||||
"autoRefresh" = "自動重新整理"
|
||||
"autoRefreshInterval" = "間隔"
|
||||
"create" = "新增"
|
||||
"update" = "修改"
|
||||
"modifyInbound" = "修改入站"
|
||||
"deleteInbound" = "刪除入站"
|
||||
"deleteInboundContent" = "確定要刪除入站嗎?"
|
||||
"deleteClient" = "刪除客戶端"
|
||||
"deleteClientContent" = "確定要刪除客戶端嗎?"
|
||||
"resetTrafficContent" = "確定要重置流量嗎?"
|
||||
"resetTrafficContent" = "確定要重設流量嗎?"
|
||||
"copyLink" = "複製連結"
|
||||
"address" = "地址"
|
||||
"address" = "位址"
|
||||
"network" = "網路"
|
||||
"destinationPort" = "目標埠"
|
||||
"targetAddress" = "目標地址"
|
||||
"destinationPort" = "目標連接埠"
|
||||
"targetAddress" = "目標位址"
|
||||
"monitorDesc" = "留空表示監聽所有 IP"
|
||||
"meansNoLimit" = "= 無限制(單位:GB)"
|
||||
"totalFlow" = "總流量"
|
||||
@ -194,41 +199,46 @@
|
||||
"certificateContent" = "檔案內容"
|
||||
"publicKey" = "公鑰"
|
||||
"privatekey" = "私鑰"
|
||||
"clickOnQRcode" = "點選二維碼複製"
|
||||
"client" = "客戶"
|
||||
"clickOnQRcode" = "點擊二維碼複製"
|
||||
"client" = "客戶/用戶"
|
||||
"export" = "匯出連結"
|
||||
"clone" = "複製"
|
||||
"cloneInbound" = "複製"
|
||||
"cloneInboundContent" = "此入站規則除埠(Port)、監聽 IP(Listening IP)和客戶端(Clients)以外的所有配置都將應用於克隆"
|
||||
"cloneInboundOk" = "建立克隆"
|
||||
"resetAllTraffic" = "重置所有入站流量"
|
||||
"resetAllTrafficTitle" = "重置所有入站流量"
|
||||
"resetAllTrafficContent" = "確定要重置所有入站流量嗎?"
|
||||
"resetInboundClientTraffics" = "重置客戶端流量"
|
||||
"resetInboundClientTrafficTitle" = "重置所有客戶端流量"
|
||||
"resetInboundClientTrafficContent" = "確定要重置此入站客戶端的所有流量嗎?"
|
||||
"resetAllClientTraffics" = "重置所有客戶端流量"
|
||||
"resetAllClientTrafficTitle" = "重置所有客戶端流量"
|
||||
"resetAllClientTrafficContent" = "確定要重置所有客戶端的所有流量嗎?"
|
||||
"clone" = "克隆"
|
||||
"cloneInbound" = "克隆"
|
||||
"cloneInboundContent" = "此入站規則除連接埠(Port)、監聽 IP(Listening IP)和客戶端(Clients)以外的所有設定都將應用於克隆"
|
||||
"cloneInboundOk" = "創建克隆"
|
||||
"resetAllTraffic" = "重設所有入站流量"
|
||||
"resetAllTrafficTitle" = "重設所有入站流量"
|
||||
"resetAllTrafficContent" = "確定要重設所有入站流量嗎?"
|
||||
"resetInboundClientTraffics" = "重設客戶端流量"
|
||||
"resetInboundClientTrafficTitle" = "重設所有客戶端流量"
|
||||
"resetInboundClientTrafficContent" = "確定要重設此入站客戶端的所有流量嗎?"
|
||||
"resetAllClientTraffics" = "重設所有客戶端流量"
|
||||
"resetAllClientTrafficTitle" = "重設所有客戶端流量"
|
||||
"resetAllClientTrafficContent" = "確定要重設所有客戶端的所有流量嗎?"
|
||||
"delDepletedClients" = "刪除流量耗盡的客戶端"
|
||||
"delDepletedClientsTitle" = "刪除流量耗盡的客戶端"
|
||||
"delDepletedClientsContent" = "確定要刪除所有流量耗盡的客戶端嗎?"
|
||||
"email" = "電子郵件"
|
||||
"emailDesc" = "電子郵件必須完全唯一"
|
||||
"emailDesc" = "電子郵件必須確保唯一"
|
||||
"IPLimit" = "IP 限制"
|
||||
"IPLimitDesc" = "如果數量超過設定值,則禁用入站流量。(0 = 禁用)"
|
||||
"IPLimitDesc" = "如果數量超過設定值,則停用入站流量。(0 = 停用)"
|
||||
"IPLimitlog" = "IP 日誌"
|
||||
"IPLimitlogDesc" = "IP 歷史日誌(要啟用被禁用的入站流量,請清除日誌)"
|
||||
"IPLimitlogDesc" = "IP 歷史日誌(要啟用被停用的入站流量,請清除日誌)"
|
||||
"IPLimitlogclear" = "清除日誌"
|
||||
"setDefaultCert" = "從面板設定證書"
|
||||
"telegramDesc" = "請提供Telegram聊天ID。(在機器人中使用'/id'命令)或(@userinfobot"
|
||||
"subscriptionDesc" = "要找到你的訂閱 URL,請導航到“詳細資訊”。此外,你可以為多個客戶端使用相同的名稱。"
|
||||
"setDefaultCert" = "從面板設定憑證"
|
||||
"telegramDesc" = "請提供 Telegram 聊天 ID。(在機器人中使用 '/id' 指令或跟 @userinfobot 機器人對話獲取)"
|
||||
"subscriptionDesc" = "要找到您的訂閱 URL,請導覽至「詳細資訊」。此外,您可以為多個客戶端使用相同的名稱。"
|
||||
"info" = "資訊"
|
||||
"same" = "相同"
|
||||
"inboundData" = "入站資料"
|
||||
"exportInbound" = "匯出入站規則"
|
||||
"import"="匯入"
|
||||
"import" = "匯入"
|
||||
"importInbound" = "匯入入站規則"
|
||||
"reviewTitle" = "請確認以下設定資訊"
|
||||
"neverExpire" = "永不過期"
|
||||
"reviewHint" = "如需修改請返回上一步"
|
||||
"unlimited" = "無限制"
|
||||
"deviceLimit" = "裝置限制"
|
||||
|
||||
[pages.client]
|
||||
"add" = "新增客戶端"
|
||||
@ -236,40 +246,40 @@
|
||||
"submitAdd" = "新增客戶端"
|
||||
"submitEdit" = "儲存修改"
|
||||
"clientCount" = "客戶端數量"
|
||||
"bulk" = "批量建立"
|
||||
"bulk" = "批次創建"
|
||||
"method" = "方法"
|
||||
"first" = "置頂"
|
||||
"last" = "置底"
|
||||
"prefix" = "字首"
|
||||
"postfix" = "字尾"
|
||||
"prefix" = "前綴"
|
||||
"postfix" = "後綴"
|
||||
"delayedStart" = "首次使用後開始"
|
||||
"expireDays" = "期間"
|
||||
"expireDays" = "到期天數/期間"
|
||||
"days" = "天"
|
||||
"renew" = "自動續訂"
|
||||
"renewDesc" = "到期後自動續訂。(0 = 禁用)(單位: 天)"
|
||||
"renew" = "自動續約"
|
||||
"renewDesc" = "到期後自動續約。(0 = 停用)(單位: 天)"
|
||||
|
||||
[pages.inbounds.toasts]
|
||||
"obtain" = "獲取"
|
||||
"updateSuccess" = "更新成功"
|
||||
"logCleanSuccess" = "日誌已清除"
|
||||
"inboundsUpdateSuccess" = "入站連接已成功更新"
|
||||
"inboundUpdateSuccess" = "入站連接已成功更新"
|
||||
"inboundCreateSuccess" = "入站連接已成功建立"
|
||||
"inboundDeleteSuccess" = "入站連接已成功刪除"
|
||||
"inboundsUpdateSuccess" = "入站連線已成功更新"
|
||||
"inboundUpdateSuccess" = "入站連線已成功更新"
|
||||
"inboundCreateSuccess" = "入站連線已成功創建"
|
||||
"inboundDeleteSuccess" = "入站連線已成功刪除"
|
||||
"inboundClientAddSuccess" = "已新增入站客戶端"
|
||||
"inboundClientDeleteSuccess" = "入站客戶端已刪除"
|
||||
"inboundClientUpdateSuccess" = "入站客戶端已更新"
|
||||
"delDepletedClientsSuccess" = "所有耗盡客戶端已刪除"
|
||||
"resetAllClientTrafficSuccess" = "客戶端所有流量已重置"
|
||||
"resetAllTrafficSuccess" = "所有流量已重置"
|
||||
"resetInboundClientTrafficSuccess" = "流量已重置"
|
||||
"trafficGetError" = "取得流量資料時發生錯誤"
|
||||
"getNewX25519CertError" = "取得X25519憑證時發生錯誤。"
|
||||
"getNewmldsa65Error" = "取得mldsa65憑證時發生錯誤。"
|
||||
"resetAllClientTrafficSuccess" = "客戶端所有流量已重設"
|
||||
"resetAllTrafficSuccess" = "所有流量已重設"
|
||||
"resetInboundClientTrafficSuccess" = "流量已重設"
|
||||
"trafficGetError" = "獲取流量資料時發生錯誤"
|
||||
"getNewX25519CertError" = "獲取 X25519 憑證時發生錯誤。"
|
||||
"getNewmldsa65Error" = "獲取 mldsa65 憑證時發生錯誤。"
|
||||
|
||||
[pages.inbounds.stream.general]
|
||||
"request" = "請求"
|
||||
"response" = "響應"
|
||||
"response" = "回應"
|
||||
"name" = "名稱"
|
||||
"value" = "值"
|
||||
|
||||
@ -279,60 +289,62 @@
|
||||
"path" = "路徑"
|
||||
"status" = "狀態"
|
||||
"statusDescription" = "狀態說明"
|
||||
"requestHeader" = "請求頭"
|
||||
"responseHeader" = "響應頭"
|
||||
"requestHeader" = "請求標頭"
|
||||
"responseHeader" = "回應標頭"
|
||||
|
||||
[pages.settings]
|
||||
"title" = "面板設定"
|
||||
"save" = "儲存"
|
||||
"infoDesc" = "此處的所有更改都需要儲存並重啟面板才能生效"
|
||||
"infoDesc" = "此處的所有變更都需要儲存並重啟面板才能生效"
|
||||
"restartPanel" = "重啟面板"
|
||||
"restartPanelDesc" = "確定要重啟面板嗎?若重啟後無法訪問面板,請前往伺服器檢視面板日誌資訊"
|
||||
"restartPanelSuccess" = "面板已成功重新啟動"
|
||||
"restartPanelDesc" = "確定要重啟面板嗎?若重啟後無法存取面板,請前往伺服器查看面板日誌資訊"
|
||||
"restartPanelSuccess" = "面板已成功重啟"
|
||||
"actions" = "操作"
|
||||
"resetDefaultConfig" = "重置為預設配置"
|
||||
"panelSettings" = "常規"
|
||||
"resetDefaultConfig" = "重設為預設設定"
|
||||
"panelSettings" = "一般"
|
||||
"securitySettings" = "安全設定"
|
||||
"TGBotSettings" = "Telegram 機器人配置"
|
||||
"TGBotSettings" = "Telegram 機器人設定"
|
||||
"panelListeningIP" = "面板監聽 IP"
|
||||
"panelListeningIPDesc" = "預設留空監聽所有 IP"
|
||||
"panelListeningDomain" = "面板監聽域名"
|
||||
"panelListeningDomainDesc" = "預設情況下留空以監視所有域名和 IP 地址"
|
||||
"panelPort" = "面板監聽埠"
|
||||
"panelListeningDomain" = "面板監聽網域"
|
||||
"panelListeningDomainDesc" = "預設情況下留空以監視所有網域和 IP 位址"
|
||||
"panelPort" = "面板監聽連接埠"
|
||||
"panelPortDesc" = "重啟面板生效"
|
||||
"publicKeyPath" = "面板證書公鑰檔案路徑"
|
||||
"publicKeyPathDesc" = "填寫一個 '/' 開頭的絕對路徑"
|
||||
"privateKeyPath" = "面板證書金鑰檔案路徑"
|
||||
"privateKeyPathDesc" = "填寫一個 '/' 開頭的絕對路徑"
|
||||
"panelUrlPath" = "面板 url 根路徑"
|
||||
"publicKeyPath" = "面板憑證公鑰檔案路徑"
|
||||
"DefaultpublicKeyPath" = "/root/.acme.sh/網域_ecc/網域.cer"
|
||||
"publicKeyPathDesc" = "填寫一個 '/' 開頭的絕對路徑,〔acme 方式〕請自行在填入時修改網域"
|
||||
"privateKeyPath" = "面板憑證金鑰檔案路徑"
|
||||
"DefaultprivateKeyPath" = "/root/.acme.sh/網域_ecc/網域.key"
|
||||
"privateKeyPathDesc" = "填寫一個 '/' 開頭的絕對路徑,〔acme 方式〕請自行在填入時修改網域"
|
||||
"panelUrlPath" = "面板登入存取路徑"
|
||||
"panelUrlPathDesc" = "必須以 '/' 開頭,以 '/' 結尾"
|
||||
"pageSize" = "分頁大小"
|
||||
"pageSizeDesc" = "定義入站表的頁面大小。設定 0 表示禁用"
|
||||
"remarkModel" = "備註模型和分隔符"
|
||||
"pageSizeDesc" = "定義入站列表的頁面大小。設定 0 表示停用"
|
||||
"remarkModel" = "備註模型與分隔符"
|
||||
"datepicker" = "日期選擇器"
|
||||
"datepickerPlaceholder" = "選擇日期"
|
||||
"datepickerDescription" = "選擇器日曆類型指定到期日期"
|
||||
"sampleRemark" = "備註示例"
|
||||
"oldUsername" = "原使用者名稱"
|
||||
"sampleRemark" = "備註範例"
|
||||
"oldUsername" = "原用戶名"
|
||||
"currentPassword" = "原密碼"
|
||||
"newUsername" = "新使用者名稱"
|
||||
"newUsername" = "新用戶名"
|
||||
"newPassword" = "新密碼"
|
||||
"telegramBotEnable" = "啟用 Telegram 機器人"
|
||||
"telegramBotEnableDesc" = "啟用 Telegram 機器人功能"
|
||||
"telegramToken" = "Telegram 機器人令牌(token)"
|
||||
"telegramTokenDesc" = "從 '@BotFather' 獲取的 Telegram 機器人令牌"
|
||||
"telegramToken" = "Telegram 機器人權杖(token)"
|
||||
"telegramTokenDesc" = "跟 '@BotFather' 對話獲取的 Telegram 機器人權杖"
|
||||
"telegramProxy" = "SOCKS5 Proxy"
|
||||
"telegramProxyDesc" = "啟用 SOCKS5 代理連線到 Telegram(根據指南調整設定)"
|
||||
"telegramAPIServer" = "Telegram API Server"
|
||||
"telegramAPIServerDesc" = "要使用的 Telegram API 伺服器。留空以使用預設伺服器。"
|
||||
"telegramChatId" = "管理員聊天 ID"
|
||||
"telegramChatIdDesc" = "Telegram 管理員聊天 ID (多個以逗號分隔)(可通過 @userinfobot 獲取,或在機器人中使用 '/id' 命令獲取)"
|
||||
"telegramChatIdDesc" = "Telegram 管理員聊天 ID (多個以逗號分隔)(可透過 @userinfobot 獲取,或在機器人中使用 '/id' 指令獲取)"
|
||||
"telegramNotifyTime" = "通知時間"
|
||||
"telegramNotifyTimeDesc" = "設定週期性的 Telegram 機器人通知時間(使用 crontab 時間格式)"
|
||||
"tgNotifyBackup" = "資料庫備份"
|
||||
"tgNotifyBackupDesc" = "傳送帶有報告的資料庫備份檔案"
|
||||
"tgNotifyLogin" = "登入通知"
|
||||
"tgNotifyLoginDesc" = "當有人試圖登入你的面板時顯示使用者名稱、IP 地址和時間"
|
||||
"tgNotifyLoginDesc" = "當有人試圖登入您的面板時顯示用戶名、IP 位址和時間"
|
||||
"sessionMaxAge" = "會話時長"
|
||||
"sessionMaxAgeDesc" = "保持登入狀態的時長(單位:分鐘)"
|
||||
"expireTimeDiff" = "到期通知閾值"
|
||||
@ -347,19 +359,19 @@
|
||||
"subEnable" = "啟用訂閱服務"
|
||||
"subEnableDesc" = "啟用訂閱服務功能"
|
||||
"subTitle" = "訂閱標題"
|
||||
"subTitleDesc" = "在VPN客戶端中顯示的標題"
|
||||
"subTitleDesc" = "在 VPN 客戶端中顯示的標題"
|
||||
"subListen" = "監聽 IP"
|
||||
"subListenDesc" = "訂閱服務監聽的 IP 地址(留空表示監聽所有 IP)"
|
||||
"subPort" = "監聽埠"
|
||||
"subPortDesc" = "訂閱服務監聽的埠號(必須是未使用的埠)"
|
||||
"subListenDesc" = "訂閱服務監聽的 IP 位址(留空表示監聽所有 IP)"
|
||||
"subPort" = "監聽連接埠"
|
||||
"subPortDesc" = "訂閱服務監聽的連接埠號(必須是未使用的連接埠)"
|
||||
"subCertPath" = "公鑰路徑"
|
||||
"subCertPathDesc" = "訂閱服務使用的公鑰檔案路徑(以 '/' 開頭)"
|
||||
"subKeyPath" = "私鑰路徑"
|
||||
"subKeyPathDesc" = "訂閱服務使用的私鑰檔案路徑(以 '/' 開頭)"
|
||||
"subPath" = "URI 路徑"
|
||||
"subPathDesc" = "訂閱服務使用的 URI 路徑(以 '/' 開頭,以 '/' 結尾)"
|
||||
"subDomain" = "監聽域名"
|
||||
"subDomainDesc" = "訂閱服務監聽的域名(留空表示監聽所有域名和 IP)"
|
||||
"subDomain" = "監聽網域"
|
||||
"subDomainDesc" = "訂閱服務監聽的網域(留空表示監聽所有網域和 IP)"
|
||||
"subUpdates" = "更新間隔"
|
||||
"subUpdatesDesc" = "客戶端應用中訂閱 URL 的更新間隔(單位:小時)"
|
||||
"subEncrypt" = "編碼"
|
||||
@ -368,12 +380,12 @@
|
||||
"subShowInfoDesc" = "客戶端應用中將顯示剩餘流量和日期資訊"
|
||||
"subURI" = "反向代理 URI"
|
||||
"subURIDesc" = "用於代理後面的訂閱 URL 的 URI 路徑"
|
||||
"externalTrafficInformEnable" = "外部交通通知"
|
||||
"externalTrafficInformEnable" = "外部流量通知"
|
||||
"externalTrafficInformEnableDesc" = "每次流量更新時通知外部 API"
|
||||
"externalTrafficInformURI" = "外部流量通知 URI"
|
||||
"externalTrafficInformURIDesc" = "流量更新將會傳送到此 URI"
|
||||
"externalTrafficInformURIDesc" = "流量更新將傳送到此 URI"
|
||||
"fragment" = "分片"
|
||||
"fragmentDesc" = "啟用 TLS hello 資料包分片"
|
||||
"fragmentDesc" = "啟用 TLS hello 封包分片"
|
||||
"fragmentSett" = "設定"
|
||||
"noisesDesc" = "啟用 Noises."
|
||||
"noisesSett" = "Noises 設定"
|
||||
@ -381,68 +393,68 @@
|
||||
"muxDesc" = "在已建立的資料流內傳輸多個獨立的資料流"
|
||||
"muxSett" = "複用器設定"
|
||||
"direct" = "直接連線"
|
||||
"directDesc" = "直接與特定國家的域或IP範圍建立連線"
|
||||
"directDesc" = "直接與特定國家的網域或 IP 範圍建立連線"
|
||||
"notifications" = "通知"
|
||||
"certs" = "證書"
|
||||
"certs" = "憑證"
|
||||
"externalTraffic" = "外部流量"
|
||||
"dateAndTime" = "日期和時間"
|
||||
"proxyAndServer" = "代理和伺服器"
|
||||
"dateAndTime" = "日期與時間"
|
||||
"proxyAndServer" = "代理與伺服器"
|
||||
"intervals" = "間隔"
|
||||
"information" = "資訊"
|
||||
"language" = "語言"
|
||||
"telegramBotLanguage" = "Telegram 機器人語言"
|
||||
|
||||
[pages.xray]
|
||||
"title" = "Xray 配置"
|
||||
"title" = "Xray 設定"
|
||||
"save" = "儲存"
|
||||
"restart" = "重新啟動 Xray"
|
||||
"restartSuccess" = "Xray 已成功重新啟動"
|
||||
"stopSuccess" = "Xray 已成功停止"
|
||||
"restartError" = "重新啟動Xray時發生錯誤。"
|
||||
"stopError" = "停止Xray時發生錯誤。"
|
||||
"basicTemplate" = "基礎配置"
|
||||
"advancedTemplate" = "高階配置"
|
||||
"generalConfigs" = "常規配置"
|
||||
"generalConfigsDesc" = "這些選項將決定常規配置"
|
||||
"restartError" = "重啟 Xray 時發生錯誤。"
|
||||
"stopError" = "停止 Xray 時發生錯誤。"
|
||||
"basicTemplate" = "基礎設定"
|
||||
"advancedTemplate" = "進階設定"
|
||||
"generalConfigs" = "一般設定"
|
||||
"generalConfigsDesc" = "這些選項將決定一般設定"
|
||||
"logConfigs" = "日誌"
|
||||
"logConfigsDesc" = "日誌可能會影響伺服器的效能,建議僅在需要時啟用"
|
||||
"blockConfigsDesc" = "這些選項將阻止使用者連線到特定協議和網站"
|
||||
"basicRouting" = "基本路由"
|
||||
"blockConnectionsConfigsDesc" = "這些選項將根據特定的請求國家阻止流量。"
|
||||
"directConnectionsConfigsDesc" = "直接連線確保特定的流量不會通過其他伺服器路由。"
|
||||
"blockips" = "阻止IP"
|
||||
"blockdomains" = "阻止域名"
|
||||
"directips" = "直接IP"
|
||||
"directdomains" = "直接域名"
|
||||
"directConnectionsConfigsDesc" = "直接連線確保特定的流量不會透過其他伺服器路由。"
|
||||
"blockips" = "阻止 IP"
|
||||
"blockdomains" = "阻止網域"
|
||||
"directips" = "直接 IP"
|
||||
"directdomains" = "直接網域"
|
||||
"ipv4Routing" = "IPv4 路由"
|
||||
"ipv4RoutingDesc" = "此選項將僅通過 IPv4 路由到目標域"
|
||||
"ipv4RoutingDesc" = "此選項將僅透過 IPv4 路由到目標網域"
|
||||
"warpRouting" = "WARP 路由"
|
||||
"warpRoutingDesc" = "注意:在使用這些選項之前,請按照面板 GitHub 上的步驟在你的伺服器上以 socks5 代理模式安裝 WARP。WARP 將通過 Cloudflare 伺服器將流量路由到網站。"
|
||||
"Template" = "高階 Xray 配置模板"
|
||||
"TemplateDesc" = "最終的 Xray 配置檔案將基於此模板生成"
|
||||
"warpRoutingDesc" = "注意:在使用這些選項之前,請按照面板 GitHub 上的步驟在您的伺服器上以 socks5 代理模式安裝 WARP。WARP 將透過 Cloudflare 伺服器將流量路由到網站。"
|
||||
"Template" = "進階 Xray 設定模板"
|
||||
"TemplateDesc" = "最終的 Xray 設定檔將基於此模板產生"
|
||||
"FreedomStrategy" = "Freedom 協議策略"
|
||||
"FreedomStrategyDesc" = "設定 Freedom 協議中網路的輸出策略"
|
||||
"RoutingStrategy" = "配置路由域策略"
|
||||
"RoutingStrategy" = "設定路由網域策略"
|
||||
"RoutingStrategyDesc" = "設定 DNS 解析的整體路由策略"
|
||||
"Torrent" = "遮蔽 BitTorrent 協議"
|
||||
"Torrent" = "封鎖 BitTorrent 協議"
|
||||
"Inbounds" = "入站規則"
|
||||
"InboundsDesc" = "接受來自特定客戶端的流量"
|
||||
"Outbounds" = "出站規則"
|
||||
"Balancers" = "負載均衡"
|
||||
"Balancers" = "負載平衡"
|
||||
"OutboundsDesc" = "設定出站流量傳出方式"
|
||||
"Routings" = "路由規則"
|
||||
"RoutingsDesc" = "每條規則的優先順序都很重要"
|
||||
"RoutingsDesc" = "每條規則的優先級都很重要"
|
||||
"completeTemplate" = "全部"
|
||||
"logLevel" = "日誌級別"
|
||||
"logLevelDesc" = "錯誤日誌的日誌級別,用於指示需要記錄的資訊"
|
||||
"accessLog" = "訪問日誌"
|
||||
"accessLogDesc" = "訪問日誌的檔案路徑。特殊值 'none' 禁用訪問日誌"
|
||||
"accessLog" = "存取日誌"
|
||||
"accessLogDesc" = "存取日誌的檔案路徑。特殊值 'none' 停用存取日誌"
|
||||
"errorLog" = "錯誤日誌"
|
||||
"errorLogDesc" = "錯誤日誌的檔案路徑。特殊值 'none' 禁用錯誤日誌"
|
||||
"errorLogDesc" = "錯誤日誌的檔案路徑。特殊值 'none' 停用錯誤日誌"
|
||||
"dnsLog" = "DNS 日誌"
|
||||
"dnsLogDesc" = "是否啟用 DNS 查詢日誌"
|
||||
"maskAddress" = "隱藏地址"
|
||||
"maskAddressDesc" = "IP 地址掩碼,啟用時會自動替換日誌中出現的 IP 地址。"
|
||||
"maskAddress" = "隱藏位址"
|
||||
"maskAddressDesc" = "IP 位址遮罩,啟用時會自動替換日誌中出現的 IP 位址。"
|
||||
"statistics" = "統計"
|
||||
"statsInboundUplink" = "入站上傳統計"
|
||||
"statsInboundUplinkDesc" = "啟用所有入站代理的上行流量統計收集。"
|
||||
@ -453,20 +465,35 @@
|
||||
"statsOutboundDownlink" = "出站下載統計"
|
||||
"statsOutboundDownlinkDesc" = "啟用所有出站代理的下行流量統計收集。"
|
||||
|
||||
[pages.navigation]
|
||||
"title" = "實用導覽"
|
||||
|
||||
[pages.xray.rules]
|
||||
"first" = "置頂"
|
||||
"last" = "置底"
|
||||
"up" = "向上"
|
||||
"down" = "向下"
|
||||
"source" = "來源"
|
||||
"dest" = "目的地址"
|
||||
"dest" = "目標位址"
|
||||
"inbound" = "入站"
|
||||
"outbound" = "出站"
|
||||
"balancer" = "負載均衡"
|
||||
"balancer" = "負載平衡"
|
||||
"info" = "資訊"
|
||||
"add" = "新增規則"
|
||||
"edit" = "編輯規則"
|
||||
"useComma" = "逗號分隔的項目"
|
||||
"DomainMatcher" = "網域匹配類型"
|
||||
"SourceIPs" = "來源 IP"
|
||||
"SourcePort" = "來源連接埠"
|
||||
"Network" = "網路類型"
|
||||
"Protocol" = "傳輸協議"
|
||||
"Attributes" = "屬性"
|
||||
"Domain" = "網域"
|
||||
"User" = "使用者"
|
||||
"Port" = "連接埠"
|
||||
"InboundTag" = "入站 Tag"
|
||||
"OutboundTag" = "出站 Tag"
|
||||
"BalancerTag" = "負載平衡 Tag"
|
||||
|
||||
[pages.xray.outbound]
|
||||
"addOutbound" = "新增出站"
|
||||
@ -475,9 +502,9 @@
|
||||
"editReverse" = "編輯反向"
|
||||
"tag" = "標籤"
|
||||
"tagDesc" = "唯一標籤"
|
||||
"address" = "地址"
|
||||
"address" = "位址"
|
||||
"reverse" = "反向"
|
||||
"domain" = "域名"
|
||||
"domain" = "網域"
|
||||
"type" = "類型"
|
||||
"bridge" = "Bridge"
|
||||
"portal" = "Portal"
|
||||
@ -489,8 +516,8 @@
|
||||
"sendThrough" = "傳送通過"
|
||||
|
||||
[pages.xray.balancer]
|
||||
"addBalancer" = "新增負載均衡"
|
||||
"editBalancer" = "編輯負載均衡"
|
||||
"addBalancer" = "新增負載平衡"
|
||||
"editBalancer" = "編輯負載平衡"
|
||||
"balancerStrategy" = "策略"
|
||||
"balancerSelectors" = "選擇器"
|
||||
"tag" = "標籤"
|
||||
@ -503,103 +530,102 @@
|
||||
"allowedIPs" = "允許的 IP"
|
||||
"endpoint" = "端點"
|
||||
"psk" = "共享金鑰"
|
||||
"domainStrategy" = "域策略"
|
||||
"domainStrategy" = "網域策略"
|
||||
|
||||
[pages.xray.dns]
|
||||
"enable" = "啟用 DNS"
|
||||
"enableDesc" = "啟用內建 DNS 伺服器"
|
||||
"tag" = "DNS 入站標籤"
|
||||
"tagDesc" = "此標籤將在路由規則中可用作入站標籤"
|
||||
"clientIp" = "客戶端IP"
|
||||
"clientIpDesc" = "用於在DNS查詢期間通知伺服器指定的IP位置"
|
||||
"disableCache" = "禁用快取"
|
||||
"disableCacheDesc" = "禁用DNS快取"
|
||||
"disableFallback" = "禁用回退"
|
||||
"disableFallbackDesc" = "禁用回退DNS查詢"
|
||||
"disableFallbackIfMatch" = "匹配時禁用回退"
|
||||
"disableFallbackIfMatchDesc" = "當DNS伺服器的匹配域名列表命中時,禁用回退DNS查詢"
|
||||
"clientIp" = "客戶端 IP"
|
||||
"clientIpDesc" = "用於在 DNS 查詢期間通知伺服器指定的 IP 位置"
|
||||
"disableCache" = "停用快取"
|
||||
"disableCacheDesc" = "停用 DNS 快取"
|
||||
"disableFallback" = "停用回退"
|
||||
"disableFallbackDesc" = "停用回退 DNS 查詢"
|
||||
"disableFallbackIfMatch" = "匹配時停用回退"
|
||||
"disableFallbackIfMatchDesc" = "當 DNS 伺服器的匹配網域列表命中時,停用回退 DNS 查詢"
|
||||
"strategy" = "查詢策略"
|
||||
"strategyDesc" = "解析域名的總體策略"
|
||||
"strategyDesc" = "解析網域的總體策略"
|
||||
"add" = "新增伺服器"
|
||||
"edit" = "編輯伺服器"
|
||||
"domains" = "域"
|
||||
"domains" = "網域"
|
||||
"expectIPs" = "預期 IP"
|
||||
"unexpectIPs" = "意外IP"
|
||||
"useSystemHosts" = "使用系統Hosts"
|
||||
"useSystemHostsDesc" = "使用已安裝系統的hosts檔案"
|
||||
"usePreset" = "使用範本"
|
||||
"dnsPresetTitle" = "DNS範本"
|
||||
"unexpectIPs" = "意外 IP"
|
||||
"useSystemHosts" = "使用系統 Hosts"
|
||||
"useSystemHostsDesc" = "使用已安裝系統的 hosts 檔案"
|
||||
"usePreset" = "使用模板"
|
||||
"dnsPresetTitle" = "DNS 模板"
|
||||
"dnsPresetFamily" = "家庭"
|
||||
|
||||
[pages.xray.fakedns]
|
||||
"add" = "新增假 DNS"
|
||||
"edit" = "編輯假 DNS"
|
||||
"ipPool" = "IP 池子網"
|
||||
"ipPool" = "IP 池子網路"
|
||||
"poolSize" = "池大小"
|
||||
|
||||
[pages.settings.security]
|
||||
"admin" = "管理員憑證"
|
||||
"twoFactor" = "雙重驗證"
|
||||
"twoFactorEnable" = "啟用2FA"
|
||||
"twoFactorEnableDesc" = "增加額外的驗證層以提高安全性。"
|
||||
"twoFactor" = "雙重驗證"
|
||||
"twoFactorEnable" = "啟用 2FA"
|
||||
"twoFactorEnableDesc" = "增加額外的驗證層以提高安全性。"
|
||||
"twoFactorModalSetTitle" = "啟用雙重認證"
|
||||
"twoFactorModalDeleteTitle" = "停用雙重認證"
|
||||
"twoFactorModalSteps" = "要設定雙重認證,請執行以下步驟:"
|
||||
"twoFactorModalFirstStep" = "1. 在認證應用程式中掃描此QR碼,或複製QR碼附近的令牌並貼到應用程式中"
|
||||
"twoFactorModalFirstStep" = "1. 在認證應用程式中掃描此 QR 碼,或複製 QR 碼附近的權杖並貼到應用程式中"
|
||||
"twoFactorModalSecondStep" = "2. 輸入應用程式中的驗證碼"
|
||||
"twoFactorModalRemoveStep" = "輸入應用程式中的驗證碼以移除雙重認證。"
|
||||
"twoFactorModalChangeCredentialsTitle" = "更改憑證"
|
||||
"twoFactorModalChangeCredentialsStep" = "輸入應用程式中的代碼以更改管理員憑證。"
|
||||
"twoFactorModalSetSuccess" = "雙重身份驗證已成功建立"
|
||||
"twoFactorModalDeleteSuccess" = "雙重身份驗證已成功刪除"
|
||||
"twoFactorModalChangeCredentialsTitle" = "變更憑證"
|
||||
"twoFactorModalChangeCredentialsStep" = "輸入應用程式中的代碼以變更管理員憑證。"
|
||||
"twoFactorModalSetSuccess" = "雙因素認證已成功建立"
|
||||
"twoFactorModalDeleteSuccess" = "雙因素認證已成功刪除"
|
||||
"twoFactorModalError" = "驗證碼錯誤"
|
||||
|
||||
[pages.settings.toasts]
|
||||
"modifySettings" = "參數已更改。"
|
||||
"getSettings" = "取得參數時發生錯誤"
|
||||
"modifySettings" = "參數已變更。"
|
||||
"getSettings" = "獲取參數時發生錯誤"
|
||||
"modifyUserError" = "變更管理員憑證時發生錯誤。"
|
||||
"modifyUser" = "您已成功變更管理員憑證。"
|
||||
"originalUserPassIncorrect" = "原使用者名稱或原密碼錯誤"
|
||||
"userPassMustBeNotEmpty" = "新使用者名稱和新密碼不能為空"
|
||||
"getOutboundTrafficError" = "取得出站流量錯誤"
|
||||
"originalUserPassIncorrect" = "原用戶名或原密碼錯誤"
|
||||
"userPassMustBeNotEmpty" = "新用戶名和新密碼不能為空"
|
||||
"getOutboundTrafficError" = "獲取出站流量錯誤"
|
||||
"resetOutboundTrafficError" = "重設出站流量錯誤"
|
||||
|
||||
[tgbot]
|
||||
"keyboardClosed" = "❌ 自定義鍵盤已關閉!"
|
||||
"keyboardClosed" = "❌ 自訂鍵盤已關閉!"
|
||||
"noResult" = "❗ 沒有結果!"
|
||||
"noQuery" = "❌ 未找到查詢!請再次使用該命令!"
|
||||
"wentWrong" = "❌ 出了點問題!"
|
||||
"noIpRecord" = "❗ 沒有IP記錄!"
|
||||
"noInbounds" = "❗ 未找到入站!"
|
||||
"unlimited" = "♾ 無限(重置)"
|
||||
"add" = "添加"
|
||||
"noQuery" = "❌ 找不到查詢!請重新使用指令!"
|
||||
"wentWrong" = "❌ 出了一點問題!"
|
||||
"noIpRecord" = "❗ 沒有 IP 記錄!"
|
||||
"noInbounds" = "❗ 找不到入站連線!"
|
||||
"unlimited" = "♾ 無限制"
|
||||
"add" = "新增"
|
||||
"month" = "月"
|
||||
"months" = "月"
|
||||
"day" = "天"
|
||||
"days" = "天"
|
||||
"hours" = "小時"
|
||||
"minutes" = "分鐘"
|
||||
"unknown" = "未知"
|
||||
"inbounds" = "入站"
|
||||
"inbounds" = "入站連線"
|
||||
"clients" = "客戶端"
|
||||
"offline" = "🔴 離線"
|
||||
"online" = "🟢 在線"
|
||||
|
||||
[tgbot.commands]
|
||||
"unknown" = "❗ 未知命令"
|
||||
"pleaseChoose" = "👇 請選擇:\r\n"
|
||||
"unknown" = "❗ 未知指令"
|
||||
"pleaseChoose" = "👇請〔按照需求〕選擇下方按鈕 :\r\n"
|
||||
"help" = "🤖 歡迎使用本機器人!它旨在為您提供來自伺服器的特定資料,並允許您進行必要的修改。\r\n\r\n"
|
||||
"start" = "👋 你好,<i>{{ .Firstname }}</i>。\r\n"
|
||||
"welcome" = "🤖 歡迎來到 <b>{{ .Hostname }}</b> 管理機器人。\r\n"
|
||||
"status" = "✅ 機器人正常執行!"
|
||||
"status" = "✅ 機器人正常運作!"
|
||||
"usage" = "❗ 請輸入要搜尋的文字!"
|
||||
"getID" = "🆔 您的 ID 為:<code>{{ .ID }}</code>"
|
||||
"helpAdminCommands" = "要重新啟動 Xray Core:\r\n<code>/restart</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>"
|
||||
"helpAdminCommands" = "要重新啟動 Xray Core:\r\n<code>/restart</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</code>"
|
||||
"restartSuccess" = "✅ 操作成功!"
|
||||
"restartSuccess" = "✅ 操作成功!"
|
||||
"restartFailed" = "❗ 操作錯誤。\r\n\r\n<code>錯誤: {{ .Error }}</code>."
|
||||
"xrayNotRunning" = "❗ Xray Core 未運行。"
|
||||
"xrayNotRunning" = "❗ Xray Core 未運作。"
|
||||
"startDesc" = "顯示主選單"
|
||||
"helpDesc" = "機器人幫助"
|
||||
"statusDesc" = "檢查機器人狀態"
|
||||
@ -608,44 +634,44 @@
|
||||
[tgbot.messages]
|
||||
"cpuThreshold" = "🔴 CPU 使用率為 {{ .Percent }}%,超過閾值 {{ .Threshold }}%"
|
||||
"selectUserFailed" = "❌ 使用者選擇錯誤!"
|
||||
"userSaved" = "✅ 電報使用者已儲存。"
|
||||
"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"
|
||||
"hostname" = "💻 主機名稱:{{ .Hostname }}\r\n"
|
||||
"version" = "🚀 3X-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"
|
||||
"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"
|
||||
"username" = "👤 用戶名:{{ .Username }}\r\n"
|
||||
"password" = "👤 密碼:{{ .Password }}\r\n"
|
||||
"time" = "⏰ 時間:{{ .Time }}\r\n"
|
||||
"inbound" = "📍 入站:{{ .Remark }}\r\n"
|
||||
"port" = "🔌 埠:{{ .Port }}\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"
|
||||
"email" = "📧 電子郵件(用戶):{{ .Email }}\r\n"
|
||||
"upload" = "🔼 上傳↑:{{ .Upload }}\r\n"
|
||||
"download" = "🔽 下載↓:{{ .Download }}\r\n"
|
||||
"total" = "📊 總計:{{ .UpDown }} / {{ .Total }}\r\n"
|
||||
"TGUser" = "👤 電報使用者:{{ .TelegramID }}\r\n"
|
||||
"TGUser" = "👤 Telegram 用戶:{{ .TelegramID }}\r\n"
|
||||
"exhaustedMsg" = "🚨 耗盡的 {{ .Type }}:\r\n"
|
||||
"exhaustedCount" = "🚨 耗盡的 {{ .Type }} 數量:\r\n"
|
||||
"onlinesCount" = "🌐 線上客戶:{{ .Count }}\r\n"
|
||||
"disabled" = "🛑 禁用:{{ .Disabled }}\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"
|
||||
@ -655,64 +681,64 @@
|
||||
"received_password" = "🔑📥 密碼已更新。"
|
||||
"received_email" = "📧📥 電子郵件已更新。"
|
||||
"received_comment" = "💬📥 評論已更新。"
|
||||
"id_prompt" = "🔑 預設 ID: {{ .ClientId }}\n\n請輸入您的 ID。"
|
||||
"pass_prompt" = "🔑 預設密碼: {{ .ClientPassword }}\n\n請輸入您的密碼。"
|
||||
"email_prompt" = "📧 預設電子郵件: {{ .ClientEmail }}\n\n請輸入您的電子郵件。"
|
||||
"comment_prompt" = "💬 預設評論: {{ .ClientComment }}\n\n請輸入您的評論。"
|
||||
"inbound_client_data_id" = "🔄 入站: {{ .InboundRemark }}\n\n🔑 ID: {{ .ClientId }}\n📧 電子郵件: {{ .ClientEmail }}\n📊 流量: {{ .ClientTraffic }}\n📅 到期日: {{ .ClientExp }}\n🌐 IP 限制: {{ .IpLimit }}\n💬 備註: {{ .ClientComment }}\n\n你現在可以將客戶加入入站了!"
|
||||
"inbound_client_data_pass" = "🔄 入站: {{ .InboundRemark }}\n\n🔑 密碼: {{ .ClientPass }}\n📧 電子郵件: {{ .ClientEmail }}\n📊 流量: {{ .ClientTraffic }}\n📅 到期日: {{ .ClientExp }}\n🌐 IP 限制: {{ .IpLimit }}\n💬 備註: {{ .ClientComment }}\n\n你現在可以將客戶加入入站了!"
|
||||
"cancel" = "❌ 程序已取消!\n\n您可以隨時使用 /start 重新開始。 🔄"
|
||||
"error_add_client" = "⚠️ 錯誤:\n\n {{ .error }}"
|
||||
"id_prompt" = "🔑 預設 ID:{{ .ClientId }}\n\n請輸入您的 ID。"
|
||||
"pass_prompt" = "🔑 預設密碼:{{ .ClientPassword }}\n\n請輸入您的密碼。"
|
||||
"email_prompt" = "📧 預設電子郵件:{{ .ClientEmail }}\n\n請輸入您的電子郵件。"
|
||||
"comment_prompt" = "💬 預設評論:{{ .ClientComment }}\n\n請輸入您的評論。"
|
||||
"inbound_client_data_id" = "🔄 入站:{{ .InboundRemark }}\n\n🔑 ID:{{ .ClientId }}\n📧 電子郵件:{{ .ClientEmail }}\n📊 流量:{{ .ClientTraffic }}\n📅 到期日期:{{ .ClientExp }}\n🌐 IP 限制:{{ .IpLimit }}\n💬 備註:{{ .ClientComment }}\n\n您現在可以將客戶新增到入站了!"
|
||||
"inbound_client_data_pass" = "🔄 入站:{{ .InboundRemark }}\n\n🔑 密碼:{{ .ClientPass }}\n📧 電子郵件:{{ .ClientEmail }}\n📊 流量:{{ .ClientTraffic }}\n📅 到期日期:{{ .ClientExp }}\n🌐 IP 限制:{{ .IpLimit }}\n💬 備註:{{ .ClientComment }}\n\n您現在可以將客戶新增到入站了!"
|
||||
"cancel" = "❌ 流程已取消!\n\n您可以隨時使用 /start 重新開始。 🔄"
|
||||
"error_add_client" = "⚠️ 錯誤:\n\n {{ .error }}"
|
||||
"using_default_value" = "好的,我會使用預設值。 😊"
|
||||
"incorrect_input" ="您的輸入無效。\n短語應連續輸入,不能有空格。\n正確示例: aaaaaa\n錯誤示例: aaa aaa 🚫"
|
||||
"AreYouSure" = "你確定嗎?🤔"
|
||||
"SuccessResetTraffic" = "📧 電子郵件: {{ .ClientEmail }}\n🏁 結果: ✅ 成功"
|
||||
"FailedResetTraffic" = "📧 電子郵件: {{ .ClientEmail }}\n🏁 結果: ❌ 失敗 \n\n🛠️ 錯誤: [ {{ .ErrorMessage }} ]"
|
||||
"FinishProcess" = "🔚 所有客戶的流量重置已完成。"
|
||||
"incorrect_input" ="您的輸入無效。\n片語應連續輸入,不能有空格。\n正確範例:aaaaaa\n錯誤範例:aaa aaa 🚫"
|
||||
"AreYouSure" = "您確定嗎?🤔"
|
||||
"SuccessResetTraffic" = "📧 電子郵件:{{ .ClientEmail }}\n🏁 結果:✅ 成功"
|
||||
"FailedResetTraffic" = "📧 電子郵件:{{ .ClientEmail }}\n🏁 結果:❌ 失敗 \n\n🛠️ 錯誤:[ {{ .ErrorMessage }} ]"
|
||||
"FinishProcess" = "🔚 所有客戶的流量重設已完成。"
|
||||
|
||||
[tgbot.buttons]
|
||||
"closeKeyboard" = "❌ 關閉鍵盤"
|
||||
"cancel" = "❌ 取消"
|
||||
"cancelReset" = "❌ 取消重置"
|
||||
"cancelReset" = "❌ 取消重設"
|
||||
"cancelIpLimit" = "❌ 取消 IP 限制"
|
||||
"confirmResetTraffic" = "✅ 確認重置流量?"
|
||||
"confirmResetTraffic" = "✅ 確認重設流量?"
|
||||
"confirmClearIps" = "✅ 確認清除 IP?"
|
||||
"confirmRemoveTGUser" = "✅ 確認移除 Telegram 使用者?"
|
||||
"confirmToggle" = "✅ 確認啟用/禁用使用者?"
|
||||
"confirmRemoveTGUser" = "✅ 確認移除 Telegram 用戶?"
|
||||
"confirmToggle" = "✅ 確認啟用/停用用戶?"
|
||||
"dbBackup" = "獲取資料庫備份"
|
||||
"serverUsage" = "伺服器使用情況"
|
||||
"serverUsage" = "伺服器狀態"
|
||||
"getInbounds" = "獲取入站資訊"
|
||||
"depleteSoon" = "即將耗盡"
|
||||
"clientUsage" = "獲取使用情況"
|
||||
"onlines" = "線上客戶端"
|
||||
"commands" = "命令"
|
||||
"onlines" = "在線客戶端"
|
||||
"commands" = "常用指令"
|
||||
"refresh" = "🔄 重新整理"
|
||||
"clearIPs" = "❌ 清除 IP"
|
||||
"removeTGUser" = "❌ 移除 Telegram 使用者"
|
||||
"selectTGUser" = "👤 選擇 Telegram 使用者"
|
||||
"selectOneTGUser" = "👤 選擇一個 Telegram 使用者:"
|
||||
"resetTraffic" = "📈 重置流量"
|
||||
"resetExpire" = "📅 更改到期日期"
|
||||
"removeTGUser" = "❌ 移除 Telegram 用戶"
|
||||
"selectTGUser" = "👤 選擇 Telegram 用戶"
|
||||
"selectOneTGUser" = "👤 選擇一個 Telegram 用戶:"
|
||||
"resetTraffic" = "📈 重設流量"
|
||||
"resetExpire" = "📅 變更到期日期"
|
||||
"ipLog" = "🔢 IP 日誌"
|
||||
"ipLimit" = "🔢 IP 限制"
|
||||
"setTGUser" = "👤 設定 Telegram 使用者"
|
||||
"toggle" = "🔘 啟用/禁用"
|
||||
"custom" = "🔢 風俗"
|
||||
"confirmNumber" = "✅ 確認: {{ .Num }}"
|
||||
"setTGUser" = "👤 設定 Telegram 用戶"
|
||||
"toggle" = "🔘 啟用/停用"
|
||||
"custom" = "🔢 自訂輸入"
|
||||
"confirmNumber" = "✅ 確認:{{ .Num }}"
|
||||
"confirmNumberAdd" = "✅ 確認新增:{{ .Num }}"
|
||||
"limitTraffic" = "🚧 流量限制"
|
||||
"getBanLogs" = "禁止日誌"
|
||||
"getBanLogs" = "封鎖日誌"
|
||||
"allClients" = "所有客戶"
|
||||
"addClient" = "新增客戶"
|
||||
"submitDisable" = "以停用方式送出 ☑️"
|
||||
"submitEnable" = "以啟用方式送出 ✅"
|
||||
"use_default" = "🏷️ 使用預設值"
|
||||
"submitDisable" = "提交為停用 ☑️"
|
||||
"submitEnable" = "提交為啟用 ✅"
|
||||
"use_default" = "🏷️ 使用預設"
|
||||
"change_id" = "⚙️🔑 ID"
|
||||
"change_password" = "⚙️🔑 密碼"
|
||||
"change_email" = "⚙️📧 電子郵件"
|
||||
"change_comment" = "⚙️💬 評論"
|
||||
"ResetAllTraffics" = "重設所有流量"
|
||||
"SortedTrafficUsageReport" = "排序過的流量使用報告"
|
||||
"SortedTrafficUsageReport" = "排序的流量使用報告"
|
||||
|
||||
[tgbot.answers]
|
||||
"successfulOperation" = "✅ 成功!"
|
||||
@ -722,17 +748,17 @@
|
||||
"canceled" = "❌ {{ .Email }}:操作已取消。"
|
||||
"clientRefreshSuccess" = "✅ {{ .Email }}:客戶端重新整理成功。"
|
||||
"IpRefreshSuccess" = "✅ {{ .Email }}:IP 重新整理成功。"
|
||||
"TGIdRefreshSuccess" = "✅ {{ .Email }}:客戶端的 Telegram 使用者重新整理成功。"
|
||||
"resetTrafficSuccess" = "✅ {{ .Email }}:流量已重置成功。"
|
||||
"setTrafficLimitSuccess" = "✅ {{ .Email }}: 流量限制儲存成功。"
|
||||
"expireResetSuccess" = "✅ {{ .Email }}:過期天數已重置成功。"
|
||||
"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 使用者已成功移除。"
|
||||
"getUserInfo" = "✅ {{ .Email }}:獲取 Telegram 用戶資訊。"
|
||||
"removedTGUserSuccess" = "✅ {{ .Email }}:Telegram 用戶已成功移除。"
|
||||
"enableSuccess" = "✅ {{ .Email }}:已成功啟用。"
|
||||
"disableSuccess" = "✅ {{ .Email }}:已成功禁用。"
|
||||
"askToAddUserId" = "未找到您的配置!\r\n請向管理員詢問,在您的配置中使用您的 Telegram 使用者 ChatID。\r\n\r\n您的使用者 ChatID:<code>{{ .TgUserID }}</code>"
|
||||
"disableSuccess" = "✅ {{ .Email }}:已成功停用。"
|
||||
"askToAddUserId" = "找不到您的設定!\r\n請向管理員詢問,在您的設定中使用您的 Telegram 用戶 ChatID。\r\n\r\n您的用戶 ChatID:<code>{{ .TgUserID }}</code>"
|
||||
"chooseClient" = "為入站 {{ .Inbound }} 選擇一個客戶"
|
||||
"chooseInbound" = "選擇一個入站"
|
||||
|
||||
118
web/web.go
@ -42,6 +42,9 @@ var i18nFS embed.FS
|
||||
|
||||
var startTime = time.Now()
|
||||
|
||||
// 预定义 IPv4 私网和回环网段
|
||||
var privateIPv4Nets []*net.IPNet
|
||||
|
||||
type wrapAssetsFS struct {
|
||||
embed.FS
|
||||
}
|
||||
@ -125,28 +128,39 @@ func (s *Server) getHtmlFiles() ([]string, error) {
|
||||
}
|
||||
|
||||
func (s *Server) getHtmlTemplate(funcMap template.FuncMap) (*template.Template, error) {
|
||||
t := template.New("").Funcs(funcMap)
|
||||
err := fs.WalkDir(htmlFS, "html", func(path string, d fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// 这里用 htmlFS(//go:embed html/*)而不是“templates”
|
||||
t := template.New("").Funcs(funcMap)
|
||||
|
||||
if d.IsDir() {
|
||||
newT, err := t.ParseFS(htmlFS, path+"/*.html")
|
||||
if err != nil {
|
||||
// ignore
|
||||
return nil
|
||||
}
|
||||
t = newT
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return t, nil
|
||||
// 递归遍历 embed 的 html 目录,解析所有 .html 模板
|
||||
err := fs.WalkDir(htmlFS, "html", func(path string, d fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if d.IsDir() {
|
||||
return nil
|
||||
}
|
||||
if !strings.HasSuffix(path, ".html") {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 读出模板内容
|
||||
b, err := htmlFS.ReadFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 去掉前缀“html/”,让 {{template "form/inbound"}} 这种名字能被正确找到
|
||||
name := strings.TrimPrefix(path, "html/")
|
||||
_, err = t.New(name).Parse(string(b))
|
||||
return err
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return t, nil
|
||||
}
|
||||
|
||||
|
||||
func (s *Server) initRouter() (*gin.Engine, error) {
|
||||
if config.IsDebug() {
|
||||
gin.SetMode(gin.DebugMode)
|
||||
@ -331,6 +345,12 @@ func (s *Server) Start() (err error) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if certFile == "" || keyFile == "" {
|
||||
// 如果没有证书,强制检查 listen 是否内部 IP,否则回退到本地
|
||||
if !isInternalIP(listen) {
|
||||
listen = fallbackToLocalhost(listen)
|
||||
}
|
||||
}
|
||||
listenAddr := net.JoinHostPort(listen, strconv.Itoa(port))
|
||||
listener, err := net.Listen("tcp", listenAddr)
|
||||
if err != nil {
|
||||
@ -400,3 +420,63 @@ func (s *Server) GetCtx() context.Context {
|
||||
func (s *Server) GetCron() *cron.Cron {
|
||||
return s.cron
|
||||
}
|
||||
|
||||
// isInternalIP 判断是否为私网或回环IP(支持IPv4和IPv6)
|
||||
func isInternalIP(ipStr string) bool {
|
||||
ip := net.ParseIP(ipStr)
|
||||
if ip == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if ip4 := ip.To4(); ip4 != nil {
|
||||
// IPv4 判断是否在私网/回环网段内
|
||||
for _, privateNet := range privateIPv4Nets {
|
||||
if privateNet.Contains(ip4) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IPv6 判断回环或链路本地地址
|
||||
if ip.IsLoopback() || ip.IsLinkLocalUnicast() {
|
||||
return true
|
||||
}
|
||||
|
||||
// 判断 IPv6 fc00::/7 私网地址段
|
||||
if ip[0]&0xfe == 0xfc {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// fallbackToLocalhost 根据传入地址返回对应的本地回环地址
|
||||
func fallbackToLocalhost(listen string) string {
|
||||
ip := net.ParseIP(listen)
|
||||
if ip == nil {
|
||||
// 无法解析则默认回退 IPv4 回环
|
||||
return "127.0.0.1"
|
||||
}
|
||||
if ip.To4() != nil {
|
||||
// IPv4 回退 IPv4 回环
|
||||
return "127.0.0.1"
|
||||
}
|
||||
// IPv6 回退 IPv6 回环
|
||||
return "::1"
|
||||
}
|
||||
|
||||
func init() {
|
||||
for _, cidr := range []string{
|
||||
"10.0.0.0/8", // A类私网
|
||||
"172.16.0.0/12", // B类私网
|
||||
"192.168.0.0/16", // C类私网
|
||||
"100.64.0.0/10", // CGNAT地址段
|
||||
"127.0.0.0/8", // 回环
|
||||
} {
|
||||
_, netw, err := net.ParseCIDR(cidr)
|
||||
if err == nil {
|
||||
privateIPv4Nets = append(privateIPv4Nets, netw)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BIN
windows_files/Win64OpenSSL_Light-3_3_0.exe
Normal file
1
windows_files/xray_no_window.ps1
Normal file
@ -0,0 +1 @@
|
||||
Start-Process -FilePath ".\xray.exe" -ArgumentList "-config .\config.json" -WindowStyle Hidden
|
||||
1
windows_files/xray_no_window.vbs
Normal file
@ -0,0 +1 @@
|
||||
CreateObject("Wscript.Shell").Run "xray.exe -config config.json",0
|
||||