3 poin oleh GN⁺ 2024-02-12 | 1 komentar | Bagikan ke WhatsApp
  • Ini adalah prosedur deployment SSO di satu Linux VM, dengan Keycloak dijalankan secara terisolasi menggunakan rootless Docker, sementara nginx sistem menangani terminasi TLS dan reverse proxy
  • Prasyaratnya adalah akses SSH, domain atau subdomain untuk Keycloak, record A, pengguna keycloak tanpa kata sandi, direktori home /srv/keycloak, dan instalasi Docker rootless
  • docker-compose.yml menggunakan postgres:16 dan quay.io/keycloak/keycloak:25.0.1, dan Keycloak hanya di-bind ke 127.0.0.1:8080 serta mengelola kata sandi dan KC_HOSTNAME di .env
  • nginx mengalihkan permintaan HTTP untuk your.tld.com ke HTTPS dan meneruskan dengan proxy_pass, lalu setelah sertifikat diterbitkan oleh Certbot, KC_PROXY_HEADERS: xforwarded diaktifkan
  • Jika memerlukan tema kustom atau menjalankan --optimized, Anda bisa membuat image sendiri dengan Dockerfile multistage, dan dalam produksi Anda juga dapat menyesuaikan tambahan seperti ukuran buffer JGroups serta pengaturan pemulihan transaksi Quarkus

Struktur deployment dan prasyarat

  • Keycloak adalah opsi IAM open source yang dapat digunakan ketika sulit mengimplementasikan manajemen pengguna dan SSO langsung di aplikasi web
  • Kompatibel dengan protokol SSO utama seperti OpenID Connect (OIDC), OAuth 2.0, dan SAML
  • Konfigurasi ini ditulis berdasarkan Keycloak 23.0.6 dan telah diuji hingga 25.0.5
  • Struktur keseluruhannya menempatkan nginx sebagai reverse proxy pusat, lalu meneruskan trafik ke localhost di namespace rootless Docker tiap layanan
    • Trafik web masuk melalui 0.0.0.0:80 dan 0.0.0.0:443, lalu nginx meneruskannya ke Keycloak di 127.0.0.1:8080
    • Tujuannya adalah konfigurasi yang hemat dengan memisahkan lingkungan layanan sambil tetap berbagi sumber daya satu host

Persiapan

  • Lingkungan dasarnya memerlukan Linux VM, akses SSH jarak jauh, dan domain atau subdomain untuk layanan Keycloak
    • Domain tersebut memerlukan record A, dan secara opsional dapat ditambahkan record AAAA
  • Konfigurasi dasar Docker rootless mengikuti prosedur di posting Mastodon terpisah
    • Membuat pengguna non-root baru keycloak tanpa kata sandi
    • Menetapkan direktori home ke /srv/keycloak
    • Menambahkan rentang pengguna keycloak ke /etc/subuid dan /etc/subgid
    • Menginstal Docker rootless dengan dockerd-rootless-setuptool.sh
    • Mengatur layanan agar otomatis dimulai untuk pengguna keycloak

Menjalankan Keycloak dengan Docker Compose

  • Untuk masuk sebagai pengguna keycloak yang baru dibuat, gunakan machinectl shell keycloak@
    • Metode sudo -u keycloak -H bash dihindari karena variabel lingkungan XDG_RUNTIME_DIR tidak disiapkan
  • Buat dulu direktori data persisten dan file Docker
    • Lokasi data PostgreSQL adalah /srv/keycloak/data/postgres16
    • File Docker ditempatkan di ~/docker
  • docker-compose.yml menggunakan image resmi Keycloak dan PostgreSQL secara langsung
    • Image PostgreSQL adalah postgres:16
    • Image Keycloak adalah quay.io/keycloak/keycloak:25.0.1
    • Di lingkungan produksi, disarankan memakai tag image spesifik alih-alih :latest
  • Pengaturan utama kontainer Keycloak adalah sebagai berikut
    • 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 di-bind hanya ke localhost dengan '127.0.0.1:8080:8080'
  • .env menyimpan nilai sensitif atau yang berbeda per lingkungan
    • POSTGRES_PASSWORD
    • KEYCLOAK_ADMIN_PASSWORD
    • KC_HOSTNAME
  • Sintaks ${KC_HOSTNAME:-your.tld.com} berarti jika KC_HOSTNAME ada di .env, nilai itu yang dipakai; jika tidak, your.tld.com digunakan sebagai default
  • /srv/keycloak/data/postgres16 menyimpan data persisten PostgreSQL sehingga harus dibackup secara berkala
    • Untuk menginisialisasi ulang sepenuhnya, hapus lalu buat kembali folder PostgreSQL tersebut, dan folder akan dibuat ulang saat startup berikutnya
  • Jika ~/docker dikelola sebagai repositori Git, tambahkan .env ke .gitignore dan Anda bisa meng-commit hanya docker-compose.yml

Pengujian lokal

  • Jalankan stack Docker Compose dan periksa log
docker compose up -d && docker compose logs --follow
  • Untuk mengakses port lokal Keycloak di VM, buat reverse SSH tunnel
ssh you@111.11.11.11 -L :8080:127.0.0.1:8080 -p 22 -N -v
  • Buka 127.0.0.1:8080 di browser untuk memastikan layar sambutan Keycloak muncul

Reverse proxy nginx dan TLS

  • Setelah logout dari pengguna keycloak, lanjutkan dengan konfigurasi nginx sistem
  • Ganti your.tld.com dengan domain sebenarnya, lalu tambahkan record A di registrar domain agar kueri DNS diarahkan ke IP VM
  • Buat dan aktifkan file konfigurasi situs nginx
nano /etc/nginx/sites-available/your.tld.com.conf
ln -s /etc/nginx/sites-available/your.tld.com.conf /etc/nginx/sites-enabled/
  • Konfigurasi nginx mengalihkan permintaan HTTP ke HTTPS, lalu mem-proxy ke Keycloak di blok server HTTPS
    • 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
  • Untuk konfigurasi SSL, disarankan menggunakan Mozilla SSL configurator for nginx guna menghasilkan nilai default yang sesuai dengan versi nginx
  • Setelah menguji konfigurasi, muat ulang nginx
nginx -t
systemctl reload nginx
  • Saat sertifikat diterbitkan dengan Certbot, baris yang diperlukan di your.tld.com.conf akan diperbarui secara otomatis
certbot --nginx -d your.tld.com
  • Setelah itu aktifkan ssl_trusted_certificate /etc/letsencrypt/live/your.tld.com/chain.pem; lalu muat ulang nginx
  • Agar berjalan di belakang nginx, aktifkan KC_PROXY_HEADERS: xforwarded di docker-compose.yml, lalu restart stack Docker
docker compose down && docker compose up -d && docker compose logs --follow

Jalur debugging

  • Setelah konfigurasi, akses your.tld.com dan verifikasi login pengguna admin dengan kata sandi dari .env
  • Titik pemeriksaan pertama adalah log Docker Compose
docker compose logs --follow
  • Log akses dan log error nginx dapat dipantau lewat file berikut
tail -f /var/log/nginx/your.tld.com-access.log
tail -f /var/log/nginx/your.tld.com-error.log
  • Jika perlu memeriksa database Keycloak secara langsung, masuk sebagai pengguna keycloak lalu jalankan psql di dalam kontainer PostgreSQL
machinectl shell keycloak@
cd ~/docker
docker compose exec postgres_db /bin/bash
psql -h localhost -p 5432 -U keycloak keycloak

Image kustom dan mode optimized

  • Konfigurasi dasar menggunakan image pra-build dari quay.io
  • Jika Anda memerlukan kustomisasi tema atau ingin menjalankan mode --optimized, bangun image sendiri
  • Dockerfile menggunakan build multistage berbasis image resmi Keycloak
    • Pada tahap builder, set ENV KC_DB=postgres
    • Jalankan /opt/keycloak/bin/kc.sh build
    • Salin /opt/keycloak/ ke image final
    • Tentukan ENTRYPOINT ["/opt/keycloak/bin/kc.sh"]
  • Di docker-compose.yml, ubah seperti berikut
    • Hapus atau beri komentar pada baris image:
    • Aktifkan build: .
    • Tambahkan command: start --optimized
  • Setelah itu hentikan stack Docker, opsional jalankan build eksplisit, lalu mulai lagi
docker compose down
docker compose build
docker compose up -d && docker compose logs --follow

Penyesuaian tambahan di lingkungan produksi

  • Peringatan buffer penerimaan MulticastSocket terkait JGroups diselesaikan dengan menambahkan nilai buffer ke /etc/sysctl.conf host
net.core.rmem_max = 26214400
net.core.wmem_max = 1048576
  • Untuk menerapkan konfigurasi, jalankan sysctl -p
  • Peringatan pemulihan transaksi XA Quarkus diselesaikan dengan menambahkan volume mount dan variabel lingkungan ke layanan Keycloak
    • Volume: /srv/keycloak/data/keycloak/ObjectStore/:/ObjectStore/
    • Variabel lingkungan: QUARKUS_TRANSACTION_MANAGER_ENABLE_RECOVERY: true
  • Sebelum startup, buat direktori ObjectStore di host, lalu ubah pemilik /ObjectStore di dalam kontainer menjadi user ID 1000

Langkah setelah konfigurasi

  • Kondisi akhirnya adalah layanan Keycloak di dalam rootless Docker berjalan di belakang reverse proxy nginx sistem, dengan nginx menangani terminasi SSL
  • Untuk pembaruan kontainer otomatis, lihat prosedur auto-update di posting Mastodon terpisah
  • Langkah konfigurasi berikutnya adalah menambahkan email di konsol admin Keycloak
  • Setelah itu Anda bisa menambahkan realm dan mengatur tema
    • Untuk tema, Anda bisa menggunakan keycloakify dan keycloakify-starter
    • Dockerfile menyertakan baris yang diberi komentar untuk menyalin JAR tema keycloakify ke /opt/keycloak/providers/

1 komentar

 
GN⁺ 2024-02-12
Opini Hacker News
  • Baru-baru ini saya memilih Authelia saat menambahkan autentikasi ke homelab
    Keycloak juga berfungsi, tetapi terlalu besar, dan untuk dipakai bersama traefik forward auth, masih perlu layanan tambahan
    Authelia tidak punya UI untuk mengedit pengguna dan juga bukan sinkronisasi dua arah dengan server LDAP backend, tetapi bisa dikonfigurasi hanya dengan file statis dan variabel lingkungan, jadi cocok untuk banyak kasus
    Kalau kebutuhannya hanya menambahkan autentikasi ke beberapa layanan dan memasang SSO pada layanan yang memungkinkan, Authelia layak dicoba lebih dulu

    • Saya bekerja di FusionAuth
      Jika membutuhkan SSO, konfigurasi mudah, dan UI admin, FusionAuth juga layak dilihat. UI/UX-nya memang terasa seperti pertengahan 2000-an, tetapi bisa diunduh dan dijalankan sendiri[0], ramah Docker[1], serta menyediakan berbagai cara konfigurasi[2], seperti mengelola OIDC atau pengaturan lain dengan Terraform[3]
      Bisa digunakan gratis, tetapi bukan open source[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
    • Saya sudah menjalankan Authelia lebih dari 2 tahun, dan mengonfigurasi integrasi LDAP dengan LLDAP[0], implementasi LDAP yang ringan
      Saya memakai Caddy sebagai reverse proxy dan mengintegrasikannya dengan Authelia[1], dan semuanya berjalan baik
      Saya memasang autentikasi dua faktor yang kuat di semua layanan, dan merasa aplikasi self-hosted saya cukup aman diakses tanpa VPN
      Namun Authelia belum merilis versi baru selama lebih dari setahun, jadi saya khawatir dari sisi keamanan
      [0] https://github.com/lldap/lldap
      [1] https://www.authelia.com/integration/proxies/caddy/
    • Baru-baru ini saya menempuh jalur yang sama, dan secara pribadi memilih caddy-security[1], sebuah plugin Caddy
      [1] https://github.com/greenpau/caddy-security
    • Authelia punya keunggulan yang sangat unik, yaitu skala instalasi yang kecil, sementara Keycloak atau authentik sulit cocok di ranah ini
      Ini use case yang sangat bagus untuk lingkungan homelab, terutama jika tidak membutuhkan atau tidak menginginkan fitur dari solusi yang lebih besar
    • Sedikit menyimpang, tetapi saya penasaran apakah sekarang ada alternatif LDAP
      Setelah mencari-cari, saya tidak menemukan bentuk seperti skema sederhana, JSON, atau HTTP, dan sulit dipercaya bahwa orang-orang yang membangun ulang hampir semuanya tidak membangun ulang LDAP
      Sejauh yang saya tahu, praktis satu-satunya standar lain adalah Active Directory
      Saya juga penasaran apakah ada standar atau protokol untuk menyerahkan kontrol akses ke pihak eksternal
      Authelia bisa mengontrol akses berdasarkan pola URL, tetapi misalnya untuk server file, saya membayangkan bentuk yang memeriksa izin ke server LDAP berdasarkan ID pengguna yang sudah terautentikasi dan kunci di database
      Ini terlihat seperti arah yang berlawanan dengan OAuth2, di mana server memperoleh hak akses ke layanan pihak ketiga
  • Baru-baru ini saya mencoba menyusun SSO yang relatif sederhana di homelab, dan tujuan utamanya adalah bisa login dengan mudah memakai autentikasi Google atau GitHub
    Di tempat kerja sebelumnya, saya pernah memakai JetBrains Hub[1] dan Keycloak, dan keduanya cukup merepotkan untuk dikonfigurasi
    JetBrains Hub benar-benar mudah untuk mulai digunakan, dan pengalaman saya sebelumnya juga begitu, tetapi merepotkan karena tidak ada tag latest di Docker registry
    Saya tahu mengunci versi itu bagus, tetapi untuk penggunaan pribadi biasanya saya ingin memperbarui semua container Docker sekaligus
    Sebaliknya, Keycloak sangat merepotkan saat mulai digunakan; di mode pengembangan memang mudah, tetapi konfigurasi produksi mentok
    Kalau tidak salah, itu terkait sertifikat wildcard Let's Encrypt, dan setelah beberapa jam saya menyerah
    Pada akhirnya saya memilih Dex[2]. Saya sempat menundanya karena dokumentasinya kurang, tetapi konfigurasi nyatanya sangat mudah; cukup YAML dasar, database SQLite, dan satu subdomain
    Saya menggabungkan Dex dengan OAuth2 Proxy[3] yang sangat bagus dan template kustom Nginx Proxy Manager, sehingga tiap layanan internal hanya butuh konfigurasi SSO dua baris, dan saya juga membuat template Dex Docker untuk unRAID[4]
    Untuk akses dari luar rumah, saya menambahkan Cloudflare Access dan WAF guna memperkuat keamanan, dan saya hanya ingin menambahkan CrowdSec untuk mendapatkan sedikit lebih banyak insight

    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
    • Saya memakai obligator sebagai penyimpanan sementara, tanpa database, dengan konfigurasi 100% berbasis kode
      Secara pribadi, menurut saya ini opsi yang paling sederhana
      https://github.com/lastlogin-io/obligator
    • Saya penasaran fitur apa yang disediakan oauth2-proxy yang tidak ada di Dex
  • Saya membuat tabel perbandingan yang belum selesai untuk beberapa server OpenID Connect yang bisa di-host sendiri[0]
    Salah satu hal yang mengejutkan adalah codebase Keycloak benar-benar sangat besar
    [0]: https://github.com/lastlogin-io/obligator?tab=readme-ov-file...

  • Gagasan bahwa Keycloak menyelesaikan masalah keamanan itu lucu
    Lihat saja daftar CVE, dan Anda akan paham maksudnya

  • Setidaknya, penyebutan https://www.keycloakify.dev/ di artikel tersebut sangat berguna
    Kelihatannya seperti alternatif yang bagus untuk pendekatan tema standar

    • Proyek yang hebat
      Saya sudah memakainya selama 2 tahun dan hanya punya hal baik untuk dikatakan
      Maintainer-nya sangat cepat merespons, dan baru-baru ini ada perubahan di Keycloak maupun keycloakify yang meningkatkan kompatibilitas masa depan untuk cara kerja tema
      Saat ini secara resmi hanya mendukung aplikasi yang dibuat dengan create-react-app, tetapi branch vite sedang dikembangkan, dan secara pribadi saya sudah cukup lama memakainya bersama vite
    • Saya bekerja di kompetitor dan kami sedang mengerjakan ulang sistem tema, jadi proyek ini tampak bagus untuk ditinjau dan dijadikan model pengerjaan ulang
  • Sedang memperhatikan authentik[1] dan authelia[2]
    Authelia terlihat sangat bagus, tetapi Keycloak punya konektor untuk Angular, sedangkan di Authelia, misalnya, kita harus mengonfigurasi sendiri plugin OIDC Angular, jadi agak berhati-hati
    Meski begitu, kalau ada konfigurasi untuk Keycloak, sepertinya akan lebih mudah untuk memulai
    [1] https://goauthentik.io/
    [2] https://www.authelia.com/

    • Kalau ada yang mempertimbangkan authentik, saya ingin memperingatkan: “di sana ada naga”
      Saya terus-menerus melindungi lebih dari 10 layanan di Docker dan Kubernetes, dan kalau Anda tidak menikmati mengatur proteksi untuk tiap layanan secara terpisah, Anda akan kerepotan dengan authentik
      authentik punya bug serius[0]: saat melindungi beberapa subdomain (app1.example.com, app2.example.com, dll.) dengan satu konfigurasi, setelah sesi kedaluwarsa lalu autentikasi ulang, pengguna akan dialihkan secara acak ke layanan lain
      [0]: https://github.com/goauthentik/authentik/issues/6886
    • Authentik benar-benar mengacaukan implementasi OAuth client credentials grant
      Ini tidak bisa diperbaiki tanpa perubahan yang memutus kompatibilitas, dan tidak berfungsi dengan banyak tool yang memakai grant cc
      Setelah melihat ini, saya benar-benar mencoretnya dari kandidat
      https://github.com/goauthentik/authentik/issues/6139
    • Saya salah satu maintainer inti Authelia
      Jika ada yang bisa saya bantu terkait konfigurasi Angular, saya dengan senang hati membantu lewat GitHub Discussions
    • Saya sedang mencoba mengambil keputusan yang sama
      Authentik tadinya terlihat lebih bagus, tetapi bug yang disebutkan di balasan lain tampak cukup buruk
  • Masalah Keycloak adalah ini proyek lama, jadi perubahannya sangat banyak
    Ia dimulai sebagai proyek JBOSS, dan menurut saya kegunaannya sebagai IdP bersinar pada autentikasi klaster on-premise, tetapi hanya sampai di situ
    Saya pernah mengimplementasikan Keycloak dalam skala besar di AWS ECS untuk sebuah divisi Fortune 500, dan membuatnya benar-benar ter-cluster rasanya seperti perang seribu tahun
    Discovery DNS tidak bekerja dengan benar, dan discovery klaster berbasis UDP, jadi tidak jalan di lingkungan cloud
    Login stateful di satu server tidak ada di server lain, sehingga load balancing sederhana tidak mungkin dilakukan, dan sticky session menjadi satu-satunya pilihan
    Menjalankan Keycloak dengan docker run dan memasangnya seperti Auth0 memang mudah, tetapi rasanya seperti membeli Ford F-150 keluaran 1996 yang sudah menempuh 250 ribu mil
    Masih bisa berjalan dan berfungsi, tetapi pemeliharaannya benar-benar mengerikan

    • Skalanya kecil, tetapi saya pernah mencobanya di Docker Swarm on-premise, dan memang menyakitkan
      Seingat saya, metode discovery default memakai multicast, yang tidak diaktifkan di jaringan cloud umum maupun jaringan overlay Swarm/Kubernetes
      Saya juga melihat database ping yang memakai RDBMS sebagai semacam mekanisme kuorum, tetapi itu tampak sangat rapuh dan terasa seperti opsi terakhir
      Pada akhirnya saya bisa memakai driver klaster Kubernetes yang menemukan node lewat DNS klaster Swarm
      Cukup sulit sampai bisa berjalan, tetapi setelah itu sejauh yang saya tahu stabil
      Sekarang tampaknya juga ada driver networking EC2 native, tetapi saya belum mengeksplorasinya sendiri
    • Saya dengar ada perbaikan setelah sepenuhnya pindah ke Quarkus
      Penasaran deployment ECS itu dilakukan kapan
    • OAuth dan OpenID Connect, serta kemampuan menambahkan app dan client ke realm, adalah penyelamat Keycloak dan satu-satunya alasan kami tetap mempertahankannya
    • Mendengar bahwa discovery klasternya memakai UDP terdengar menyakitkan
      Di tempat kami, UDP hanya diizinkan untuk DNS
  • Keycloak bagus, tetapi bisa cukup membingungkan bagi pemula
    Fiturnya banyak dan dokumentasinya bukan yang terbaik
    Baru-baru ini saya mencoba Zitadel, dan jauh lebih mudah digunakan
    Namun karena tidak bisa dijalankan dengan database bawaan, self-hosting jadi sedikit lebih sulit

    • Benar, butuh database sendiri
      Ke depannya arahnya memakai Postgres sebagai database, jadi saya berharap akan lebih mudah dideploy bersama tool lain
  • Atasan saya baru-baru ini menyebut Keycloak sebagai “barang yang terus memberi hadiah”, tetapi maksudnya sebenarnya adalah terus munculnya tiket Jira baru untuk mencari tahu bagaimana melakukan sesuatu
    Meski begitu, kami punya Terraform yang membuat klaster EKS dan men-deploy Keycloak, membuat client SAML/OIDC, menambahkan penyedia ID eksternal, bahkan mengatur AWS IAM Identity Provider
    Setelah mengetahui apa saja yang bisa dilakukan, bagaimana melakukannya di UI, dan bagaimana mengotomatisasikannya dengan Terraform provider mrparkers, penggunaannya sendiri menjadi sangat mudah

    • Penasaran apakah Terraform itu dipublikasikan sebagai open source di suatu tempat
      Teman saya membutuhkannya :)
  • Setelah memakai Keycloak selama beberapa tahun, jujur saya muak dengan segala perilaku anehnya dan mulai mencari alternatif
    Beberapa kandidat seperti Authentik tampak oke, tetapi Zitadel[1] menarik perhatian saya, dan sejak itu saya tidak pernah menoleh ke belakang
    [1] https://zitadel.com/blog/zitadel-vs-keycloak

    • Senang mendengar Anda menyukainya
      Penasaran, bagian apa yang paling menentukan sehingga Anda tertarik?