Files
57_Wolve 7faa9098de feat: unified launcher, multi-OS hardening, login alerts & auto-updates
Restructure around a single entry point (automations.sh) with a Gum wizard and
a self-extracting bundle for repo-less installs. Add scripts/oslib.sh so the
provisioning scripts (setup-host, harden-ssh, harden-jumphost, sshuser) run on
Alpine/Debian/Alma; seed root keys from globals/.

- ntfy SSH-login alerts (user, source IP, key, region, jump target) via pam_exec
- daily auto-updates with AUTO_REBOOT=idle (reboots only when no SSH active) and
  opt-in Alpine stable-branch upgrades
- generic + per-deployment cloud-init; Gitea release workflow on tag
- README/LICENSE/.gitignore/.gitattributes (force LF); repo URLs -> Gitea
2026-06-12 14:56:02 -05:00

251 lines
7.6 KiB
Markdown

# 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.