k8s接入ldap

weixin_33782386發表於2018-09-06

為了對接上 LDAP,可謂是煞費苦心。網上能找到的對接上 LDAP 的方案,都得在 LDAP 上自定義一個 token 的 schema,然後將在 k8s 叢集上已建立好的 service account 的 token 跟 LDAP 繫結起來。這樣,在進行 webhook 認證時,便能帶著 token 去 LDAP 上進行認證。例如這裡所描述的:Kubernetes-LDAP-Authentication。另外,還有些是對接上 OpenID connect token,然後再這些服務提供系統那裡對接上 LDAP,例如:Step by step guide to integrate LDAP with Kubernetes。這種辦法又覺得太複雜,麻煩了。

使用 webhook 進行 LDAP 認證,平常的使用者名稱密碼認證行不通的主要原因是 k8s apiserver 進行認證請求時,帶過來只有使用者名稱和 bearer token,沒有密碼。為了能夠使用使用者名稱密碼和 bearer token 去 ldap 進行認證,這裡做了些 trick 的東西。

如下圖所示,客戶端通過 nginx 訪問 apiserver,在 nginx 一層裡,配置了 auth-request,將 basic auth 的請求傳送給後端的 ldap 認證代理,ldap 認證代理認證通過後,會隨機生成一段 bearer token,並通過相應頭部告訴給 nginx。nginx 收到這個響應頭部後,就配置使用 bearer token 訪問 apiserver。也就是說,請求到達 apiserver 的時候,使用的是 bearer token 這種方式進行認證。apiserver 收到請求後,會同時出發內部認證機制和 webhook 認證機制,webhook 認證在這裡同樣配置了 nginx 的 ldap 認證代理。由於 ldap 認證代理儲存了所有經過 ldap 認證的使用者的 bearer token,因此便可以通過 apiserver 帶過來的 bearer token 成功認證使用者!

18127-5d3d54857a18ea57.png
ldap認證流程圖

如果需要更細粒度的許可權控制,可以在 ldap 認證代理那裡,接入公司的一些內部系統,根據不同的使用者,返回不同的使用者組即可。

附 nginx 關鍵配置

 location / {
       auth_request /auth-proxy;
       # 這裡獲取從ldap認證服務返回來的bearer token 
       auth_request_set $bearer_token $upstream_http_x_token;
       proxy_set_header   Host             $host;
       proxy_set_header X-Real-IP $remote_addr;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       # 設定bearer token認證
       proxy_set_header Authorization "Bearer $bearer_token";
       proxy_ssl_verify       off;
       proxy_ssl_session_reuse on;
       proxy_pass         https://dashboard-k8s;
    }
 
    location = /auth-proxy {
        internal;
        proxy_pass http://k8s-ldap-backend/ldap-auth;
        proxy_pass_request_body off;
        proxy_set_header Content-Length "";
        proxy_cache ldap_auth_cache;
        proxy_cache_valid 200 30m;
        proxy_cache_key "$http_authorization$cookie_nginxauth";
    }

相關文章