前言

最近在研究 EKS 用戶身份認證流程,做個筆記記錄一下。

流程

  1. 當用戶使用 kubectl 操作時,kubectl 會去讀取 ~/.kube/config 檔案內容
  2. ~/.kube/config 檔案內容再使用 EKS 場景下,一般都是透過 aws eks update-kubeconfig –name 指令產生,因此,內容大致如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ cat ~/.kube/config
- name: arn:aws:eks:ap-northeast-1:123456789012:cluster/eks-124
user:
exec:
apiVersion: client.authentication.k8s.io/v1beta1
args:
- --region
- ap-northeast-1
- eks
- get-token
- --cluster-name
- eks-124
- --output
- json
command: aws

上述文件內容表明了 ~/.kube/config 中的 token 是透過 aws eks get-token –cluster-name –region –output json 指令產生。若是攤開成命令,示例如下:

1
2
3
4
5
6
7
8
9
10
$ aws eks get-token --cluster-name eks-124 --region ap-northeast-1
{
"kind": "ExecCredential",
"apiVersion": "client.authentication.k8s.io/v1beta1",
"spec": {},
"status": {
"expirationTimestamp": "2024-07-13T18:08:55Z",
"token": "k8s-aws-v1.aHR0cHM6Ly9zdHMuYXAtbm9ydGhlYXN0LTEuYW1hem9uYXdzLmNvbS8_QWN0aW9uPUdldENhbGxlcklkZW50aXR5JlZlcnNpb249MjAxMS0wNi0xNSZYLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFVTkpDV0JISE9CNlRZUUc0JTJGMjAyNDA3MTMlMkZhcC1ub3J0aGVhc3QtMSUyRnN0cyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNzEzVDE3NTQ1NVomWC1BbXotRXhwaXJlcz02MCZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QlM0J4LWs4cy1hd3MtaWQmWC1BbXotU2lnbmF0dXJlPWQ1OTQxNmY4YWZmMGEwMTA3NzE4YTM0NDg1MzA5ZDEzZGQ0NDRmZWYyOTc3M2QzNDIwZjRjZjUzZWRmMDNiMDk"
}
}

kubectl 在向 API Server 發請求時,會在 header 中以 bearer token 的方式帶入這個 token 來做認證。我們可以透過 curl 驗證這個 token 可用性:

1
2
3
4
5
6
7
8
9
$ token=k8s-aws-v1.aHR0cHM6Ly9zdHMuYXAtbm9ydGhlYXN0LTEuYW1hem9uYXdzLmNvbS8_QWN0aW9uPUdldENhbGxlcklkZW50aXR5JlZlcnNpb249MjAxMS0wNi0xNSZYLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFVTkpDV0JISE9CNlRZUUc0JTJGMjAyNDA3MTMlMkZhcC1ub3J0aGVhc3QtMSUyRnN0cyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNzEzVDE3NTQ1NVomWC1BbXotRXhwaXJlcz02MCZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QlM0J4LWs4cy1hd3MtaWQmWC1BbXotU2lnbmF0dXJlPWQ1OTQxNmY4YWZmMGEwMTA3NzE4YTM0NDg1MzA5ZDEzZGQ0NDRmZWYyOTc3M2QzNDIwZjRjZjUzZWRmMDNiMDk
$ curl https://ABCDEFGHIJKLMNOPQRSTUVWXYZ123456.gr7.ap-northeast-1.eks.amazonaws.com --insecure -H "Authorization: Bearer $token"
{
"paths": [
"/.well-known/openid-configuration",
"/api",
"/api/v1",
...
}
  1. 當請求發送到 API Server 時,API Server 會將請求 header 中的 bearer token 轉給 authentication webhook,authentication webhook 會去解開 token 當中的內容,並呼叫內容當中的 pre-signed URL(GetCallerIdentity)與 IAM 服務進行用戶認證,並取得 account id,、account Arn、UserId 等資訊,如下示例:
1
2
$ echo "aHR0cHM6Ly9zdHMuYXAtbm9ydGhlYXN0LTEuYW1hem9uYXdzLmNvbS8_QWN0aW9uPUdldENhbGxlcklkZW50aXR5JlZlcnNpb249MjAxMS0wNi0xNSZYLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFVTkpDV0JISE9CNlRZUUc0JTJGMjAyNDA3MTMlMkZhcC1ub3J0aGVhc3QtMSUyRnN0cyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNzEzVDE3NTQ1NVomWC1BbXotRXhwaXJlcz02MCZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QlM0J4LWs4cy1hd3MtaWQmWC1BbXotU2lnbmF0dXJlPWQ1OTQxNmY4YWZmMGEwMTA3NzE4YTM0NDg1MzA5ZDEzZGQ0NDRmZWYyOTc3M2QzNDIwZjRjZjUzZWRmMDNiMDk" | base64 -d
https://sts.ap-northeast-1.amazonaws.com/?Action=GetCallerIdentity&Version=2011-06-15&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAUNJCWBHHOB6TYQG4%2F20240713%2Fap-northeast-1%2Fsts%2Faws4_request&X-Amz-Date=20240713T175455Z&X-Amz-Expires=60&X-Amz-SignedHeaders=host%3Bx-k8s-aws-id&X-Amz-Signature=d59416f8aff0a0107718a34485309d13dd444fef29773d3420f4cf53edf03b

在取得這些資訊之後,authentication webhook 會將結果回傳給 API Server

  1. API Server 取得 account id、account Arn、UserId 等資訊後,會去讀取 aws-auth ConfigMap 取得用戶在 kubernetes 當中對應的 RBAC 身份組,並確認用戶是否有權限操作資源。

參考

[1] https://aws.github.io/aws-eks-best-practices/security/docs/iam/#controlling-access-to-eks-clusters
[2] https://betterprogramming.pub/kubernetes-authentication-in-aws-eks-using-iam-authenticator-de3a586e885c