改为手动触发流水线

This commit is contained in:
admin8800
2026-05-10 15:28:59 +08:00
parent b21144ca46
commit 39d18aabd1
7 changed files with 1868 additions and 1888 deletions
+54 -32
View File
@@ -1,28 +1,36 @@
name: Docker Image CI
name: Docker 镜像 CI
on:
push:
tags:
- "*"
workflow_dispatch:
inputs:
tag:
description: "发布标签"
required: true
default: "v1.4.1"
type: string
jobs:
frontend-build:
runs-on: ubuntu-24.04
steps:
- name: Checkout repository
- name: 检出仓库
uses: actions/checkout@v6.0.2
with:
ref: ${{ inputs.tag }}
submodules: recursive
- name: Set up Node.js
- name: 设置 Node.js
uses: actions/setup-node@v6
with:
node-version: 25
- name: Install dependencies and build frontend
- name: 安装依赖并构建前端
run: |
cd frontend
npm install
npm run build
- name: Upload frontend build artifact
- name: 上传前端构建产物
uses: actions/upload-artifact@v7
with:
name: frontend-dist
@@ -41,18 +49,23 @@ jobs:
- { platform: linux/arm/v6 }
runs-on: ubuntu-24.04
steps:
- name: Checkout repository
- name: 检出仓库
uses: actions/checkout@v6.0.2
- name: Download frontend build artifact
with:
ref: ${{ inputs.tag }}
- name: 下载前端构建产物
uses: actions/download-artifact@v8
with:
name: frontend-dist
path: frontend_dist
- name: Prepare
- name: 准备
run: |
platform="${{ matrix.platform }}"
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
- name: Docker meta
- name: Docker 元数据
id: meta
uses: docker/metadata-action@v6
with:
@@ -60,32 +73,36 @@ jobs:
alireza7/s-ui
ghcr.io/alireza0/s-ui
tags: |
type=ref,event=branch
type=ref,event=tag
type=pep440,pattern={{version}}
- name: Set up QEMU
type=raw,value=${{ inputs.tag }}
- name: 设置 QEMU
uses: docker/setup-qemu-action@v4
- name: Set up Docker Buildx
- name: 设置 Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Cache Docker layers
- name: 缓存 Docker 层
uses: actions/cache@v5
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ matrix.platform }}-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-${{ matrix.platform }}-
- name: Login to Docker Hub
- name: 登录 Docker Hub
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_TOKEN }}
- name: Login to GHCR
- name: 登录 GHCR
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push by digest
- name: 按摘要构建并推送
id: build
uses: docker/build-push-action@v7
with:
@@ -99,12 +116,14 @@ jobs:
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache,mode=max
outputs: type=image,push-by-digest=true,name-canonical=true,push=true
- name: Export digest
- name: 导出摘要
run: |
mkdir -p ${{ runner.temp }}/digests
digest="${{ steps.build.outputs.digest }}"
echo "${digest#sha256:}" > "${{ runner.temp }}/digests/${digest#sha256:}"
- name: Upload digest
- name: 上传摘要
uses: actions/upload-artifact@v7
with:
name: digests-${{ env.PLATFORM_PAIR }}
@@ -116,26 +135,30 @@ jobs:
needs: build
runs-on: ubuntu-24.04
steps:
- name: Download digests
- name: 下载摘要
uses: actions/download-artifact@v8
with:
path: ${{ runner.temp }}/digests
pattern: digests-*
merge-multiple: true
- name: Login to Docker Hub
- name: 登录 Docker Hub
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_TOKEN }}
- name: Login to GHCR
- name: 登录 GHCR
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Docker Buildx
- name: 设置 Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Docker meta
- name: Docker 元数据
id: meta
uses: docker/metadata-action@v6
with:
@@ -143,10 +166,9 @@ jobs:
alireza7/s-ui
ghcr.io/alireza0/s-ui
tags: |
type=ref,event=branch
type=ref,event=tag
type=pep440,pattern={{version}}
- name: Create manifest list and push
type=raw,value=${{ inputs.tag }}
- name: 创建清单列表并推送
env:
DOCKER_METADATA_OUTPUT_JSON: ${{ steps.meta.outputs.json }}
working-directory: ${{ runner.temp }}/digests
+36 -45
View File
@@ -1,22 +1,13 @@
name: Release S-UI
name: 发布 S-UI
on:
workflow_dispatch:
release:
types: [published]
push:
branches:
- main
tags:
- "*"
paths:
- '.github/workflows/release.yml'
- 'frontend/**'
- '**.sh'
- '**.go'
- 'go.mod'
- 'go.sum'
- 's-ui.service'
inputs:
tag:
description: "发布标签"
required: true
default: "v1.4.1"
type: string
env:
NODE_VERSION: "25"
@@ -28,34 +19,35 @@ jobs:
build-frontend:
runs-on: ubuntu-latest
steps:
- name: Checkout repository (frontend only)
- name: 检出仓库(仅前端)
uses: actions/checkout@v6.0.2
with:
ref: ${{ inputs.tag }}
submodules: recursive
fetch-depth: 1
- name: Setup Node.js
- name: 设置 Node.js
uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
cache-dependency-path: frontend/package-lock.json
- name: Build frontend
- name: 构建前端
run: |
cd frontend
npm install
npm run build
cd ..
- name: Upload frontend dist
- name: 上传前端 dist
uses: actions/upload-artifact@v7
with:
name: frontend-dist
path: frontend/dist/
build-linux:
name: build-${{ matrix.platform }}
name: 构建-${{ matrix.platform }}
needs: build-frontend
strategy:
fail-fast: false
@@ -70,23 +62,25 @@ jobs:
- { platform: s390x, arch: s390x, bootlin: s390x-z13, naive: false }
runs-on: ubuntu-latest
steps:
- name: Checkout repository
- name: 检出仓库
uses: actions/checkout@v6.0.2
with:
ref: ${{ inputs.tag }}
- name: Download frontend dist
- name: 下载前端 dist
uses: actions/download-artifact@v8
with:
name: frontend-dist
path: web/html
- name: Setup Go
- name: 设置 Go
uses: actions/setup-go@v6
with:
cache: false
go-version-file: go.mod
# Naive platforms: use cronet toolchain only (no Bootlin).
- name: Clone cronet-go (cronet toolchain for naive)
# Naive 平台:仅使用 cronet 工具链(不使用 Bootlin)。
- name: 克隆 cronet-gonaive 使用的 cronet 工具链)
if: matrix.naive
run: |
set -e
@@ -96,7 +90,7 @@ jobs:
git -C ~/cronet-go checkout FETCH_HEAD
git -C ~/cronet-go submodule update --init --recursive --depth=1
- name: Regenerate Debian keyring (cronet sysroot)
- name: 重新生成 Debian keyringcronet sysroot
if: matrix.naive
run: |
set -e
@@ -104,7 +98,7 @@ jobs:
cd ~/cronet-go
GPG_TTY=/dev/null ./naiveproxy/src/build/linux/sysroot_scripts/generate_keyring.sh
- name: Cache Chromium toolchain
- name: 缓存 Chromium 工具链
if: matrix.naive
id: cache-chromium-toolchain
uses: actions/cache@v5
@@ -116,7 +110,7 @@ jobs:
~/cronet-go/naiveproxy/src/out/sysroot-build/
key: chromium-toolchain-${{ matrix.platform }}-musl-${{ env.CRONET_GO_VERSION }}
- name: Build cronet lib and set toolchain env (CC, CXX, CGO_LDFLAGS, PATH)
- name: 构建 cronet 库并设置工具链环境(CC、CXXCGO_LDFLAGSPATH
if: matrix.naive
run: |
set -e
@@ -128,24 +122,24 @@ jobs:
echo "$line" >> $GITHUB_ENV
done
- name: Set Go build env (all platforms)
- name: 设置 Go 构建环境(所有平台)
run: |
echo "CGO_ENABLED=1" >> $GITHUB_ENV
echo "GOOS=linux" >> $GITHUB_ENV
echo "GOARCH=${{ matrix.arch }}" >> $GITHUB_ENV
if [ -n "${{ matrix.goarm }}" ]; then echo "GOARM=${{ matrix.goarm }}" >> $GITHUB_ENV; fi
# Non-naive platforms only: Bootlin musl (armv5, s390x).
- name: Set up Bootlin musl (armv5, s390x)
# 仅非 naive 平台:Bootlin muslarmv5s390x)。
- name: 设置 Bootlin muslarmv5s390x
if: ${{ matrix.naive != true }}
run: |
set -e
BOOTLIN_ARCH="${{ matrix.bootlin }}"
echo "Resolving Bootlin musl toolchain for arch=$BOOTLIN_ARCH (platform=${{ matrix.platform }})"
echo "正在解析 arch=$BOOTLIN_ARCH 的 Bootlin musl 工具链(平台=${{ matrix.platform }}"
TARBALL_BASE="${{ env.BOOTLIN_BASE_URL }}/$BOOTLIN_ARCH/tarballs/"
TARBALL_URL=$(curl -fsSL "$TARBALL_BASE" | grep -oE "${BOOTLIN_ARCH}--musl--stable-[^\"]+\\.tar\\.xz" | sort -r | head -n1)
[ -z "$TARBALL_URL" ] && { echo "Failed to locate Bootlin musl toolchain for arch=$BOOTLIN_ARCH" >&2; exit 1; }
echo "Downloading: $TARBALL_URL"
[ -z "$TARBALL_URL" ] && { echo "未找到 arch=$BOOTLIN_ARCH 的 Bootlin musl 工具链" >&2; exit 1; }
echo "正在下载:$TARBALL_URL"
cd /tmp
curl -fL -sS -o "$(basename "$TARBALL_URL")" "$TARBALL_BASE/$TARBALL_URL"
tar -xf "$(basename "$TARBALL_URL")"
@@ -154,7 +148,7 @@ jobs:
BIN_DIR="$TOOLCHAIN_DIR/bin"
echo "PATH=$BIN_DIR:$PATH" >> $GITHUB_ENV
CC=$(find "$BIN_DIR" -maxdepth 1 \( -name '*-gcc.br_real' -o -name '*-gcc' \) -type f -executable 2>/dev/null | grep -v g++ | head -n1)
[ -z "$CC" ] && { echo "No gcc found in $BIN_DIR" >&2; exit 1; }
[ -z "$CC" ] && { echo "在 $BIN_DIR 中未找到 gcc" >&2; exit 1; }
echo "CC=$(realpath "$CC")" >> $GITHUB_ENV
SYSROOT=""
F=$(find "$TOOLCHAIN_DIR" -name "libc-header-start.h" 2>/dev/null | head -1)
@@ -164,38 +158,35 @@ jobs:
echo "CGO_LDFLAGS=--sysroot=$SYSROOT -static" >> $GITHUB_ENV
fi
- name: Build s-ui
- name: 构建 s-ui
run: |
set -e
BUILD_TAGS="with_quic,with_grpc,with_utls,with_acme,with_gvisor,badlinkname,tfogo_checklinkname0,with_tailscale"
[ "${{ matrix.naive }}" = "true" ] && BUILD_TAGS="${BUILD_TAGS},with_naive_outbound,with_musl"
go build -ldflags="-w -s -checklinkname=0 -linkmode external -extldflags '-static'" -tags "$BUILD_TAGS" -o sui main.go
file sui
ldd sui 2>/dev/null || echo "Static binary confirmed"
ldd sui 2>/dev/null || echo "已确认静态二进制文件"
mkdir s-ui
cp sui s-ui/
cp s-ui.service s-ui/
cp s-ui.sh s-ui/
- name: Package
- name: 打包
run: tar -zcvf s-ui-linux-${{ matrix.platform }}.tar.gz s-ui
- name: Upload artifact
- name: 上传构建产物
uses: actions/upload-artifact@v7
with:
name: s-ui-linux-${{ matrix.platform }}
path: ./s-ui-linux-${{ matrix.platform }}.tar.gz
retention-days: 30
- name: Upload to Release
- name: 上传到 Release
uses: svenstaro/upload-release-action@v2
if: |
(github.event_name == 'release' && github.event.action == 'published') ||
(github.event_name == 'push' && startsWith(github.ref, 'refs/tags/'))
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
tag: ${{ github.event_name == 'release' && github.event.release.tag_name || github.ref_name }}
tag: ${{ inputs.tag }}
file: s-ui-linux-${{ matrix.platform }}.tar.gz
asset_name: s-ui-linux-${{ matrix.platform }}.tar.gz
prerelease: true
+28 -36
View File
@@ -1,21 +1,13 @@
name: Build S-UI for Windows
name: 构建 Windows 版 S-UI
on:
workflow_dispatch:
release:
types: [published]
push:
branches:
- main
tags:
- "*"
paths:
- '.github/workflows/windows.yml'
- 'frontend/**'
- '**.go'
- 'go.mod'
- 'go.sum'
- 'windows/**'
inputs:
tag:
description: "发布标签"
required: true
default: "v1.4.1"
type: string
env:
NODE_VERSION: "25"
@@ -26,26 +18,27 @@ jobs:
build-frontend:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
- name: 检出仓库
uses: actions/checkout@v6.0.2
with:
ref: ${{ inputs.tag }}
submodules: recursive
fetch-depth: 1
- name: Setup Node.js
- name: 设置 Node.js
uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
registry-url: 'https://registry.npmjs.org'
- name: Build frontend
- name: 构建前端
run: |
cd frontend
npm install
npm run build
cd ..
- name: Upload frontend artifact
- name: 上传前端构建产物
uses: actions/upload-artifact@v7
with:
name: frontend-dist
@@ -54,7 +47,7 @@ jobs:
build-windows:
needs: build-frontend
name: build-windows-${{ matrix.arch }}
name: 构建-windows-${{ matrix.arch }}
strategy:
fail-fast: false
matrix:
@@ -63,42 +56,44 @@ jobs:
- { arch: arm64, runner: ubuntu-latest, cgo: "0" }
runs-on: ${{ matrix.runner }}
steps:
- name: Checkout repository
- name: 检出仓库
uses: actions/checkout@v6.0.2
with:
ref: ${{ inputs.tag }}
- name: Download frontend artifact
- name: 下载前端构建产物
uses: actions/download-artifact@v8
with:
name: frontend-dist
path: web/html
- name: Setup Go
- name: 设置 Go
uses: actions/setup-go@v6
with:
cache: false
go-version-file: go.mod
- name: Install zip for Windows
- name: Windows 安装 zip
if: matrix.arch == 'amd64'
shell: powershell
run: |
# Install Chocolatey if not available
# 如果 Chocolatey 不可用,则安装 Chocolatey
if (!(Get-Command choco -ErrorAction SilentlyContinue)) {
Set-ExecutionPolicy Bypass -Scope Process -Force
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
}
# Install zip
# 安装 zip
choco install zip -y
- name: Build s-ui
- name: 构建 s-ui
shell: bash
run: |
export CGO_ENABLED=${{ matrix.cgo }}
export GOOS=windows
export GOARCH=${{ matrix.arch }}
echo "Building for Windows ${{ matrix.arch }}"
echo "正在为 Windows ${{ matrix.arch }} 构建"
go version
go env GOOS GOARCH
@@ -109,31 +104,28 @@ jobs:
cp sui.exe s-ui-windows/
cp -r windows/* s-ui-windows/
- name: Download libcronet-go
- name: 下载 libcronet-go
shell: bash
run: |
curl -qsL -o s-ui-windows/libcronet.dll ${{ env.LIBCRONET_BASE_URL }}/libcronet-windows-${{ matrix.arch }}.dll
- name: Package
- name: 打包
shell: bash
run: |
zip -r "s-ui-windows-${{ matrix.arch }}.zip" s-ui-windows
- name: Upload files to Artifacts
- name: 上传文件到构建产物
uses: actions/upload-artifact@v7
with:
name: s-ui-windows-${{ matrix.arch }}
path: ./s-ui-windows-${{ matrix.arch }}.zip
retention-days: 30
- name: Upload to Release
- name: 上传到 Release
uses: svenstaro/upload-release-action@v2
if: |
(github.event_name == 'release' && github.event.action == 'published') ||
(github.event_name == 'push' && startsWith(github.ref, 'refs/tags/'))
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
tag: ${{ github.ref }}
tag: ${{ inputs.tag }}
file: s-ui-windows-${{ matrix.arch }}.zip
asset_name: s-ui-windows-${{ matrix.arch }}.zip
prerelease: true
+107 -127
View File
@@ -1,101 +1,85 @@
# S-UI
**An Advanced Web Panel • Built on SagerNet/Sing-Box**
**基于 SagerNet/Sing-Box 构建的高级 Web 面板**
![](https://img.shields.io/github/v/release/alireza0/s-ui.svg)
![S-UI Docker pull](https://img.shields.io/docker/pulls/alireza7/s-ui.svg)
[![Go Report Card](https://goreportcard.com/badge/github.com/admin8800/s-ui)](https://goreportcard.com/report/github.com/admin8800/s-ui)
[![Downloads](https://img.shields.io/github/downloads/alireza0/s-ui/total.svg)](https://img.shields.io/github/downloads/alireza0/s-ui/total.svg)
[![License](https://img.shields.io/badge/license-GPL%20V3-blue.svg?longCache=true)](https://www.gnu.org/licenses/gpl-3.0.en.html)
> **Disclaimer:** This project is only for personal learning and communication, please do not use it for illegal purposes, please do not use it in a production environment
> **免责声明:** 本项目仅供个人学习与交流使用,请勿用于非法用途,请勿在生产环境中使用。
**If you think this project is helpful to you, you may wish to give a**:star2:
**Want to contribute?** See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, coding conventions, testing, and the pull request process.
[!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/alireza7)
<a href="https://nowpayments.io/donation/alireza7" target="_blank" rel="noreferrer noopener">
<img src="https://nowpayments.io/images/embeds/donation-button-white.svg" alt="Crypto donation button by NOWPayments">
</a>
## Quick Overview
| Features | Enable? |
## 快速概览
| 功能 | 是否支持 |
| -------------------------------------- | :----------------: |
| Multi-Protocol | :heavy_check_mark: |
| Multi-Language | :heavy_check_mark: |
| Multi-Client/Inbound | :heavy_check_mark: |
| Advanced Traffic Routing Interface | :heavy_check_mark: |
| Client & Traffic & System Status | :heavy_check_mark: |
| Subscription Link (link/json/clash + info)| :heavy_check_mark: |
| Dark/Light Theme | :heavy_check_mark: |
| API Interface | :heavy_check_mark: |
| 多协议 | :heavy_check_mark: |
| 多语言 | :heavy_check_mark: |
| 多客户端/入站 | :heavy_check_mark: |
| 高级流量路由界面 | :heavy_check_mark: |
| 客户端、流量与系统状态 | :heavy_check_mark: |
| 订阅链接(link/json/clash + info | :heavy_check_mark: |
| 深色/浅色主题 | :heavy_check_mark: |
| API 接口 | :heavy_check_mark: |
## Supported Platforms
| Platform | Architecture | Status |
## 支持平台
| 平台 | 架构 | 状态 |
|----------|--------------|---------|
| Linux | amd64, arm64, armv7, armv6, armv5, 386, s390x | ✅ Supported |
| Windows | amd64, 386, arm64 | ✅ Supported |
| macOS | amd64, arm64 | 🚧 Experimental |
| Linux | amd64, arm64, armv7, armv6, armv5, 386, s390x | 支持 |
| Windows | amd64, 386, arm64 | 支持 |
| macOS | amd64, arm64 | 实验性支持 |
## Screenshots
## 截图
!["Main"](https://github.com/admin8800/s-ui-frontend/raw/main/media/main.png)
!["主界面"](https://github.com/admin8800/s-ui-frontend/raw/main/media/main.png)
[Other UI Screenshots](https://github.com/admin8800/s-ui-frontend/blob/main/screenshots.md)
## API 文档
## API Documentation
[API 文档 Wiki](https://github.com/admin8800/s-ui/wiki/API-Documentation)
[API-Documentation Wiki](https://github.com/admin8800/s-ui/wiki/API-Documentation)
## 默认安装信息
- 面板端口:2095
- 面板路径:/app/
- 订阅端口:2096
- 订阅路径:/sub/
- 用户名/密码:admin
## Default Installation Information
- Panel Port: 2095
- Panel Path: /app/
- Subscription Port: 2096
- Subscription Path: /sub/
- User/Password: admin
## Install & Upgrade to Latest Version
## 安装或升级到最新版本
### Linux/macOS
```sh
bash <(curl -Ls https://raw.githubusercontent.com/alireza0/s-ui/master/install.sh)
bash <(curl -Ls https://raw.githubusercontent.com/admin8800/s-ui/main/install.sh)
```
### Windows
1. Download the latest Windows release from [GitHub Releases](https://github.com/admin8800/s-ui/releases/latest)
2. Extract the ZIP file
3. Run `install-windows.bat` as Administrator
4. Follow the installation wizard
1. [GitHub Releases](https://github.com/admin8800/s-ui/releases/latest) 下载最新 Windows 版本。
2. 解压 ZIP 文件。
3. 以管理员身份运行 `install-windows.bat`
4. 按照安装向导操作。
## Install legacy Version
## 安装旧版本
**Step 1:** To install your desired legacy version, add the version to the end of the installation command. e.g., ver `1.0.0`:
**步骤 1** 如果要安装指定旧版本,请在安装命令末尾追加版本号。例如版本 `1.0.0`
```sh
VERSION=1.0.0 && bash <(curl -Ls https://raw.githubusercontent.com/alireza0/s-ui/$VERSION/install.sh) $VERSION
VERSION=1.0.0 && bash <(curl -Ls https://raw.githubusercontent.com/admin8800/s-ui/$VERSION/install.sh) $VERSION
```
## Manual installation
## 手动安装
### Linux/macOS
1. Get the latest version of S-UI based on your OS/Architecture from GitHub: [https://github.com/admin8800/s-ui/releases/latest](https://github.com/admin8800/s-ui/releases/latest)
2. **OPTIONAL** Get the latest version of `s-ui.sh` [https://raw.githubusercontent.com/alireza0/s-ui/master/s-ui.sh](https://raw.githubusercontent.com/alireza0/s-ui/master/s-ui.sh)
3. **OPTIONAL** Copy `s-ui.sh` to /usr/bin/ and run `chmod +x /usr/bin/s-ui`.
4. Extract s-ui tar.gz file to a directory of your choice and navigate to the directory where you extracted the tar.gz file.
5. Copy *.service files to /etc/systemd/system/ and run `systemctl daemon-reload`.
6. Enable autostart and start S-UI service using `systemctl enable s-ui --now`
7. Start sing-box service using `systemctl enable sing-box --now`
1. 根据你的系统和架构,从 GitHub 获取最新版本 S-UI[https://github.com/admin8800/s-ui/releases/latest](https://github.com/admin8800/s-ui/releases/latest)
2. **可选:** 获取最新版 `s-ui.sh`[https://raw.githubusercontent.com/admin8800/s-ui/main/s-ui.sh](https://raw.githubusercontent.com/admin8800/s-ui/main/s-ui.sh)
3. **可选:** `s-ui.sh` 复制到 `/usr/bin/`,并执行 `chmod +x /usr/bin/s-ui`
4. s-ui tar.gz 文件解压到你选择的目录,并进入解压后的目录。
5. `*.service` 文件复制到 `/etc/systemd/system/`,然后执行 `systemctl daemon-reload`
6. 使用 `systemctl enable s-ui --now` 启用开机自启并启动 S-UI 服务。
7. 使用 `systemctl enable sing-box --now` 启动 sing-box 服务。
### Windows
1. Get the latest Windows version from GitHub: [https://github.com/admin8800/s-ui/releases/latest](https://github.com/admin8800/s-ui/releases/latest)
2. Download the appropriate Windows package (e.g., `s-ui-windows-amd64.zip`)
3. Extract the ZIP file to a directory of your choice
4. Run `install-windows.bat` as Administrator
5. Follow the installation wizard
6. Access the panel at http://localhost:2095/app
1. 从 GitHub 获取最新 Windows 版本:[https://github.com/admin8800/s-ui/releases/latest](https://github.com/admin8800/s-ui/releases/latest)
2. 下载适合的 Windows 包,例如 `s-ui-windows-amd64.zip`
3. 将 ZIP 文件解压到你选择的目录。
4. 以管理员身份运行 `install-windows.bat`
5. 按照安装向导操作。
6. 访问面板:http://localhost:2095/app
## Uninstall S-UI
## 卸载 S-UI
```sh
sudo -i
@@ -109,30 +93,30 @@ rm -fr /usr/local/s-ui
rm /usr/bin/s-ui
```
## Install using Docker
## 使用 Docker 安装
<details>
<summary>Click for details</summary>
<summary>点击查看详情</summary>
### Usage
### 使用方式
**Step 1:** Install Docker
**步骤 1** 安装 Docker
```shell
curl -fsSL https://get.docker.com | sh
```
**Step 2:** Install S-UI
**步骤 2** 安装 S-UI
> Docker compose method
> Docker compose 方式
```shell
mkdir s-ui && cd s-ui
wget -q https://raw.githubusercontent.com/alireza0/s-ui/master/docker-compose.yml
wget -q https://raw.githubusercontent.com/admin8800/s-ui/main/docker-compose.yml
docker compose up -d
```
> Use docker
> 直接使用 docker
```shell
mkdir s-ui && cd s-ui
@@ -144,7 +128,7 @@ docker run -itd \
alireza7/s-ui:latest
```
> Build your own image
> 自行构建镜像
```shell
git clone https://github.com/admin8800/s-ui
@@ -154,94 +138,93 @@ docker build -t s-ui .
</details>
## Manual run ( contribution )
## 手动运行(贡献开发)
<details>
<summary>Click for details</summary>
<summary>点击查看详情</summary>
### Build and run whole project
### 构建并运行完整项目
```shell
./runSUI.sh
```
### Clone the repository
### 克隆仓库
```shell
# clone repository
# 克隆仓库
git clone https://github.com/admin8800/s-ui
# clone submodules
# 克隆子模块
git submodule update --init --recursive
```
### - 前端
### - Frontend
前端代码请查看 [s-ui-frontend](https://github.com/admin8800/s-ui-frontend)。
Visit [s-ui-frontend](https://github.com/admin8800/s-ui-frontend) for frontend code
### - 后端
> 请先至少构建一次前端。
### - Backend
> Please build frontend once before!
To build backend:
构建后端:
```shell
# remove old frontend compiled files
# 删除旧的前端编译文件
rm -fr web/html/*
# apply new frontend compiled files
# 应用新的前端编译文件
cp -R frontend/dist/ web/html/
# build
# 构建
go build -o sui main.go
```
To run backend (from root folder of repository):
运行后端(在仓库根目录执行):
```shell
./sui
```
</details>
## Languages
## 语言
- English
- Farsi
- Vietnamese
- Chinese (Simplified)
- Chinese (Traditional)
- Russian
- 英语
- 波斯语
- 越南语
- 简体中文
- 繁体中文
- 俄语
## Features
## 功能
- Supported protocols:
- General: Mixed, SOCKS, HTTP, HTTPS, Direct, Redirect, TProxy
- V2Ray based: VLESS, VMess, Trojan, Shadowsocks
- Other protocols: ShadowTLS, Hysteria, Hysteria2, Naive, TUIC
- Supports XTLS protocols
- An advanced interface for routing traffic, incorporating PROXY Protocol, External, and Transparent Proxy, SSL Certificate, and Port
- An advanced interface for inbound and outbound configuration
- Clients traffic cap and expiration date
- Displays online clients, inbounds and outbounds with traffic statistics, and system status monitoring
- Subscription service with ability to add external links and subscription
- HTTPS for secure access to the web panel and subscription service (self-provided domain + SSL certificate)
- Dark/Light theme
- 支持的协议:
- 通用协议:MixedSOCKSHTTPHTTPSDirectRedirectTProxy
- 基于 V2Ray 的协议:VLESSVMessTrojanShadowsocks
- 其他协议:ShadowTLSHysteriaHysteria2NaiveTUIC
- 支持 XTLS 协议。
- 提供高级流量路由界面,支持 PROXY ProtocolExternal、透明代理、SSL 证书和端口配置。
- 提供高级入站和出站配置界面。
- 支持客户端流量上限和到期时间。
- 显示在线客户端、入站、出站流量统计和系统状态监控。
- 订阅服务支持添加外部链接和订阅。
- Web 面板和订阅服务支持 HTTPS 安全访问(需自行提供域名和 SSL 证书)。
- 深色/浅色主题。
## Environment Variables
## 环境变量
<details>
<summary>Click for details</summary>
<summary>点击查看详情</summary>
### Usage
### 使用方式
| Variable | Type | Default |
| 变量 | 类型 | 默认值 |
| -------------- | :--------------------------------------------: | :------------ |
| SUI_LOG_LEVEL | `"debug"` \| `"info"` \| `"warn"` \| `"error"` | `"info"` |
| SUI_DEBUG | `boolean` | `false` |
| SUI_BIN_FOLDER | `string` | `"bin"` |
| SUI_DB_FOLDER | `string` | `"db"` |
| SINGBOX_API | `string` | - |
| SUI_LOG_LEVEL | `"debug"` \| `"info"` \| `"warn"` \| `"error"` | `"info"` |
| SUI_DEBUG | `boolean` | `false` |
| SUI_BIN_FOLDER | `string` | `"bin"` |
| SUI_DB_FOLDER | `string` | `"db"` |
| SINGBOX_API | `string` | - |
</details>
## SSL Certificate
## SSL 证书
<details>
<summary>Click for details</summary>
<summary>点击查看详情</summary>
### Certbot
@@ -250,10 +233,7 @@ snap install core; snap refresh core
snap install --classic certbot
ln -s /snap/bin/certbot /usr/bin/certbot
certbot certonly --standalone --register-unsafely-without-email --non-interactive --agree-tos -d <Your Domain Name>
certbot certonly --standalone --register-unsafely-without-email --non-interactive --agree-tos -d <你的域名>
```
</details>
## Stargazers over Time
[![Stargazers over time](https://starchart.cc/alireza0/s-ui.svg)](https://starchart.cc/alireza0/s-ui)
+1 -6
View File
@@ -1,7 +1,6 @@
---
services:
s-ui:
image: alireza7/s-ui
image: admin8800/s-ui
container_name: s-ui
hostname: "s-ui"
volumes:
@@ -16,7 +15,3 @@ services:
- s-ui
entrypoint: "./entrypoint.sh"
networks:
s-ui:
driver: bridge
+42 -42
View File
@@ -7,10 +7,10 @@ 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
# 检查 root 权限
[[ $EUID -ne 0 ]] && echo -e "${red}致命错误:${plain}请使用 root 权限运行此脚本 \n " && exit 1
# Check OS and set release variable
# 检查系统并设置 release 变量
if [[ -f /etc/os-release ]]; then
source /etc/os-release
release=$ID
@@ -18,10 +18,10 @@ 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 "检测系统失败,请联系作者!" >&2
exit 1
fi
echo "The OS release is: $release"
echo "当前系统发行版为:$release"
arch() {
case "$(uname -m)" in
@@ -32,11 +32,11 @@ arch() {
armv6* | armv6) echo 'armv6' ;;
armv5* | armv5) echo 'armv5' ;;
s390x) echo 's390x' ;;
*) echo -e "${green}Unsupported CPU architecture! ${plain}" && rm -f install.sh && exit 1 ;;
*) echo -e "${green}不支持的 CPU 架构!${plain}" && rm -f install.sh && exit 1 ;;
esac
}
echo "arch: $(arch)"
echo "架构:$(arch)"
install_base() {
case "${release}" in
@@ -59,25 +59,25 @@ install_base() {
}
config_after_install() {
echo -e "${yellow}Migration... ${plain}"
echo -e "${yellow}正在迁移... ${plain}"
/usr/local/s-ui/sui migrate
echo -e "${yellow}Install/update finished! For security it's recommended to modify panel settings ${plain}"
read -p "Do you want to continue with the modification [y/n]? ": config_confirm
echo -e "${yellow}安装/更新完成!出于安全考虑,建议修改面板设置 ${plain}"
read -p "是否继续修改设置 [y/n]": config_confirm
if [[ "${config_confirm}" == "y" || "${config_confirm}" == "Y" ]]; then
echo -e "Enter the ${yellow}panel port${plain} (leave blank for existing/default value):"
echo -e "请输入${yellow}面板端口${plain}(留空则使用现有/默认值):"
read config_port
echo -e "Enter the ${yellow}panel path${plain} (leave blank for existing/default value):"
echo -e "请输入${yellow}面板路径${plain}(留空则使用现有/默认值):"
read config_path
# Sub configuration
echo -e "Enter the ${yellow}subscription port${plain} (leave blank for existing/default value):"
# 订阅配置
echo -e "请输入${yellow}订阅端口${plain}(留空则使用现有/默认值):"
read config_subPort
echo -e "Enter the ${yellow}subscription path${plain} (leave blank for existing/default value):"
echo -e "请输入${yellow}订阅路径${plain}(留空则使用现有/默认值):"
read config_subPath
# Set configs
echo -e "${yellow}Initializing, please wait...${plain}"
# 设置配置
echo -e "${yellow}正在初始化,请稍候...${plain}"
params=""
[ -z "$config_port" ] || params="$params -port $config_port"
[ -z "$config_path" ] || params="$params -path $config_path"
@@ -85,47 +85,47 @@ config_after_install() {
[ -z "$config_subPath" ] || params="$params -subPath $config_subPath"
/usr/local/s-ui/sui setting ${params}
read -p "Do you want to change admin credentials [y/n]? ": admin_confirm
read -p "是否修改管理员账号密码 [y/n]": admin_confirm
if [[ "${admin_confirm}" == "y" || "${admin_confirm}" == "Y" ]]; then
# First admin credentials
read -p "Please set up your username:" config_account
read -p "Please set up your password:" config_password
# 首个管理员账号密码
read -p "请设置用户名:" config_account
read -p "请设置密码:" config_password
# Set credentials
echo -e "${yellow}Initializing, please wait...${plain}"
# 设置账号密码
echo -e "${yellow}正在初始化,请稍候...${plain}"
/usr/local/s-ui/sui admin -username ${config_account} -password ${config_password}
else
echo -e "${yellow}Your current admin credentials: ${plain}"
echo -e "${yellow}当前管理员账号密码:${plain}"
/usr/local/s-ui/sui admin -show
fi
else
echo -e "${red}cancel...${plain}"
echo -e "${red}已取消...${plain}"
if [[ ! -f "/usr/local/s-ui/db/s-ui.db" ]]; then
local usernameTemp=$(head -c 6 /dev/urandom | base64)
local passwordTemp=$(head -c 6 /dev/urandom | base64)
echo -e "this is a fresh installation,will generate random login info for security concerns:"
echo -e "这是全新安装,出于安全考虑将生成随机登录信息:"
echo -e "###############################################"
echo -e "${green}username:${usernameTemp}${plain}"
echo -e "${green}password:${passwordTemp}${plain}"
echo -e "${green}用户名:${usernameTemp}${plain}"
echo -e "${green}密码:${passwordTemp}${plain}"
echo -e "###############################################"
echo -e "${red}if you forgot your login info,you can type ${green}s-ui${red} for configuration menu${plain}"
echo -e "${red}如果忘记登录信息,可以输入 ${green}s-ui${red} 打开配置菜单${plain}"
/usr/local/s-ui/sui admin -username ${usernameTemp} -password ${passwordTemp}
else
echo -e "${red} this is your upgrade,will keep old settings,if you forgot your login info,you can type ${green}s-ui${red} for configuration menu${plain}"
echo -e "${red}这是升级安装,将保留旧设置;如果忘记登录信息,可以输入 ${green}s-ui${red} 打开配置菜单${plain}"
fi
fi
}
prepare_services() {
if [[ -f "/etc/systemd/system/sing-box.service" ]]; then
echo -e "${yellow}Stopping sing-box service... ${plain}"
echo -e "${yellow}正在停止 sing-box 服务... ${plain}"
systemctl stop sing-box
rm -f /usr/local/s-ui/bin/sing-box /usr/local/s-ui/bin/runSingbox.sh /usr/local/s-ui/bin/signal
fi
if [[ -e "/usr/local/s-ui/bin" ]]; then
echo -e "###############################################################"
echo -e "${green}/usr/local/s-ui/bin${red} directory exists yet!"
echo -e "Please check the content and delete it manually after migration ${plain}"
echo -e "${green}/usr/local/s-ui/bin${red} 目录已存在!"
echo -e "请检查其中内容,并在迁移后手动删除 ${plain}"
echo -e "###############################################################"
fi
systemctl daemon-reload
@@ -135,24 +135,24 @@ install_s-ui() {
cd /tmp/
if [ $# == 0 ]; then
last_version=$(curl -Ls "https://api.github.com/repos/alireza0/s-ui/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
last_version=$(curl -Ls "https://api.github.com/repos/admin8800/s-ui/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
if [[ ! -n "$last_version" ]]; then
echo -e "${red}Failed to fetch s-ui version, it maybe due to Github API restrictions, please try it later${plain}"
echo -e "${red}获取 s-ui 版本失败,可能是 Github API 限制导致,请稍后重试${plain}"
exit 1
fi
echo -e "Got s-ui latest version: ${last_version}, beginning the installation..."
echo -e "已获取 s-ui 最新版本:${last_version},开始安装..."
wget -N --no-check-certificate -O /tmp/s-ui-linux-$(arch).tar.gz https://github.com/admin8800/s-ui/releases/download/${last_version}/s-ui-linux-$(arch).tar.gz
if [[ $? -ne 0 ]]; then
echo -e "${red}Downloading s-ui failed, please be sure that your server can access Github ${plain}"
echo -e "${red}下载 s-ui 失败,请确认服务器可以访问 Github ${plain}"
exit 1
fi
else
last_version=$1
url="https://github.com/admin8800/s-ui/releases/download/${last_version}/s-ui-linux-$(arch).tar.gz"
echo -e "Beginning the install s-ui v$1"
echo -e "开始安装 s-ui v$1"
wget -N --no-check-certificate -O /tmp/s-ui-linux-$(arch).tar.gz ${url}
if [[ $? -ne 0 ]]; then
echo -e "${red}download s-ui v$1 failed,please check the version exists${plain}"
echo -e "${red}下载 s-ui v$1 失败,请检查该版本是否存在${plain}"
exit 1
fi
fi
@@ -175,14 +175,14 @@ install_s-ui() {
systemctl enable s-ui --now
echo -e "${green}s-ui v${last_version}${plain} installation finished, it is up and running now..."
echo -e "You may access the Panel with following URL(s):${green}"
echo -e "${green}s-ui v${last_version}${plain} 安装完成,现已启动并运行..."
echo -e "你可以通过以下 URL 访问面板:${green}"
/usr/local/s-ui/sui uri
echo -e "${plain}"
echo -e ""
s-ui help
}
echo -e "${green}Executing...${plain}"
echo -e "${green}正在执行...${plain}"
install_base
install_s-ui $1
+187 -187
View File
@@ -6,18 +6,18 @@ yellow='\033[0;33m'
plain='\033[0m'
function LOGD() {
echo -e "${yellow}[DEG] $* ${plain}"
echo -e "${yellow}[调试] $* ${plain}"
}
function LOGE() {
echo -e "${red}[ERR] $* ${plain}"
echo -e "${red}[错误] $* ${plain}"
}
function LOGI() {
echo -e "${green}[INF] $* ${plain}"
echo -e "${green}[信息] $* ${plain}"
}
[[ $EUID -ne 0 ]] && LOGE "ERROR: You must be root to run this script! \n" && exit 1
[[ $EUID -ne 0 ]] && LOGE "错误:必须使用 root 权限运行此脚本!\n" && exit 1
if [[ -f /etc/os-release ]]; then
source /etc/os-release
@@ -26,20 +26,20 @@ 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 "检测系统失败,请联系作者!" >&2
exit 1
fi
echo "The OS release is: $release"
echo "当前系统发行版为:$release"
confirm() {
if [[ $# > 1 ]]; then
echo && read -p "$1 [Default$2]: " temp
echo && read -p "$1 [默认$2]: " temp
if [[ x"${temp}" == x"" ]]; then
temp=$2
fi
else
read -p "$1 [y/n]: " temp
read -p "$1 [y/n] " temp
fi
if [[ x"${temp}" == x"y" || x"${temp}" == x"Y" ]]; then
return 0
@@ -49,7 +49,7 @@ confirm() {
}
confirm_restart() {
confirm "Restart the ${1} service" "y"
confirm "重启 ${1} 服务" "y"
if [[ $? == 0 ]]; then
restart
else
@@ -58,12 +58,12 @@ confirm_restart() {
}
before_show_menu() {
echo && echo -n -e "${yellow}Press enter to return to the main menu: ${plain}" && read temp
echo && echo -n -e "${yellow}按回车返回主菜单:${plain}" && read temp
show_menu
}
install() {
bash <(curl -Ls https://raw.githubusercontent.com/alireza0/s-ui/main/install.sh)
bash <(curl -Ls https://raw.githubusercontent.com/admin8800/s-ui/main/install.sh)
if [[ $? == 0 ]]; then
if [[ $# == 0 ]]; then
start
@@ -74,40 +74,40 @@ install() {
}
update() {
confirm "This function will forcefully reinstall the latest version, and the data will not be lost. Do you want to continue?" "n"
confirm "此功能将强制重装最新版本,数据不会丢失。是否继续?" "n"
if [[ $? != 0 ]]; then
LOGE "Cancelled"
LOGE "已取消"
if [[ $# == 0 ]]; then
before_show_menu
fi
return 0
fi
bash <(curl -Ls https://raw.githubusercontent.com/alireza0/s-ui/main/install.sh)
bash <(curl -Ls https://raw.githubusercontent.com/admin8800/s-ui/main/install.sh)
if [[ $? == 0 ]]; then
LOGI "Update is complete, Panel has automatically restarted "
LOGI "更新完成,面板已自动重启"
exit 0
fi
}
custom_version() {
echo "Enter the panel version (like 0.0.1):"
echo "请输入面板版本(例如 0.0.1):"
read panel_version
if [ -z "$panel_version" ]; then
echo "Panel version cannot be empty. Exiting."
echo "面板版本不能为空。正在退出。"
exit 1
fi
download_link="https://raw.githubusercontent.com/alireza0/s-ui/master/install.sh"
download_link="https://raw.githubusercontent.com/admin8800/s-ui/main/install.sh"
install_command="bash <(curl -Ls $download_link) $panel_version"
echo "Downloading and installing panel version $panel_version..."
echo "正在下载并安装面板版本 $panel_version..."
eval $install_command
}
uninstall() {
confirm "Are you sure you want to uninstall the panel?" "n"
confirm "确定要卸载面板吗?" "n"
if [[ $? != 0 ]]; then
if [[ $# == 0 ]]; then
show_menu
@@ -123,7 +123,7 @@ uninstall() {
rm /usr/local/s-ui/ -rf
echo ""
echo -e "Uninstalled Successfully, If you want to remove this script, then after exiting the script run ${green}rm /usr/local/s-ui -f${plain} to delete it."
echo -e "卸载成功。如果要删除此脚本,请在退出脚本后运行 ${green}rm /usr/local/s-ui -f${plain}"
echo ""
if [[ $# == 0 ]]; then
@@ -132,8 +132,8 @@ uninstall() {
}
reset_admin() {
echo "It is not recommended to set admin's credentials to default!"
confirm "Are you sure you want to reset admin's credentials to default ?" "n"
echo "不建议将管理员账号密码设置为默认值!"
confirm "确定要将管理员账号密码重置为默认值吗?" "n"
if [[ $? == 0 ]]; then
/usr/local/s-ui/sui admin -reset
fi
@@ -141,9 +141,9 @@ reset_admin() {
}
set_admin() {
echo "It is not recommended to set admin's credentials to a complex text."
read -p "Please set up your username:" config_account
read -p "Please set up your password:" config_password
echo "不建议将管理员账号密码设置为过于复杂的文本。"
read -p "请设置用户名:" config_account
read -p "请设置密码:" config_password
/usr/local/s-ui/sui admin -username ${config_account} -password ${config_password}
before_show_menu
}
@@ -154,7 +154,7 @@ view_admin() {
}
reset_setting() {
confirm "Are you sure you want to reset settings to default ?" "n"
confirm "确定要将设置重置为默认值吗?" "n"
if [[ $? == 0 ]]; then
/usr/local/s-ui/sui setting -reset
fi
@@ -162,17 +162,17 @@ reset_setting() {
}
set_setting() {
echo -e "Enter the ${yellow}panel port${plain} (leave blank for existing/default value):"
echo -e "请输入${yellow}面板端口${plain}(留空则使用现有/默认值):"
read config_port
echo -e "Enter the ${yellow}panel path${plain} (leave blank for existing/default value):"
echo -e "请输入${yellow}面板路径${plain}(留空则使用现有/默认值):"
read config_path
echo -e "Enter the ${yellow}subscription port${plain} (leave blank for existing/default value):"
echo -e "请输入${yellow}订阅端口${plain}(留空则使用现有/默认值):"
read config_subPort
echo -e "Enter the ${yellow}subscription path${plain} (leave blank for existing/default value):"
echo -e "请输入${yellow}订阅路径${plain}(留空则使用现有/默认值):"
read config_subPath
echo -e "${yellow}Initializing, please wait...${plain}"
echo -e "${yellow}正在初始化,请稍候...${plain}"
params=""
[ -z "$config_port" ] || params="$params -port $config_port"
[ -z "$config_path" ] || params="$params -path $config_path"
@@ -191,10 +191,10 @@ view_setting() {
view_uri() {
info=$(/usr/local/s-ui/sui uri)
if [[ $? != 0 ]]; then
LOGE "Get current uri error"
LOGE "获取当前 URI 失败"
before_show_menu
fi
LOGI "You may access the Panel with following URL(s):"
LOGI "你可以通过以下 URL 访问面板:"
echo -e "${green}${info}${plain}"
}
@@ -202,15 +202,15 @@ start() {
check_status $1
if [[ $? == 0 ]]; then
echo ""
LOGI -e "${1} is running, No need to start again, If you need to restart, please select restart"
LOGI -e "${1} 正在运行,无需再次启动;如果需要重启,请选择重启"
else
systemctl start $1
sleep 2
check_status $1
if [[ $? == 0 ]]; then
LOGI "${1} Started Successfully"
LOGI "${1} 启动成功"
else
LOGE "Failed to start ${1}, Probably because it takes longer than two seconds to start, Please check the log information later"
LOGE "启动 ${1} 失败,可能是启动时间超过两秒,请稍后查看日志信息"
fi
fi
@@ -223,15 +223,15 @@ stop() {
check_status $1
if [[ $? == 1 ]]; then
echo ""
LOGI "${1} stopped, No need to stop again!"
LOGI "${1} 已停止,无需再次停止!"
else
systemctl stop $1
sleep 2
check_status
if [[ $? == 1 ]]; then
LOGI "${1} stopped successfully"
LOGI "${1} 停止成功"
else
LOGE "Failed to stop ${1}, Probably because the stop time exceeds two seconds, Please check the log information later"
LOGE "停止 ${1} 失败,可能是停止时间超过两秒,请稍后查看日志信息"
fi
fi
@@ -245,9 +245,9 @@ restart() {
sleep 2
check_status $1
if [[ $? == 0 ]]; then
LOGI "${1} Restarted successfully"
LOGI "${1} 重启成功"
else
LOGE "Failed to restart ${1}, Probably because it takes longer than two seconds to start, Please check the log information later"
LOGE "重启 ${1} 失败,可能是启动时间超过两秒,请稍后查看日志信息"
fi
if [[ $# == 1 ]]; then
before_show_menu
@@ -264,9 +264,9 @@ status() {
enable() {
systemctl enable $1
if [[ $? == 0 ]]; then
LOGI "Set ${1} to boot automatically on startup successfully"
LOGI "已成功设置 ${1} 开机自启"
else
LOGE "Failed to set ${1} Autostart"
LOGE "设置 ${1} 开机自启失败"
fi
if [[ $# == 1 ]]; then
@@ -277,9 +277,9 @@ enable() {
disable() {
systemctl disable $1
if [[ $? == 0 ]]; then
LOGI "Autostart ${1} Cancelled successfully"
LOGI "已成功取消 ${1} 开机自启"
else
LOGE "Failed to cancel ${1} autostart"
LOGE "取消 ${1} 开机自启失败"
fi
if [[ $# == 1 ]]; then
@@ -298,11 +298,11 @@ update_shell() {
wget -O /usr/bin/s-ui -N --no-check-certificate https://github.com/admin8800/s-ui/raw/main/s-ui.sh
if [[ $? != 0 ]]; then
echo ""
LOGE "Failed to download script, Please check whether the machine can connect Github"
LOGE "下载脚本失败,请检查当前机器是否可以连接 Github"
before_show_menu
else
chmod +x /usr/bin/s-ui
LOGI "Upgrade script succeeded, Please rerun the script" && exit 0
LOGI "脚本升级成功,请重新运行脚本" && exit 0
fi
}
@@ -331,7 +331,7 @@ check_uninstall() {
check_status s-ui
if [[ $? != 2 ]]; then
echo ""
LOGE "Panel is already installed, Please do not reinstall"
LOGE "面板已安装,请勿重复安装"
if [[ $# == 0 ]]; then
before_show_menu
fi
@@ -345,7 +345,7 @@ check_install() {
check_status s-ui
if [[ $? == 2 ]]; then
echo ""
LOGE "Please install the panel first"
LOGE "请先安装面板"
if [[ $# == 0 ]]; then
before_show_menu
fi
@@ -359,15 +359,15 @@ show_status() {
check_status $1
case $? in
0)
echo -e "${1} state: ${green}Running${plain}"
echo -e "${1} 状态:${green}运行中${plain}"
show_enable_status $1
;;
1)
echo -e "${1} state: ${yellow}Not Running${plain}"
echo -e "${1} 状态:${yellow}未运行${plain}"
show_enable_status $1
;;
2)
echo -e "${1} state: ${red}Not Installed${plain}"
echo -e "${1} 状态:${red}未安装${plain}"
;;
esac
}
@@ -375,9 +375,9 @@ show_status() {
show_enable_status() {
check_enabled $1
if [[ $? == 0 ]]; then
echo -e "Start ${1} automatically: ${green}Yes${plain}"
echo -e "${1} 开机自启:${green}${plain}"
else
echo -e "Start ${1} automatically: ${red}No${plain}"
echo -e "${1} 开机自启:${red}${plain}"
fi
}
@@ -393,17 +393,17 @@ check_s-ui_status() {
show_s-ui_status() {
check_s-ui_status
if [[ $? == 0 ]]; then
echo -e "s-ui state: ${green}Running${plain}"
echo -e "s-ui 状态:${green}运行中${plain}"
else
echo -e "s-ui state: ${red}Not Running${plain}"
echo -e "s-ui 状态:${red}未运行${plain}"
fi
}
bbr_menu() {
echo -e "${green}\t1.${plain} Enable BBR"
echo -e "${green}\t2.${plain} Disable BBR"
echo -e "${green}\t0.${plain} Back to Main Menu"
read -p "Choose an option: " choice
echo -e "${green}\t1.${plain} 启用 BBR"
echo -e "${green}\t2.${plain} 禁用 BBR"
echo -e "${green}\t0.${plain} 返回主菜单"
read -p "请选择一个选项: " choice
case "$choice" in
0)
show_menu
@@ -414,28 +414,28 @@ bbr_menu() {
2)
disable_bbr
;;
*) echo "Invalid choice" ;;
*) echo "无效选择" ;;
esac
}
disable_bbr() {
if ! grep -q "net.core.default_qdisc=fq" /etc/sysctl.conf || ! grep -q "net.ipv4.tcp_congestion_control=bbr" /etc/sysctl.conf; then
echo -e "${yellow}BBR is not currently enabled.${plain}"
echo -e "${yellow}当前未启用 BBR。${plain}"
exit 0
fi
sed -i 's/net.core.default_qdisc=fq/net.core.default_qdisc=pfifo_fast/' /etc/sysctl.conf
sed -i 's/net.ipv4.tcp_congestion_control=bbr/net.ipv4.tcp_congestion_control=cubic/' /etc/sysctl.conf
sysctl -p
if [[ $(sysctl net.ipv4.tcp_congestion_control | awk '{print $3}') == "cubic" ]]; then
echo -e "${green}BBR has been replaced with CUBIC successfully.${plain}"
echo -e "${green}已成功将 BBR 替换为 CUBIC。${plain}"
else
echo -e "${red}Failed to replace BBR with CUBIC. Please check your system configuration.${plain}"
echo -e "${red} BBR 替换为 CUBIC 失败。请检查系统配置。${plain}"
fi
}
enable_bbr() {
if grep -q "net.core.default_qdisc=fq" /etc/sysctl.conf && grep -q "net.ipv4.tcp_congestion_control=bbr" /etc/sysctl.conf; then
echo -e "${green}BBR is already enabled!${plain}"
echo -e "${green}BBR 已启用!${plain}"
exit 0
fi
case "${release}" in
@@ -452,7 +452,7 @@ enable_bbr() {
pacman -Sy --noconfirm ca-certificates
;;
*)
echo -e "${red}Unsupported operating system. Please check the script and install the necessary packages manually.${plain}\n"
echo -e "${red}不支持的操作系统。请检查脚本并手动安装必要的软件包。${plain}\n"
exit 1
;;
esac
@@ -460,56 +460,56 @@ enable_bbr() {
echo "net.ipv4.tcp_congestion_control=bbr" | tee -a /etc/sysctl.conf
sysctl -p
if [[ $(sysctl net.ipv4.tcp_congestion_control | awk '{print $3}') == "bbr" ]]; then
echo -e "${green}BBR has been enabled successfully.${plain}"
echo -e "${green}BBR 启用成功。${plain}"
else
echo -e "${red}Failed to enable BBR. Please check your system configuration.${plain}"
echo -e "${red}启用 BBR 失败。请检查系统配置。${plain}"
fi
}
install_acme() {
cd ~
LOGI "install acme..."
LOGI "正在安装 acme..."
curl https://get.acme.sh | sh
if [ $? -ne 0 ]; then
LOGE "install acme failed"
LOGE "安装 acme 失败"
return 1
else
LOGI "install acme succeed"
LOGI "安装 acme 成功"
fi
return 0
}
ssl_cert_issue_main() {
echo -e "${green}\t1.${plain} Get SSL"
echo -e "${green}\t2.${plain} Revoke"
echo -e "${green}\t3.${plain} Force Renew"
echo -e "${green}\t4.${plain} Self-signed Certificate"
read -p "Choose an option: " choice
echo -e "${green}\t1.${plain} 获取 SSL"
echo -e "${green}\t2.${plain} 吊销证书"
echo -e "${green}\t3.${plain} 强制续签"
echo -e "${green}\t4.${plain} 自签名证书"
read -p "请选择一个选项: " choice
case "$choice" in
1) ssl_cert_issue ;;
2)
local domain=""
read -p "Please enter your domain name to revoke the certificate: " domain
read -p "请输入要吊销证书的域名: " domain
~/.acme.sh/acme.sh --revoke -d ${domain}
LOGI "Certificate revoked"
LOGI "证书已吊销"
;;
3)
local domain=""
read -p "Please enter your domain name to forcefully renew an SSL certificate: " domain
read -p "请输入要强制续签 SSL 证书的域名: " domain
~/.acme.sh/acme.sh --renew -d ${domain} --force ;;
4)
generate_self_signed_cert
;;
*) echo "Invalid choice" ;;
*) echo "无效选择" ;;
esac
}
ssl_cert_issue() {
if ! command -v ~/.acme.sh/acme.sh &>/dev/null; then
echo "acme.sh could not be found. we will install it"
echo "未找到 acme.sh,将进行安装"
install_acme
if [ $? -ne 0 ]; then
LOGE "install acme failed, please check logs"
LOGE "安装 acme 失败,请检查日志"
exit 1
fi
fi
@@ -527,29 +527,29 @@ ssl_cert_issue() {
pacman -Sy --noconfirm socat
;;
*)
echo -e "${red}Unsupported operating system. Please check the script and install the necessary packages manually.${plain}\n"
echo -e "${red}不支持的操作系统。请检查脚本并手动安装必要的软件包。${plain}\n"
exit 1
;;
esac
if [ $? -ne 0 ]; then
LOGE "install socat failed, please check logs"
LOGE "安装 socat 失败,请检查日志"
exit 1
else
LOGI "install socat succeed..."
LOGI "安装 socat 成功..."
fi
local domain=""
read -p "Please enter your domain name:" domain
LOGD "your domain is:${domain},check it..."
read -p "请输入你的域名:" domain
LOGD "你的域名是:${domain},正在检查..."
local currentCert=$(~/.acme.sh/acme.sh --list | tail -1 | awk '{print $1}')
if [ ${currentCert} == ${domain} ]; then
local certInfo=$(~/.acme.sh/acme.sh --list)
LOGE "system already has certs here,can not issue again,current certs details:"
LOGE "系统中已存在证书,不能重复签发,当前证书详情:"
LOGI "$certInfo"
exit 1
else
LOGI "your domain is ready for issuing cert now..."
LOGI "你的域名已准备好签发证书..."
fi
certPath="/root/cert/${domain}"
@@ -561,40 +561,40 @@ ssl_cert_issue() {
fi
local WebPort=80
read -p "please choose which port do you use,default will be 80 port:" WebPort
read -p "请选择使用的端口,默认使用 80 端口:" WebPort
if [[ ${WebPort} -gt 65535 || ${WebPort} -lt 1 ]]; then
LOGE "your input ${WebPort} is invalid,will use default port"
LOGE "输入的 ${WebPort} 无效,将使用默认端口"
fi
LOGI "will use port:${WebPort} to issue certs,please make sure this port is open..."
LOGI "将使用端口 ${WebPort} 签发证书,请确保该端口已开放..."
~/.acme.sh/acme.sh --set-default-ca --server letsencrypt
~/.acme.sh/acme.sh --issue -d ${domain} --standalone --httpport ${WebPort}
if [ $? -ne 0 ]; then
LOGE "issue certs failed,please check logs"
LOGE "签发证书失败,请检查日志"
rm -rf ~/.acme.sh/${domain}
exit 1
else
LOGE "issue certs succeed,installing certs..."
LOGE "证书签发成功,正在安装证书..."
fi
~/.acme.sh/acme.sh --installcert -d ${domain} \
--key-file /root/cert/${domain}/privkey.pem \
--fullchain-file /root/cert/${domain}/fullchain.pem
if [ $? -ne 0 ]; then
LOGE "install certs failed,exit"
LOGE "安装证书失败,退出"
rm -rf ~/.acme.sh/${domain}
exit 1
else
LOGI "install certs succeed,enable auto renew..."
LOGI "安装证书成功,正在启用自动续签..."
fi
~/.acme.sh/acme.sh --upgrade --auto-upgrade
if [ $? -ne 0 ]; then
LOGE "auto renew failed, certs details:"
LOGE "自动续签失败,证书详情:"
ls -lah cert/*
chmod 755 $certPath/*
exit 1
else
LOGI "auto renew succeed, certs details:"
LOGI "自动续签成功,证书详情:"
ls -lah cert/*
chmod 755 $certPath/*
fi
@@ -602,11 +602,11 @@ ssl_cert_issue() {
ssl_cert_issue_CF() {
echo -E ""
LOGD "******Instructions for use******"
echo "1) New certificate from Cloudflare"
echo "2) Force renew existing Certificates"
echo "3) Back to Menu"
read -p "Enter your choice [1-3]: " choice
LOGD "******使用说明******"
echo "1) Cloudflare 申请新证书"
echo "2) 强制续签已有证书"
echo "3) 返回菜单"
read -p "请输入你的选择 [1-3] " choice
certPath="/root/cert-CF"
@@ -615,24 +615,24 @@ ssl_cert_issue_CF() {
force_flag=""
if [ "$choice" -eq 2 ]; then
force_flag="--force"
echo "Forcing SSL certificate reissuance..."
echo "正在强制重新签发 SSL 证书..."
else
echo "Starting SSL certificate issuance..."
echo "开始签发 SSL 证书..."
fi
LOGD "******Instructions for use******"
LOGI "This Acme script requires the following data:"
LOGI "1.Cloudflare Registered e-mail"
LOGI "2.Cloudflare Global API Key"
LOGI "3.The domain name that has been resolved DNS to the current server by Cloudflare"
LOGI "4.The script applies for a certificate. The default installation path is /root/cert "
confirm "Confirmed?[y/n]" "y"
LOGD "******使用说明******"
LOGI " Acme 脚本需要以下数据:"
LOGI "1.Cloudflare 注册邮箱"
LOGI "2.Cloudflare 全局 API Key"
LOGI "3.已通过 Cloudflare 将 DNS 解析到当前服务器的域名"
LOGI "4.脚本将申请证书,默认安装路径为 /root/cert"
confirm "是否确认?[y/n]" "y"
if [ $? -eq 0 ]; then
if ! command -v ~/.acme.sh/acme.sh &>/dev/null; then
echo "acme.sh could not be found. Installing..."
echo "未找到 acme.sh。正在安装..."
install_acme
if [ $? -ne 0 ]; then
LOGE "Install acme failed, please check logs"
LOGE "安装 acme 失败,请检查日志"
exit 1
fi
fi
@@ -645,23 +645,23 @@ ssl_cert_issue_CF() {
mkdir -p $certPath
fi
LOGD "Please set a domain name:"
read -p "Input your domain here: " CF_Domain
LOGD "Your domain name is set to: ${CF_Domain}"
LOGD "请设置域名:"
read -p "请在此输入域名: " CF_Domain
LOGD "你的域名已设置为:${CF_Domain}"
CF_GlobalKey=""
CF_AccountEmail=""
LOGD "Please set the API key:"
read -p "Input your key here: " CF_GlobalKey
LOGD "Your API key is: ${CF_GlobalKey}"
LOGD "请设置 API key"
read -p "请在此输入 key " CF_GlobalKey
LOGD "你的 API key 为:${CF_GlobalKey}"
LOGD "Please set up registered email:"
read -p "Input your email here: " CF_AccountEmail
LOGD "Your registered email address is: ${CF_AccountEmail}"
LOGD "请设置注册邮箱:"
read -p "请在此输入邮箱: " CF_AccountEmail
LOGD "你的注册邮箱为:${CF_AccountEmail}"
~/.acme.sh/acme.sh --set-default-ca --server letsencrypt
if [ $? -ne 0 ]; then
LOGE "Default CA, Let's Encrypt failed, script exiting..."
LOGE "设置默认 CA Let's Encrypt 失败,脚本退出..."
exit 1
fi
@@ -670,15 +670,15 @@ ssl_cert_issue_CF() {
~/.acme.sh/acme.sh --issue --dns dns_cf -d ${CF_Domain} -d *.${CF_Domain} $force_flag --log
if [ $? -ne 0 ]; then
LOGE "Certificate issuance failed, script exiting..."
LOGE "证书签发失败,脚本退出..."
exit 1
else
LOGI "Certificate issued Successfully, Installing..."
LOGI "证书签发成功,正在安装..."
fi
mkdir -p ${certPath}/${CF_Domain}
if [ $? -ne 0 ]; then
LOGE "Failed to create directory: ${certPath}/${CF_Domain}"
LOGE "创建目录失败:${certPath}/${CF_Domain}"
exit 1
fi
@@ -687,18 +687,18 @@ ssl_cert_issue_CF() {
--key-file ${certPath}/${CF_Domain}/privkey.pem
if [ $? -ne 0 ]; then
LOGE "Certificate installation failed, script exiting..."
LOGE "证书安装失败,脚本退出..."
exit 1
else
LOGI "Certificate installed Successfully, Turning on automatic updates..."
LOGI "证书安装成功,正在开启自动更新..."
fi
~/.acme.sh/acme.sh --upgrade --auto-upgrade
if [ $? -ne 0 ]; then
LOGE "Auto update setup failed, script exiting..."
LOGE "自动更新设置失败,脚本退出..."
exit 1
else
LOGI "The certificate is installed and auto-renewal is turned on."
LOGI "证书已安装,并已开启自动续签。"
ls -lah ${certPath}/${CF_Domain}
chmod 755 ${certPath}/${CF_Domain}
fi
@@ -706,11 +706,11 @@ ssl_cert_issue_CF() {
show_menu
;;
3)
echo "Exiting..."
echo "正在退出..."
show_menu
;;
*)
echo "Invalid choice, please select again."
echo "无效选择,请重新选择。"
show_menu
;;
esac
@@ -719,13 +719,13 @@ ssl_cert_issue_CF() {
generate_self_signed_cert() {
cert_dir="/etc/sing-box"
mkdir -p "$cert_dir"
LOGI "Choose certificate type:"
echo -e "${green}\t1.${plain} Ed25519 (*recommended*)"
LOGI "请选择证书类型:"
echo -e "${green}\t1.${plain} Ed25519(推荐)"
echo -e "${green}\t2.${plain} RSA 2048"
echo -e "${green}\t3.${plain} RSA 4096"
echo -e "${green}\t4.${plain} ECDSA prime256v1"
echo -e "${green}\t5.${plain} ECDSA secp384r1"
read -p "Enter your choice [1-5, default 1]: " cert_type
read -p "请输入你的选择 [1-5,默认 1] " cert_type
cert_type=${cert_type:-1}
case "$cert_type" in
@@ -755,75 +755,75 @@ generate_self_signed_cert() {
;;
esac
LOGI "Generating self-signed certificate ($algo)..."
LOGI "正在生成自签名证书($algo..."
sudo openssl req -x509 -nodes -days 3650 $key_opt \
-keyout "${cert_dir}/self.key" \
-out "${cert_dir}/self.crt" \
-subj "/CN=myserver"
if [[ $? -eq 0 ]]; then
sudo chmod 600 "${cert_dir}/self."*
LOGI "Self-signed certificate generated successfully!"
LOGI "Certificate path: ${cert_dir}/self.crt"
LOGI "Key path: ${cert_dir}/self.key"
LOGI "自签名证书生成成功!"
LOGI "证书路径:${cert_dir}/self.crt"
LOGI "密钥路径:${cert_dir}/self.key"
else
LOGE "Failed to generate self-signed certificate."
LOGE "生成自签名证书失败。"
fi
before_show_menu
}
show_usage() {
echo -e "S-UI Control Menu Usage"
echo -e "S-UI 控制菜单用法"
echo -e "------------------------------------------"
echo -e "SUBCOMMANDS:"
echo -e "s-ui - Admin Management Script"
echo -e "s-ui start - Start s-ui"
echo -e "s-ui stop - Stop s-ui"
echo -e "s-ui restart - Restart s-ui"
echo -e "s-ui status - Current Status of s-ui"
echo -e "s-ui enable - Enable Autostart on OS Startup"
echo -e "s-ui disable - Disable Autostart on OS Startup"
echo -e "s-ui log - Check s-ui Logs"
echo -e "s-ui update - Update"
echo -e "s-ui install - Install"
echo -e "s-ui uninstall - Uninstall"
echo -e "s-ui help - Control Menu Usage"
echo -e "子命令:"
echo -e "s-ui - 管理员管理脚本"
echo -e "s-ui start - 启动 s-ui"
echo -e "s-ui stop - 停止 s-ui"
echo -e "s-ui restart - 重启 s-ui"
echo -e "s-ui status - 查看 s-ui 当前状态"
echo -e "s-ui enable - 启用开机自启"
echo -e "s-ui disable - 禁用开机自启"
echo -e "s-ui log - 查看 s-ui 日志"
echo -e "s-ui update - 更新"
echo -e "s-ui install - 安装"
echo -e "s-ui uninstall - 卸载"
echo -e "s-ui help - 控制菜单用法"
echo -e "------------------------------------------"
}
show_menu() {
echo -e "
${green}S-UI Admin Management Script ${plain}
————————————————————————————————
${green}0.${plain} Exit
————————————————————————————————
${green}1.${plain} Install
${green}2.${plain} Update
${green}3.${plain} Custom Version
${green}4.${plain} Uninstall
————————————————————————————————
${green}5.${plain} Reset admin credentials to default
${green}6.${plain} Set admin credentials
${green}7.${plain} View admin credentials
————————————————————————————————
${green}8.${plain} Reset Panel Settings
${green}9.${plain} Set Panel settings
${green}10.${plain} View Panel Settings
————————————————————————————————
${green}11.${plain} S-UI Start
${green}12.${plain} S-UI Stop
${green}13.${plain} S-UI Restart
${green}14.${plain} S-UI Check State
${green}15.${plain} S-UI Check Logs
${green}16.${plain} S-UI Enable Autostart
${green}17.${plain} S-UI Disable Autostart
————————————————————————————————
${green}18.${plain} Enable or Disable BBR
${green}19.${plain} SSL Certificate Management
${green}20.${plain} Cloudflare SSL Certificate
————————————————————————————————
${green}S-UI 管理脚本 ${plain}
---------------------------------------------------------------
${green}0.${plain} 退出
---------------------------------------------------------------
${green}1.${plain} 安装
${green}2.${plain} 更新
${green}3.${plain} 自定义版本
${green}4.${plain} 卸载
---------------------------------------------------------------
${green}5.${plain} 将管理员账号密码重置为默认值
${green}6.${plain} 设置管理员账号密码
${green}7.${plain} 查看管理员账号密码
---------------------------------------------------------------
${green}8.${plain} 重置面板设置
${green}9.${plain} 设置面板设置
${green}10.${plain} 查看面板设置
---------------------------------------------------------------
${green}11.${plain} 启动 S-UI
${green}12.${plain} 停止 S-UI
${green}13.${plain} 重启 S-UI
${green}14.${plain} 查看 S-UI 状态
${green}15.${plain} 查看 S-UI 日志
${green}16.${plain} 启用 S-UI 开机自启
${green}17.${plain} 禁用 S-UI 开机自启
---------------------------------------------------------------
${green}18.${plain} 启用或禁用 BBR
${green}19.${plain} SSL 证书管理
${green}20.${plain} Cloudflare SSL 证书
---------------------------------------------------------------
"
show_status s-ui
echo && read -p "Please enter your selection [0-20]: " num
echo && read -p "请输入你的选择 [0-20] " num
case "${num}" in
0)
@@ -890,7 +890,7 @@ show_menu() {
ssl_cert_issue_CF
;;
*)
LOGE "Please enter the correct number [0-20]"
LOGE "请输入正确的数字 [0-20]"
;;
esac
}