#cloud-config # ============================================================================= # Realms App Server Cloud-Init Configuration # Production server for streaming platform - Docker-based deployment # ============================================================================= write_files: # SSH daemon configuration (non-standard port, VPC only access) - path: /etc/ssh/sshd_config.d/99-hardening.conf content: | # Non-standard port (VPC access only via jump host) Port ${ssh_port} # Authentication hardening PermitRootLogin prohibit-password PasswordAuthentication no PubkeyAuthentication yes AuthenticationMethods publickey # Security settings MaxAuthTries 3 LoginGraceTime 30 PermitEmptyPasswords no X11Forwarding no AllowTcpForwarding yes AllowAgentForwarding no PermitUserEnvironment no MaxSessions 5 # Session settings ClientAliveInterval 300 ClientAliveCountMax 2 # Logging LogLevel VERBOSE permissions: '0644' # Fail2ban configuration for SSH - path: /etc/fail2ban/jail.d/sshd.local content: | [sshd] enabled = true port = ${ssh_port} filter = sshd logpath = /var/log/auth.log backend = systemd bantime = 1h findtime = 10m maxretry = 3 permissions: '0644' # Docker daemon configuration - path: /etc/docker/daemon.json content: | { "log-driver": "json-file", "log-opts": { "max-size": "50m", "max-file": "5" }, "storage-driver": "overlay2", "live-restore": true, "no-new-privileges": true } permissions: '0644' # UFW configuration script - path: /usr/local/bin/configure-firewall.sh content: | #!/bin/bash set -e # Reset UFW ufw --force reset # Default policies ufw default deny incoming ufw default deny outgoing # Inbound: HTTP/HTTPS ufw allow in 80/tcp comment 'HTTP' ufw allow in 443/tcp comment 'HTTPS' # Inbound: Streaming ports ufw allow in 1935/tcp comment 'RTMP' ufw allow in 9999/udp comment 'SRT' ufw allow in 3333/tcp comment 'WebRTC TCP' ufw allow in 3333/udp comment 'WebRTC UDP' ufw allow in 3334/tcp comment 'WebRTC TCP fallback' # Inbound: VPC traffic (includes system SSH) ufw allow in from ${vpc_ip_range} comment 'VPC internal' # Outbound: Necessary traffic ufw allow out 53/tcp comment 'DNS' ufw allow out 53/udp comment 'DNS' ufw allow out 80/tcp comment 'HTTP' ufw allow out 443/tcp comment 'HTTPS' ufw allow out 123/udp comment 'NTP' ufw allow out to ${vpc_ip_range} comment 'VPC' # Enable logging ufw logging medium # Enable UFW ufw --force enable echo "Firewall configured successfully" permissions: '0755' # Swap configuration script (for 4GB RAM) - path: /usr/local/bin/configure-swap.sh content: | #!/bin/bash set -e SWAP_FILE="/swapfile" SWAP_SIZE="4G" if [ ! -f "$SWAP_FILE" ]; then echo "Creating $SWAP_SIZE swap file..." fallocate -l $SWAP_SIZE $SWAP_FILE chmod 600 $SWAP_FILE mkswap $SWAP_FILE swapon $SWAP_FILE # Add to fstab echo "$SWAP_FILE none swap sw 0 0" >> /etc/fstab # Adjust swappiness echo "vm.swappiness=10" >> /etc/sysctl.conf sysctl vm.swappiness=10 echo "Swap configured successfully" else echo "Swap file already exists" fi permissions: '0755' # Unattended upgrades configuration - path: /etc/apt/apt.conf.d/50unattended-upgrades content: | Unattended-Upgrade::Allowed-Origins { "$${distro_id}:$${distro_codename}"; "$${distro_id}:$${distro_codename}-security"; "$${distro_id}:$${distro_codename}-updates"; }; Unattended-Upgrade::AutoFixInterruptedDpkg "true"; Unattended-Upgrade::MinimalSteps "true"; Unattended-Upgrade::Remove-Unused-Dependencies "true"; Unattended-Upgrade::Automatic-Reboot "false"; permissions: '0644' # Auto-upgrades configuration - path: /etc/apt/apt.conf.d/20auto-upgrades content: | APT::Periodic::Update-Package-Lists "1"; APT::Periodic::Unattended-Upgrade "1"; APT::Periodic::AutocleanInterval "7"; permissions: '0644' # Message of the day - path: /etc/motd content: | +---------------------------------------------------------------+ | REALMS APP SERVER | | | | Domain: ${domain} | SSH Port: ${ssh_port} (VPC only) | | | App location: /opt/realms | | Docker compose: /opt/realms/docker-compose.yml | | | | Commands: | | cd /opt/realms && docker compose logs -f | | cd /opt/realms && docker compose pull && up -d | | | +---------------------------------------------------------------+ permissions: '0644' runcmd: # Ensure .ssh directory exists - mkdir -p /root/.ssh && chmod 700 /root/.ssh # Configure SSH - grep -q 'Include /etc/ssh/sshd_config.d' /etc/ssh/sshd_config || sed -i '1i Include /etc/ssh/sshd_config.d/*.conf' /etc/ssh/sshd_config - sed -i 's/^Port /#Port /' /etc/ssh/sshd_config - systemctl restart sshd # Wait for dpkg lock - while fuser /var/lib/dpkg/lock-frontend >/dev/null 2>&1; do echo "Waiting for dpkg lock..."; sleep 5; done # Install prerequisites - apt-get update - DEBIAN_FRONTEND=noninteractive apt-get -o DPkg::Lock::Timeout=60 install -y ca-certificates curl gnupg fail2ban ufw unattended-upgrades apt-listchanges vim git # Add Docker's official GPG key and repository - install -m 0755 -d /etc/apt/keyrings - curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg - chmod a+r /etc/apt/keyrings/docker.gpg - echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian $(. /etc/os-release && echo $VERSION_CODENAME) stable" > /etc/apt/sources.list.d/docker.list # Install Docker - apt-get update - DEBIAN_FRONTEND=noninteractive apt-get -o DPkg::Lock::Timeout=60 install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin # Enable and start Docker - systemctl enable docker - systemctl start docker # Enable and start fail2ban - systemctl enable fail2ban - systemctl restart fail2ban # Configure swap - /usr/local/bin/configure-swap.sh # Configure firewall - /usr/local/bin/configure-firewall.sh # Create app directory - mkdir -p /opt/realms - mkdir -p /opt/realms/uploads # Enable unattended upgrades - systemctl enable unattended-upgrades - systemctl start unattended-upgrades final_message: "Realms app server ready after $UPTIME seconds. Deploy via Forgejo CI/CD."