diff --git a/README.MD b/README.MD index 2c6f13a..9ce5114 100644 --- a/README.MD +++ b/README.MD @@ -1 +1,50 @@ -стартовые скрипты для настройки серверов \ No newline at end of file +# Стартовые скрипты для настройки серверов + +Этот репозиторий содержит скрипт `core.sh` для базовой подготовки Ubuntu/Debian сервера. Скрипт автоматизирует установку полезных пакетов, создание пользователя, настройку сетевой безопасности и журналирования. + +## Возможности `core.sh` +- обновление пакетов и установка базового софта; +- создание нового пользователя с `sudo` без пароля; +- настройка SSH‑доступа только по указанному ключу; +- настройка межсетевого экрана UFW; +- установка Docker и разрешение работы без `root`; +- установка и настройка Fail2Ban для защиты SSH; +- включение автоматических обновлений `unattended-upgrades`; +- установка часового пояса Europe/Moscow; +- ротация логов и их отправка через Vector, включая логи Docker; +- установка и запуск Netbird по ключу с добавлением правила UFW для центрального сервера. +- проверки запуска UFW, Docker, Vector, Netbird и конфигурации SSH. + +## Требования +- Скрипт должен запускаться от `root`. +- Требуется подключение к интернету для установки пакетов. + +## Использование + +Запуск осуществляется одной командой: + +```bash +curl -fsSL https://raw.githubusercontent.com/deadcxap/init_scripts/main/core.sh | \ + sudo bash -s -- --user --sshkey "" \ + [--ssh-ip ] [--monitor-ip ] \ + [--vector ] \ + [--compose-url --compose-dir ] \ + [--netbird-key [--netbird-ip --netbird-port ]] +``` + +Параметры: +- `-u, --user` — имя создаваемого пользователя; +- `-k, --sshkey` — строка публичного SSH‑ключа (например `"ssh-rsa AAAA..."`); +- `-s, --ssh-ip` — IP‑адрес, с которого разрешён SSH‑доступ (если не указан — порт открыт всем); +- `-m, --monitor-ip` — IP‑адрес сервера мониторинга для порта 45876/tcp (если не указан — порт не открывается); +- `-v, --vector` — URL приёмника логов Vector (если не указан — Vector не устанавливается); +- `-c, --compose-url` — ссылка на `docker-compose.yml` (например с GitHub); +- `-d, --compose-dir` — каталог, куда сохранить и запустить композ (указывается вместе с `--compose-url`). +- `-n, --netbird-key` — ключ настройки Netbird; +- `-i, --netbird-ip` — IP центрального сервера Netbird (если указан вместе с портом, добавляется правило UFW); +- `-p, --netbird-port` — порт центрального сервера Netbird (используется вместе с IP). + +Логи выполнения сохраняются в `/var/log/core_setup.log`, по завершении выводится краткая сводка по каждому шагу. + +## Примечание +Перед запуском рекомендуется ознакомиться с содержимым скрипта и адаптировать его под свои требования. diff --git a/core.sh b/core.sh old mode 100644 new mode 100755 index e69de29..f070593 --- a/core.sh +++ b/core.sh @@ -0,0 +1,256 @@ +#!/usr/bin/env bash +set -euo pipefail + +LOG_FILE=/var/log/core_setup.log +exec > >(tee -a "$LOG_FILE") 2>&1 + +log() { + echo "[$(date +'%Y-%m-%d %H:%M:%S')] $*" +} + +SUMMARY=() + +run() { + local desc="$1" + shift + log "$desc" + if "$@"; then + log "OK: $desc" + SUMMARY+=("$desc: OK") + else + local rc=$? + log "ERROR: $desc (code $rc)" + SUMMARY+=("$desc: ERROR") + exit $rc + fi +} + +print_summary() { + echo "\n==== Итоговая сводка ====" + for item in "${SUMMARY[@]}"; do + echo "$item" + done +} + +cleanup() { + local rc=$? + if [[ $rc -ne 0 ]]; then + log "Скрипт завершился с ошибкой (код $rc)" + else + log "Скрипт завершился успешно" + fi + print_summary +} + +trap 'log "Ошибка (код $?) на строке $LINENO"' ERR +trap cleanup EXIT + +usage() { + cat <&2 + exit 1 +fi + +install_packages() { + run "Updating package index" apt-get update -y + run "Installing base packages" apt-get install -y sudo curl wget git ufw logrotate unattended-upgrades ca-certificates gnupg lsb-release apt-transport-https +} + +setup_timezone() { + run "Setting timezone to Europe/Moscow" timedatectl set-timezone Europe/Moscow +} + +setup_unattended_upgrades() { + run "Configuring unattended upgrades" bash -c "cat >/etc/apt/apt.conf.d/20auto-upgrades <<'EOF' +APT::Periodic::Update-Package-Lists \"1\"; +APT::Periodic::Download-Upgradeable-Packages \"1\"; +APT::Periodic::AutocleanInterval \"7\"; +APT::Periodic::Unattended-Upgrade \"1\"; +EOF" + run "Enabling unattended upgrades" systemctl enable --now unattended-upgrades.service +} + +create_user() { + run "Creating user $USERNAME" bash -c "id '$USERNAME' >/dev/null 2>&1 || adduser --disabled-password --gecos '' '$USERNAME'" + run "Granting sudo privileges to $USERNAME" bash -c "usermod -aG sudo '$USERNAME' && printf '%s ALL=(ALL) NOPASSWD:ALL\\n' '$USERNAME' >/etc/sudoers.d/90-$USERNAME" +} + +configure_ssh() { + run "Configuring SSH access" bash -c "install -d -m 700 /home/$USERNAME/.ssh && cat >/home/$USERNAME/.ssh/authorized_keys <<'KEY' +$SSH_KEY +KEY +chmod 600 /home/$USERNAME/.ssh/authorized_keys && chown -R '$USERNAME':'$USERNAME' /home/$USERNAME/.ssh && sed -i 's/^#\\?PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config && sed -i 's/^#\\?PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config && systemctl restart sshd" + run "Checking SSH configuration" bash -c "sshd -T | grep -q '^passwordauthentication no' && sshd -T | grep -q '^permitrootlogin no'" +} + +configure_ufw() { + run "Resetting UFW" ufw --force reset + run "Setting UFW defaults" bash -c "ufw default deny incoming && ufw default allow outgoing" + run "Allow HTTPS" ufw allow 443/tcp comment 'HTTPS' + if [[ -n "$SSH_ALLOWED_IP" ]]; then + run "Allow SSH from $SSH_ALLOWED_IP" ufw allow from "$SSH_ALLOWED_IP" to any port 22 proto tcp comment 'SSH' + else + run "Allow SSH from anywhere" ufw allow 22/tcp comment 'SSH' + fi + if [[ -n "$MONITOR_IP" ]]; then + run "Allow Beszel from $MONITOR_IP" ufw allow from "$MONITOR_IP" to any port 45876 proto tcp comment 'Beszel monitoring' + fi + if [[ -n "$NETBIRD_KEY" && -n "$NETBIRD_IP" && -n "$NETBIRD_PORT" ]]; then + run "Allow Netbird central from $NETBIRD_IP:$NETBIRD_PORT" ufw allow from "$NETBIRD_IP" to any port "$NETBIRD_PORT" proto tcp comment 'Netbird central' + fi + run "Enable UFW" ufw --force enable + run "Checking UFW active" bash -c "ufw status | grep -q 'Status: active'" + run "Checking UFW SSH rule" bash -c "ufw status | grep -q '22/tcp'" + run "Checking UFW HTTPS rule" bash -c "ufw status | grep -q '443/tcp'" + if [[ -n "$MONITOR_IP" ]]; then + run "Checking UFW Beszel rule" bash -c "ufw status | grep -q '45876/tcp'" + fi + if [[ -n "$NETBIRD_KEY" && -n "$NETBIRD_IP" && -n "$NETBIRD_PORT" ]]; then + run "Checking UFW Netbird rule" bash -c "ufw status | grep -q '$NETBIRD_PORT/tcp'" + fi +} + +install_docker() { + if ! command -v docker >/dev/null 2>&1; then + run "Installing Docker" bash -c "install -m 0755 -d /etc/apt/keyrings && curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg && echo 'deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable' | tee /etc/apt/sources.list.d/docker.list >/dev/null && apt-get update -y && apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin" + fi + run "Adding $USERNAME to docker group" usermod -aG docker "$USERNAME" + run "Checking Docker service" systemctl is-active --quiet docker + run "Checking Docker CLI" docker --version + run "Checking docker compose" docker compose version + run "Checking docker ps" docker ps >/dev/null +} + +configure_fail2ban() { + run "Installing fail2ban" apt-get install -y fail2ban + run "Configuring fail2ban" bash -c "cat >/etc/fail2ban/jail.local <<'EOF' +[sshd] +enabled = true +bantime = 10m +findtime = 10m +maxretry = 3 +EOF" + run "Enabling fail2ban" systemctl enable --now fail2ban +} + +configure_logrotate() { + run "Configuring logrotate for Docker logs" bash -c "cat >/etc/logrotate.d/docker <<'EOF' +/var/lib/docker/containers/*/*.log { + rotate 7 + daily + compress + missingok + delaycompress + copytruncate +} +EOF" +} + +install_netbird() { + [[ -z "$NETBIRD_KEY" ]] && return + run "Installing Netbird" bash -c "curl -fsSL https://pkgs.netbird.io/install.sh | sh" + run "Starting Netbird" netbird up --setup-key "$NETBIRD_KEY" + run "Checking Netbird service" systemctl is-active --quiet netbird + run "Checking Netbird connection" bash -c "netbird status | grep -qi 'connected'" +} + +setup_vector() { + [[ -z "$VECTOR_ENDPOINT" ]] && return + if ! command -v vector >/dev/null 2>&1; then + run "Installing Vector" bash -c "curl -1sLf 'https://repositories.timber.io/public/vector/cfg/setup/bash.deb.sh' | bash && apt-get install -y vector" + fi + run "Configuring Vector" bash -c "cat >/etc/vector/vector.toml <<'EOF' +[sources.syslog] + type = 'file' + include = ['/var/log/*.log'] + +[sources.docker] + type = 'docker_logs' + +[sinks.out] + type = 'http' + inputs = ['syslog', 'docker'] + uri = '$VECTOR_ENDPOINT' + encoding.codec = 'json' +EOF" + run "Enabling Vector" systemctl enable --now vector + run "Checking Vector service" systemctl is-active --quiet vector +} + +setup_compose() { + [[ -z "$COMPOSE_URL" ]] && return + run "Creating directory $COMPOSE_DIR" mkdir -p "$COMPOSE_DIR" + run "Downloading compose file" curl -fsSL "$COMPOSE_URL" -o "$COMPOSE_DIR/docker-compose.yml" + run "Setting ownership for compose dir" chown -R "$USERNAME:$USERNAME" "$COMPOSE_DIR" + run "Starting docker compose" bash -c "cd '$COMPOSE_DIR' && docker compose up -d" +} + +main() { + install_packages + setup_timezone + setup_unattended_upgrades + create_user + configure_ssh + configure_ufw + install_docker + configure_fail2ban + configure_logrotate + install_netbird + setup_vector + setup_compose +} + +main