homelab/services/remnawave/remnawave-nodes/boostrap.sh
2026-03-10 22:19:53 +03:00

230 lines
4.9 KiB
Bash

#!/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" <<EOF
SECRET_KEY=${SECRET_KEY}
NODE_PORT=${NODE_PORT}
API_HOST=${MASTER_API_URL}
EOF
cat >"${NODE_DIR}/docker-compose.yml" <<EOF
services:
remnanode:
image: remnawave/node:latest
container_name: remnanode
hostname: ${NODE_NAME}
network_mode: host
restart: unless-stopped
env_file:
- .env
cap_add:
- NET_ADMIN
volumes:
- /var/log/remnanode:/var/log/remnanode
ulimits:
nofile:
soft: 1048576
hard: 1048576
logging:
driver: json-file
options:
max-size: "50m"
max-file: "3"
EOF
cd "${NODE_DIR}"
log "Starting node"
docker compose up -d
docker compose ps
echo
echo "Node installation complete"
echo
echo "Master API: ${MASTER_API_URL}"
echo "Node name: ${NODE_NAME}"
echo "Node dir: ${NODE_DIR}"
echo "Logs dir: /var/log/remnanode"
echo