feat: автоматизация установки и настройки WireGuard сервера и клиента

This commit is contained in:
Ruslan
2026-04-14 00:04:06 +03:00
commit a31f1a1090
8 changed files with 1416 additions and 0 deletions

231
lib/common.sh Executable file
View File

@@ -0,0 +1,231 @@
#!/usr/bin/env bash
# Общие функции для скриптов проекта WireGuard.
if [[ -t 1 ]]; then
C_RESET='\033[0m'
C_RED='\033[0;31m'
C_GREEN='\033[0;32m'
C_YELLOW='\033[1;33m'
C_BLUE='\033[0;34m'
else
C_RESET=''
C_RED=''
C_GREEN=''
C_YELLOW=''
C_BLUE=''
fi
LOG_FILE="${LOG_FILE:-}"
timestamp() {
date '+%Y-%m-%d %H:%M:%S'
}
_write_log() {
local level="$1"
local msg="$2"
local line="[$(timestamp)] [$level] $msg"
if [[ -n "${LOG_FILE}" ]]; then
mkdir -p "$(dirname "$LOG_FILE")"
printf '%s\n' "$line" >> "$LOG_FILE"
fi
}
log_info() {
local msg="$*"
printf '%b[INFO]%b %s\n' "$C_BLUE" "$C_RESET" "$msg"
_write_log "INFO" "$msg"
}
log_warn() {
local msg="$*"
printf '%b[WARN]%b %s\n' "$C_YELLOW" "$C_RESET" "$msg"
_write_log "WARN" "$msg"
}
log_error() {
local msg="$*"
printf '%b[ERR ]%b %s\n' "$C_RED" "$C_RESET" "$msg" >&2
_write_log "ERROR" "$msg"
}
log_success() {
local msg="$*"
printf '%b[ OK ]%b %s\n' "$C_GREEN" "$C_RESET" "$msg"
_write_log "SUCCESS" "$msg"
}
die() {
log_error "$*"
exit 1
}
require_root() {
if [[ "${EUID}" -ne 0 ]]; then
die "Скрипт должен выполняться от root."
fi
}
require_cmd() {
local cmd="$1"
command -v "$cmd" >/dev/null 2>&1 || die "Не найдена команда: $cmd"
}
check_os_supported() {
if [[ ! -r /etc/os-release ]]; then
die "Не найден файл /etc/os-release, определить ОС не удалось."
fi
# shellcheck disable=SC1091
source /etc/os-release
local id="${ID:-}"
local like="${ID_LIKE:-}"
if [[ "$id" != "debian" && "$id" != "ubuntu" && "$like" != *"debian"* ]]; then
die "Поддерживаются только Debian/Ubuntu. Обнаружено: ${PRETTY_NAME:-unknown}"
fi
}
apt_install_if_missing() {
local pkgs=()
local pkg
for pkg in "$@"; do
if ! dpkg -s "$pkg" >/dev/null 2>&1; then
pkgs+=("$pkg")
fi
done
if ((${#pkgs[@]} == 0)); then
log_info "Все необходимые пакеты уже установлены."
return
fi
log_info "Устанавливаю пакеты: ${pkgs[*]}"
export DEBIAN_FRONTEND=noninteractive
apt-get update -y
apt-get install -y "${pkgs[@]}"
}
backup_file() {
local file="$1"
if [[ -f "$file" ]]; then
local backup="${file}.bak.$(date +%Y%m%d_%H%M%S)"
cp -a "$file" "$backup"
log_info "Создана резервная копия: $backup"
fi
}
ensure_line_in_file() {
local line="$1"
local file="$2"
touch "$file"
if ! grep -Fxq "$line" "$file"; then
printf '%s\n' "$line" >> "$file"
fi
}
set_kv_in_file() {
local key="$1"
local value="$2"
local file="$3"
touch "$file"
if grep -Eq "^${key}=" "$file"; then
sed -i "s|^${key}=.*|${key}=${value}|" "$file"
else
printf '%s=%s\n' "$key" "$value" >> "$file"
fi
}
is_valid_port() {
local p="$1"
[[ "$p" =~ ^[0-9]+$ ]] || return 1
((p >= 1 && p <= 65535))
}
is_valid_cidr_list() {
local input="$1"
local cidr
IFS=',' read -r -a _cidrs <<< "$input"
for cidr in "${_cidrs[@]}"; do
cidr="$(echo "$cidr" | xargs)"
[[ -n "$cidr" ]] || return 1
if ! [[ "$cidr" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}/([0-9]|[12][0-9]|3[0-2])$|^::/0$ ]]; then
return 1
fi
done
}
ask_with_default() {
local prompt="$1"
local default="$2"
local var_name="$3"
local answer
read -r -p "$prompt [$default]: " answer
answer="${answer:-$default}"
printf -v "$var_name" '%s' "$answer"
}
ask_secret() {
local prompt="$1"
local var_name="$2"
local answer
read -r -s -p "$prompt: " answer
echo
printf -v "$var_name" '%s' "$answer"
}
confirm() {
local prompt="$1"
local ans
read -r -p "$prompt [y/N]: " ans
[[ "$ans" =~ ^([yY][eE][sS]|[yY])$ ]]
}
detect_public_ip() {
local ip
for url in "https://api.ipify.org" "https://ifconfig.me/ip" "https://icanhazip.com"; do
if ip="$(curl -4fsS --max-time 5 "$url" 2>/dev/null | tr -d '[:space:]')"; then
if [[ "$ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
echo "$ip"
return 0
fi
fi
done
return 1
}
detect_default_iface() {
ip route show default 2>/dev/null | awk '{print $5; exit}'
}
detect_default_gateway() {
ip route show default 2>/dev/null | awk '{print $3; exit}'
}
safe_chmod_600() {
local file="$1"
[[ -f "$file" ]] || return 0
chmod 600 "$file"
}
safe_chmod_700() {
local dir="$1"
[[ -d "$dir" ]] || return 0
chmod 700 "$dir"
}
systemd_enable_now() {
local unit="$1"
systemctl daemon-reload
systemctl enable --now "$unit"
}
sanitize_name() {
local input="$1"
echo "$input" | tr '[:upper:]' '[:lower:]' | tr -cd 'a-z0-9_.-' | sed 's/^[-.]*//;s/[-.]*$//'
}
random_alnum() {
local len="${1:-20}"
tr -dc 'A-Za-z0-9' </dev/urandom | head -c "$len"
}