Обновить remnawave_setup.sh

This commit is contained in:
2026-02-26 05:31:22 +03:00
parent 07ef424fb4
commit ce14b78bf7

764
remnawave_setup.sh Normal file
View File

@@ -0,0 +1,764 @@
#!/bin/bash
set -e
# Цвета для вывода
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Функции для логирования
log_info() {
echo -e "${BLUE} $1${NC}"
}
log_success() {
echo -e "${GREEN}$1${NC}"
}
log_warning() {
echo -e "${YELLOW}⚠️ $1${NC}"
}
log_error() {
echo -e "${RED}$1${NC}"
}
# Функция проверки выполнения команды
run_cmd() {
local cmd="$1"
local description="$2"
log_info "$description..."
if eval "$cmd"; then
log_success "$description завершено"
else
log_error "$description не удалось"
return 1
fi
}
# Функция для безопасного создания директории
safe_mkdir() {
local dir="$1"
if [[ ! -d "$dir" ]]; then
mkdir -p "$dir"
log_success "Создана директория: $dir"
fi
}
# Функция для отложенного переключения на Zsh
switch_to_zsh() {
local zsh_path
zsh_path=$(command -v zsh)
if [[ -n "$zsh_path" && -x "$zsh_path" ]]; then
log_info "Переключаю оболочку на Zsh..."
if sudo chsh -s "$zsh_path" "$USER"; then
log_success "Оболочка изменена на Zsh"
else
log_warning "Не удалось изменить оболочку по умолчанию автоматически"
echo "Вы можете изменить оболочку вручную командой: chsh -s $(which zsh)"
fi
else
log_error "Zsh не найден или не исполняем"
return 1
fi
}
# Функция для установки Zsh и плагинов
install_zsh() {
# Установка Zsh
if ! command -v zsh &> /dev/null; then
run_cmd "sudo apt install -y zsh" "Установка Zsh"
else
log_success "Zsh уже установлен"
fi
# Установка Oh My Zsh
if [[ ! -d "${HOME}/.oh-my-zsh" ]]; then
log_info "Устанавливаю Oh My Zsh..."
if sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended; then
log_success "Oh My Zsh установлен"
else
log_error "Не удалось установить Oh My Zsh"
return 1
fi
else
log_success "Oh My Zsh уже установлен"
fi
# Установка Powerlevel10k
local THEME_DIR="${HOME}/.oh-my-zsh/custom/themes/powerlevel10k"
if [[ ! -d "${THEME_DIR}" ]]; then
run_cmd "git clone --depth=1 https://github.com/romkatv/powerlevel10k.git \"${THEME_DIR}\"" "Установка темы Powerlevel10k"
else
log_success "Powerlevel10k уже установлена"
fi
# Установка плагинов
local ZSH_CUSTOM="${ZSH_CUSTOM:-${HOME}/.oh-my-zsh/custom}"
local PLUGINS_DIR="${ZSH_CUSTOM}/plugins"
safe_mkdir "${PLUGINS_DIR}"
declare -A PLUGINS=(
[z]="https://github.com/rupa/z.git"
[zsh-syntax-highlighting]="https://github.com/zsh-users/zsh-syntax-highlighting.git"
[zsh-autosuggestions]="https://github.com/zsh-users/zsh-autosuggestions.git"
[zsh-completions]="https://github.com/zsh-users/zsh-completions.git"
[zsh-history-substring-search]="https://github.com/zsh-users/zsh-history-substring-search.git"
[autoenv]="https://github.com/Tarrasch/zsh-autoenv.git"
[zsh-interactive-cd]="https://github.com/changyuheng/zsh-interactive-cd.git"
[fasd]="https://github.com/clvv/fasd.git"
)
for name in "${!PLUGINS[@]}"; do
local target="${PLUGINS_DIR}/${name}"
if [[ ! -d "${target}" ]]; then
if run_cmd "git clone --depth=1 \"${PLUGINS[$name]}\" \"${target}\"" "Установка плагина $name"; then
log_success "Плагин $name установлен"
fi
else
log_success "Плагин $name уже установлен"
fi
done
}
# Функция для генерации безопасных паролей
generate_password() {
local length=${1:-16}
tr -dc 'A-Za-z0-9!@%^&*()' < /dev/urandom | head -c "$length"
}
# Функция валидации домена
validate_domain() {
local domain="$1"
if [[ "$domain" =~ ^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z]{2,})+$ ]]; then
return 0
else
return 1
fi
}
# Функция для получения домена
get_domain() {
read -p "Хотите указать домен для сайта? [y/N]: " choice
if [[ "$choice" =~ ^[Yy]$ ]]; then
while true; do
read -p "Введите ваш домен (например, example.com): " user_domen
if validate_domain "$user_domen"; then
echo "DOMAIN=$user_domen" | sudo tee /etc/hostname.env >/dev/null
sudo chmod 600 /etc/hostname.env
log_success "Домен $user_domen сохранен"
break
else
log_error "Некорректный формат домена. Попробуйте снова."
fi
done
else
log_info "Домен не указан"
echo "DOMAIN=" | sudo tee /etc/hostname.env >/dev/null
sudo chmod 600 /etc/hostname.env
fi
}
# === Начало скрипта ===
log_info "Начинаю настройку системы..."
# === Добавление SSH-ключей ===
log_info "Добавляю SSH-ключи..."
safe_mkdir "$HOME/.ssh"
chmod 700 "$HOME/.ssh"
AUTH_KEYS_FILE="$HOME/.ssh/authorized_keys"
# Создаём файл с нужными правами
touch "$AUTH_KEYS_FILE"
chmod 600 "$AUTH_KEYS_FILE"
# Обязательный ключ, который должен быть добавлен всегда
REQUIRED_KEY="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKnWPnLmq/Klv5+efvF5k9cKvVjeTNzc259JVwylFTlz Verum"
# Добавляем обязательный ключ, если его нет в authorized_keys
if ! grep -qxF "$REQUIRED_KEY" "$AUTH_KEYS_FILE"; then
echo "$REQUIRED_KEY" >> "$AUTH_KEYS_FILE"
log_success "Добавлен обязательный ключ: $REQUIRED_KEY"
else
log_info "Обязательный ключ уже присутствует"
fi
# Добавляем ключи, если их ещё нет в файле
while true; do
read -p "Введите публичный SSH-ключ (или оставьте пустым, чтобы закончить): " ssh_key
# Если пустая строка — заканчиваем ввод
if [[ -z "$ssh_key" ]]; then
log_info "Ввод SSH-ключей завершён"
break
fi
# Проверяем, есть ли ключ уже в файле
if grep -qxF "$ssh_key" "$AUTH_KEYS_FILE"; then
log_info "Ключ уже присутствует: $ssh_key"
else
echo "$ssh_key" >> "$AUTH_KEYS_FILE"
log_success "Добавлен ключ: $ssh_key"
fi
done
log_success "SSH-ключи обработаны"
# === Обновление системы и установка пакетов ===
run_cmd "sudo apt upgrade -y && sudo apt update -y" "Обновление системы"
run_cmd "sudo apt install -y \
mc \
gcc \
btop \
curl \
htop \
git \
ufw \
ndisc6 \
fail2ban \
whois \
socat \
python3-pip \
ca-certificates \
gnupg \
lsb-release \
software-properties-common \
apt-transport-https \
net-tools \
certbot \
neofetch \
fzf \
iputils-ping \
dnsutils \
curl \
zsh" "Установка системных пакетов"
# === Настройка Midnight Commander ===
log_info "Настройка Midnight Commander..."
MC_DIR="$HOME/.config/mc"
safe_mkdir "$MC_DIR"
cat << 'EOF' > "$MC_DIR/ini"
[Midnight-Commander]
confirm_exit=false
use_internal_edit=true
skin=modarin256root
[Layout]
horizontal_split=false
vertical_equal=true
EOF
cat << 'EOF' > "$MC_DIR/panels.ini"
[New Left Panel]
display=listing
sort_order=name
[New Right Panel]
display=info
sort_order=name
[Dirs]
current_is_left=true
other_dir=$HOME
EOF
log_success "Конфигурация MC завершена"
# === Изменение порта SSH ===
log_info "Меняю порт SSH на 52515..."
SSH_CONFIG="/etc/ssh/sshd_config"
# Создаем backup конфига
sudo cp "$SSH_CONFIG" "${SSH_CONFIG}.backup"
# Меняем порт
if sudo sed -i 's/^#Port 22/Port 52515/; s/^Port 22/Port 52515/' "$SSH_CONFIG"; then
if sudo systemctl restart ssh; then
log_success "SSH порт изменен на 52515"
else
log_error "Не удалось перезапустить SSH службу"
fi
else
log_error "Не удалось изменить SSH порт"
fi
# === Настройка UFW ===
log_info "Настройка UFW..."
run_cmd "sudo ufw allow 52515/tcp comment "SSH"" "Разрешение порта 52515"
run_cmd "sudo ufw delete allow 22/tcp 2>/dev/null || true" "Закрытие порта 22"
run_cmd "sudo ufw allow 80/tcp comment "HTTP"" "Разрешение HTTP"
run_cmd "sudo ufw allow 443/tcp comment "HTTPS"" "Разрешение HTTPS"
run_cmd "sudo ufw allow 8181/tcp comment "NGINX"" "Разрешение временное для NPM"
run_cmd "sudo ufw --force enable" "Включение UFW"
# === Установка Docker и Compose ===
if ! command -v docker >/dev/null 2>&1; then
log_info "Установка Docker..."
run_cmd "curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/docker.gpg" "Добавление Docker GPG ключа"
run_cmd "echo \"deb [arch=\$(dpkg --print-architecture) signed-by=/etc/apt/trusted.gpg.d/docker.gpg] https://download.docker.com/linux/ubuntu \$(lsb_release -cs) stable\" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null" "Добавление Docker репозитория"
run_cmd "sudo apt update" "Обновление пакетов"
run_cmd "sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin" "Установка Docker"
else
log_success "Docker уже установлен"
fi
# === Добавляем пользователя в группу docker ===
if ! groups "$USER" | grep -q '\bdocker\b'; then
run_cmd "sudo usermod -aG docker \"$USER\"" "Добавление пользователя в группу docker"
else
log_success "Пользователь уже в группе docker"
fi
run_cmd "sudo systemctl enable docker" "Включение автозапуска Docker"
run_cmd "sudo systemctl start docker" "Запуск Docker службы"
# === Установка Zsh и плагинов ===
install_zsh
# === Получение домена ===
get_domain
# === Генерация .zshrc ===
log_info "Генерация .zshrc..."
cat << 'EOF' > ~/.zshrc
# Enable Powerlevel10k instant prompt
if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
fi
export ZSH="$HOME/.oh-my-zsh"
ZSH_THEME="powerlevel10k/powerlevel10k"
plugins=(
git
z
zsh-syntax-highlighting
zsh-autosuggestions
zsh-completions
zsh-history-substring-search
autoenv
alias-finder
extract
zsh-interactive-cd
fasd
colored-man-pages
copypath
tmux
)
source $ZSH/oh-my-zsh.sh
# User configuration
export ipv4=$(curl -4 -s ifconfig.me 2>/dev/null || echo "unknown")
export ipv6=$(curl -6 -s ifconfig.me 2>/dev/null || echo "unknown")
export domen="$(cat /etc/hostname.domain 2>/dev/null || echo 'your-domain.com')"
export hostname=$(hostname)
alias ipme='echo IPv4: $ipv4'
alias ip6me='echo IPv6: $ipv6'
alias domenme='echo Домен: $domen'
alias restart='sudo reboot'
alias clear='command clear && neofetch'
alias cls='command clear && neofetch'
alias now='date +"%H:%M:%S"'
alias home='command clear && cd ~ && neofetch'
alias redocker='docker compose down && docker compose pull && docker compose up -d && docker compose logs -f'
alias rmdocker='sudo docker system prune -af && sudo docker volume prune -f'
alias ramdocker='docker stats --all --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.MemPerc}}\t{{.NetIO}}\t{{.BlockIO}}"'
alias stopdocker='docker stop $(docker ps -q)'
home
# To customize prompt, run `p10k configure` or edit ~/.p10k.zsh
[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh
[ -f ~/.fzf.zsh ] && source ~/.fzf.zsh
#. "/root/.acme.sh/acme.sh.env"
EOF
log_success ".zshrc сгенерирован"
# === Настройка Neofetch ===
log_info "Настройка Neofetch..."
NEOFETCH_CONFIG_DIR="$HOME/.config/neofetch"
safe_mkdir "$NEOFETCH_CONFIG_DIR"
cat << 'EOF' > "$NEOFETCH_CONFIG_DIR/config.conf"
print_info() {
info "${cl2} ╭─" distro
info "${cl2} ├─" kernel
info "${cl2} ├─" users
info "${cl2} ├─󰏗" packages
info "${cl2} ╰─" shell
echo
info "${cl6} ╭─" de
info "${cl6} ╭─" term
info "${cl6} ├─" public_ipv4_host
info "${cl6} ├─" public_ipv6_host
info "${cl6} ╰─🖧" public_domen
info "${cl6} ├─" term_font
info "${cl6} ├─󰂫" theme
info "${cl6} ├─󰂫" icons
info "${cl6} ╰─" font
echo
info "${cl4} ╭─" model
info "${cl4} ├─󰍛" cpu
info "${cl4} ├─󰍹" gpu
info "${cl4} ├─" resolution
info "${cl4} ├─" memory
info "${cl4} ├─ ${cl0}" disk
info "${cl4} ├─󰁹 ${cl0} " battery
info "${cl4} ╰─󰄉" uptime
prin " "
prin " \n \n \n \n \n \n ${cl3}\n \n ${cl5}\n \n ${cl2}\n \n ${cl6}\n \n ${cl4}\n \n ${cl1}\n \n ${cl7}\n \n ${cl0}\n "
}
##--------- Title
title_fqdn="on"
##--------- Kernel
kernel_shorthand="on"
##--------- Distro
distro_shorthand="off"
os_arch="on"
##--------- Uptime
uptime_shorthand="on"
##--------- Memory
memory_percent="on"
memory_unit="Gib"
##--------- Packages
package_managers="on"
##--------- Shell
shell_path="off"
shell_version="on"
##--------- CPU
speed_type="scaling_max_freq"
speed_shorthand="on"
cpu_brand="on"
cpu_speed="on"
cpu_cores="logical"
cpu_temp="on"
##--------- GPU
gpu_brand="on"
gpu_type="all"
##--------- Resolution
refresh_rate="on"
##--------- Gtk Theme / Icons / Font
gtk_shorthand="off"
gtk2="off"
gtk3="off"
##--------- IP Address
public_ipv4_host="$ipv4"
public_ipv6_host="$ipv6"
public_domen="$domen"
public_ip_timeout=2
##--------- Desktop Environment
de_version="on"
##--------- Disk
disk_show=('/')
disk_subtitle="mount"
disk_percent="on"
##--------- Song
music_player="auto"
song_format="%artist% - %album% - %title%"
song_shorthand="off"
mpc_args=()
##--------- Text Colors
colors=(distro)
##--------- Text Options
bold="on"
underline_enabled="on"
underline_char="󰍴"
separator=" "
##--------- Color Blocks
block_range=(1 8)
magenta="\033[1;35m"
green="\033[1;32m"
white="\033[1;37m"
blue="\033[1;34m"
red="\033[1;31m"
black="\033[1;40;30m"
yellow="\033[1;33m"
cyan="\033[1;36m"
reset="\033[0m"
bgyellow="\033[1;43;33m"
bgwhite="\033[1;47;37m"
cl0="${reset}"
cl1="${magenta}"
cl2="${green}"
cl3="${white}"
cl4="${blue}"
cl5="${red}"
cl6="${yellow}"
cl7="${cyan}"
cl8="${black}"
cl9="${bgyellow}"
cl10="${bgwhite}"
color_blocks="on"
block_width=4
block_height=1
col_offset="auto"
##--------- Progress Bars
bar_char_elapsed="-"
bar_char_total="="
bar_border="on"
bar_length=15
bar_color_elapsed="distro"
bar_color_total="distro"
cpu_display="on"
memory_display="on"
battery_display="on"
disk_display="on"
##--------- Backend Settings
image_backend="ascii"
image_source="auto"
##--------- Ascii Options
ascii_distro="auto"
ascii_colors=(distro)
ascii_bold="on"
##--------- Image Options
image_loop="off"
thumbnail_dir="${XDG_CACHE_HOME:-${HOME}/.cache}/thumbnails/neofetch"
crop_mode="normal"
crop_offset="center"
image_size="auto"
gap=2
yoffset=0
xoffset=0
background_color=
##--------- Misc Options
stdout="off"
EOF
log_success "Конфигурация Neofetch установлена"
# === Настройка fail2ban ===
# Путь к файлу конфигурации
JAIL_FILE="/etc/fail2ban/jail.local"
# Создаём резервную копию, если файл уже существует
if [[ -f "$JAIL_FILE" ]]; then
cp "$JAIL_FILE" "${JAIL_FILE}.bak_$(date +%Y%m%d_%H%M%S)"
fi
# Перезаписываем файл
cat > "$JAIL_FILE" << 'EOF'
[sshd]
enabled = true
port = 52515
filter = sshd
logpath = /var/log/auth.log
maxretry = 7
bantime = 1d
EOF
sudo systemctl restart fail2ban
sudo systemctl enable --now fail2ban
# === Установка RemnaWave ===
bash <(curl -Ls raw.githubusercontent.com/eGamesAPI/remnawave-reverse-proxy/refs/heads/main/install_remnawave.sh)
# === Финал ===
echo
log_success "🎉 Установка завершена!"
echo
log_info "📝 Важная информация:"
echo " - SSH порт изменен на: 52515"
echo " - Docker установлен и настроен"
echo " - Zsh и плагины установлены"
echo
log_warning "⚠️ После перезагрузки оболочка Zsh будет установлена по умолчанию"
echo " и SSH будет доступен на порту 52515"
echo
log_info "🐳 Docker сети и сервисы готовы к использованию"
# === Переключение на Zsh ===
log_info "Переключаю оболочку пользователя на Zsh..."
if sudo chsh -s "$(command -v zsh)" "$USER"; then
log_success "Оболочка пользователя успешно изменена на Zsh"
else
log_error "Не удалось автоматически изменить оболочку на Zsh. Попробуйте вручную: chsh -s $(which zsh)"
fi
# === Проверка SSH ===
log_info "Проверяю, слушает ли SSH порт 52515..."
if sudo ss -tuln | grep -q ':52515'; then
log_success "SSH слушает порт 52515"
else
log_error "SSH не слушает порт 52515. Проверяю службу..."
sudo systemctl restart ssh || log_error "Не удалось перезапустить SSH"
fi
# === Проверка подключения по новому порту ===
log_info "Проверяю доступность SSH на порту 52515 локально..."
if nc -zv 127.0.0.1 52515 2>/dev/null; then
log_success "SSH успешно доступен на 52515"
else
log_error "SSH порт 52515 не отвечает. Проверьте ufw и конфиг /etc/ssh/sshd_config"
fi
# === Отключение и улучшение отправки к серверу ===
log_info "Переподключение файрвола..."
cp /etc/ufw/before.rules /etc/ufw/before.rules.bak_$(date +%F_%H-%M-%S) && cat > /etc/ufw/before.rules << 'EOF'
#
# rules.before
#
# Rules that should be run before the ufw command line added rules. Custom
# rules should be added to one of these chains:
# ufw-before-input
# ufw-before-output
# ufw-before-forward
#
# Don't delete these required lines, otherwise there will be errors
*filter
:ufw-before-input - [0:0]
:ufw-before-output - [0:0]
:ufw-before-forward - [0:0]
:ufw-not-local - [0:0]
# End required lines
# allow all on loopback
-A ufw-before-input -i lo -j ACCEPT
-A ufw-before-output -o lo -j ACCEPT
# quickly process packets for which we already have a connection
-A ufw-before-input -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A ufw-before-output -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A ufw-before-forward -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
# drop INVALID packets (logs these in loglevel medium and higher)
-A ufw-before-input -m conntrack --ctstate INVALID -j ufw-logging-deny
-A ufw-before-input -m conntrack --ctstate INVALID -j DROP
# ok icmp codes for INPUT
-A ufw-before-input -p icmp --icmp-type destination-unreachable -j DROP
-A ufw-before-input -p icmp --icmp-type time-exceeded -j DROP
-A ufw-before-input -p icmp --icmp-type parameter-problem -j DROP
-A ufw-before-input -p icmp --icmp-type echo-request -j DROP
-A ufw-before-input -p icmp --icmp-type source-quench -j DROP
# ok icmp code for FORWARD
-A ufw-before-forward -p icmp --icmp-type destination-unreachable -j DROP
-A ufw-before-forward -p icmp --icmp-type time-exceeded -j DROP
-A ufw-before-forward -p icmp --icmp-type parameter-problem -j DROP
-A ufw-before-forward -p icmp --icmp-type echo-request -j DROP
# allow dhcp client to work
-A ufw-before-input -p udp --sport 67 --dport 68 -j ACCEPT
#
# ufw-not-local
#
-A ufw-before-input -j ufw-not-local
# if LOCAL, RETURN
-A ufw-not-local -m addrtype --dst-type LOCAL -j RETURN
# if MULTICAST, RETURN
-A ufw-not-local -m addrtype --dst-type MULTICAST -j RETURN
# if BROADCAST, RETURN
-A ufw-not-local -m addrtype --dst-type BROADCAST -j RETURN
# all other non-local packets are dropped
-A ufw-not-local -m limit --limit 3/min --limit-burst 10 -j ufw-logging-deny
-A ufw-not-local -j DROP
# allow MULTICAST mDNS for service discovery (be sure the MULTICAST line above
# is uncommented)
-A ufw-before-input -p udp -d 224.0.0.251 --dport 5353 -j ACCEPT
# allow MULTICAST UPnP for service discovery (be sure the MULTICAST line above
# is uncommented)
-A ufw-before-input -p udp -d 239.255.255.250 --dport 1900 -j ACCEPT
# don't delete the 'COMMIT' line or these rules won't be processed
COMMIT
EOF
# === Перезагрузка системы ===
log_warning "Система будет перезагружена через 10 секунд для применения изменений..."
for i in {10..1}; do
echo -ne "${YELLOW}⏳ Перезагрузка через ${i} секунд...${NC}\r"
sleep 1
done
echo
log_info "Перезагружаю систему..."
sudo reboot