為了對(duì)接上 LDAP搞动,可謂是煞費(fèi)苦心仗岖。網(wǎng)上能找到的對(duì)接上 LDAP 的方案,都得在 LDAP 上自定義一個(gè) token 的 schema捕虽,然后將在 k8s 集群上已創(chuàng)建好的 service account 的 token 跟 LDAP 綁定起來(lái)幸海。這樣祟身,在進(jìn)行 webhook 認(rèn)證時(shí),便能帶著 token 去 LDAP 上進(jìn)行認(rèn)證涕烧。例如這里所描述的:Kubernetes-LDAP-Authentication月而。另外,還有些是對(duì)接上 OpenID connect token议纯,然后再這些服務(wù)提供系統(tǒng)那里對(duì)接上 LDAP父款,例如:Step by step guide to integrate LDAP with Kubernetes。這種辦法又覺(jué)得太復(fù)雜瞻凤,麻煩了憨攒。
使用 webhook 進(jìn)行 LDAP 認(rèn)證,平常的用戶(hù)名密碼認(rèn)證行不通的主要原因是 k8s apiserver 進(jìn)行認(rèn)證請(qǐng)求時(shí)阀参,帶過(guò)來(lái)只有用戶(hù)名和 bearer token肝集,沒(méi)有密碼。為了能夠使用用戶(hù)名密碼和 bearer token 去 ldap 進(jìn)行認(rèn)證蛛壳,這里做了些 trick 的東西杏瞻。
如下圖所示,客戶(hù)端通過(guò) nginx 訪問(wèn) apiserver衙荐,在 nginx 一層里捞挥,配置了 auth-request,將 basic auth 的請(qǐng)求發(fā)送給后端的 ldap 認(rèn)證代理忧吟,ldap 認(rèn)證代理認(rèn)證通過(guò)后砌函,會(huì)隨機(jī)生成一段 bearer token,并通過(guò)相應(yīng)頭部告訴給 nginx。nginx 收到這個(gè)響應(yīng)頭部后讹俊,就配置使用 bearer token 訪問(wèn) apiserver垦沉。也就是說(shuō),請(qǐng)求到達(dá) apiserver 的時(shí)候仍劈,使用的是 bearer token 這種方式進(jìn)行認(rèn)證厕倍。apiserver 收到請(qǐng)求后,會(huì)同時(shí)出發(fā)內(nèi)部認(rèn)證機(jī)制和 webhook 認(rèn)證機(jī)制耳奕,webhook 認(rèn)證在這里同樣配置了 nginx 的 ldap 認(rèn)證代理绑青。由于 ldap 認(rèn)證代理保存了所有經(jīng)過(guò) ldap 認(rèn)證的用戶(hù)的 bearer token,因此便可以通過(guò) apiserver 帶過(guò)來(lái)的 bearer token 成功認(rèn)證用戶(hù)屋群!
如果需要更細(xì)粒度的權(quán)限控制,可以在 ldap 認(rèn)證代理那里坏挠,接入公司的一些內(nèi)部系統(tǒng)芍躏,根據(jù)不同的用戶(hù),返回不同的用戶(hù)組即可降狠。
附 nginx 關(guān)鍵配置
location / {
auth_request /auth-proxy;
# 這里獲取從ldap認(rèn)證服務(wù)返回來(lái)的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;
# 設(shè)置bearer token認(rèn)證
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";
}