3 puan yazan GN⁺ 2024-02-12 | 1 yorum | WhatsApp'ta paylaş
  • Tek bir Linux VM üzerinde Keycloak’u rootless Docker ile izole çalıştırıp sistem nginx’inin TLS sonlandırma ve ters proxy görevini üstlendiği bir SSO dağıtım prosedürüdür
  • Ön koşullar: SSH erişimi, Keycloak için alan adı veya alt alan adı, A kaydı, parolasız keycloak kullanıcısı, /srv/keycloak home dizini ve Docker rootless kurulumudur
  • docker-compose.yml, postgres:16 ve quay.io/keycloak/keycloak:25.0.1 kullanır; Keycloak yalnızca 127.0.0.1:8080 adresine bind edilir ve parolalar ile KC_HOSTNAME .env üzerinden yönetilir
  • nginx, your.tld.com için HTTP isteklerini HTTPS’e yönlendirir ve proxy_pass ile iletir; Certbot sertifikası alındıktan sonra KC_PROXY_HEADERS: xforwarded etkinleştirilir
  • Özel tema veya --optimized çalıştırma gerekiyorsa çok aşamalı Dockerfile ile özel imaj oluşturulabilir; üretimde JGroups tampon boyutu ve Quarkus transaction recovery ayarları ayrıca ince ayarlanabilir

Dağıtım yapısı ve ön koşullar

  • Keycloak, web uygulamalarında kullanıcı yönetimi ve SSO’yu doğrudan uygulamanın zor olduğu durumlarda kullanılabilecek açık kaynak IAM seçeneklerinden biridir
  • OpenID Connect (OIDC), OAuth 2.0, SAML gibi başlıca SSO protokolleriyle birlikte çalışır
  • Yapılandırma Keycloak 23.0.6 temel alınarak yazılmış ve 25.0.5 sürümüne kadar test edilmiştir
  • Genel yapı, nginx’i merkezi ters proxy olarak konumlandırıp trafiği localhost üzerinden hizmetlere özel rootless Docker namespace’lerine aktarma biçimindedir
    • Web trafiği 0.0.0.0:80 ve 0.0.0.0:443 üzerinden gelir; nginx bunu 127.0.0.1:8080 üzerindeki Keycloak’a iletir
    • Amaç, tek bir host’un kaynaklarını paylaşırken servis ortamlarını ayıran ekonomik bir yapı kurmaktır

Hazırlık çalışmaları

  • Temel ortam olarak Linux VM, SSH ile uzaktan erişim ve Keycloak servisi için alan adı veya alt alan adı gerekir
    • Alan adı için A kaydı gerekir; isteğe bağlı olarak AAAA kaydı eklenebilir
  • Docker rootless temel kurulumu, ayrı Mastodon yazısındaki prosedürü izler
    • Parolasız yeni non-root keycloak kullanıcısı oluşturma
    • Home dizinini /srv/keycloak olarak ayarlama
    • /etc/subuid ve /etc/subgid içine keycloak kullanıcısı için aralık ekleme
    • dockerd-rootless-setuptool.sh ile Docker rootless kurulumu
    • keycloak kullanıcısı için otomatik servis başlatmayı ayarlama

Docker Compose ile Keycloak çalıştırma

  • Yeni oluşturulan keycloak kullanıcısına geçerken machinectl shell keycloak@ kullanılır
    • sudo -u keycloak -H bash yöntemi, XDG_RUNTIME_DIR ortam değişkeni hazırlanmadığı için kaçınılır
  • Kalıcı veri ve Docker dosya dizinleri önce oluşturulur
    • PostgreSQL veri yolu /srv/keycloak/data/postgres16
    • Docker dosyaları ~/docker altında tutulur
  • docker-compose.yml, resmi Keycloak imajını ve PostgreSQL’i doğrudan kullanır
    • PostgreSQL imajı postgres:16
    • Keycloak imajı quay.io/keycloak/keycloak:25.0.1
    • Üretim ortamında :latest yerine belirli bir imaj etiketi kullanılması önerilir
  • Keycloak konteynerinin başlıca ayarları şöyledir
    • KC_DB: postgres
    • KC_DB_URL: jdbc:postgresql://postgres_db/keycloak
    • KC_HOSTNAME: ${KC_HOSTNAME:-your.tld.com}
    • KC_HTTP_ENABLED: true
    • HTTP_ADDRESS_FORWARDING: true
    • KEYCLOAK_ADMIN: admin
    • Port yalnızca localhost’a, '127.0.0.1:8080:8080' olarak bind edilir
  • .env içinde hassas veya ortama göre değişen değerler tutulur
    • POSTGRES_PASSWORD
    • KEYCLOAK_ADMIN_PASSWORD
    • KC_HOSTNAME
  • ${KC_HOSTNAME:-your.tld.com} söz dizimi, .env içinde KC_HOSTNAME varsa o değeri kullanır; yoksa varsayılan olarak your.tld.com kullanılır
  • /srv/keycloak/data/postgres16, PostgreSQL kalıcı verilerini içerdiği için düzenli yedekleme kapsamına alınmalıdır
    • Tamamen sıfırlamak için ilgili PostgreSQL klasörü silinip yeniden oluşturulursa, bir sonraki başlangıçta tekrar oluşturulur
  • ~/docker bir Git deposu olarak yönetiliyorsa .env, .gitignore içine eklenebilir ve yalnızca docker-compose.yml commit edilebilir

Yerel test

  • Docker Compose stack’ini başlatıp logları kontrol edin
docker compose up -d && docker compose logs --follow
  • VM’deki Keycloak yerel portuna erişmek için ters SSH tüneli oluşturun
ssh you@111.11.11.11 -L :8080:127.0.0.1:8080 -p 22 -N -v
  • Tarayıcıda 127.0.0.1:8080 adresini açarak Keycloak karşılama ekranını kontrol edin

nginx ters proxy ve TLS

  • keycloak kullanıcısından çıkış yaptıktan sonra sistem nginx yapılandırmasına geçin
  • your.tld.com yerine gerçek alan adınızı yazın ve alan adı kayıt kuruluşunda A kaydı ekleyerek DNS sorgularının VM IP’sine gitmesini sağlayın
  • nginx site yapılandırma dosyasını oluşturup etkinleştirin
nano /etc/nginx/sites-available/your.tld.com.conf
ln -s /etc/nginx/sites-available/your.tld.com.conf /etc/nginx/sites-enabled/
  • nginx yapılandırması HTTP isteklerini HTTPS’e yönlendirir ve HTTPS server bloğunda Keycloak’a proxy eder
    • proxy_set_header Host $host
    • proxy_set_header X-Real-IP $remote_addr
    • proxy_set_header X-Forwarded-For $remote_addr
    • proxy_set_header X-Forwarded-Proto $scheme
    • proxy_pass http://127.0.0.1:8080
  • SSL ayarları için nginx için Mozilla SSL configurator kullanılarak nginx sürümüne uygun varsayılanların oluşturulması önerilir
  • Yapılandırmayı test ettikten sonra nginx’i yeniden yükleyin
nginx -t
systemctl reload nginx
  • Certbot ile sertifika alındığında your.tld.com.conf içindeki gerekli satırlar otomatik güncellenir
certbot --nginx -d your.tld.com
  • Ardından ssl_trusted_certificate /etc/letsencrypt/live/your.tld.com/chain.pem; satırını etkinleştirip nginx’i yeniden yükleyin
  • nginx arkasında çalışması için docker-compose.yml içindeki KC_PROXY_HEADERS: xforwarded değerini etkinleştirip Docker stack’ini yeniden başlatın
docker compose down && docker compose up -d && docker compose logs --follow

Hata ayıklama yolu

  • Yapılandırmadan sonra your.tld.com adresine bağlanıp .env içindeki parolayla admin kullanıcısının girişini doğrulayın
  • İlk kontrol noktası Docker Compose loglarıdır
docker compose logs --follow
  • nginx erişim ve hata loglarını aşağıdaki dosyaları izleyerek kontrol edin
tail -f /var/log/nginx/your.tld.com-access.log
tail -f /var/log/nginx/your.tld.com-error.log
  • Keycloak veritabanını doğrudan kontrol etmek gerekirse keycloak kullanıcısına geçip PostgreSQL konteyneri içinde psql çalıştırın
machinectl shell keycloak@
cd ~/docker
docker compose exec postgres_db /bin/bash
psql -h localhost -p 5432 -U keycloak keycloak

Özel imaj ve optimized çalıştırma

  • Temel yapılandırma, quay.io üzerindeki önceden derlenmiş imajı kullanır
  • Tema özelleştirmesi veya --optimized modunda çalıştırma gerekiyorsa özel imaj derlenir
  • Dockerfile, resmi Keycloak imajını temel alarak çok aşamalı build kullanır
    • builder aşamasında ENV KC_DB=postgres ayarlanır
    • /opt/keycloak/bin/kc.sh build çalıştırılır
    • Son imaja /opt/keycloak/ kopyalanır
    • ENTRYPOINT ["/opt/keycloak/bin/kc.sh"] belirtilir
  • docker-compose.yml içinde şu şekilde değiştirilir
    • image: satırını kaldırın veya yorum satırı yapın
    • build: . değerini etkinleştirin
    • command: start --optimized ekleyin
  • Ardından Docker stack’ini kapatın, isteğe bağlı olarak açıkça build çalıştırın ve tekrar başlatın
docker compose down
docker compose build
docker compose up -d && docker compose logs --follow

Üretim ortamında ek ayarlanan öğeler

  • JGroups ile ilgili MulticastSocket alma tamponu uyarısı, host’taki /etc/sysctl.conf dosyasına tampon değerleri eklenerek çözülür
net.core.rmem_max = 26214400
net.core.wmem_max = 1048576
  • Ayarları uygulamak için sysctl -p çalıştırılır
  • Quarkus XA transaction recovery uyarısı, Keycloak servisine volume mount ve ortam değişkeni eklenerek çözülür
    • Volume: /srv/keycloak/data/keycloak/ObjectStore/:/ObjectStore/
    • Ortam değişkeni: QUARKUS_TRANSACTION_MANAGER_ENABLE_RECOVERY: true
  • Başlamadan önce host üzerinde ObjectStore dizinini oluşturun ve konteyner içinde /ObjectStore sahibini kullanıcı ID’si 1000 olacak şekilde değiştirin

Yapılandırma sonrası adımlar

  • Son durumda, rootless Docker içindeki Keycloak servisi sistem nginx ters proxy’sinin arkasında çalışır ve nginx SSL sonlandırmadan sorumlu olur
  • Otomatik konteyner güncellemeleri için ayrı Mastodon yazısındaki otomatik güncelleme prosedürüne bakılır
  • Sonraki yapılandırma adımı, Keycloak yönetici konsolunda e-posta eklemektir
  • Daha sonra realm ekleme ve tema ayarları yapılabilir
    • Tema için keycloakify ve keycloakify-starter kullanılabilir
    • Dockerfile içinde keycloakify tema JAR’ını /opt/keycloak/providers/ altına kopyalayan yorum satırı hâlinde bir satır bulunur

1 yorum

 
GN⁺ 2024-02-12
Hacker News yorumları
  • Yakın zamanda homelab’ime kimlik doğrulama eklerken Authelia’yı seçtim
    Keycloak da çalışıyor ama fazlasıyla büyük; traefik forward auth ile kullanmak için de ek bir servise daha ihtiyaç duyuyor
    Authelia’da kullanıcı düzenleme UI’ı yok ve arka uç LDAP sunucusuyla çift yönlü senkronizasyon da yapmıyor; ancak yalnızca statik dosyalar ve ortam değişkenleriyle yapılandırılabildiği için birçok durumda iyi uyuyor
    Birkaç servise kimlik doğrulama eklemek ve destekleyen servislere SSO bağlamak gibi bir hedefiniz varsa Authelia ile başlamak denemeye değer

    • FusionAuth’ta çalışıyorum
      SSO, kolay kurulum ve yönetici UI’ı gerekiyorsa FusionAuth’a da bakmaya değer. UI/UX’i 2000’lerin ortası hissi verse de indirip kendiniz çalıştırabilirsiniz[0], Docker dostudur[1] ve OIDC ya da diğer ayarları Terraform[3] ile yönetmek gibi çeşitli yapılandırma yöntemleri[2] sunar
      Ücretsiz kullanılabilir ama açık kaynak değildir[4]
      0: https://fusionauth.io/download
      1: https://fusionauth.io/docs/get-started/download-and-install/...
      2: https://fusionauth.io/docs/operate/deploy/configuration-mana...
      3: https://fusionauth.io/docs/operate/deploy/terraform
      4: https://fusionauth.io/license-faq#28
    • Authelia’yı 2 yılı aşkın süredir çalıştırıyorum ve hafif LDAP uygulaması LLDAP[0] ile LDAP entegrasyonu kurdum
      Caddy’yi reverse proxy olarak kullanıp Authelia ile entegre ettim[1], gayet iyi çalışıyor
      Tüm servislere sağlam iki faktörlü kimlik doğrulama ekledim ve kendi barındırdığım uygulamalara VPN olmadan erişmenin de yeterince güvenli olduğunu hissediyorum
      Ancak Authelia’nın 1 yıldan uzun süredir yeni sürüm yayımlamaması güvenlik açısından beni endişelendiriyor
      [0] https://github.com/lldap/lldap
      [1] https://www.authelia.com/integration/proxies/caddy/
    • Yakın zamanda benzer bir yoldan geçtim; kişisel olarak Caddy eklentisi caddy-security’yi[1] seçtim
      [1] https://github.com/greenpau/caddy-security
    • Authelia’nın küçük kurulum ölçeği gibi çok kendine özgü bir avantajı var; Keycloak veya authentik bu alana kolay kolay iyi oturmuyor
      Homelab ortamı için çok iyi bir kullanım senaryosu ve daha büyük çözümlerin özelliklerine ihtiyacınız yoksa ya da istemiyorsanız özellikle uygun
    • Konu dışı sayılır ama bugünlerde LDAP alternatifi olup olmadığını merak ediyorum
      Arayınca basit şema, JSON, HTTP gibi bir şey bulamıyorum; neredeyse her şeyi baştan yapan insanların LDAP’ı yeniden yapmamış olmasına inanamıyorum
      Bildiğim kadarıyla fiilen diğer tek standart Active Directory
      Ayrıca erişim denetimini dışarıya devretmek için bir standart ya da protokol olup olmadığını da merak ediyorum
      Authelia URL kalıplarıyla erişimi denetleyebiliyor; ama örneğin bir dosya sunucusu söz konusuysa, kimliği doğrulanmış kullanıcı ID’si ve veritabanındaki anahtara göre LDAP sunucusundan yetki kontrolü yapmasını beklerdim
      Bu, sunucunun üçüncü taraf servise erişim yetkisi aldığı OAuth2’nin ters yönü gibi görünüyor
  • Yakın zamanda homelab'imde nispeten basit bir SSO kurmak için araştırma yaptım; ana hedefim Google ya da GitHub kimlik doğrulamasıyla kolayca oturum açabilmekti
    Önceki işimde hem JetBrains Hub[1] hem de Keycloak kullanmıştım; ikisinin de ayarı epey zahmetliydi
    JetBrains Hub'a başlamak gerçekten kolaydı ve önceki deneyimim de böyleydi, ancak Docker registry'sinde latest etiketinin olmaması can sıkıcıydı
    Sürüm sabitlemenin iyi olduğunu biliyorum ama kişisel kullanımda genelde tüm Docker container'larını tek seferde güncellemek istiyorum
    Buna karşılık Keycloak'a başlamak çok zahmetliydi; geliştirme modunda kolaydı ama production yapılandırmasında takıldım
    Hatırladığım kadarıyla wildcard Let's Encrypt sertifikasıyla ilgiliydi ve birkaç saat sonra vazgeçtim
    Sonunda Dex[2]'i seçtim. Dokümantasyon eksik olduğu için ertelemiştim ama gerçek kurulum çok kolaydı; temel bir YAML, SQLite veritabanı ve bir subdomain yeterli oldu
    Dex'i harika OAuth2 Proxy[3] ve özel bir Nginx Proxy Manager şablonuyla birleştirerek her dahili servis için iki satırlık SSO ayarı haline getirdim; unRAID için Dex Docker şablonu[4] da oluşturdum
    Buna ev dışından erişim için Cloudflare Access ve WAF ekleyerek güvenliği güçlendirdim; biraz daha fazla içgörü elde etmek için yalnızca CrowdSec eklemek istiyorum

    1. https://www.jetbrains.com/hub/
    2. https://dexidp.io/
    3. https://github.com/oauth2-proxy/oauth2-proxy
    4. https://github.com/alex3305/unraid-docker-templates
    • obligator'ı geçici depolama, veritabanı yok ve %100 kod tabanlı ayarla kullanıyorum
      Şahsen bunun en basit seçenek olduğunu düşünüyorum
      https://github.com/lastlogin-io/obligator
    • oauth2-proxy'nin Dex'te olmayan hangi özellikleri sunduğunu merak ediyorum
  • Kendi barındırabileceğiniz çeşitli OpenID Connect sunucuları için tamamlanmamış bir karşılaştırma tablosu hazırladım[0]
    Şaşırtıcı noktalardan biri, Keycloak kod tabanının gerçekten devasa olmasıydı
    [0]: https://github.com/lastlogin-io/obligator?tab=readme-ov-file...

  • Keycloak'ın güvenlik sorunlarını çözdüğünü düşünmek komik
    CVE listesine bakarsanız ne demek istediğimi anlarsınız

  • En azından ilgili yazıda https://www.keycloakify.dev/'dan bahsedilmiş olması çok faydalı
    Standart tema yaklaşımına harika bir alternatif gibi görünüyor

    • Harika bir proje
      2 yıldır kullanıyorum ve hakkında söyleyecek yalnızca iyi şeylerim var
      Bakımcısı çok hızlı yanıt veriyor; yakın zamanda hem Keycloak hem de keycloakify tarafında tema yönteminin geleceğe dönük uyumluluğunu artıran değişiklikler de yapıldı
      Şu anda resmî olarak yalnızca create-react-app ile oluşturulmuş uygulamalar destekleniyor, ancak vite branch geliştirme aşamasında ve ben şahsen bir süredir vite ile birlikte kullanıyorum
    • Rakip bir şirkette çalışıyorum ve tema sistemini yeniden elden geçiriyoruz; bu projeyi inceleyip yeniden çalışma modeli olarak almak iyi görünüyor
  • authentik[1] ve authelia[2] dikkatimi çekiyor
    Authelia çok iyi görünüyor, ancak Keycloak’ın Angular için bir bağlayıcısı varken Authelia’da örneğin OIDC Angular eklentisini kendiniz yapılandırmanız gerektiği için biraz temkinliydim
    Yine de Keycloak için bir yapılandırma varsa başlangıç daha kolay olur gibi
    [1] https://goauthentik.io/
    [2] https://www.authelia.com/

    • authentik’i düşünen biri varsa “ejderhaların kol gezdiği yer” diye uyarmak isterim
      Docker ve Kubernetes’te sürekli 10’dan fazla servisi koruyorum; her servis için koruma ayarını bağımsız yapmaktan hoşlanmıyorsanız authentik’te zorlanırsınız
      authentik’te birden fazla alt alan adını (app1.example.com, app2.example.com vb.) tek bir ayarla korurken, oturum süresi dolduktan sonra yeniden kimlik doğrulaması yapıldığında kullanıcının rastgele başka bir servise yönlendirilmesine neden olan ciddi bir hata[0] var
      [0]: https://github.com/goauthentik/authentik/issues/6886
    • Authentik, OAuth client credentials grant uygulamasını tamamen berbat etmiş
      Uyumluluğu bozan bir değişiklik yapmadan düzeltilemiyor ve cc grant kullanan birçok araçla çalışmıyor
      Bunu gördükten sonra aday listesinden tamamen çıkardım
      https://github.com/goauthentik/authentik/issues/6139
    • Authelia’nın çekirdek bakımcılarından biriyim
      Angular yapılandırmasında yardımcı olabileceğim bir şey varsa GitHub Discussions üzerinden memnuniyetle yardımcı olurum
    • Şu anda benzer bir karar vermeye çalışıyorum
      Authentik daha iyi görünüyordu, ama diğer yanıtta bahsedilen hata epey kötü görünüyor
  • Keycloak’ın sorunu eski bir proje olması ve bu yüzden inanılmaz çok değişim geçirmiş olması
    Bir JBOSS projesi olarak başladı; IdP olarak faydası şirket içi küme kimlik doğrulamasında parlıyor ama bence oraya kadar
    Bir Fortune 500 bölümünde AWS ECS üzerinde Keycloak’ı büyük ölçekte hayata geçirdim; düzgün kümelenmesini sağlama süreci adeta bin yıl savaşları gibiydi
    DNS discovery düzgün çalışmıyordu, cluster discovery ise UDP tabanlı olduğu için bulut ortamında çalışmıyordu
    Bir sunucudaki durum tutan oturum açma bilgisi diğer sunucuda olmadığından basit yük dengeleme mümkün değildi; tek seçenek sticky session idi
    Keycloak’ı docker run ile ayağa kaldırıp Auth0 gibi tak-çalıştır kullanmak kolay, ama 250 bin mil yapmış 1996 model bir Ford F-150 satın almak gibi
    Gidiyor ve çalışıyor, ama bakımı gerçekten korkunç

    • Daha küçük ölçekte olsa da şirket içi Docker Swarm içinde denemiştim ve gerçekten sancılıydı
      Hatırladığım kadarıyla varsayılan discovery yöntemi multicast kullanıyor, ancak bu tipik bulut ağlarında veya Swarm/Kubernetes overlay ağlarında etkin değil
      RDBMS’i bir tür quorum mekanizması olarak kullanan database ping’i de gördüm ama çok kırılgan görünüyordu, son çare gibi hissettirdi
      Sonunda Swarm kümesinin DNS’iyle düğümleri bulan Kubernetes cluster driver’ını kullanabildim
      Çalışır hale getirmek epey uğraştırdı, ama ondan sonra bildiğim kadarıyla stabil
      Şimdilerde yerel bir EC2 networking driver da var gibi, ama kendim incelemedim
    • Tamamen Quarkus’a taşındıktan sonra iyileşmeler olduğunu duydum
      ECS dağıtımını ne zaman yaptığınızı merak ettim
    • OAuth ve OpenID Connect ile realm’e uygulama ve client ekleyebilmek Keycloak’ın kurtarıcı yanıydı; onu elde tutmamızın tek nedeni buydu
    • Cluster discovery’nin UDP olması kulağa acı verici geliyor
      Bizde UDP yalnızca DNS için izinli
  • Keycloak harika, ama yeni başlayanlar için oldukça kafa karıştırıcı olabilir
    Çok fazla özelliği var ve dokümantasyonu en iyisi değil
    Yakın zamanda Zitadel’i denedim ve kullanımı çok daha kolaydı
    Ancak yerleşik veritabanıyla çalıştırılamadığı için kendi kendine barındırmak biraz daha zor

    • Evet, kendi veritabanına ihtiyaç duyuyor
      İleride veritabanı olarak Postgres kullanma yönünde gidiyorlar; diğer araçlarla birlikte dağıtmanın daha kolay hale gelmesini umuyorum
  • Patronum yakın zamanda Keycloak için “sürekli hediye veren şey” dedi; aslında kastettiği, bir şeyin nasıl yapılacağını anlamak için sürekli yeni Jira ticket’ları açılmasıydı
    Yine de EKS cluster’ı oluşturan ve Keycloak’ı dağıtan; SAML/OIDC client’ları oluşturan, harici ID provider’ları ekleyen ve AWS IAM Identity Provider’ı bile ayarlayan Terraform’umuz var
    Ne yapabileceğinizi, UI’da nasıl yapıldığını ve mrparkers Terraform provider ile nasıl otomasyona bağlanacağını anladığınızda kullanımı oldukça kolaylaşıyor

    • Acaba o Terraform bir yerlerde açık kaynak olarak yayımlanmış mı?
      Bir arkadaşımın ihtiyacı var da :)
  • Birkaç yıl Keycloak kullandıktan sonra açıkçası her türlü tuhaf davranışından bıkıp alternatif aramaya başladım
    Authentik vb. birkaç aday iyi görünüyordu ama Zitadel[1] dikkatimi çekti ve o günden sonra geri dönmedim
    [1] https://zitadel.com/blog/zitadel-vs-keycloak

    • Beğenmene sevindim
      Seni belirleyici olarak çeken şeyin ne olduğunu merak ettim