157 lines
4.5 KiB
YAML
157 lines
4.5 KiB
YAML
#cloud-config
|
|
# Aegis402 — VPS bootstrap (SporeStack / Hetzner / any cloud-init compatible host)
|
|
# Hardened, no telemetry, no third-party agent.
|
|
# Replace AEGIS402_PUBLIC_URL and AEGIS402_WALLET_PASS placeholders before launch.
|
|
|
|
hostname: aegis402
|
|
preserve_hostname: false
|
|
manage_etc_hosts: true
|
|
timezone: UTC
|
|
|
|
users:
|
|
- name: aegis
|
|
sudo: ALL=(ALL) NOPASSWD:ALL
|
|
shell: /bin/bash
|
|
lock_passwd: true
|
|
ssh_authorized_keys:
|
|
- REPLACE_WITH_YOUR_SSH_PUBKEY
|
|
|
|
package_update: true
|
|
package_upgrade: true
|
|
packages:
|
|
- python3.12
|
|
- python3.12-venv
|
|
- python3-pip
|
|
- git
|
|
- ufw
|
|
- fail2ban
|
|
- sqlite3
|
|
- nginx
|
|
- certbot
|
|
- python3-certbot-nginx
|
|
- unattended-upgrades
|
|
|
|
write_files:
|
|
- path: /etc/aegis402.env
|
|
permissions: '0600'
|
|
owner: aegis:aegis
|
|
content: |
|
|
AEGIS402_X402_ENABLED=1
|
|
AEGIS402_X402_STRICT=1
|
|
AEGIS402_X402_FACILITATOR=https://x402.org/facilitator
|
|
AEGIS402_PUBLIC_URL=https://REPLACE_DOMAIN/
|
|
AEGIS402_WALLET_PASS=REPLACE_32CHAR_RANDOM_PASS_FROM_LOCAL
|
|
|
|
- path: /etc/systemd/system/aegis402.service
|
|
content: |
|
|
[Unit]
|
|
Description=Aegis402 API
|
|
After=network-online.target
|
|
Wants=network-online.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=aegis
|
|
Group=aegis
|
|
WorkingDirectory=/home/aegis/aegis402
|
|
EnvironmentFile=/etc/aegis402.env
|
|
ExecStart=/home/aegis/aegis402/venv/bin/uvicorn src.server:app \
|
|
--host 127.0.0.1 --port 8743 --workers 2 --log-level info
|
|
Restart=always
|
|
RestartSec=5
|
|
NoNewPrivileges=true
|
|
PrivateTmp=true
|
|
ProtectSystem=strict
|
|
ProtectHome=read-only
|
|
ReadWritePaths=/home/aegis/aegis402/data
|
|
LimitNOFILE=4096
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
|
|
- path: /etc/systemd/system/aegis402-ingest.service
|
|
content: |
|
|
[Unit]
|
|
Description=Aegis402 ingest GHSA + KEV
|
|
After=network-online.target
|
|
Wants=network-online.target
|
|
|
|
[Service]
|
|
Type=oneshot
|
|
User=aegis
|
|
Group=aegis
|
|
WorkingDirectory=/home/aegis/aegis402
|
|
EnvironmentFile=/etc/aegis402.env
|
|
ExecStart=/home/aegis/aegis402/venv/bin/python -m src.ingest_ghsa
|
|
ExecStart=/home/aegis/aegis402/venv/bin/python -m src.ingest_kev
|
|
Nice=10
|
|
TimeoutStartSec=900
|
|
|
|
- path: /etc/systemd/system/aegis402-ingest.timer
|
|
content: |
|
|
[Unit]
|
|
Description=Aegis402 ingest every 60 min
|
|
Requires=aegis402-ingest.service
|
|
|
|
[Timer]
|
|
OnBootSec=3min
|
|
OnUnitActiveSec=60min
|
|
RandomizedDelaySec=120
|
|
Persistent=true
|
|
Unit=aegis402-ingest.service
|
|
|
|
[Install]
|
|
WantedBy=timers.target
|
|
|
|
- path: /etc/nginx/sites-available/aegis402
|
|
content: |
|
|
server {
|
|
listen 80 default_server;
|
|
server_name _;
|
|
location / {
|
|
proxy_pass http://127.0.0.1:8743;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_read_timeout 30s;
|
|
client_max_body_size 256k;
|
|
}
|
|
}
|
|
|
|
runcmd:
|
|
# Firewall
|
|
- ufw default deny incoming
|
|
- ufw default allow outgoing
|
|
- ufw allow 22/tcp
|
|
- ufw allow 80/tcp
|
|
- ufw allow 443/tcp
|
|
- ufw --force enable
|
|
|
|
# Unattended security upgrades
|
|
- dpkg-reconfigure -f noninteractive unattended-upgrades
|
|
|
|
# App install
|
|
- sudo -u aegis git clone https://REPLACE_GIT_REMOTE /home/aegis/aegis402
|
|
- sudo -u aegis python3.12 -m venv /home/aegis/aegis402/venv
|
|
- sudo -u aegis /home/aegis/aegis402/venv/bin/pip install --upgrade pip
|
|
- sudo -u aegis /home/aegis/aegis402/venv/bin/pip install -r /home/aegis/aegis402/requirements.txt
|
|
- sudo -u aegis mkdir -p /home/aegis/aegis402/data
|
|
- sudo -u aegis /home/aegis/aegis402/venv/bin/python -c "from src.db import init_db; init_db()"
|
|
- sudo -u aegis /home/aegis/aegis402/venv/bin/python -m src.wallet
|
|
- sudo -u aegis /home/aegis/aegis402/venv/bin/python -m src.ingest_ghsa
|
|
- sudo -u aegis /home/aegis/aegis402/venv/bin/python -m src.ingest_kev
|
|
|
|
# Nginx + TLS
|
|
- ln -s /etc/nginx/sites-available/aegis402 /etc/nginx/sites-enabled/aegis402
|
|
- rm -f /etc/nginx/sites-enabled/default
|
|
- nginx -t && systemctl restart nginx
|
|
# Replace REPLACE_DOMAIN below before launch:
|
|
# - certbot --nginx -d REPLACE_DOMAIN --non-interactive --agree-tos -m REPLACE_EMAIL --redirect
|
|
|
|
# Services
|
|
- systemctl daemon-reload
|
|
- systemctl enable --now aegis402.service
|
|
- systemctl enable --now aegis402-ingest.timer
|
|
|
|
final_message: "Aegis402 bootstrap complete. Set DNS to this IP, then run certbot."
|