Initial commit - realms platform

This commit is contained in:
doomtube 2026-01-05 22:54:27 -05:00
parent c590ab6d18
commit c717c3751c
234 changed files with 74103 additions and 15231 deletions

View file

@ -0,0 +1,175 @@
#cloud-config
# =============================================================================
# Jump Host (Bastion) Cloud-Init Configuration
# Minimal attack surface - SSH only, no Docker
# =============================================================================
# NOTE: We install packages via runcmd instead of packages: section
# because DigitalOcean's base image cloud-init can interfere with the packages module
# SSH hardening configuration
write_files:
# SSH daemon configuration
- path: /etc/ssh/sshd_config.d/99-hardening.conf
content: |
# Non-standard port
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 no
AllowAgentForwarding no
PermitUserEnvironment no
MaxSessions 3
# Session settings
ClientAliveInterval 300
ClientAliveCountMax 2
# Logging
LogLevel VERBOSE
permissions: '0644'
# Fail2ban SSH jail configuration
- 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'
# 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: SSH on non-standard port
ufw allow in ${ssh_port}/tcp comment 'SSH'
# Inbound: VPC traffic
ufw allow in from ${vpc_ip_range} comment 'VPC internal'
# Outbound: Only necessary traffic (matching DO firewall)
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 for security audit
ufw logging high
# Enable UFW
ufw --force enable
echo "Firewall configured successfully"
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: |
╔═══════════════════════════════════════════════════════════════╗
║ JUMP HOST / BASTION ║
║ ║
║ This is a restricted access server. ║
║ All connections are logged and monitored. ║
║ ║
║ Use this host to access internal infrastructure: ║
║ ssh -p 52913 root@10.10.0.x ║
║ ║
╚═══════════════════════════════════════════════════════════════╝
permissions: '0644'
# Internal SSH private key (for accessing Forgejo and other internal servers)
- path: /root/.ssh/id_ed25519
content: |
${indent(6, internal_private_key)}
permissions: '0600'
# SSH config for internal servers
- path: /root/.ssh/config
content: |
Host 10.10.0.*
StrictHostKeyChecking accept-new
IdentityFile ~/.ssh/id_ed25519
User root
permissions: '0600'
runcmd:
# Ensure sshd_config includes the .d directory (Debian 12 fix)
- 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
# Comment out Port in main sshd_config so sshd_config.d takes precedence (Debian 12 fix)
- sed -i 's/^Port /#Port /' /etc/ssh/sshd_config
# Restart SSH with new configuration
- systemctl restart sshd
# Wait for any background apt processes to finish (DO images run apt on boot)
- while fuser /var/lib/dpkg/lock-frontend >/dev/null 2>&1; do echo "Waiting for dpkg lock..."; sleep 5; done
# Install all required packages (more reliable than packages: section on DO images)
- apt-get update
- DEBIAN_FRONTEND=noninteractive apt-get -o DPkg::Lock::Timeout=60 install -y fail2ban ufw unattended-upgrades apt-listchanges curl vim
# Enable and start fail2ban
- systemctl enable fail2ban
- systemctl restart fail2ban
# Configure firewall
- /usr/local/bin/configure-firewall.sh
# Enable unattended upgrades
- systemctl enable unattended-upgrades
- systemctl start unattended-upgrades
final_message: "Jump host initialization complete after $UPTIME seconds"

View file

@ -0,0 +1,39 @@
# =============================================================================
# Jump Host (Bastion) Droplet
# =============================================================================
data "cloudinit_config" "jump_host" {
gzip = false
base64_encode = false
part {
content_type = "text/cloud-config"
content = templatefile("${path.module}/cloud-init.yaml.tpl", {
ssh_port = var.ssh_port
vpc_ip_range = var.vpc_ip_range
internal_private_key = var.internal_private_key
})
}
}
resource "digitalocean_droplet" "jump_host" {
name = "${var.project_name}-jump-${var.environment}"
size = var.droplet_size
image = var.droplet_image
region = var.region
vpc_uuid = var.vpc_uuid
ssh_keys = var.ssh_keys
backups = var.enable_backups
monitoring = true
ipv6 = true
user_data = data.cloudinit_config.jump_host.rendered
tags = var.tags
lifecycle {
create_before_destroy = false
ignore_changes = [user_data] # Don't recreate on cloud-init changes
}
}

View file

@ -0,0 +1,19 @@
output "droplet_id" {
description = "ID of the jump host droplet"
value = digitalocean_droplet.jump_host.id
}
output "public_ip" {
description = "Public IPv4 address of the jump host"
value = digitalocean_droplet.jump_host.ipv4_address
}
output "private_ip" {
description = "Private IPv4 address of the jump host (VPC)"
value = digitalocean_droplet.jump_host.ipv4_address_private
}
output "urn" {
description = "URN of the jump host droplet"
value = digitalocean_droplet.jump_host.urn
}

View file

@ -0,0 +1,65 @@
variable "project_name" {
description = "Project name"
type = string
}
variable "environment" {
description = "Environment name"
type = string
}
variable "region" {
description = "DigitalOcean region"
type = string
}
variable "vpc_uuid" {
description = "UUID of the VPC"
type = string
}
variable "vpc_ip_range" {
description = "IP range of the VPC (CIDR notation)"
type = string
}
variable "ssh_keys" {
description = "List of SSH key IDs to add to the droplet"
type = list(string)
}
variable "droplet_size" {
description = "Size slug for the droplet"
type = string
default = "s-1vcpu-512mb-10gb"
}
variable "droplet_image" {
description = "Image slug for the droplet"
type = string
default = "debian-12-x64"
}
variable "ssh_port" {
description = "SSH port (non-standard for security)"
type = number
default = 49822
}
variable "enable_backups" {
description = "Enable automated backups"
type = bool
default = true
}
variable "tags" {
description = "Tags to apply to the droplet"
type = list(string)
default = []
}
variable "internal_private_key" {
description = "Private SSH key for accessing internal servers (Forgejo, etc.)"
type = string
sensitive = true
}

View file

@ -0,0 +1,12 @@
terraform {
required_providers {
digitalocean = {
source = "digitalocean/digitalocean"
version = ">= 2.34"
}
cloudinit = {
source = "hashicorp/cloudinit"
version = ">= 2.3"
}
}
}