Add server setup scripts (manual + cloud-init)
Two deployment options for recreating the kirgysia server: - manual-setup/: bash script for manual server provisioning - cloud-init/: cloud-init config + data upload script for automated VPS setup Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
# Настройка нового сервера (копия kirgysia)
|
||||
|
||||
## Что внутри
|
||||
|
||||
```
|
||||
server-setup/
|
||||
├── setup.sh # Скрипт автоматической настройки
|
||||
├── README.md # Эта инструкция
|
||||
└── data/
|
||||
├── x-ui.db # База данных 3x-ui
|
||||
├── fullchain.pem # SSL-сертификат
|
||||
├── privkey.pem # SSL-ключ
|
||||
└── authorized_keys # SSH-ключ для доступа
|
||||
```
|
||||
|
||||
## Требования
|
||||
|
||||
- Ubuntu 22.04 LTS
|
||||
- Root-доступ
|
||||
|
||||
## Быстрый старт
|
||||
|
||||
### 1. Скопировать папку на новый сервер
|
||||
|
||||
```bash
|
||||
scp -r server-setup/ root@IP_НОВОГО_СЕРВЕРА:/root/
|
||||
```
|
||||
|
||||
### 2. Подключиться к серверу
|
||||
|
||||
```bash
|
||||
ssh root@IP_НОВОГО_СЕРВЕРА
|
||||
```
|
||||
|
||||
### 3. Запустить скрипт
|
||||
|
||||
```bash
|
||||
cd /root/server-setup
|
||||
sudo bash setup.sh
|
||||
```
|
||||
|
||||
Всё. Скрипт сам установит пакеты, создаст пользователя, настроит SSH, поднимет 3x-ui в Docker.
|
||||
|
||||
## Настройки (при необходимости)
|
||||
|
||||
В начале `setup.sh` есть переменные — обычно менять их не нужно:
|
||||
|
||||
| Переменная | По умолчанию | Описание |
|
||||
|-------------|----------------|----------|
|
||||
| `NEW_USER` | `eberkheev` | Имя пользователя |
|
||||
| `SSH_PORT` | `10001` | Порт SSH |
|
||||
| `TIMEZONE` | `UTC` | Часовой пояс |
|
||||
| `STATIC_IP` | *(пусто)* | IP сервера, например `5.144.180.119/24`. Оставить пустым если сеть настраивается автоматически (DHCP) — так на большинстве VPS |
|
||||
| `GATEWAY` | *(пусто)* | IP шлюза, например `5.144.180.1`. Нужен только если задан `STATIC_IP` |
|
||||
| `DNS` | `8.8.8.8,8.8.4.4` | DNS-серверы |
|
||||
|
||||
## Что настраивает скрипт
|
||||
|
||||
1. Обновление системы
|
||||
2. Установка пакетов: docker, git, htop, mc, nmap, fail2ban, certbot, curl, wget, unzip
|
||||
3. Создание пользователя с sudo (без пароля)
|
||||
4. SSH: порт 10001, вход только по ключу, root запрещён
|
||||
5. Сеть (только если задан STATIC_IP)
|
||||
6. 3x-ui в Docker (network_mode: host) с восстановлением базы и сертификатов
|
||||
7. Скрипт обновления `~/update.sh`
|
||||
|
||||
## После установки
|
||||
|
||||
Подключение:
|
||||
```bash
|
||||
ssh -p 10001 eberkheev@IP_НОВОГО_СЕРВЕРА
|
||||
```
|
||||
|
||||
Панель 3x-ui:
|
||||
```
|
||||
https://IP_НОВОГО_СЕРВЕРА:10002
|
||||
```
|
||||
(порт панели зависит от настроек в x-ui.db)
|
||||
|
||||
Проверка контейнера:
|
||||
```bash
|
||||
docker ps
|
||||
```
|
||||
|
||||
Обновление 3x-ui:
|
||||
```bash
|
||||
bash ~/update.sh
|
||||
```
|
||||
|
||||
## Обновление сертификатов
|
||||
|
||||
Если нужен новый сертификат — положите `fullchain.pem` и `privkey.pem` в `~/3x-ui/cert/` и перезапустите контейнер:
|
||||
```bash
|
||||
docker restart 3xui_app
|
||||
```
|
||||
Executable
+296
@@ -0,0 +1,296 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Server Setup Script — воссоздание конфигурации сервера kirgysia
|
||||
# OS: Ubuntu 22.04 LTS
|
||||
# Запуск: sudo bash setup.sh
|
||||
#
|
||||
# Перед запуском:
|
||||
# 1. Положите рядом файлы:
|
||||
# - ../data/x-ui.db (база 3x-ui — скопировать с оригинала)
|
||||
# - ../data/fullchain.pem (SSL-сертификат)
|
||||
# - ../data/privkey.pem (SSL-ключ)
|
||||
# - ../data/authorized_keys (SSH-ключи для доступа)
|
||||
# 2. Отредактируйте переменные ниже под новый сервер
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# ============================================================
|
||||
# НАСТРОЙКИ — отредактируйте под новый сервер
|
||||
# ============================================================
|
||||
NEW_USER="eberkheev"
|
||||
SSH_PORT="10001"
|
||||
TIMEZONE="UTC"
|
||||
# Сетевой интерфейс (узнать: ip link show)
|
||||
NET_IFACE="ens18"
|
||||
# Статический IP (оставьте пустым для DHCP)
|
||||
STATIC_IP="" # например: "5.144.180.119/24"
|
||||
GATEWAY="" # например: "5.144.180.1"
|
||||
DNS="8.8.8.8,8.8.4.4"
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
DATA_DIR="$SCRIPT_DIR/../data"
|
||||
|
||||
# ============================================================
|
||||
# Проверки
|
||||
# ============================================================
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "ERROR: Запустите с sudo: sudo bash $0"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d "$DATA_DIR" ]; then
|
||||
echo "ERROR: Директория $DATA_DIR не найдена."
|
||||
echo "Создайте её и положите туда: x-ui.db, fullchain.pem, privkey.pem, authorized_keys"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "=== [1/8] Обновление системы ==="
|
||||
apt update && apt upgrade -y
|
||||
|
||||
echo "=== [2/8] Установка пакетов ==="
|
||||
apt install -y \
|
||||
curl \
|
||||
wget \
|
||||
git \
|
||||
htop \
|
||||
mc \
|
||||
nmap \
|
||||
net-tools \
|
||||
unzip \
|
||||
fail2ban \
|
||||
certbot \
|
||||
docker.io \
|
||||
docker-compose \
|
||||
ufw
|
||||
|
||||
systemctl enable docker
|
||||
systemctl start docker
|
||||
|
||||
echo "=== [3/8] Настройка часового пояса ==="
|
||||
timedatectl set-timezone "$TIMEZONE"
|
||||
|
||||
echo "=== [4/8] Создание пользователя ==="
|
||||
if ! id "$NEW_USER" &>/dev/null; then
|
||||
adduser --disabled-password --gecos "" "$NEW_USER"
|
||||
usermod -aG sudo "$NEW_USER"
|
||||
# Разрешить sudo без пароля (опционально — удалите если не нужно)
|
||||
echo "$NEW_USER ALL=(ALL) NOPASSWD:ALL" > "/etc/sudoers.d/$NEW_USER"
|
||||
chmod 440 "/etc/sudoers.d/$NEW_USER"
|
||||
echo "Пользователь $NEW_USER создан"
|
||||
else
|
||||
echo "Пользователь $NEW_USER уже существует"
|
||||
fi
|
||||
|
||||
usermod -aG docker "$NEW_USER"
|
||||
|
||||
# SSH-ключи
|
||||
USER_HOME="/home/$NEW_USER"
|
||||
mkdir -p "$USER_HOME/.ssh"
|
||||
if [ -f "$DATA_DIR/authorized_keys" ]; then
|
||||
cp "$DATA_DIR/authorized_keys" "$USER_HOME/.ssh/authorized_keys"
|
||||
chmod 600 "$USER_HOME/.ssh/authorized_keys"
|
||||
fi
|
||||
chown -R "$NEW_USER:$NEW_USER" "$USER_HOME/.ssh"
|
||||
|
||||
echo "=== [5/8] Настройка SSH ==="
|
||||
cat > /etc/ssh/sshd_config <<SSHEOF
|
||||
Include /etc/ssh/sshd_config.d/*.conf
|
||||
|
||||
Port $SSH_PORT
|
||||
PermitRootLogin no
|
||||
PasswordAuthentication no
|
||||
PermitEmptyPasswords no
|
||||
KbdInteractiveAuthentication no
|
||||
UsePAM yes
|
||||
X11Forwarding yes
|
||||
PrintMotd no
|
||||
AcceptEnv LANG LC_*
|
||||
Subsystem sftp /usr/lib/openssh/sftp-server
|
||||
SSHEOF
|
||||
|
||||
systemctl restart ssh
|
||||
echo "SSH настроен на порт $SSH_PORT"
|
||||
|
||||
echo "=== [6/8] Настройка сети ==="
|
||||
if [ -n "$STATIC_IP" ]; then
|
||||
cat > /etc/netplan/01-netcfg.yaml <<NETEOF
|
||||
network:
|
||||
version: 2
|
||||
ethernets:
|
||||
$NET_IFACE:
|
||||
addresses:
|
||||
- $STATIC_IP
|
||||
gateway4: $GATEWAY
|
||||
nameservers:
|
||||
addresses:
|
||||
- ${DNS//,/$'\n - '}
|
||||
search: []
|
||||
NETEOF
|
||||
netplan apply
|
||||
echo "Статический IP настроен: $STATIC_IP"
|
||||
else
|
||||
echo "Сеть: используется DHCP (не настраивалась)"
|
||||
fi
|
||||
|
||||
echo "=== [7/8] Установка 3x-ui ==="
|
||||
XUI_DIR="$USER_HOME/3x-ui"
|
||||
|
||||
if [ ! -d "$XUI_DIR" ]; then
|
||||
sudo -u "$NEW_USER" git clone https://github.com/MHSanaei/3x-ui.git "$XUI_DIR"
|
||||
else
|
||||
echo "3x-ui уже склонирован"
|
||||
fi
|
||||
|
||||
# Создаём директории для данных
|
||||
mkdir -p "$XUI_DIR/db" "$XUI_DIR/cert" "$USER_HOME/cert"
|
||||
|
||||
# Копируем базу данных
|
||||
if [ -f "$DATA_DIR/x-ui.db" ]; then
|
||||
cp "$DATA_DIR/x-ui.db" "$XUI_DIR/db/x-ui.db"
|
||||
cp "$DATA_DIR/x-ui.db" "$USER_HOME/x-ui-backup.db"
|
||||
echo "База данных x-ui скопирована"
|
||||
else
|
||||
echo "WARNING: x-ui.db не найден в $DATA_DIR — пропущено"
|
||||
fi
|
||||
|
||||
# Копируем сертификаты
|
||||
if [ -f "$DATA_DIR/fullchain.pem" ] && [ -f "$DATA_DIR/privkey.pem" ]; then
|
||||
cp "$DATA_DIR/fullchain.pem" "$XUI_DIR/cert/"
|
||||
cp "$DATA_DIR/privkey.pem" "$XUI_DIR/cert/"
|
||||
cp "$DATA_DIR/fullchain.pem" "$USER_HOME/cert/"
|
||||
cp "$DATA_DIR/privkey.pem" "$USER_HOME/cert/"
|
||||
echo "Сертификаты скопированы"
|
||||
else
|
||||
echo "WARNING: Сертификаты не найдены в $DATA_DIR — пропущено"
|
||||
fi
|
||||
|
||||
# docker-compose.yml
|
||||
cat > "$XUI_DIR/docker-compose.yml" <<'DCEOF'
|
||||
services:
|
||||
3xui:
|
||||
image: ghcr.io/mhsanaei/3x-ui:latest
|
||||
container_name: 3xui_app
|
||||
volumes:
|
||||
- ./db/:/etc/x-ui/
|
||||
- ./cert/:/root/cert/
|
||||
environment:
|
||||
XRAY_VMESS_AEAD_FORCED: "false"
|
||||
XUI_ENABLE_FAIL2BAN: "true"
|
||||
tty: true
|
||||
network_mode: host
|
||||
restart: unless-stopped
|
||||
DCEOF
|
||||
|
||||
chown -R "$NEW_USER:$NEW_USER" "$XUI_DIR"
|
||||
|
||||
# Скрипт обновления
|
||||
cat > "$USER_HOME/update.sh" <<'UPDATEEOF'
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
BACKUP_PATH="/home/eberkheev/x-ui-backup.db"
|
||||
XUI_PATH="/home/eberkheev/3x-ui"
|
||||
DOCKER_IMAGE="ghcr.io/mhsanaei/3x-ui:latest"
|
||||
|
||||
BUILD_MODE="pull"
|
||||
if [ "$1" = "--build" ]; then
|
||||
BUILD_MODE="build"
|
||||
fi
|
||||
|
||||
echo "=== Mode: $BUILD_MODE ==="
|
||||
|
||||
echo "=== System update ==="
|
||||
sudo apt update && sudo apt upgrade -y
|
||||
|
||||
echo "=== Finding x-ui container ==="
|
||||
CONTAINER=$(sudo docker ps --format "{{.Names}}" | grep -i "xui\|x-ui\|3xui" | head -n 1)
|
||||
|
||||
if [ -z "$CONTAINER" ]; then
|
||||
echo "WARNING: x-ui container not found, skipping backup..."
|
||||
if [ ! -f "$BACKUP_PATH" ]; then
|
||||
echo "ERROR: No container and no backup found, aborting!"
|
||||
exit 1
|
||||
fi
|
||||
echo "Existing backup found at $BACKUP_PATH, continuing..."
|
||||
else
|
||||
echo "Found container: $CONTAINER"
|
||||
echo "=== Backup x-ui database ==="
|
||||
sudo docker cp $CONTAINER:/etc/x-ui/x-ui.db $BACKUP_PATH
|
||||
echo "Backup saved to $BACKUP_PATH"
|
||||
fi
|
||||
|
||||
echo "=== Pulling latest from main ==="
|
||||
cd $XUI_PATH
|
||||
sudo git checkout main
|
||||
sudo git pull origin main
|
||||
|
||||
echo "=== Stopping old container ==="
|
||||
sudo docker-compose down
|
||||
|
||||
if [ "$BUILD_MODE" = "build" ]; then
|
||||
echo "--- Building from source ---"
|
||||
sudo docker-compose build --no-cache
|
||||
sudo docker-compose up -d
|
||||
else
|
||||
echo "--- Pulling prebuilt image: $DOCKER_IMAGE ---"
|
||||
sudo docker pull $DOCKER_IMAGE
|
||||
sudo docker rm -f 3xui_app 2>/dev/null || true
|
||||
sudo docker run -d \
|
||||
--name 3xui_app \
|
||||
--restart unless-stopped \
|
||||
--network host \
|
||||
--env XRAY_VMESS_AEAD_FORCED=false \
|
||||
--env XUI_ENABLE_FAIL2BAN=true \
|
||||
-v $XUI_PATH/db/:/etc/x-ui/ \
|
||||
-v $XUI_PATH/cert/:/root/cert/ \
|
||||
-t \
|
||||
$DOCKER_IMAGE
|
||||
fi
|
||||
|
||||
echo "=== Restoring database from backup ==="
|
||||
NEW_CONTAINER=$(sudo docker ps --format "{{.Names}}" | grep -i "xui\|x-ui\|3xui" | head -n 1)
|
||||
if [ -z "$NEW_CONTAINER" ]; then
|
||||
echo "ERROR: Container not found after restart!"
|
||||
exit 1
|
||||
fi
|
||||
sudo docker cp $BACKUP_PATH $NEW_CONTAINER:/etc/x-ui/x-ui.db
|
||||
echo "Database restored, restarting container..."
|
||||
sudo docker restart $NEW_CONTAINER
|
||||
|
||||
echo "=== Status ==="
|
||||
sudo docker ps | grep -i "xui\|x-ui\|3xui"
|
||||
sudo docker logs $NEW_CONTAINER --tail=30
|
||||
|
||||
echo "=== Done! ==="
|
||||
UPDATEEOF
|
||||
|
||||
chown "$NEW_USER:$NEW_USER" "$USER_HOME/update.sh"
|
||||
|
||||
echo "=== [8/8] Запуск 3x-ui ==="
|
||||
cd "$XUI_DIR"
|
||||
docker pull ghcr.io/mhsanaei/3x-ui:latest
|
||||
docker run -d \
|
||||
--name 3xui_app \
|
||||
--restart unless-stopped \
|
||||
--network host \
|
||||
--env XRAY_VMESS_AEAD_FORCED=false \
|
||||
--env XUI_ENABLE_FAIL2BAN=true \
|
||||
-v "$XUI_DIR/db/:/etc/x-ui/" \
|
||||
-v "$XUI_DIR/cert/:/root/cert/" \
|
||||
-t \
|
||||
ghcr.io/mhsanaei/3x-ui:latest
|
||||
|
||||
echo ""
|
||||
echo "============================================"
|
||||
echo " Сервер настроен!"
|
||||
echo "============================================"
|
||||
echo ""
|
||||
echo " SSH: порт $SSH_PORT, пользователь $NEW_USER"
|
||||
echo " 3x-ui: запущен в Docker (network_mode: host)"
|
||||
echo " Панель: https://<IP>:10002 (или порт из x-ui.db)"
|
||||
echo ""
|
||||
echo " Для обновления: bash ~/update.sh"
|
||||
echo " Для проверки: docker ps"
|
||||
echo ""
|
||||
Reference in New Issue
Block a user