From 90d5468ad6119d8668343802cb63f1a6a9fc2152 Mon Sep 17 00:00:00 2001 From: Jaka Hudoklin Date: Mon, 12 Dec 2016 01:27:14 +0100 Subject: [PATCH] kubernetes module: authorization improvements --- nixos/modules/services/cluster/kubernetes.nix | 131 +++++++++++++----- 1 file changed, 99 insertions(+), 32 deletions(-) diff --git a/nixos/modules/services/cluster/kubernetes.nix b/nixos/modules/services/cluster/kubernetes.nix index f7464ca0557..8177233b3ed 100644 --- a/nixos/modules/services/cluster/kubernetes.nix +++ b/nixos/modules/services/cluster/kubernetes.nix @@ -39,12 +39,9 @@ let }]; }); - policyFile = pkgs.writeText "kube-policy" - (concatStringsSep "\n" (map builtins.toJSON cfg.apiserver.authorizationPolicy)); - cniConfig = pkgs.buildEnv { name = "kubernetes-cni-config"; - paths = imap1 (i: entry: + paths = imap (i: entry: pkgs.writeTextDir "${toString (10+i)}-${entry.type}.conf" (builtins.toJSON entry) ) cfg.kubelet.cni.config; }; @@ -205,23 +202,33 @@ in { type = types.nullOr types.path; }; - tokenAuth = mkOption { + tokenAuthFile = mkOption { description = '' Kubernetes apiserver token authentication file. See ''; default = null; - example = ''token,user,uid,"group1,group2,group3"''; - type = types.nullOr types.lines; + type = types.nullOr types.path; + }; + + basicAuthFile = mkOption { + description = '' + Kubernetes apiserver basic authentication file. See + + ''; + default = pkgs.writeText "users" '' + kubernetes,admin,0 + ''; + type = types.nullOr types.path; }; authorizationMode = mkOption { description = '' - Kubernetes apiserver authorization mode (AlwaysAllow/AlwaysDeny/ABAC). See - + Kubernetes apiserver authorization mode (AlwaysAllow/AlwaysDeny/ABAC/RBAC). See + ''; - default = "AlwaysAllow"; - type = types.enum ["AlwaysAllow" "AlwaysDeny" "ABAC"]; + default = ["ABAC" "RBAC"]; + type = types.listOf (types.enum ["AlwaysAllow" "AlwaysDeny" "ABAC" "RBAC"]); }; authorizationPolicy = mkOption { @@ -229,21 +236,72 @@ in { Kubernetes apiserver authorization policy file. See ''; - default = []; - example = literalExample '' - [ - {user = "admin";} - {user = "scheduler"; readonly = true; kind= "pods";} - {user = "scheduler"; kind = "bindings";} - {user = "kubelet"; readonly = true; kind = "bindings";} - {user = "kubelet"; kind = "events";} - {user= "alice"; ns = "projectCaribou";} - {user = "bob"; readonly = true; ns = "projectCaribou";} - ] - ''; + default = [ + { + apiVersion = "abac.authorization.kubernetes.io/v1beta1"; + kind = "Policy"; + spec = { + user = "admin"; + namespace = "*"; + resource = "*"; + apiGroup = "*"; + nonResourcePath = "*"; + }; + } + { + apiVersion = "abac.authorization.kubernetes.io/v1beta1"; + kind = "Policy"; + spec = { + user = "kubecfg"; + namespace = "*"; + resource = "*"; + apiGroup = "*"; + nonResourcePath = "*"; + }; + } + { + apiVersion = "abac.authorization.kubernetes.io/v1beta1"; + kind = "Policy"; + spec = { + user = "kubelet"; + namespace = "*"; + resource = "*"; + apiGroup = "*"; + nonResourcePath = "*"; + }; + } + { + apiVersion = "abac.authorization.kubernetes.io/v1beta1"; + kind = "Policy"; + spec = { + user = "kube"; + namespace = "*"; + resource = "*"; + apiGroup = "*"; + nonResourcePath = "*"; + }; + } + { + apiVersion = "abac.authorization.kubernetes.io/v1beta1"; + kind = "Policy"; + spec = { + user = "system:serviceaccount:kube-system:default"; + namespace = "*"; + resource = "*"; + apiGroup = "*"; + nonResourcePath = "*"; + }; + } + ]; type = types.listOf types.attrs; }; + autorizationRBACSuperAdmin = mkOption { + description = "Role based authorization super admin"; + default = "admin"; + type = types.str; + }; + allowPrivileged = mkOption { description = "Whether to allow privileged containers on kubernetes."; default = true; @@ -261,7 +319,7 @@ in { Api runtime configuration. See ''; - default = ""; + default = "rbac.authorization.k8s.io/v1alpha1"; example = "api/all=false,api/v1=true"; type = types.str; }; @@ -654,9 +712,11 @@ in { "--tls-cert-file=${cfg.apiserver.tlsCertFile}"} \ ${optionalString (cfg.apiserver.tlsKeyFile != null) "--tls-private-key-file=${cfg.apiserver.tlsKeyFile}"} \ - ${optionalString (cfg.apiserver.tokenAuth != null) - "--token-auth-file=${cfg.apiserver.tokenAuth}"} \ - --kubelet-https=${boolToString cfg.apiserver.kubeletHttps} \ + ${optionalString (cfg.apiserver.tokenAuthFile != null) + "--token-auth-file=${cfg.apiserver.tokenAuthFile}"} \ + ${optionalString (cfg.apiserver.basicAuthFile != null) + "--basic-auth-file=${cfg.apiserver.basicAuthFile}"} \ + --kubelet-https=${if cfg.apiserver.kubeletHttps then "true" else "false"} \ ${optionalString (cfg.apiserver.kubeletClientCaFile != null) "--kubelet-certificate-authority=${cfg.apiserver.kubeletClientCaFile}"} \ ${optionalString (cfg.apiserver.kubeletClientCertFile != null) @@ -665,9 +725,15 @@ in { "--kubelet-client-key=${cfg.apiserver.kubeletClientKeyFile}"} \ ${optionalString (cfg.apiserver.clientCaFile != null) "--client-ca-file=${cfg.apiserver.clientCaFile}"} \ - --authorization-mode=${cfg.apiserver.authorizationMode} \ - ${optionalString (cfg.apiserver.authorizationMode == "ABAC") - "--authorization-policy-file=${policyFile}"} \ + --authorization-mode=${concatStringsSep "," cfg.apiserver.authorizationMode} \ + ${optionalString (elem "ABAC" cfg.apiserver.authorizationMode) + "--authorization-policy-file=${ + pkgs.writeText "kube-auth-policy" + (concatMapStringsSep "\n" (l: builtins.toJSON l) cfg.apiserver.authorizationPolicy) + }" + } \ + ${optionalString (elem "RBAC" cfg.apiserver.authorizationMode) + "--authorization-rbac-super-user=${cfg.apiserver.autorizationRBACSuperAdmin}"} \ --secure-port=${toString cfg.apiserver.securePort} \ --service-cluster-ip-range=${cfg.apiserver.portalNet} \ ${optionalString (cfg.apiserver.runtimeConfig != "") @@ -730,8 +796,9 @@ in { ${if (cfg.controllerManager.serviceAccountKeyFile!=null) then "--service-account-private-key-file=${cfg.controllerManager.serviceAccountKeyFile}" else "--service-account-private-key-file=/var/run/kubernetes/apiserver.key"} \ - ${optionalString (cfg.controllerManager.rootCaFile!=null) - "--root-ca-file=${cfg.controllerManager.rootCaFile}"} \ + ${if (cfg.controllerManager.rootCaFile!=null) + then "--root-ca-file=${cfg.controllerManager.rootCaFile}" + else "--root-ca-file=/var/run/kubernetes/apiserver.crt"} \ ${optionalString (cfg.controllerManager.clusterCidr!=null) "--cluster-cidr=${cfg.controllerManager.clusterCidr}"} \ --allocate-node-cidrs=true \