Homelab sunucumdaki servis sayısı çift hanelere ulaştığında, her bir uygulama için ayrı şifre yönetmek ve hangisinde iki aşamalı doğrulamanın (2FA) aktif olduğunu takip etmek tam bir operasyonel yük haline gelmişti. Tarayıcıda açık kalan sekmeler, her servis için ayrı veritabanlarında tutulan kullanıcı tabloları ve yerel ağda bile olsa şifrelerin açık gitme riski beni tek bir merkezi kimlik doğrulama noktası kurmaya zorladı. Bu yazıda, yerel ağınızda veya dış dünyaya açık servislerinizde güvenliği en üst seviyeye çıkaracak Homelab’ında Tek Giriş (SSO) mimarisini Authentik kullanarak nasıl sıfırdan inşa edeceğimizi anlatıyorum.
Bu rehberi tamamladığınızda, Docker üzerinde koşan tüm servislerinizin önünde tek bir kimlik doğrulama duvarı olacak. Kullanıcılar bir kez giriş yaptıktan sonra yetkileri dahilindeki tüm iç servislere (Portainer, Grafana, Home Assistant vb.) şifre girmeden, sadece tek bir OTP (One-Time Password) veya donanımsal anahtar kullanarak erişebilecekler.
Homelab’ında Tek Giriş (SSO) İhtiyacı Nereden Doğuyor?
Yerel ağda çalışan servislerin birçoğu ya varsayılan olarak kimlik doğrulamadan yoksun geliyor ya da sundukları yerleşik login mekanizmaları kaba kuvvet (brute-force) saldırılarına karşı korumasız oluyor. Kendi sunucumda çalıştırdığım basit bir monitoring arayüzünün bile internete sızması durumunda tüm ağ topolojimi açığa çıkarabileceğini fark ettiğimde, her servisin önüne bir güvenlik katmanı koymanın şart olduğunu anladım. Homelab’ında Tek Giriş (SSO) yapısı kurmak, sadece şifre ezberleme zahmetinden kurtarmıyor; aynı zamanda tüm ağ trafiğini tek bir kapıdan geçirerek loglamayı ve izlemeyi de standartlaştırıyor.
Geleneksel olarak her uygulamaya tek tek güçlü şifreler tanımlamak sürdürülebilir bir yöntem değildir. Bir servisin güncellemesi aksadığında veya zero-day zafiyeti çıktığında, o servisin login ekranı doğrudan saldırganların hedefi haline gelir. SSO mimarisi sayesinde, uygulamanın kendi login mekanizmasını tamamen devre dışı bırakıp (veya bypass edip) kimlik doğrulama yükünü tamamen bu iş için özelleştirilmiş, sürekli güncellenen ve güvenlik standartlarına (OAuth2, OIDC, SAML) sadık kalan bir araca devrediyoruz.
graph TD; User["Kullanıcı"] --> Proxy["Nginx Reverse Proxy"] Proxy -->|Auth Check| Authentik["Authentik SSO (2FA)"] Authentik -->|Onay/Token| Proxy Proxy -->|Yönlendirme| ServiceA["Portainer (Servis A)"] Proxy -->|Yönlendirme| ServiceB["Grafana (Servis B)"]
Authentik Nedir ve Neden Diğer Alternatiflere Karşı Tercih Ettim?
Piyasada Authelia, Keycloak ve Authentik gibi popüler açık kaynaklı kimlik doğrulama çözümleri bulunuyor. Keycloak kurumsal dünyada standart olsa da kaynak tüketimi (JVM tabanlı olması sebebiyle) ve homelab ölçeğindeki karmaşık arayüzü benim gibi minimal kaynakla maksimum performans almak isteyenler için biraz ağır kalıyor. Authelia ise son derece hafif ve başarılı bir alternatif olmasına rağmen, görsel bir yönetim arayüzünün olmaması ve tüm konfigürasyonun YAML dosyaları üzerinden yapılması, dinamik olarak yeni servis eklerken veya kullanıcı yönetirken süreci hantallaştırıyor.
Authentik, bu iki dünyanın en iyi yönlerini bir araya getiriyor. Python ve Go ile yazılmış modern mimarisi, zengin bir web arayüzü sunarken aynı zamanda arka planda son derece esnek politikalar (policies) ve akışlar (flows) tanımlamanıza izin veriyor. Outpost mimarisi sayesinde reverse proxy entegrasyonunu (Forward Auth) yerleşik olarak destekliyor ve yerel ağınızdaki LDAP/Active Directory gibi dizin servisleriyle de sorunsuz konuşabiliyor.
Authentik Kurulumu: Docker Compose ile Ayaklandırma
Authentik’i en kararlı şekilde çalıştırmanın yolu Docker Compose kullanmaktır. Kuruluma başlamadan önce sunucunuzda Docker ve Docker Compose eklentisinin kurulu olduğundan emin olun. Authentik; bir web sunucusu (server), bir arka plan işleyicisi (worker), önbellekleme için Redis ve veri saklama için PostgreSQL veritabanı olmak üzere birkaç bileşenden oluşur.
Aşağıdaki docker-compose.yml dosyası, homelab ortamı için optimize edilmiş, yerel volume paylaşımları içeren ve dışarıdan gelebilecek ataklara karşı izole edilmiş bir ağ yapısını tanımlar.
version: '3.8'
services:
postgresql:
image: postgres:16-alpine
container_name: authentik-postgres
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:
- pgdata:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: ${PG_PASS:?database password required}
POSTGRES_USER: ${PG_USER:-authentik}
POSTGRES_DB: ${PG_DB:-authentik}
env_file:
- .env
redis:
image: redis:7-alpine
container_name: authentik-redis
command: --save 60 1 --loglevel warning
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
start_period: 20s
interval: 30s
retries: 5
timeout: 3s
volumes:
- redisdata:/data
server:
image: ghcr.io/goauthentik/server:2026.5.1
container_name: authentik-server
restart: unless-stopped
command: start
environment:
AUTHENTIK_REDIS__HOST: redis
AUTHENTIK_POSTGRESQL__HOST: postgresql
AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
volumes:
- ./media:/media
- ./custom-templates:/templates
env_file:
- .env
ports:
- "${AUTHENTIK_PORT_HTTP:-9000}:9000"
- "${AUTHENTIK_PORT_HTTPS:-9443}:9443"
depends_on:
postgresql:
condition: service_healthy
redis:
condition: service_healthy
worker:
image: ghcr.io/goauthentik/server:2026.5.1
container_name: authentik-worker
restart: unless-stopped
command: start_worker
environment:
AUTHENTIK_REDIS__HOST: redis
AUTHENTIK_POSTGRESQL__HOST: postgresql
AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
user: root
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./media:/media
- ./certs:/certs
- ./custom-templates:/templates
env_file:
- .env
depends_on:
postgresql:
condition: service_healthy
redis:
condition: service_healthy
volumes:
pgdata:
driver: local
redisdata:
driver: local
Bu konfigürasyonu çalıştırmadan önce aynı dizinde bir .env dosyası oluşturmamız gerekiyor. Bu dosyada şifreleme anahtarları ve veritabanı bilgileri yer alacak. AUTHENTIK_SECRET_KEY değerini üretmek için terminalde openssl rand -base64 36 komutunu kullanabilirsiniz.
PG_PASS=U7yK9pX2wZ4mQ1sN_Sifre_Uretin
PG_USER=authentik
PG_DB=authentik
AUTHENTIK_PORT_HTTP=9000
AUTHENTIK_PORT_HTTPS=9443
AUTHENTIK_SECRET_KEY=openssl_ile_urettiginiz_secure_key
AUTHENTIK_ERROR_REPORTING__ENABLED=false
docker compose up -d komutu ile tüm stack’i ayağa kaldırabilirsiniz. Servislerin tamamen hazır hale gelmesi bir dakika kadar sürebilir. Tarayıcınızdan http://<sunucu-ip-adresiniz>:9000/if/flow/initial-setup/ adresine giderek ilk yönetici (admin) hesabınızı oluşturun.
Reverse Proxy Entegrasyonu: Nginx Proxy Manager ve Authentik Forward Auth
SSO sisteminin kalbi, gelen tüm istekleri karşılayan ve Authentik’e “Bu kullanıcı giriş yapmış mı?” diye soran reverse proxy katmanıdır. Ben homelab ortamında esnekliği ve kolay yönetimi nedeniyle Nginx Proxy Manager (NPM) veya doğrudan saf Nginx kullanıyorum. Authentik ile proxy entegrasyonunu sağlamak için Forward Auth veya Proxy Provider yöntemlerinden birini seçmeliyiz.
Forward Auth yöntemi, Nginx’in her istekte Authentik’in hafif bir kontrol endpoint’ine (Outpost) HTTP alt isteği (subrequest) göndermesi prensibiyle çalışır. Eğer kullanıcı doğrulanmışsa, Nginx isteğin asıl hedefe gitmesine izin verir; doğrulanmamışsa kullanıcıyı Authentik login sayfasına yönlendirir.
Aşağıda, Nginx üzerinde korumaya almak istediğiniz herhangi bir servis (örneğin Portainer) için kullanabileceğiniz örnek bir custom_locations veya location bloğu yer alıyor:
# Authentik Forward Auth Entegrasyonu
location / {
# Kullanıcının asıl gitmek istediği yerel servis portu
proxy_pass http://192.168.1.50:9000;
# Authentik Outpost yönlendirmesi
auth_request /outpost.goauthentik.io/auth/nginx;
error_page 401 = @goauthentik_search_redirection;
# Auth isteğinden dönen kullanıcı bilgilerini header olarak servise aktar
auth_request_set $auth_cookie $upstream_http_set_cookie;
add_header Set-Cookie $auth_cookie;
auth_request_set $authentik_username $upstream_http_x_authentik_username;
proxy_set_header X-Remote-User $authentik_username;
}
location = /outpost.goauthentik.io/auth/nginx {
proxy_pass http://192.168.1.100:9000/outpost.goauthentik.io/auth/nginx;
proxy_set_header Host $host;
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Alt isteklerde body göndermeyerek bant genişliğini koru
proxy_pass_request_body off;
proxy_set_header Content-Length "";
}
location @goauthentik_search_redirection {
return 302 $scheme://$http_host/outpost.goauthentik.io/start?rd=$request_uri;
}
Uygulamaları SSO Arkasına Almak: Adım Adım Entegrasyon Süreci
Sistemi ayağa kaldırıp proxy ayarlarını yaptıktan sonra, Authentik panelinde uygulamalarımızı tanımlamamız gerekiyor. Authentik dünyasında her korunan servis bir Application ve bu uygulamaya nasıl erişileceğini tanımlayan bir Provider ile eşleşir.
| Terim | Açıklama | Homelab Örneği |
|---|---|---|
| Application | Kullanıcının göreceği uygulama kartı ve adı | Portainer, Grafana, Home Assistant |
| Provider | Kimlik doğrulama protokolü ve yetkilendirme tipi | OIDC, SAML, Forward Auth (Single App) |
| Outpost | Proxy isteklerini işleyen ve token doğrulayan servis | Authentik Embedded Outpost |
Uygulama ekleme adımları sırasıyla şu şekildedir:
- Provider Oluşturma: Authentik Admin arayüzünde
Applications -> Providersyolunu izleyin. “Create” butonuna tıklayın ve “Proxy Provider” seçeneğini seçin. - Ayarları Yapılandırma: Provider ismini girin. “Authorization flow” olarak varsayılan
default-provider-authorization-implicit-consentakışını seçin. “External host” alanına uygulamanın dışarıdan erişileceği tam URL’yi girin (örn.https://portainer.local.lan). - Application Tanımlama:
Applications -> Applicationsmenüsüne gidin. “Create with Provider” seçeneğini kullanarak yeni bir uygulama oluşturun. Az önce oluşturduğunuz Provider’ı bu uygulamaya bağlayın. - Outpost Güncelleme:
Applications -> Outpostssekmesinde yer alan “authentik Embedded Outpost” kaydını düzenleyin ve yeni oluşturduğunuz uygulamayı bu outpost’un “Applications” listesine ekleyin. Bu adım atlanırsa, proxy istekleri yetkilendirme hatası (500 veya 401) döndürecektir.
Multi-Factor Authentication (MFA/2FA) Yapılandırması ve Güvenlik Sıkılaştırma
Homelab’ınızın güvenliğini gerçekten bir üst seviyeye taşımak istiyorsanız, sadece kullanıcı adı ve şifre yeterli değildir. Authentik, yerleşik olarak TOTP (Google Authenticator, Aegis, Bitwarden) ve WebAuthn (Yubikey, Passkey, TouchID) destekler. Ben tüm kullanıcılarım için (aile üyeleri dahil) TOTP kullanımını zorunlu tutuyorum.
Bunu yapılandırmak için Authentik üzerindeki “Flows” (Akışlar) mekanizmasını kullanacağız. Flows and Stages -> Flows sekmesine gidin. default-authentication-flow akışını bulun. Bu akış, kullanıcıların sisteme giriş yaparken geçtiği aşamaları tanımlar.
MFA zorunluluğunu devreye sokmak için şu adımları uygulayın:
Flows and Stages -> Stageskısmından yeni bir “Authenticator Validation Stage” oluşturun. Burada hangi 2FA yöntemlerine izin vereceğinizi seçin (TOTP, WebAuthn).default-authentication-flowakışının içerisine girin ve “Bindings” sekmesine tıklayın.- Kullanıcı adı ve şifre aşamalarından hemen sonraya, az önce oluşturduğunuz “Authenticator Validation Stage” aşamasını ekleyin.
- Kullanıcılar ilk girişlerinde otomatik olarak bir QR kod ekranı ile karşılaşacak ve 2FA kurulumu yapmadan sisteme erişemeyeceklerdir.
Homelab SSO Altyapısında Karşılaşılan Yaygın Hatalar ve Çözümleri
Kendi kurulumlarımda ve çevremden aldığım geri bildirimlerde, SSO entegrasyonu sırasında en çok zaman kaybettiren konunun SSL sertifikaları ve yönlendirme döngüleri (redirect loops) olduğunu gördüm. Eğer tarayıcınız “Too many redirects” hatası veriyorsa, Nginx üzerindeki X-Forwarded-Proto header’ının doğru set edilmediğinden emin olun.
# Yönlendirme döngülerini engellemek için Nginx proxy bloklarına ekleyin
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
Bir diğer yaygın sorun ise Docker konteynerlerinin birbirleriyle konuşamamasıdır. Eğer Authentik sunucunuz ve Nginx Proxy Manager farklı Docker network’lerindeyse, Forward Auth istekleri 502 Bad Gateway hatası ile sonuçlanır. Çözüm için her iki servisi de ortak bir Docker network’üne (örneğin proxy-net) bağlamanız gerekir:
# Ortak network oluşturma
docker network create proxy-net
Ardından her iki servisinizin docker-compose.yml dosyasına bu network’ü harici (external) olarak tanımlayıp servislerin altına ekleyin. Bu sayede servisler birbirlerine IP adresleri yerine konteyner isimleri üzerinden güvenli bir şekilde erişebilirler.
Sonuç
Bu rehberle birlikte homelab ortamınızdaki karmaşık şifre yönetimini tarihe gömüp, tüm servislerinizi tek bir güvenli kapının arkasına topladınız. Authentik ile kurduğumuz bu Homelab’ında Tek Giriş (SSO) yapısı, gelecekte ekleyeceğiniz her yeni servis için güvenlik şablonunuzu standart hale getirecektir. Artık sadece tek bir güçlü şifre ve fiziksel güvenlik anahtarı (veya TOTP uygulaması) ile tüm yerel ağınızı güvenle yönetebilirsiniz.
Sonraki adımda, Authentik üzerinde kullanıcı grupları oluşturarak aile üyelerinize sadece belirli servislere (örneğin sadece Jellyfin veya Plex) erişim yetkisi vermeyi deneyebilirsiniz.