From 1c0104ab733ce709eb6075f3a26d9684df575929 Mon Sep 17 00:00:00 2001 From: Hyunsoo Kim Date: Tue, 7 Oct 2025 10:04:30 -0400 Subject: [PATCH] filter_kubernetes: use service account issuer to detect EKS env Signed-off-by: Hyunsoo Kim --- plugins/filter_kubernetes/kube_conf.h | 5 +- plugins/filter_kubernetes/kubernetes_aws.c | 106 +++++++++++++++++++-- 2 files changed, 99 insertions(+), 12 deletions(-) diff --git a/plugins/filter_kubernetes/kube_conf.h b/plugins/filter_kubernetes/kube_conf.h index 1c8cad038fb..cb36f2d7ac9 100644 --- a/plugins/filter_kubernetes/kube_conf.h +++ b/plugins/filter_kubernetes/kube_conf.h @@ -74,11 +74,10 @@ #define SERVICE_NAME_SOURCE_MAX_LEN 64 /* - * Configmap used for verifying whether if FluentBit is - * on EKS or native Kubernetes + * Namespace and token path used for verifying whether FluentBit is + * on EKS or native Kubernetes by inspecting serviceaccount token issuer */ #define KUBE_SYSTEM_NAMESPACE "kube-system" -#define AWS_AUTH_CONFIG_MAP "aws-auth" /* * Possible platform values for Kubernetes plugin diff --git a/plugins/filter_kubernetes/kubernetes_aws.c b/plugins/filter_kubernetes/kubernetes_aws.c index 340c1913989..7418de93b98 100644 --- a/plugins/filter_kubernetes/kubernetes_aws.c +++ b/plugins/filter_kubernetes/kubernetes_aws.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "kube_conf.h" #include "kube_meta.h" @@ -282,19 +283,106 @@ int fetch_pod_service_map(struct flb_kube *ctx, char *api_server_url, return 0; } -/* Determine platform by checking aws-auth configmap */ +/* Determine platform by checking serviceaccount token issuer */ int determine_platform(struct flb_kube *ctx) { int ret; - char *config_buf; - size_t config_size; - - ret = get_api_server_configmap(ctx, KUBE_SYSTEM_NAMESPACE, AWS_AUTH_CONFIG_MAP, &config_buf, &config_size); - if (ret != -1) { - flb_free(config_buf); - return 1; + char *token_buf = NULL; + size_t token_size; + char *payload = NULL; + size_t payload_len; + char *issuer_start, *issuer_end; + + /* Read serviceaccount token */ + ret = flb_utils_read_file(FLB_KUBE_TOKEN, &token_buf, &token_size); + if (ret != 0 || !token_buf) { + return -1; + } + + /* JWT tokens have 3 parts separated by dots: header.payload.signature */ + char *first_dot = strchr(token_buf, '.'); + if (!first_dot) { + flb_free(token_buf); + return -1; + } + + char *second_dot = strchr(first_dot + 1, '.'); + if (!second_dot) { + flb_free(token_buf); + return -1; + } + + /* Extract and decode the payload (middle part) */ + size_t payload_b64_len = second_dot - (first_dot + 1); + char *payload_b64 = flb_malloc(payload_b64_len + 1); + if (!payload_b64) { + flb_free(token_buf); + return -1; + } + + memcpy(payload_b64, first_dot + 1, payload_b64_len); + payload_b64[payload_b64_len] = '\0'; + + /* Base64 decode the payload */ + payload = flb_malloc(payload_b64_len * 3 / 4 + 4); /* Conservative size estimate */ + if (!payload) { + flb_free(token_buf); + flb_free(payload_b64); + return -1; + } + + ret = flb_base64_decode((unsigned char *)payload, payload_b64_len * 3 / 4 + 4, + &payload_len, (unsigned char *)payload_b64, payload_b64_len); + + flb_free(token_buf); + flb_free(payload_b64); + + if (ret != 0) { + flb_free(payload); + return -1; + } + + payload[payload_len] = '\0'; + + /* Look for "iss" field in the JSON payload */ + issuer_start = strstr(payload, "\"iss\":"); + if (!issuer_start) { + flb_free(payload); + return -1; + } + + /* Skip to the value part */ + issuer_start = strchr(issuer_start, ':'); + if (!issuer_start) { + flb_free(payload); + return -1; } - return -1; + issuer_start++; + + /* Skip whitespace and opening quote */ + while (*issuer_start == ' ' || *issuer_start == '\t') issuer_start++; + if (*issuer_start != '"') { + flb_free(payload); + return -1; + } + issuer_start++; + + /* Find closing quote */ + issuer_end = strchr(issuer_start, '"'); + if (!issuer_end) { + flb_free(payload); + return -1; + } + + /* Check if issuer contains EKS OIDC URL pattern */ + /* EKS OIDC URLs follow pattern: https://oidc.eks.{region}.amazonaws.com/id/{cluster-id} */ + if (strstr(issuer_start, "oidc.eks.") && strstr(issuer_start, ".amazonaws.com/id/")) { + flb_free(payload); + return 1; /* EKS detected */ + } + + flb_free(payload); + return -1; /* Not EKS */ } /* Gather pods list information from Kubelet */