帶有 pam_krb5 的 PAM 用於驗證 nginx 請求
我知道這里和“Unix/Linux”上的 gazzilion pam / nginx 問題,但它們要麼沒有答案,要麼與我的設置無關 - 所以我再試一次:)
TL;博士
雖然該設置與
Apache+mod_kerb_auth
組合完美配合,但在使用時我無法讓自動票證轉發工作nginx+pam_krb5
- 雖然針對 kerberos 的基本身份驗證工作。問題是,可能是什麼原因和/或如何進一步調試它。您可以在下面找到所有詳細資訊、配置和環境
我的設置:
- 實驗室中的 Windows 2012 DC(為 KDC 全新安裝和配置)
- Debian Stretch Linux 作為我們的“服務”
- 在那個 Debian 盒子上,我有:kerb-client MIT、Apache2+mod_kerb_auth 和 nignx+nginx_pam+pam
- 一個 MacOS 客戶端
什麼工作:
- 我有 keytab 文件的正常設置,/etc/krb5.conf 以及所有領域/default_realm 的點點滴滴。(見下文)
- 我可以使用 keytab 文件和我的 SPN 啟動:(
HTTP/wiki.kwtest.local
見下文)- 在同一個 Debian 伺服器上使用 Apache2 + mod_kerb_auth,它完全包括票證轉發(確認 krb5.conf / keytab / KDC /infra setup 我猜是有效的)。所以我可以在我的 OSX 上使用
kinit
+curl --negotiate
或 Safari 並立即獲得訪問權限。- 添加 pam 身份驗證(見下文)和 pam 設置,我可以在通過 safari 訪問時驗證輸入 AD 使用者憑據(由於 curl 立即獲得 401
-u
)……但票證轉發/驗證不起作用設置詳細資訊:
Kerberos 客戶端配置
/etc/krb5.conf
[libdefaults] default_realm = KWTEST.LOCAL kdc_timesync = 1 # https://web.mit.edu/kerberos/krb5-1.12/doc/basic/ccache_def.html # we do not want the keyring due to docker ccache_type = 3 forwardable = true proxiable = true # no reverse lookup rdns = false [realms] KWTEST.LOCAL = { kdc = kdc.kwtest.local admin_server = kdc.kwtest.local } [login] krb4_convert = true krb4_get_tickets = false [logging] default = FILE:/var/log/kdc.log:SYSLOG kdc = FILE:/var/log/kdc.log:SYSLOG # https://web.mit.edu/kerberos/krb5-1.12/doc/admin/conf_files/krb5_conf.html?highlight=appdefaults#appdefaults [appdefaults] forwardable = true # https://manpages.debian.org/stretch/libpam-heimdal/pam_krb5.5.en.html pam = { ignore_k5login=true debug=true forwardable = true proxiable = true minimum_uid = 0 realm = KWTEST.LOCAL keytab = /mnt/config/kerberos/drupalwiki.keytab }
Pam 配置在
/etc/pam.d/dw-kerb-nginx
cat /etc/pam.d/dw-kerb-nginx auth required pam_krb5.so keytab=/mnt/config/kerberos/drupalwiki.keytab minimum_uid=20 forwardable=true realm=KWTEST.LOCAL trace=/var/log/pamtrace silent=false debug=true account required pam_unix.so keytab=/mnt/config/kerberos/drupalwiki.keytab minimum_uid=20 forwardable=true realm=KWTEST.LOCAL trace=/var/log/pamtrace silent=false debug=true
該預設伺服器的 Nginx 配置位於
/etc/nginx/sites-enabled/default
cat /etc/nginx/sites-enabled/default server { listen 80 default_server; listen [::]:80 default_server; root /var/www/html; index index.html index.htm index.nginx-debian.html; server_name _; error_log /var/log/nginx/error.log debug; location / { auth_pam "Secure Zone"; auth_pam_service_name "dw-kerb-nginx"; try_files $uri $uri/ =404; } }
KVNO 號碼匹配
#kdc KVNO kvno HTTP/wiki.kwtest.local@KWTEST.LOCAL HTTP/wiki.kwtest.local@KWTEST.LOCAL: kvno = 16 #client KVNO klist -ke /mnt/config/kerberos/drupalwiki.keytab Keytab name: FILE:/mnt/config/kerberos/drupalwiki.keytab KVNO Principal ---- -------------------------------------------------------------------------- 16 HTTP/wiki.kwtest.local@KWTEST.LOCAL (arcfour-hmac)
/mnt/config/kerberos/drupalwiki.keytab
來自列出 SPN 的服務 Keytab 文件klist -ke /mnt/config/kerberos/drupalwiki.keytab Keytab name: FILE:/mnt/config/kerberos/drupalwiki.keytab KVNO Principal ---- -------------------------------------------------------------------------- 16 HTTP/wiki.kwtest.local@KWTEST.LOCAL (arcfour-hmac)
keytab
使用 SPN 使用文件登錄kinit -k -t /mnt/config/kerberos/drupalwiki.keytab HTTP/wiki.kwtest.local@KWTEST.LOCAL klist Ticket cache: FILE:/tmp/krb5cc_0 Default principal: HTTP/wiki.kwtest.local@KWTEST.LOCAL Valid starting Expires Service principal 01/07/2019 12:50:18 01/07/2019 22:50:18 krbtgt/KWTEST.LOCAL@KWTEST.LOCAL renew until 01/08/2019 12:50:18
問題(事情不工作):
票證轉發,因此現有的客戶票證,沒有經過驗證,而是提供了一個基本身份驗證表單來輸入憑據 - 如果我這樣做,我可以進行身份驗證。所以基本的 krb 身份驗證已經有效,只是不能進行票證轉發/驗證。
請注意,完全相同的客戶端(OSX Safari、OSX curl、Linux Curl),完全相同的 Debian Stretch 伺服器可以與
Apache2+mod_ker_auth
.keytab
所以它幾乎不可能是服務文件的直接問題/etc/krb5.conf
,否則 apache2 也不會工作,對吧?我是如何測試的
使用我的 OSX 客戶端進行測試
# wikiuser is an user in the same AD/KDC ( not the user of the SPN) kinit wikiuser@KWTEST.LOCAL # ticket exists klist Credentials cache: API:34173A61-DFBB-4191-A39C-62EF67F1AC39 Principal: wikiuser@KWTEST.LOCAL Issued Expires Principal Jan 7 13:26:38 2019 Jan 7 23:26:20 2019 krbtgt/KWTEST.LOCAL@KWTEST.LOCAL # the actual test curl -u : --negotiate http://wiki.kwtest.local/index.html <html> <head><title>401 Authorization Required</title></head> <body bgcolor="white"> <center><h1>401 Authorization Required</h1></center> <hr><center>nginx/1.10.3</center> </body> </html>
做同樣的測試,同時停止 nginx 並啟動 apache2
# on the Debian Service box service nginx stop && service apache2 start
現在在我的 OSX 盒子上
kinit curl -u : --negotiate http://wiki.kwtest.local/index.html worked!%
我試圖解決的問題
- 嘗試使用 rsyslog 和 debug=true / trace=/var/log/pamtrace 設置使 pam 盡可能詳細,但我從來沒有在那裡得到任何輸出。PAM 似乎只是以某種方式無法記錄身份驗證嘗試。只有當我填寫基本表單並實際驗證成功時,我才會在日誌中看到此嘗試 - 但使用現有票證的失敗嘗試根本不會記錄任何內容
- 玩弄所有的
pam_krb5
參數和設置之類的realm
,但我還是不能讓它工作- 使用 linux 客戶端使用 curl 進行測試,結果相同
現在讓我告訴我,如果我忘記了設置細節或資訊中的任何內容,我完全知道 kerberos 對所有這些東西都很複雜和敏感,我希望包括所有的點點滴滴
這個問題的簡短回答是,nginx_pam 根本不可能。
我要求的技術術語/協議是“GSSAPI”或基於 SPENGO 的 kerberos 票證身份驗證,因此如果使用者擁有現有的 kerberos 票證,則會自動登錄。
nginx_pam 沒有實現 SPENGO/GSSAPI,因此它永遠不會起作用。應該發生的是
- 在第一個請求中,客戶端請求資源(尚未發送任何身份驗證標頭)
- 我們的 nginx 將通過 nginx_pam 將其傳遞給 pam,然後 pam 應返回“未授權”(不存在 auth 標頭)。Nginx 現在應該向瀏覽器返回一個帶有“WWW-Authorize:negotiation”標頭的“401”(然後瀏覽器會自動發送一個新請求,其中包含“Authorization”標頭中的路邊票
- nginx 現在應該解壓該票證(基於 64 解碼等)並將票證傳遞給 pam (pam_krb)
- pam 將返回“ok”或“forbidden”(此使用者不允許).. 前者是 200,後者是 403,用於傳遞給客戶端的 nginx
步驟 2 不是 nginx_pam 實現的。另外,我猜(不確定),pam 只支持“授權”或“未授權”,所以是布爾值,而不是“未經身份驗證”、“授權”、“禁止”……所以第 2 步和第 4 步不能確定(相同)
**解決方案:**我切換到https://github.com/stnoonan/spnego-http-auth-nginx-module以獲得正確的基於 GSSAPI 的實現。