Skip to content

Commit 721ae39

Browse files
committed
filter_kubernetes: use service account issuer to detect EKS env
1 parent 912b7d7 commit 721ae39

File tree

2 files changed

+99
-12
lines changed

2 files changed

+99
-12
lines changed

plugins/filter_kubernetes/kube_conf.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,10 @@
7474
#define SERVICE_NAME_SOURCE_MAX_LEN 64
7575

7676
/*
77-
* Configmap used for verifying whether if FluentBit is
78-
* on EKS or native Kubernetes
77+
* Namespace and token path used for verifying whether FluentBit is
78+
* on EKS or native Kubernetes by inspecting serviceaccount token issuer
7979
*/
8080
#define KUBE_SYSTEM_NAMESPACE "kube-system"
81-
#define AWS_AUTH_CONFIG_MAP "aws-auth"
8281

8382
/*
8483
* Possible platform values for Kubernetes plugin

plugins/filter_kubernetes/kubernetes_aws.c

Lines changed: 97 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <fluent-bit/flb_jsmn.h>
2424
#include <fluent-bit/flb_record_accessor.h>
2525
#include <fluent-bit/flb_ra_key.h>
26+
#include <fluent-bit/flb_utils.h>
2627

2728
#include "kube_conf.h"
2829
#include "kube_meta.h"
@@ -282,19 +283,106 @@ int fetch_pod_service_map(struct flb_kube *ctx, char *api_server_url,
282283
return 0;
283284
}
284285

285-
/* Determine platform by checking aws-auth configmap */
286+
/* Determine platform by checking serviceaccount token issuer */
286287
int determine_platform(struct flb_kube *ctx)
287288
{
288289
int ret;
289-
char *config_buf;
290-
size_t config_size;
291-
292-
ret = get_api_server_configmap(ctx, KUBE_SYSTEM_NAMESPACE, AWS_AUTH_CONFIG_MAP, &config_buf, &config_size);
293-
if (ret != -1) {
294-
flb_free(config_buf);
295-
return 1;
290+
char *token_buf = NULL;
291+
size_t token_size;
292+
char *payload = NULL;
293+
size_t payload_len;
294+
char *issuer_start, *issuer_end;
295+
296+
/* Read serviceaccount token */
297+
ret = flb_utils_read_file(FLB_KUBE_TOKEN, &token_buf, &token_size);
298+
if (ret != 0 || !token_buf) {
299+
return -1;
300+
}
301+
302+
/* JWT tokens have 3 parts separated by dots: header.payload.signature */
303+
char *first_dot = strchr(token_buf, '.');
304+
if (!first_dot) {
305+
flb_free(token_buf);
306+
return -1;
307+
}
308+
309+
char *second_dot = strchr(first_dot + 1, '.');
310+
if (!second_dot) {
311+
flb_free(token_buf);
312+
return -1;
313+
}
314+
315+
/* Extract and decode the payload (middle part) */
316+
size_t payload_b64_len = second_dot - (first_dot + 1);
317+
char *payload_b64 = flb_malloc(payload_b64_len + 1);
318+
if (!payload_b64) {
319+
flb_free(token_buf);
320+
return -1;
321+
}
322+
323+
memcpy(payload_b64, first_dot + 1, payload_b64_len);
324+
payload_b64[payload_b64_len] = '\0';
325+
326+
/* Base64 decode the payload */
327+
payload = flb_malloc(payload_b64_len * 3 / 4 + 4); /* Conservative size estimate */
328+
if (!payload) {
329+
flb_free(token_buf);
330+
flb_free(payload_b64);
331+
return -1;
332+
}
333+
334+
ret = flb_base64_decode((unsigned char *)payload, payload_b64_len * 3 / 4 + 4,
335+
&payload_len, (unsigned char *)payload_b64, payload_b64_len);
336+
337+
flb_free(token_buf);
338+
flb_free(payload_b64);
339+
340+
if (ret != 0) {
341+
flb_free(payload);
342+
return -1;
343+
}
344+
345+
payload[payload_len] = '\0';
346+
347+
/* Look for "iss" field in the JSON payload */
348+
issuer_start = strstr(payload, "\"iss\":");
349+
if (!issuer_start) {
350+
flb_free(payload);
351+
return -1;
352+
}
353+
354+
/* Skip to the value part */
355+
issuer_start = strchr(issuer_start, ':');
356+
if (!issuer_start) {
357+
flb_free(payload);
358+
return -1;
296359
}
297-
return -1;
360+
issuer_start++;
361+
362+
/* Skip whitespace and opening quote */
363+
while (*issuer_start == ' ' || *issuer_start == '\t') issuer_start++;
364+
if (*issuer_start != '"') {
365+
flb_free(payload);
366+
return -1;
367+
}
368+
issuer_start++;
369+
370+
/* Find closing quote */
371+
issuer_end = strchr(issuer_start, '"');
372+
if (!issuer_end) {
373+
flb_free(payload);
374+
return -1;
375+
}
376+
377+
/* Check if issuer contains EKS OIDC URL pattern */
378+
/* EKS OIDC URLs follow pattern: https://oidc.eks.{region}.amazonaws.com/id/{cluster-id} */
379+
if (strstr(issuer_start, "oidc.eks.") && strstr(issuer_start, ".amazonaws.com/id/")) {
380+
flb_free(payload);
381+
return 1; /* EKS detected */
382+
}
383+
384+
flb_free(payload);
385+
return -1; /* Not EKS */
298386
}
299387

300388
/* Gather pods list information from Kubelet */

0 commit comments

Comments
 (0)