#!/usr/bin/env bash set -Eeuo pipefail # ========================= # Config # ========================= ADMIN_USER="${ADMIN_USER:-pvlx}" SSH_PORT="${SSH_PORT:-22}" NODE_NAME="${NODE_NAME:-fin-node-01}" NODE_DIR="${NODE_DIR:-/opt/remnanode}" SECRET_KEY="${SECRET_KEY:-}" MASTER_API_URL="${MASTER_API_URL:-https://rat-api.sesur.dev}" NODE_PORT="${NODE_PORT:-2222}" ENABLE_UFW="${ENABLE_UFW:-true}" # ========================= # Helpers # ========================= log() { echo echo "==> $1" } require_root() { if [[ "${EUID}" -ne 0 ]]; then echo "Run as root" exit 1 fi } require_secret() { if [[ -z "${SECRET_KEY}" ]]; then echo "SECRET_KEY is empty." echo 'Run like:' echo 'SECRET_KEY="your-secret" MASTER_API_URL="https://rat-api.sesur.dev" bash bootstrap-remnanode.sh' exit 1 fi } # ========================= # Main # ========================= require_root require_secret log "Updating system" apt-get update DEBIAN_FRONTEND=noninteractive apt-get upgrade -y log "Installing base packages" DEBIAN_FRONTEND=noninteractive apt-get install -y \ ca-certificates curl gnupg lsb-release \ ufw unattended-upgrades nano logrotate log "Enable automatic security updates" dpkg-reconfigure -f noninteractive unattended-upgrades || true log "Creating admin user" if ! id -u "${ADMIN_USER}" >/dev/null 2>&1; then adduser --disabled-password --gecos "" "${ADMIN_USER}" fi usermod -aG sudo "${ADMIN_USER}" log "Configuring passwordless sudo for ${ADMIN_USER}" echo "${ADMIN_USER} ALL=(ALL) NOPASSWD:ALL" >/etc/sudoers.d/90-${ADMIN_USER} chmod 440 /etc/sudoers.d/90-${ADMIN_USER} log "Installing SSH key for ${ADMIN_USER}" mkdir -p "/home/${ADMIN_USER}/.ssh" echo "${SSH_PUBLIC_KEY}" > "/home/${ADMIN_USER}/.ssh/authorized_keys" chown -R "${ADMIN_USER}:${ADMIN_USER}" "/home/${ADMIN_USER}/.ssh" chmod 700 "/home/${ADMIN_USER}/.ssh" chmod 600 "/home/${ADMIN_USER}/.ssh/authorized_keys" log "Hardening SSH" SSHD_CONFIG="/etc/ssh/sshd_config" cp "${SSHD_CONFIG}" "${SSHD_CONFIG}.bak.$(date +%s)" sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin no/' "${SSHD_CONFIG}" sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication no/' "${SSHD_CONFIG}" sed -i 's/^#\?PubkeyAuthentication.*/PubkeyAuthentication yes/' "${SSHD_CONFIG}" if grep -q '^AllowUsers' "${SSHD_CONFIG}"; then sed -i "s/^AllowUsers.*/AllowUsers ${ADMIN_USER}/" "${SSHD_CONFIG}" else echo "AllowUsers ${ADMIN_USER}" >> "${SSHD_CONFIG}" fi systemctl restart ssh || systemctl restart sshd log "Installing Docker" if ! command -v docker >/dev/null; then curl -fsSL https://get.docker.com | sh fi systemctl enable docker systemctl start docker usermod -aG docker "${ADMIN_USER}" log "Configure Docker logs" mkdir -p /etc/docker cat >/etc/docker/daemon.json <<'EOF' { "log-driver": "json-file", "log-opts": { "max-size": "50m", "max-file": "3" } } EOF systemctl restart docker log "Applying kernel network hardening" cat >/etc/sysctl.d/99-remnanode-security.conf <<'EOF' net.ipv4.tcp_syncookies = 1 net.ipv4.conf.all.rp_filter = 1 net.ipv4.conf.default.rp_filter = 1 net.ipv4.icmp_echo_ignore_broadcasts = 1 net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.default.accept_redirects = 0 net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.default.send_redirects = 0 net.ipv4.conf.all.accept_source_route = 0 net.ipv4.conf.default.accept_source_route = 0 EOF sysctl --system if [[ "${ENABLE_UFW}" == "true" ]]; then log "Configuring firewall" ufw --force reset ufw default deny incoming ufw default allow outgoing ufw allow "${SSH_PORT}/tcp" ufw allow 443/tcp ufw allow 1080/tcp ufw allow 1080/udp ufw allow "${NODE_PORT}/tcp" ufw --force enable fi log "Creating log directory" mkdir -p /var/log/remnanode chown root:root /var/log/remnanode chmod 755 /var/log/remnanode log "Configuring logrotate for remnanode" cat >/etc/logrotate.d/remnanode <<'EOF' /var/log/remnanode/*.log { size 50M rotate 5 compress missingok notifempty copytruncate } EOF log "Creating Remnawave node" mkdir -p "${NODE_DIR}" cat >"${NODE_DIR}/.env" <"${NODE_DIR}/docker-compose.yml" <