Add comprehensive documentation for CI/CD pipeline, NATS, security practices, Tailscale networking, and troubleshooting guide
- Created CI/CD pipeline documentation detailing workflows, triggers, and actions for `asepharyana-hub`. - Added NATS + JetStream guide covering architecture, configuration, CLI tools, and event topics. - Introduced a security guide outlining best practices for secrets management, TLS, container security, and access control. - Documented Tailscale networking setup and troubleshooting for connectivity between VPS and bare-metal nodes. - Compiled a troubleshooting guide addressing common issues across deployment, Dapr, NATS, Traefik, Tailscale, Docker, database, and submodules.
This commit is contained in:
@@ -0,0 +1,211 @@
|
||||
# Security Guide
|
||||
|
||||
Praktik keamanan untuk infrastruktur `asepharyana-hub`.
|
||||
|
||||
## Ringkasan
|
||||
|
||||
| Area | Status | Prioritas |
|
||||
|------|--------|-----------|
|
||||
| Secrets management | GitHub encrypted secrets | Tinggi |
|
||||
| TLS termination | Traefik + cert volume mounts | Tinggi |
|
||||
| Container security | Non-root user (scraper-api) | Sedang |
|
||||
| Network security | Tailscale overlay, app-shared-net | Sedang |
|
||||
| Access control | SSH key, GitHub permissions | Sedang |
|
||||
| Monitoring | Belum ada alert system | Rendah |
|
||||
| Firewall | UFW/iptables (manual) | Sedang |
|
||||
| Backup | lihat `docs/backup-recovery.md` | Sedang |
|
||||
|
||||
## Secrets Management
|
||||
|
||||
### Yang Tidak Boleh di-Commit
|
||||
|
||||
- [ ] `.env` production (disimpan sebagai GitHub secret `ENV_FILE_PRODUCTION`)
|
||||
- [ ] SSH private keys
|
||||
- [ ] API tokens, JWT secret
|
||||
- [ ] Docker registry tokens
|
||||
- [ ] Database passwords
|
||||
- [ ] TLS certificate private keys
|
||||
|
||||
### GitHub Secrets
|
||||
|
||||
Setting di Settings > Secrets and variables > Actions:
|
||||
|
||||
| Secret | Tujuan | Rotasi |
|
||||
|--------|--------|--------|
|
||||
| `SSH_PRIVATE_KEY` | Akses SSH ke VPS | 6 bulan |
|
||||
| `VPS_HOST` | IP VPS | Tidak berubah |
|
||||
| `VPS_USER` | User SSH | Tidak berubah |
|
||||
| `VPS_TARGET_DIR` | Directory di VPS | Tidak berubah |
|
||||
| `ENV_FILE_PRODUCTION` | Full `.env` production | Saat ada perubahan |
|
||||
|
||||
### Update Secrets dengan aman
|
||||
|
||||
```bash
|
||||
# Baca current .env dari VPS via SSH
|
||||
ssh root@45.127.35.244 "cat /root/asepharyana-hub/.env" | gh secret set ENV_FILE_PRODUCTION --repo asepharyana/asepharyana-hub --repos
|
||||
```
|
||||
|
||||
### Production `.env` tidak boleh di-commit
|
||||
|
||||
`.env` di root repo adalah untuk development lokal. Production `.env` hanya ada di:
|
||||
1. GitHub secret `ENV_FILE_PRODUCTION`
|
||||
2. File `/root/asepharyana-hub/.env` di VPS (hasil SCP dari CI/CD)
|
||||
|
||||
## TLS / SSL
|
||||
|
||||
### Konfigurasi
|
||||
|
||||
```yaml
|
||||
# Traefik TLS certs dari file mount (bukan auto-ACME)
|
||||
volumes:
|
||||
- ${TRAEFIK_CERT_MY_ID_PEM:-/root/asepharyana.my.id.pem}:/etc/traefik/certs/asepharyana.my.id.pem:ro
|
||||
- ${TRAEFIK_CERT_MY_ID_KEY:-/root/asepharyana.my.id.key}:/etc/traefik/certs/asepharyana.my.id.key:ro
|
||||
```
|
||||
|
||||
### Best Practices
|
||||
|
||||
- Certificates disimpan di host (`/root/`), bukan di repo
|
||||
- Volume mount read-only (`:ro`)
|
||||
- Private key hanya bisa dibaca oleh root (chmod 600)
|
||||
- Renew certificates sebelum expired (monitor expiry)
|
||||
- Dua domain: `asepharyana.my.id` + `asepharyana.web.id`
|
||||
|
||||
## Container Security
|
||||
|
||||
### Non-Root User
|
||||
|
||||
Scraper API berjalan sebagai `appuser` (UID 1001):
|
||||
|
||||
```dockerfile
|
||||
RUN groupadd -g 1001 appgroup && \
|
||||
useradd -u 1001 -g appgroup -s /bin/sh appuser
|
||||
USER appuser
|
||||
```
|
||||
|
||||
Service baru harus mengikuti pattern yang sama.
|
||||
|
||||
### Read-Only Filesystem
|
||||
|
||||
Untuk container yang tidak perlu write ke filesystem:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
app:
|
||||
image: app:latest
|
||||
read_only: true
|
||||
tmpfs:
|
||||
- /tmp
|
||||
```
|
||||
|
||||
### Docker Socket
|
||||
|
||||
Hanya Traefik yang perlu akses ke Docker socket (read-only):
|
||||
|
||||
```yaml
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
```
|
||||
|
||||
Service lain tidak boleh mount Docker socket.
|
||||
|
||||
### Image Security
|
||||
|
||||
- Build dari base image resmi dan minimal (`debian:bookworm-slim`, `redis:alpine`, `nats:latest`)
|
||||
- Multi-stage build untuk production image (tidak include build tools)
|
||||
- Update base image secara berkala
|
||||
|
||||
## Network Security
|
||||
|
||||
### Firewall (UFW/iptables)
|
||||
|
||||
Di VPS (`orangevps`):
|
||||
|
||||
```bash
|
||||
# Hanya buka port yang diperlukan
|
||||
sudo ufw default deny incoming
|
||||
sudo ufw default allow outgoing
|
||||
sudo ufw allow 22/tcp # SSH
|
||||
sudo ufw allow 80/tcp # HTTP redirect
|
||||
sudo ufw allow 443/tcp # HTTPS
|
||||
sudo ufw allow 4222/tcp # NATS (jika perlu external akses)
|
||||
sudo ufw enable
|
||||
```
|
||||
|
||||
Di `imrnes`:
|
||||
|
||||
```bash
|
||||
# Hanya dari Tailscale interface
|
||||
sudo ufw allow in on tailscale0 to any port 6432 proto tcp # PostgreSQL
|
||||
sudo ufw allow in on tailscale0 to any port 6379 proto tcp # Redis
|
||||
sudo ufw enable
|
||||
```
|
||||
|
||||
### Network Segmentation
|
||||
|
||||
- Semua container di network `app-shared-net` (internal bridge)
|
||||
- Tidak ada port yang di-expose ke host kecuali Traefik (80,443)
|
||||
- Redis hanya accessible via Docker DNS (`redis:6379`) — tidak di-expose
|
||||
- Database hanya via Tailscale — tidak accessible dari public internet
|
||||
|
||||
### SSH Hardening
|
||||
|
||||
Konfigurasi di `/etc/ssh/sshd_config`:
|
||||
|
||||
```
|
||||
Port 22
|
||||
PermitRootLogin prohibit-password
|
||||
PasswordAuthentication no
|
||||
PubkeyAuthentication yes
|
||||
AllowUsers root
|
||||
MaxAuthTries 3
|
||||
ClientAliveInterval 300
|
||||
ClientAliveCountMax 2
|
||||
```
|
||||
|
||||
## Access Control
|
||||
|
||||
### GitHub Repository
|
||||
|
||||
- `contents: write` hanya untuk workflow `update-manifest` dan `update-submodule`
|
||||
- `packages: write` hanya untuk workflow `build`
|
||||
- `security-events: write` hanya untuk workflow `security`
|
||||
- Branch protection di `main`: require PR review, status checks
|
||||
|
||||
### VPS
|
||||
|
||||
- SSH hanya dengan key-based authentication
|
||||
- Key disimpan di GitHub secret, bukan di repo
|
||||
- Rotate SSH key secara berkala (minimal 6 bulan)
|
||||
- Jangan gunakan password login
|
||||
|
||||
## Monitoring Keamanan
|
||||
|
||||
### Saat Ini
|
||||
|
||||
- Traefik access logs (format JSON, buffer size 100)
|
||||
- Docker logs via `docker logs`
|
||||
- CodeQL analysis untuk Rust code (setiap PR + weekly)
|
||||
|
||||
### Rekomendasi
|
||||
|
||||
- [ ] Alert untuk SSH failed login (fail2ban)
|
||||
- [ ] Log monitoring (Loki / Promtail)
|
||||
- [ ] Container vulnerability scanning (Trivy / Snyk)
|
||||
- [ ] Certificate expiry monitoring
|
||||
- [ ] Disk usage alert
|
||||
- [ ] Unauthorized access detection
|
||||
|
||||
## Checklist Security
|
||||
|
||||
- [ ] SSH password authentication disabled
|
||||
- [ ] Root login via SSH key only
|
||||
- [ ] UFW/iptables configured
|
||||
- [ ] Docker socket only mounted where necessary (read-only)
|
||||
- [ ] Container berjalan sebagai non-root user
|
||||
- [ ] `.env` tidak di-commit
|
||||
- [ ] GitHub secrets ter-encrypt
|
||||
- [ ] TLS certificates valid dan belum expired
|
||||
- [ ] CodeQL analysis berjalan
|
||||
- [ ] Backup database berjalan
|
||||
- [ ] SSH key di-rotate
|
||||
- [ ] Docker image di-scan untuk vulnerability
|
||||
Reference in New Issue
Block a user