Tutorial Setup Authentik & Traefik v3: Build Zero Trust Proxy di VPS
Poin Kunci Artikel Ini:
- VPS Linux OS Ubuntu 22.04 LTS atau 24.04 LTS. Minimal 2 vCPU Core, 4GB RAM.
- IP Publik Statis terpasang pada interface jaringan VPS.
- Docker Engine v24.0+ dan Docker Compose v2.20+ terpasang.
Arsitektur Zero Trust & Identity-Aware Proxy (IAP)
Bahaya Ekspos Port Publik vs Akses VPN
Ekspos port admin (Portainer, Grafana, PgAdmin, REST API) langsung ke publik berisiko tinggi. Scanners bot dan peretas lakukan credential stuffing, brute force, serta eksploitasi kerentanan 0-day pada IP VPS publik. Pendekatan lama gunakan VPN (WireGuard atau OpenVPN) amankan port, tetapi ciptakan masalah baru: overhead operasional tinggi, latensi koneksi bertambah, dan over-privileged network access (user VPN dapat memindai seluruh subnet internal).
Solusi standar industri: Zero Trust Network Access (ZTNA) lewat Identity-Aware Proxy (IAP). Prinsip utama: never trust, always verify. Reverse proxy (Traefik v3) mencegat seluruh masuk HTTP request pada Layer 7. Traefik memverifikasi identitas dan hak akses user ke Identity Provider (Authentik) sebelum meneruskan traffic ke service backend internal.
Mekanisme Kerja ForwardAuth Layer 7
Alur verifikasi identitas IAP saat request masuk:
- Step 1: Request Client. User akses URL
dashboard.example.com. Traffic masuk ke Traefik v3 via port 443 (TLS/SSL). - Step 2: Intersepsi Middleware. Router Traefik panggil middleware
ForwardAuth. Traefik kirim sub-request HTTP internal ke endpoint Authentik Outpost. - Step 3: Cek Sesi Authentik. Authentik periksa session cookie user. Jika valid dan terotentikasi, Authentik kirim response
HTTP 200 OK. Jika tidak valid, Authentik kirim responseHTTP 302 Founduntuk redirect browser ke halaman login SSO Authentik. - Step 4: Otentikasi User & MFA. User masukkan kredensial dan kode TOTP/WebAuthn di halaman SSO Authentik. Setelah valid, Authentik terbitkan session cookie terenkripsi.
- Step 5: Injeksi Header & Meneruskan Request. Authentik kembalikan status
HTTP 200 OKke Traefik beserta header identitas (X-authentik-username,X-authentik-email,X-authentik-groups). Traefik teruskan request asli beserta header terverifikasi ke service internal.
Persiapan VPS & Deployment via Docker Compose
Prasyarat Infrastruktur Server
- VPS Linux OS Ubuntu 22.04 LTS atau 24.04 LTS. Minimal 2 vCPU Core, 4GB RAM.
- IP Publik Statis terpasang pada interface jaringan VPS.
- Domain aktif. DNS Record A Wildcard
*.example.comdanexample.commengarah ke IP publik VPS. - Docker Engine v24.0+ dan Docker Compose v2.20+ terpasang.
- Port HTTP 80 dan HTTPS 443 terbuka di security group firewall server.
Struktur Direktori Project
Jalankan command terminal untuk buat hirarki folder setup:
mkdir -p /opt/containers/edge-proxy/{traefik,authentik}
cd /opt/containers/edge-proxy
Konfigurasi Engine Traefik v3 (traefik.yml)
Buat file traefik/traefik.yml untuk mengatur routing global, entrypoints, resolver SSL Let's Encrypt, dan integrasi Docker Provider:
api:
dashboard: false
entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: websecure
scheme: https
permanent: true
websecure:
address: ":443"
http:
tls:
certResolver: letsencrypt
certificatesResolvers:
letsencrypt:
acme:
email: admin@example.com
storage: /etc/traefik/acme.json
httpChallenge:
entryPoint: web
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
Konfigurasi Environment Authentik (.env)
Buat file authentik/.env. Generate kunci rahasia dan password database menggunakan OpenSSL:
PG_PASS=SecretPostgresPassword123!
AUTHENTIK_SECRET_KEY=GenerateRandomSecretKeyHere36CharsLong
AUTHENTIK_ERROR_REPORTING__ENABLED=false
AUTHENTIK_POSTGRESQL__HOST=postgresql
AUTHENTIK_POSTGRESQL__USER=authentik
AUTHENTIK_POSTGRESQL__NAME=authentik
AUTHENTIK_POSTGRESQL__PASSWORD=SecretPostgresPassword123!
AUTHENTIK_REDIS__HOST=redis
Stack Deployment (docker-compose.yml)
Buat file docker-compose.yml pada path root /opt/containers/edge-proxy:
version: '3.8'
networks:
proxy-net:
name: proxy-net
driver: bridge
services:
traefik:
image: traefik:v3.0
container_name: traefik
restart: unless-stopped
security_opt:
- no-new-privileges:true
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./traefik/traefik.yml:/etc/traefik/traefik.yml:ro
- ./traefik/acme.json:/etc/traefik/acme.json
networks:
- proxy-net
postgresql:
image: docker.io/library/postgres:16-alpine
container_name: authentik-db
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"]
start_period: 20s
interval: 30s
retries: 5
timeout: 5s
volumes:
- ./authentik/db:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: ${PG_PASS}
POSTGRES_USER: authentik
POSTGRES_DB: authentik
env_file:
- ./authentik/.env
networks:
- proxy-net
redis:
image: docker.io/library/redis:alpine
container_name: authentik-redis
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
start_period: 20s
interval: 30s
retries: 5
timeout: 5s
networks:
- proxy-net
authentik-server:
image: ghcr.io/goauthentik/server:2024.4.1
container_name: authentik-server
restart: unless-stopped
command: server
environment:
AUTHENTIK_REDIS__HOST: redis
AUTHENTIK_POSTGRESQL__HOST: postgresql
AUTHENTIK_POSTGRESQL__USER: authentik
AUTHENTIK_POSTGRESQL__NAME: authentik
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}
volumes:
- ./authentik/media:/media
- ./authentik/custom-templates:/templates
env_file:
- ./authentik/.env
ports:
- "9000:9000"
- "9443:9443"
depends_on:
postgresql:
condition: service_healthy
redis:
condition: service_healthy
networks:
- proxy-net
labels:
- "traefik.enable=true"
- "traefik.http.routers.authentik.rule=Host(`auth.example.com`)"
- "traefik.http.routers.authentik.entrypoints=websecure"
- "traefik.http.routers.authentik.tls.certresolver=letsencrypt"
- "traefik.http.services.authentik.loadbalancer.server.port=9000"
authentik-worker:
image: ghcr.io/goauthentik/server:2024.4.1
container_name: authentik-worker
restart: unless-stopped
command: worker
environment:
AUTHENTIK_REDIS__HOST: redis
AUTHENTIK_POSTGRESQL__HOST: postgresql
AUTHENTIK_POSTGRESQL__USER: authentik
AUTHENTIK_POSTGRESQL__NAME: authentik
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}
user: root
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./authentik/media:/media
- ./authentik/certs:/certs
- ./authentik/custom-templates:/templates
env_file:
- ./authentik/.env
depends_on:
postgresql:
condition: service_healthy
redis:
condition: service_healthy
networks:
- proxy-net
Inisialisasi izin file sertifikat Let's Encrypt dan jalankan seluruh container stack:
touch traefik/acme.json && chmod 600 traefik/acme.json
docker compose up -d
Konfigurasi Middleware ForwardAuth & SSO OIDC
Langkah 1: Setup Awal Administrator Authentik
- Buka browser, akses URL
https://auth.example.com/if/flow/initial-setup/. - Buat kredensial admin utama (email dan password).
- Masuk ke dashboard Admin Interface.
Langkah 2: Konfigurasi Provider & Application di Authentik Panel
- Navigasi ke menu Applications > Providers > Klik tombol Create.
- Pilih opsi Proxy Provider. Klik Next.
- Isi parameter Provider:
- Name:
Provider-ForwardAuth-Single - Authorization flow:
default-provider-authorization-implicit-consent - External host:
https://auth.example.com - Mode:
Forward auth (single application)
- Name:
- Klik Finish untuk menyimpan provider.
- Navigasi ke menu Applications > Applications > Klik Create.
- Isi parameter Application:
- Name:
Internal Dashboard Proxy - Slug:
internal-dashboard - Provider: Pilih
Provider-ForwardAuth-Single
- Name:
- Klik Save.
Langkah 3: Integrasi Traefik Middleware via Docker Labels
Pasang label Traefik ForwardAuth pada service backend yang ingin dilindungi (contoh: service whoami-internal atau portainer). Tambahkan definisi service ke docker-compose.yml:
whoami-internal:
image: traefik/whoami
container_name: whoami-internal
restart: unless-stopped
networks:
- proxy-net
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`dashboard.example.com`)"
- "traefik.http.routers.whoami.entrypoints=websecure"
- "traefik.http.routers.whoami.tls.certresolver=letsencrypt"
# Pasang Middleware ForwardAuth
- "traefik.http.routers.whoami.middlewares=authentik-auth@docker"
# Definisi Middleware ForwardAuth Authentik Outpost
- "traefik.http.middlewares.authentik-auth.forwardauth.address=http://authentik-server:9000/outpost.goauthentik.io/auth/traefik"
- "traefik.http.middlewares.authentik-auth.forwardauth.trustForwardHeader=true"
- "traefik.http.middlewares.authentik-auth.forwardauth.authResponseHeaders=X-authentik-username,X-authentik-groups,X-authentik-email,X-authentik-name,X-authentik-uid"
Deploy pembaruan konfigurasi stack:
docker compose up -d
Uji akses melalui browser ke https://dashboard.example.com. Traefik otomatis memicu intersepsi dan mengalihkan browser ke https://auth.example.com untuk autentikasi SSO.
Hardening Keamanan Session, Rate Limiting, & Network
Penutupan Port Publik via UFW Firewall
Port internal 9000 dan 9443 (Authentik direct UI) serta port 5432 (PostgreSQL) dan 6379 (Redis) tidak boleh diakses publik. Hanya port 80 (HTTP redirect) dan 443 (HTTPS) yang diizinkan masuk dari publik.
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
Catatan Penting Security: Docker memodifikasi tabel iptables secara langsung dan mengabaikan rule UFW default. Penggunaan opsi ports: - "80:80" hanya mempublikasikan Traefik. Jangan menambahkan pemetaan port ports: pada service backend internal agar tidak bisa diakses langsung via IP VPS (misal: http://IP-VPS:8080).
Traefik Rate Limiting Middleware
Mencegah serangan brute force login dan serangan layer 7 DDoS pada endpoint autentikasi. Deklarasikan middleware rate-limit di labels authentik-server pada docker-compose.yml:
labels:
- "traefik.enable=true"
- "traefik.http.routers.authentik.rule=Host(`auth.example.com`)"
- "traefik.http.routers.authentik.entrypoints=websecure"
- "traefik.http.routers.authentik.tls.certresolver=letsencrypt"
- "traefik.http.routers.authentik.middlewares=ratelimit-auth@docker"
# Rate Limit: Rata-rata 10 request/detik, burst 20 request
- "traefik.http.middlewares.ratelimit-auth.ratelimit.average=10"
- "traefik.http.middlewares.ratelimit-auth.ratelimit.burst=20"
- "traefik.http.services.authentik.loadbalancer.server.port=9000"
Pengaturan Cookie & Kebijakan Multi-Factor Authentication (MFA)
Buka Authentik Admin Panel (System > Settings):
- Cookie Domain: Set nilai ke
example.com(root domain). Pengaturan ini memastikan Single Sign-On (SSO) session berlaku universal di seluruh sub-domain (dashboard.example.com,grafana.example.com). - Session Lifetime: Set durasi token maksimum
hours=8untuk mewajibkan re-otentikasi harian saat jam kerja selesai. - Enforce Mandatory MFA: Masuk ke Flows & Stages > Flows > Edit
default-authentication-flow. Tambahkan Stagedefault-authentication-mfa-validationsebagai langkah wajib. Paksa seluruh pengguna mendaftarkan TOTP (Google Authenticator) atau WebAuthn/FIDO2 YubiKey saat login pertama kali.
Verifikasi & Testing Koneksi Zero Trust
Lakukan verifikasi status HTTP header dari terminal luar VPS menggunakan curl:
curl -Iv https://dashboard.example.com
Output sukses verifikasi:
- Response HTTP status code awal:
HTTP/2 302. HeaderLocationmengarah kehttps://auth.example.com/if/flow/default-provider-authorization-implicit-consent/.... - Setelah login Authentik sukses, response pada backend menerima header internal:
X-Authentik-Username: admin,X-Authentik-Email: admin@example.com. Port backendwhoami-internalterbukti aman tanpa terekspos langsung ke IP publik server.
Kesimpulan
Kombinasi Traefik v3 dan Authentik menghadirkan arsitektur Identity-Aware Proxy (Zero Trust) yang tangguh di lingkungan VPS Linux. Seluruh service internal terisolasi penuh dari internet publik tanpa memerlukan koneksi VPN client yang rumit. Manajemen identitas terpusat, penegakan MFA wajib, dan proteksi jaringan Layer 7 meminimalkan attack surface server dari ancaman pemindaian otomatis dan eksploitasi zero-day.


