# SimpleX Relay Server Deployment Complete automated deployment for SimpleX Chat relay servers on Alpine Linux with post-quantum SSH hardening, Tor hidden services, and encrypted backups. ## Quick Start ### 1. Clone This Repository The installer fetches its scripts straight from this monorepo's layout: ``` automations/ ├── scripts/ │ └── harden-ssh.sh # generic SSH hardening (PQ KEX + Ed25519) ├── deployments/simplex/ │ ├── deploy-simplex.sh # SMP + XFTP + Tor deployment │ ├── backup.sh # age-encrypted backup creation │ ├── restore.sh # disaster recovery from backup │ ├── install-simplex.sh # master installer (cloud-init compatible) │ ├── cloud-init.yml # example cloud-init configuration │ └── README.md # this file └── globals/ └── age-pubkey.txt # your age public key(s) for backups ``` Point `REPO_URL` at your fork of this repo. The installer resolves `harden-ssh.sh` under `scripts/` and the simplex scripts under `deployments/simplex/` automatically (overridable via `HARDEN_PATH` / `SIMPLEX_PATH`). ### 2. Generate Backup Keys ```bash # Generate age keypair for backups age-keygen -o backup-private-key.txt # Save the public key to the shared globals/ folder echo "age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p" > globals/age-pubkey.txt # Store the private key securely (NOT in your repo) cp backup-private-key.txt ~/safe-location/ ``` ### 3. Deploy via Cloud-Init Create a cloud instance with this user-data: ```yaml #cloud-config runcmd: - | curl -fsSL https://git.anomalous.dev/57_Wolve/automations/raw/branch/main/deployments/simplex/install-simplex.sh | \ REPO_URL=https://git.anomalous.dev/57_Wolve/automations.git \ DOMAIN=relay.example.com \ ACME_EMAIL=admin@example.com \ XFTP_QUOTA=100gb \ SSH_PORT=2222 \ ALLOWED_IP=1.2.3.4 \ bash ``` ### 4. Manual Deployment ```bash # On a fresh Alpine Linux host: curl -fsSL https://git.anomalous.dev/57_Wolve/automations/raw/branch/main/deployments/simplex/install-simplex.sh | \ REPO_URL=https://git.anomalous.dev/57_Wolve/automations.git \ DOMAIN=relay.example.com \ ACME_EMAIL=admin@example.com \ XFTP_QUOTA=50gb \ SSH_PORT=2222 \ bash ``` ## Configuration Options | Variable | Required | Default | Description | |----------|----------|---------|-------------| | `REPO_URL` | ✅ | | Git repository URL containing deployment scripts | | `DOMAIN` | ✅ | | Apex domain (creates smp.DOMAIN, xftp.DOMAIN) | | `ACME_EMAIL` | ✅ | | Email for Let's Encrypt registration | | `XFTP_QUOTA` | | 50gb | Disk quota for file storage | | `SSH_PORT` | | 22 | SSH port (recommend changing from default) | | `ALLOWED_IP` | | | Your IP to whitelist in sshguard | | `KEY_TYPE` | | rsa4096 | Caddy TLS key type (rsa4096, p384, ed25519) | | `SMP_PASS` | | | Optional password for SMP queue creation | | `XFTP_PASS` | | | Optional password for XFTP uploads | | `SKIP_PROMPTS` | | 0 | Set to 1 for non-interactive installation | ## What Gets Deployed ### Security Features - **Post-quantum SSH**: Hybrid KEX (mlkem768x25519, sntrup761x25519) + Ed25519 keys - **Minimal attack surface**: Only SSH terminal + SFTP, no forwarding/tunnels - **Firewall**: awall with explicit allow-list for required ports only - **Brute-force protection**: sshguard with progressive IP bans ### SimpleX Infrastructure - **SMP server**: Message relay on port 5223 - **XFTP server**: File transfer on port 5443 - **Tor hidden services**: .onion addresses for both servers - **TLS termination**: Caddy with Let's Encrypt and strong crypto - **Docker compose**: Orchestrated deployment with health checks ### Operational Features - **Encrypted backups**: All private keys backed up with age encryption - **CA key removal**: Private keys removed from disk after backup - **Service monitoring**: OpenRC integration with auto-restart - **Address discovery**: Scripts to show server fingerprints and .onion URLs ## Server Addresses After deployment, your relay will be accessible at: ``` # Clearnet smp://FINGERPRINT@smp.yourdomain.com xftp://FINGERPRINT@xftp.yourdomain.com # Tor (clients with Orbot/Tor) smp://FINGERPRINT@smp.yourdomain.com,ONIONADDRESS.onion xftp://FINGERPRINT@xftp.yourdomain.com,ONIONADDRESS.onion ``` Get the full addresses with: `cd /opt/simplex && ./print-addresses.sh` ## Backup & Recovery ### Creating Backups ```bash # Manual backup (on the server) AGE_RECIPIENT_FILE=/path/to/age-pubkey.txt bash backup.sh # Or with a single recipient AGE_RECIPIENT=age1ql3z7... bash backup.sh ``` ### Disaster Recovery ```bash # 1. Fresh Alpine install # 2. Upload restore script and backup scp restore.sh backup-20250101-120000.tar.gz.age root@new-host:/root/ # 3. Restore (preserves all server identities) ssh root@new-host bash restore.sh backup-20250101-120000.tar.gz.age # 4. Update DNS to point at new host ``` ## DNS Configuration Create these DNS records before deployment: ``` smp.yourdomain.com. 300 IN A 1.2.3.4 xftp.yourdomain.com. 300 IN A 1.2.3.4 ``` Replace `1.2.3.4` with your server's IP address. ## Architecture ``` Internet ↓ [Caddy :80,:443] ← Let's Encrypt ACME ↓ [Docker Network] ├─ [SMP Server :5223] ← Tor Hidden Service └─ [XFTP Server :5443] ← Tor Hidden Service ``` - **Ports 80/443**: Caddy (HTTP redirect + ACME + info pages) - **Port 5223**: SMP protocol (TCP, server's own TLS) - **Port 5443**: XFTP protocol (TCP, server's own TLS) - **Port 22/2222**: SSH (PQ KEX + Ed25519 only) ## File Locations - **Deployment**: `/opt/simplex/` (docker-compose.yml, configs, scripts) - **Server keys**: `/opt/simplex/{smp,xftp}_configs/` (CA keys removed after backup) - **Tor keys**: `/opt/simplex/{smp,xftp}_tor/` (hidden service identity) - **SSH config**: `/etc/ssh/` (hardened sshd_config + Ed25519 host key) - **Firewall**: `/etc/awall/optional/` (JSON policy files) - **Backups**: `/tmp/simplex-backup-YYYYMMDD-HHMMSS.tar.gz.age` ## Security Notes ### What's Quantum-Safe - **Session keys**: PQ hybrid KEX protects against "store now, decrypt later" - **Authentication**: Ed25519 keys (classical, but strongest practical choice today) ### Network Hardening - Only required ports open (22/2222, 80, 443, 5223, 5443) - SSH locked to key-only auth, no forwarding, rate-limited - sshguard blocks brute-force attempts with progressive delays ### Key Management - CA private keys backed up encrypted, then removed from disk - Tor onion keys preserved for stable .onion addresses - SSH host key preserved for stable fingerprint - All backups encrypted with age (modern, simple, secure) ## Troubleshooting ### Check Service Status ```bash cd /opt/simplex docker compose ps # Container status docker compose logs -f smp-server # SMP logs docker compose logs -f xftp-server # XFTP logs ./print-addresses.sh # Show server addresses ``` ### SSH Issues ```bash # Test SSH config sshd -t # View SSH attempts journalctl -u sshd -f # Check sshguard blocks iptables -L sshguard -n ``` ### Firewall Issues ```bash awall list # Show firewall policies awall translate # Test policy compilation iptables -L -n # Show active rules ``` ### Certificate Issues ```bash docker exec simplex-caddy caddy list-certificates docker logs simplex-caddy ``` ## Contributing 1. Fork this repository 2. Make your changes 3. Test on a fresh Alpine instance 4. Submit a pull request ## License This deployment is provided as-is for educational and operational use. The SimpleX Chat software itself is licensed under AGPL-3.0.