kubectl to allow user to only to copy files in and out of the pods - kubernetes

I have a Kubernetes cluster where my application is deployed.
there are some other users they should only be able to copy files into and from a pod. Using kubectl cp command.
This user context should not allow the user to do any other operations on the cluster other than kubectl cp.

kubectl cp internally uses exec. There is no way to provide permission to only copy but you can provide only exec permission.
Create a role with permission to pods/exec
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-exec
rules:
- apiGroups: [""]
resources: ["pods/exec"]
verbs: ["create"]
Create a Rolebinding to assign the above role to a user.
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: pod-exec-binding
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: pod-exec
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: user

Rather than use kubectl cp, instead run a sidecar container with an sftp or rsync server. That will give you better control at all levels.

You can use opa and admission controller which only permit to run api manifest has a specific label like "cp" or "username" etc. and also benefits from gatekeeper
https://www.youtube.com/watch?v=ZJgaGJm9NJE&t=3040s

Related

Kubernetes RBAC roles with resourceName and listing objects

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: p-viewer-role
namespace: pepsi
rules:
- apiGroups:
- ""
resourceNames:
- p83
resources:
- pods
verbs:
- list
- get
- watch
When we use resourceNames in the Roles, the following command works
kubectl get pods -n pepsi p83
returns a proper value. However,
kubectl get pods -n pepsi
returns forbidden. Why doesn't it list p83
RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: p-viewer-rolebinding
namespace: pepsi
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: p-viewer-role
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: pepsi-project-viewer
namespace: project
This is expected behavior. You have defined a role which is scoped to the namespace pepsi to pod resources with specific resourceName p83.
For kubectl get pods -n peps command to work you need to remove the resourceNames p83 from the Role
This kind of advanced validation is best handled by OPA where you can define fine grained policies.
Short answer:
list(and watch)actually can be restricted by their resource name, and permits list(and watch) requests using a fieldSelector of metadata.name=... to match a single object (for example, /api/v1/namespaces/$ns/configmaps?fieldSelector=metadata.name=foo)
For more details and some tests you can check this link: https://github.com/kubernetes/website/pull/29468
#sftim and #liggitt do offer a lot of help!

RBAC not working as expected when trying to lock namespace

I'm trying to lock down a namespace in kubernetes using RBAC so I followed this tutorial.
I'm working on a baremetal cluster (no minikube, no cloud provider) and installed kubernetes using Ansible.
I created the folowing namespace :
apiVersion: v1
kind: Namespace
metadata:
name: lockdown
Service account :
apiVersion: v1
kind: ServiceAccount
metadata:
name: sa-lockdown
namespace: lockdown
Role :
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: lockdown
rules:
- apiGroups: [""] # "" indicates the core API group
resources: [""]
verbs: [""]
RoleBinding :
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: rb-lockdown
subjects:
- kind: ServiceAccount
name: sa-lockdown
roleRef:
kind: Role
name: lockdown
apiGroup: rbac.authorization.k8s.io
And finally I tested the authorization using the next command
kubectl auth can-i get pods --namespace lockdown --as system:serviceaccount:lockdown:sa-lockdown
This SHOULD be returning "No" but I got "Yes" :-(
What am I doing wrong ?
Thx
A couple possibilities:
are you running the "can-i" check against the secured port or unsecured port (add --v=6 to see). Requests made against the unsecured (non-https) port are always authorized.
RBAC is additive, so if there is an existing clusterrolebinding or rolebinding granting "get pods" permissions to that service account (or one of the groups system:serviceaccounts:lockdown, system:serviceaccounts, or system:authenticated), then that service account will have that permission. You cannot "ungrant" permissions by binding more restrictive roles
I finally found what was the problem.
The role and rolebinding must be created inside the targeted namespace.
I changed the following role and rolebinding types by specifying the namespace inside the yaml directly.
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: lockdown
namespace: lockdown
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- watch
- list
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: rb-lockdown
namespace: lockdown
subjects:
- kind: ServiceAccount
name: sa-lockdown
roleRef:
kind: Role
name: lockdown
apiGroup: rbac.authorization.k8s.io
In this example I gave permission to the user sa-lockdown to get, watch and list the pods in the namespace lockdown.
Now if I ask to get the pods : kubectl auth can-i get pods --namespace lockdown --as system:serviceaccount:lockdown:sa-lockdown it will return yes.
On the contrary if ask to get the deployments : kubectl auth can-i get deployments --namespace lockdown --as system:serviceaccount:lockdown:sa-lockdown it will return no.
You can also leave the files like they were in the question and simply create them using kubectl create -f <file> -n lockdown.

Problems with simple RBAC example

I want to make a very simple example to learn how to use RBAC authorization in kubernetes. Therefore I use the example from the docs:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: dev
name: dev-readpods-role
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: dev-tester-rolebinding
namespace: dev
subjects:
- kind: User
name: Tester
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: dev-readpods-role
apiGroup: rbac.authorization.k8s.io
The role and the rolebinding are created.
When I log in with Tester and try
kubectl get pods -n dev
I get
Error from server (Forbidden): pods is forbidden: User "<url>:<port>/oidc/endpoint/OP#Tester" cannot list pods in the namespace "dev"
I read here (RBAC Error in Kubernetes) that the api-server have to be started with --authorization-mode=…,RBAC. How can I check this? I read somewhere else that if I run
kubectl api-versions | findstr rbac
and find entries RBAC should be activated. Is that true?
What am I doing wrong? Is there a good way to troubleshoot?
Thanks!
P.S. I'm running kubernetes inside IBM Cloud Private.
In ICP, it looks encouraging to use Teams (ICP's own term, I think). Try starting with it. But you need an LDAP server outside of ICP.
https://www.ibm.com/support/knowledgecenter/en/SSBS6K_2.1.0.3/user_management/admin.html
You would need to determine the invocation of the apiserver to see what --authorization-mode flag was passed to it. Normally this is contained in a systemd unit file or pod manifest. I'm not sure how IBM Cloud launches the apiserver

restricting EKS user access

I am trying to add new user to EKS cluster and giving then access. So far I was able to add the user just by editing configmap/aws-auth (kubectl edit -n kube-system configmap/aws-auth) and adding new user to
mapUsers: |
- userarn: arn:aws:iam::123456789:user/user01
username: user01
groups:
- system:masters
How can add user to EKS cluster and give full access to to specific namespace, but nothing outside of it ?
I tried to create Roles & RoleBinding as
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: namespace1
name: namespace1-user
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["*"]
# This role binding allows "user01" to read pods in the "namespace1" namespace.
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: namespace1-user-role-binding
namespace: namespace1
subjects:
- kind: User
name: user01
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: namespace1-user
user01 can see all the pods from other users with kubectl get pods --all-namespaces, is there any way to restrict this ?
Essentially what you want is to define a cluster role and use a role binding to apply it to a specific namespace. Using a cluster role (rather than a role) allows you to re-use it across namespaces. Using a role binding allows you to target a specific namespace rather than giving cluster-wide permissions.

Connecting to the kubernetes API for Kubernetes Executor in Gitlab

According to https://docs.gitlab.com/runner/executors/kubernetes.html#connecting-to-the-kubernetes-api, I can connect to another K8s cluster from my current Gitlab runner, but the thing is that they do not provide any information of what do you do or where do you need to specify these options.
EDIT: Finally managed to specify these options in the config.toml, but now any time my Gitlab-runner gets a job it fails as it follows:
ERROR: Job failed (system failure): User "system:serviceaccount:test-djg:default" cannot create secrets in project "gitlab" job=17304 project=3128 runner=c36ccf98
Any idea?
You get this error because executor pod doesn't have necessary permissions to run when RBAC is enabled in cluster. You should create a Role and RoleBinding and maybe a ServiceAccount based on your setup.
There is a pending merge request in gitlab-runner project that documents necessary permission and some other info about RBAC.
But for now if you want a quick setup it's possible to allow full access to namespace with following snippet. Note that you're gonna need to modifications to match you setup.
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
namespace: gitlab
name: gitlab-admin
rules:
- apiGroups: [""] # The API group "" indicates the core API Group.
resources: ["*"]
verbs: ["*"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: gitlab-admin
namespace: gitlab
subjects:
- kind: ServiceAccount # May be "User", "Group" or "ServiceAccount"
name: default
namespace: gitlab
roleRef:
kind: Role
name: gitlab-admin
apiGroup: rbac.authorization.k8s.io