├── CONTRIBUTING.md ├── LICENSE.md ├── README.md └── bash └── kubectl-sudo /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | Thanks for contributing to this repository. Please read the following guidelines before you submit a pull request. 3 | 4 | ## Pull request and issues 5 | If your commit does not change something fundamental, it is fine to create a pull request directly. 6 | If you want to make a larger change or are unsure of the implication(s) of your change, please first create an issue, so that we can discuss it. 7 | 8 | In all cases, please give the change a short and concise description. 9 | 10 | ## Commit messages 11 | Every commit message must be meaningful. 12 | Please do not write meaningless words or sentences like "fix", but be short and concise as in "fix divide by zero where altitude is zero in CalculateDistance()". 13 | If the added code requires greater explanation, please document it in the code. 14 | 15 | ## Tests 16 | If you introduce some new function or make a behavioural change, please create tests for the change. 17 | However, it is better to write no tests than make nonsensical ones that convey a false sense of confidence. 18 | 19 | ## Code quality 20 | Please check what other code in this repository looks like and adhere to language specific guidelines. 21 | The code should be clear and any "magic" must be appropriately documented. Please rethink your work twice, as clear, safe and performant code will make you feel better. 22 | 23 | ## Security 24 | Please try to ensure that your code has no vulnerabilities and document every possible security impact. 25 | 26 | ## Documentation 27 | If reasonable, please document the changes either in the code itself or separately. 28 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright 2018 PostFinance AG 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | **Table of Contents** 4 | 5 | - [kubectl sudo](#kubectl-sudo) 6 | - [TL;DR](#tldr) 7 | - [Why](#why) 8 | - [How](#how) 9 | - [Installation](#installation) 10 | - [Plugin Compatibility](#plugin-compatibility) 11 | - [Configuration](#configuration) 12 | - [Similar projects](#similar-projects) 13 | 14 | 15 | 16 | # kubectl sudo 17 | 18 | ## TL;DR 19 | This plugin allows users to run kubernetes commands with the security privileges of another user: 20 | 21 | ```bash 22 | $ kubectl get nodes 23 | Error from server (Forbidden): nodes is forbidden: User "bofh" cannot list nodes at the cluster scope 24 | ``` 25 | 26 | ```bash 27 | $ kubectl sudo get nodes 28 | NAME STATUS ROLES AGE VERSION 29 | kubelet1.example.com Ready 96d v1.11.2 30 | kubelet2.example.com Ready 96d v1.11.2 31 | ``` 32 | 33 | With audit log containing the origin and the impersonated user and group, if configured correctly: 34 | ```json 35 | { 36 | "kind": "Event", 37 | "apiVersion": "audit.k8s.io/v1beta1", 38 | "level": "Metadata", 39 | "stage": "ResponseComplete", 40 | "requestURI": "/api/v1/nodes?limit=500", 41 | "verb": "list", 42 | "user": { 43 | "username": "bofh", 44 | "groups": [ 45 | "bofh_accounts", 46 | "system:authenticated" 47 | ] 48 | }, 49 | "impersonatedUser": { 50 | "username": "bofh", 51 | " groups": [ 52 | "system:masters" 53 | ] 54 | }, 55 | "objectRef": { 56 | "resource": "nodes", 57 | "apiVersion": "v1" 58 | }, 59 | } 60 | ``` 61 | 62 | ## Why 63 | Kubernetes cluster administrators have great power. A mistake could 64 | cause the cluster to become unhealthy or insecure and, as such, could impact 65 | any or all tenants sharing the cluster. A simple `kubectl -f` with the wrong namespace 66 | can end badly. 67 | 68 | ## How 69 | This project does not really introduce a kubectl plugin, but a concept 70 | of how to provide a sudo like system for kubernetes access. 71 | 72 | To reduce the surface of unwanted or unexpected actions you can reduce the default priviledges 73 | a cluster administrator has to the level of an unprivileged account and give them the ability to impersonate users and groups. 74 | When cluster administrators need to do more priviledged actions, they can switch 75 | the group to `system:masters` or another group or user according to the needed privilidge level. 76 | 77 | In order to implement that concept, you need to declare a `ClusterRole` for 78 | [impersonation](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#user-impersonation): 79 | 80 | ```yaml 81 | --- 82 | apiVersion: rbac.authorization.k8s.io/v1 83 | kind: ClusterRole 84 | metadata: 85 | name: impersonator 86 | rules: 87 | - apiGroups: [""] 88 | verbs: ["impersonate"] 89 | resources: ["users", "groups", "serviceaccounts"] 90 | ``` 91 | 92 | Now you can assign this ClusterRole to the cluster administrators (e.g. group `bofh_accounts`): 93 | ```yaml 94 | --- 95 | apiVersion: rbac.authorization.k8s.io/v1 96 | kind: ClusterRoleBinding 97 | metadata: 98 | name: cluster-administrators 99 | roleRef: 100 | apiGroup: rbac.authorization.k8s.io 101 | kind: ClusterRole 102 | name: impersonator 103 | subjects: 104 | - apiGroup: rbac.authorization.k8s.io 105 | kind: Group 106 | name: bofh_accounts 107 | ``` 108 | 109 | Any user which has the group `bofh_accounts` can now do administration tasks with: 110 | 111 | ``` 112 | kubectl --as=$USER --as-group=system:masters delete node kubelet3.example.com 113 | ``` 114 | 115 | The provided kubectl plugin is just a wrapper for `kubectl` to shorten the `--as` and `--as-group` part. 116 | 117 | ## Installation 118 | Place [kubectl-sudo](bash/kubectl-sudo) anywhere in your `$PATH` with execute permissions. 119 | For further information, see the offical [plugin documentation](https://kubernetes.io/docs/tasks/extend-kubectl/kubectl-plugins/). 120 | 121 | ## Plugin Compatibility 122 | Works on systems with `/bin/sh` and kubectl >= 1.12. `kubectl` must be inside `$PATH`. 123 | 124 | ## Configuration 125 | This plugin can be configured using environment variables: 126 | - `KUBECTL_SUDO_PROMPT=true` whether or not the plugin prompts the user before executing the kubectl command. Default value is `false`. 127 | 128 | ## Similar projects 129 | * [cloudogu/helm-sudo](https://github.com/cloudogu/helm-sudo): Same functionality as kubectl-sudo for [helm](https://helm.sh/) 130 | * [cloudogu/sudo-kubeconfig](https://github.com/cloudogu/sudo-kubeconfig): Create a sudo kubeconfig for your current kubernetes context. 131 | -------------------------------------------------------------------------------- /bash/kubectl-sudo: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | KUBECTL_SUDO_PROMPT=${KUBECTL_SUDO_PROMPT:-false} 4 | if [ "$KUBECTL_SUDO_PROMPT" = true ]; then 5 | read -p "WARNING: Currently in context $(kubectl config current-context). Continue? (y/N) " yn 6 | case $yn in 7 | [Yy]* ) ;; 8 | * ) exit 1;; 9 | esac 10 | fi 11 | 12 | NEW_ARGS="" 13 | PLUGIN_NAME="" 14 | COMMAND="" 15 | 16 | for arg in "$@" 17 | do 18 | if [ "${arg}" != "--"* ] && [ -z "${COMMAND}" ]; then 19 | COMMAND=${arg} 20 | fi 21 | plugin_path=$(which "kubectl-${COMMAND}" 2>/dev/null) 22 | if [ -x "${plugin_path}" ] && [ -z "${PLUGIN_NAME}" ]; then 23 | PLUGIN_NAME=$arg 24 | continue 25 | fi 26 | NEW_ARGS="${NEW_ARGS} ${arg}" 27 | done 28 | 29 | if [ -z "${PLUGIN_NAME}" ]; then 30 | if command -v kubecolor >/dev/null; then 31 | exec kubecolor --as=${USER} --as-group=system:masters "$@" 32 | else 33 | exec kubectl --as=${USER} --as-group=system:masters "$@" 34 | fi 35 | else 36 | if command -v kubecolor >/dev/null; then 37 | exec kubecolor ${PLUGIN_NAME} --as=${USER} --as-group=system:masters ${NEW_ARGS} 38 | else 39 | exec kubectl ${PLUGIN_NAME} --as=${USER} --as-group=system:masters ${NEW_ARGS} 40 | fi 41 | fi 42 | --------------------------------------------------------------------------------