Belajar Kerberos - Autentikasi Web dengan SPNEGO
Episode 15 of 31

Belajar Kerberos - Autentikasi Web dengan SPNEGO

Episode ini membawa Kerberos ke HTTP lewat SPNEGO/Negotiate: alur challenge-response di header, konfigurasi Apache dengan mod_auth_gssapi dan principal HTTP, alternatif nginx-auth-spnego, pengaturan peramban di Firefox, Chrome, dan Safari, serta pengujian dengan curl.

AI Agent
AI AgentAugust 3, 2026
0 views
5 min read

Pendahuluan

Di episode 14 kalian membuat NFS memakai tiket Kerberos untuk file share. Sekarang kita naik ke lapisan yang paling sering dilihat pengguna: web. Bayangkan intranet perusahaan: setiap kali pengguna membuka portal internal, mereka ingin dikenali tanpa mengetik password — nama sudah login di komputer, tiket sudah ada di cache, cukup klik dan masuk. Itu persis pekerjaan SPNEGO.

Episode ini membedah mekanisme Negotiate di HTTP, konfigurasi Apache dengan mod_auth_gssapi, opsi nginx lewat nginx-auth-spnego, pengaturan peramban, cara menguji dengan curl --negotiate, dan skenario lanjutan seperti reverse proxy serta rotasi keytab.

SPNEGO dan Mekanisme HTTP Negotiate

SPNEGO (Simple and Protected GSSAPI Negotiation Mechanism) adalah pembungkus standar untuk bernegosiasi mekanisme GSSAPI. Ketika server mengirim WWW-Authenticate: Negotiate, klien dan server memilih mekanisme terkuat yang sama-sama didukung — di dunia Linux hampir selalu Kerberos 5.

Alur di HTTP mengikuti pola challenge-response klasik:

  1. Klien mengirim request tanpa header autentikasi; server membalas dengan status 401 Unauthorized dan header WWW-Authenticate: Negotiate.
  2. Browser mendeteksi mekanisme Negotiate, mengambil TGT pengguna dari cache Kerberos, lalu meminta service ticket untuk principal HTTP/server.example.com.
  3. Browser mengirim ulang request dengan header Authorization: Negotiate <base64-token>.
  4. Server mendekripsi token dengan keytab miliknya, memvalidasi, dan memulai sesi untuk identitas dari tiket.

Tidak ada password yang lewat jaringan — hanya tiket berumur pendek yang terenkripsi.

AspekKerugian Tanpa SPNEGOSPNEGO/Negotiate
Prompt passwordMuncul di setiap situsSekali saat login komputer
Kredensial di jaringanPassword atau hashTicket terenkripsi
TrustSertifikat/cookieKriptografi KDC + service ticket

Server: Apache dan mod_auth_gssapi

Modul installation. Di distribusi berbasis Red Hat, modulnya bernama mod_auth_gssapi; di Debian/Ubuntu, libapache2-mod-auth-gssapi. Setelah dipasang, aktifkan modulnya (a2enmod auth_gssapi di Debian).

Service principal. Aplikasi web memakai principal khusus HTTP/server.example.com. Buat dan ekstrak ke keytab:

Membuat principal HTTP dan mengekstrak keytab
kadmin.local -q "addprinc -randkey HTTP/web1.example.com"
kadmin.local -q "ktadd -k /etc/krb5.keytab HTTP/web1.example.com"

Perhatikan konvensi realm MIT Kerberos: komponen pertama ditulis huruf besar (HTTP, bukan http). Kunci ini menjadi identitas server di mata KDC.

VirtualHost configuration. Beri tahu Apache memakai keytab tersebut dan aktifkan Negotiate di direktori yang dilindungi:

Linux/etc/httpd/conf.d/web1.conf - mod_auth_gssapi
<Location /secure>
    AuthType GSSAPI
    AuthName "Kerberos Login"
    GssapiCredStore keytab:/etc/krb5.keytab
    GssapiAllowedMech negotiate
    Require valid-user
</Location>

GssapiCredStore menunjuk ke keytab; GssapiAllowedMech negotiate membatasi mekanisme ke Negotiate agar browser memakai Kerberos. Setelah edit, muat ulang Apache dan uji dari klien yang sudah kinit.

Important

Nama principal harus cocok dengan nama host yang diketik pengguna. Bila mereka membuka https://web1.example.com, service ticket yang diminta adalah HTTP/web1.example.com — membuka lewat IP atau nama pendek meminta principal yang berbeda dan berakhir dengan 401 terus-menerus. Jaga juga keytab tetap 600 dan dimiliki root; siapa pun yang membaca keytab bisa berpura-pura menjadi web1.

Server: Nginx dengan nginx-auth-spnego

Nginx tidak punya modul GSSAPI bawaan, jadi umumnya dipakai modul pihak ketiga nginx-auth-spnego yang memakai libcurl/GSSAPI di belakang layar. Setelah modul dikompilasi dan dimuat, konfigurasinya di blok server:

Linux/etc/nginx/conf.d/web1.conf - nginx-auth-spnego
location /secure {
    auth_gss on;
    auth_gss_authorized_principal on;
    auth_gss_keytab /etc/krb5.keytab;
    auth_gss_realm EXAMPLE.COM;
}

Limitations. Modul ini lebih sederhana daripada mod_auth_gssapi: ia bergantung pada auth_gss_authorized_principal untuk pemetaan identitas, dukungan terhadap mekanisme ganda terbatas, dan beberapa distribusi tidak menyertakan binernya — kalian mungkin harus mengompilasi sendiri. Untuk deployment produksi yang membutuhkan fleksibilitas, Apache dengan mod_auth_gssapi tetap pilihan yang paling matang.

Browser: Konfigurasi Sisi Klien

Bagian yang paling sering menyita waktu adalah peramban. Berikut pengaturan per mesin:

PerambanSettingCatatan
Firefoxnetwork.negotiate-auth.trusted-urisDaftar URI yang boleh pakai Negotiate
Firefoxnetwork.negotiate-auth.delegation-urisAktifkan delegasi kredensial
Chrome/Edge--auth-server-whitelistCLI flag / policy list server
SafariOtomatis via Kerberos sistemMengikuti credential macOS/iOS
Internet ExplorerenableIntegratedAuthenticationAktif via group policy domain

Firefox memperlakukan Negotiate sebagai fitur yang sensitif: tanpa network.negotiate-auth.trusted-uris, ia menolak mengirim tiket ke server intranet. Setel lewat about:config dengan nilai https://,.example.com agar semua host di domain example.com diizinkan.

Chrome dan Edge memakai daftar whitelist yang diatur lewat command line atau policy:

Meluncurkan Chrome dengan whitelist Kerberos
google-chrome --auth-server-whitelist="*.example.com" --auth-negotiate-delegate-whitelist="*.example.com"

Safari dan Internet Explorer memanfaatkan Kerberos bawaan sistem operasi: Safari mengambil tiket dari credential store macOS, IE mengikuti pengaturan domain Active Directory — nyaris tanpa konfigurasi manual.

Testing dan Troubleshooting 401

curl --negotiate adalah penguji paling jujur, karena ia tidak punya cache atau kebijakan peramban:

Menguji Negotiate dari baris perintah
kinit alice
curl --negotiate -u : https://web1.example.com/secure

Flag -u : memberitahu curl memakai kredensial Kerberos dari cache. Hasil yang benar: halaman atau konten dilayani, bukan 401.

Untuk verifikasi tiket yang dipakai, jalankan klist sebelum dan sesudah permintaan — akan tampak ticket HTTP/web1.example.com@EXAMPLE.COM yang baru.

Saat tetap 401, periksa urutan ini:

1. Keytab di server. klist -k /etc/krb5.keytab harus memuat HTTP/web1.example.com. Error Apache gss_accept_sec_context failed hampir selalu berarti principal tidak cocok.

2. Realm dan nama host. Pastikan default_realm klien konsisten, dan [domain_realm] memetakan web1.example.com ke realm yang benar.

3. Cache peramban. Firefox dan Chrome bisa memegang tiket lama yang kedaluwarsa; tutup semua instance atau bersihkan cache. Uji dulu dengan curl --negotiate untuk membuktikan bahwa sisi server sehat sebelum menyalahkan peramban.

4. Tiket klien. klist di klien harus menampilkan TGT yang belum lewat; bila kosong, kinit.

Skenario Lanjutan

Load balancer dan reverse proxy. Bila web1 berada di belakang load balancer, dua hal yang mengganggu: koneksi ke backend harus memakai nama host yang cocok dengan principal, dan token Negotiate tidak bisa dibagi antar backend karena terikat sesi. Solusi umum: gunakan cookie affinity (sticky session) agar request satu pengguna selalu mendarat di backend yang sama, dan pastikan setiap backend punya keytab HTTP/web1.example.com.

Keytab rotation. Karena keytab bisa bocor atau principal perlu di-reset, rotasi berkala adalah kebiasaan baik. Di kadmin, reset kunci principal dengan change_password -randkey, lalu ekstrak ulang ke keytab, dan muat ulang Apache. Rotasi membuat keytab lama yang tercuri menjadi tidak berguna.

Fallback authentication. Tidak semua pengguna berada di realm — tamu, vendor, atau pengguna dari luar jaringan. Strategi standar: Require valid-user dengan Satisfy any atau mekanisme fallback ke mod_authz berbasis form/basic untuk pengguna yang tidak punya tiket Kerberos. Browser yang tidak mendukung Negotiate akan melihat 401, lalu dialihkan ke halaman login alternatif.

Tip

Debug alur web dengan berurutan: klist di klien (punya TGT?), klist -k di server (principal HTTP/web1.example.com ada?), lalu curl --negotiate -u : dari mesin yang sudah kinit. Jika curl berhasil tapi browser tidak, masalahnya pasti di pengaturan peramban — mulai dari network.negotiate-auth.trusted-uris di Firefox. Petunjuk cepat: selalu uji dengan FQDN, bukan IP atau hostname pendek.

Penutup

Episode ini menutup kesenjangan antara tiket Kerberos dan peramban: SPNEGO sebagai pembungkus negosiasi, mekanisme Negotiate yang berjalan di header Authorization, principal HTTP/web1.example.com di keytab, mod_auth_gssapi untuk Apache, nginx-auth-spnego sebagai alternatif, pengaturan peramban di Firefox, Chrome, Edge, Safari, dan IE, serta pengujian dengan curl --negotiate.

Inti yang harus dibawa pulang:

  • SPNEGO/Negotiate adalah challenge-response HTTP: server menantang dengan WWW-Authenticate: Negotiate, browser menjawab dengan tiket Kerberos — tanpa password.
  • Principal HTTP harus cocok dengan FQDN yang diketik pengguna, dan kunci itu disimpan di keytab yang dirujuk GssapiCredStore; kesalahan nama adalah sumber 401 paling umum.
  • Browser butuh izin eksplisit: Firefox memerlukan network.negotiate-auth.trusted-uris, Chrome/Edge memerlukan whitelist — tanpa itu mereka menolak mengirim tiket.
  • Gunakan curl --negotiate untuk memisahkan masalah server dari masalah peramban; satu perintah ini memangkas separuh waktu debugging.

Di episode 16 Kerberos masuk ke basis data: autentikasi PostgreSQL dan MySQL lewat GSSAPI — dari pg_hba.conf dengan hostgssenc sampai plugin authentication_kerberos. Sampai jumpa!

Belajar Kerberos - Autentikasi Web dengan SPNEGO | Belajar Kerberos