Coder Social home page Coder Social logo

postfinance / kubelet-csr-approver Goto Github PK

View Code? Open in Web Editor NEW
153.0 153.0 32.0 616 KB

Kubernetes controller to enable automatic kubelet CSR validation after a series of (configurable) security checks

License: MIT License

Go 94.54% Smarty 5.46%
controller controller-runtime go kubelet kubernetes

kubelet-csr-approver's People

Contributors

clementnuss avatar dependabot[bot] avatar f1ko avatar ghouscht avatar hansedong avatar havefun83 avatar j4m3s-s avatar jcpunk avatar jkroepke avatar lett00r avatar networkhermit avatar rajan123456 avatar remmen-io avatar sftim avatar stephan2012 avatar treydock avatar zbindenren avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

kubelet-csr-approver's Issues

Image Tags

Hey, I checked images on dockerhub but there is no tag information. I think a tag should exist to use a specific version in values.YAML. What can we do about it?

Cannot run without --bypass-dns-resolution=true

I'm experiencing troubles with kubelet-csr-approver without passing the option --bypass-dns-resolution=true

"Denying kubelet-serving CSR. DNS checks failed. Reason:The SAN DNS Name could not be resolved, denying the CSR"

$ dig A k8snode03u @10.96.0.10
$ dig A k8snode03u.cluster.local @10.96.0.10

Doesn't resolve to the node IP address.

Am I doing something wrong on my cluster?
Is having core-dns resolving the node's hostname a usually expected behavior?
How do you enable such feature on your cluster?

Consider alternate image registry to Docker Hub

Since Docker Hub has been applying rate limits on image pulls for a while now, and their more recent move to scrap free teams I feel that Docker Hub is becoming more and more hostile towards the OSS/hobbyist community.

I would like to propose providing GitHub Container Registry as an alternative (or completely switching over to it) for the project.
Would you be open to this?

Thank you for considering!

Verify requests by IP address

kubeadm registers Kubernetes nodes by their canonical hostname instead of the FQDN, making it hard to find a regex that universally matches and provides more security than .*. Would it be an option to verify legitimate certificate requests against a list of allowed IP subnets?

The CSR contains the node IP address:

$ kubectl get csr csr-5pq5z -o jsonpath='{.spec.request}' |base64 -d |openssl req -noout -text
Certificate Request:
    Data:
        Version: 1 (0x0)
        Subject: O = system:nodes, CN = system:node:n0218
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:5e:a7:2e:34:53:bf:88:71:f7:e5:f1:26:63:57:
                    be:0b:db:d1:68:87:ae:17:a5:e7:5d:45:16:e6:f7:
                    df:7f:64:d6:bc:b1:e9:c7:a5:4c:5b:c9:91:31:89:
                    26:82:8c:cc:70:f2:1c:ec:45:8f:e6:a2:81:b8:f2:
                    80:ec:09:1e:8b
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        Attributes:
        Requested Extensions:
            X509v3 Subject Alternative Name: 
                DNS:n0218, IP Address:192.168.8.58
    Signature Algorithm: ecdsa-with-SHA256
         30:45:02:21:00:d5:17:3e:d4:56:04:c4:4c:b5:ff:47:3c:1e:
         98:92:d1:20:e3:52:39:28:34:2a:eb:c3:53:93:b6:34:0d:93:
         4b:02:20:0c:d4:a2:68:f0:6e:22:e8:ca:f6:c9:27:78:55:bb:
         7c:5a:4c:01:af:78:42:1f:2e:b7:5a:39:a9:b5:36:93:85

Feature: Add podLabels

Hi & thanks for the project.
I've seen it’s possible to set additional Annotations to pods via podAnnotations.
Would be great if this was also the case for labels – eg podLabels.
Thanks again for the work.

Error: INSTALLATION FAILED: failed parsing --set data: error parsing index: strconv.Atoi: parsing "0-5": invalid syntax

helm install kubelet-csr-approver kubelet-csr-approver/kubelet-csr-approver -n kube-system \
  --set providerRegex='^cn-[a-z]+\.192\.168\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})$' \
  --set providerIpPrefixes='192.168.0.0/16' \
  --set maxExpirationSeconds='86400'

return results: Error: INSTALLATION FAILED: failed parsing --set data: error parsing index: strconv.Atoi: parsing "0-5": invalid syntax

I want to match: cn-xxxxx.192.168.xxx.xxx

Feature request: add a flag to disable node DNS validation

It is important to understand that the node DNS name needs to be resolvable for the kubelet-csr-approver to work properly. If this is an issue for you, please file an issue and I'll add a flag to disable this validation.

This is an issue for me :)

Kubernetes node names don't have to be resolvable, and mine are not.

Fwiw, I use /etc/machine-id as the k8s node name (via systemd %m substitution), uname -n returns localhost on all my hosts, and none of my node IPs are in DNS (nor even have static IPs across reboots). About the only thing they have is a TLS private key, and a cert that links that to their k8s node name - they use their client cert to update their Node entry with their current IP - and apiserver->node always uses IP anyway.

Node DNS name validation issue

In the Readme it is mentioned :
It is important to understand that the node DNS name needs to be resolvable for the kubelet-csr-approver to work properly. If this is an issue for you, please file an issue and I'll add a flag to disable this validation.

For some situations like local clusters where there is no DNS server to map node to ip, this type of requirement makes CSR leave Denied. So adding a related flag to disable this validation makes sense.

Denies when hostname is not the dns name

We explicity change the hostname of the box to a different naming convention the certificates get rejected because of this reason.

The SAN DNS Name in the x509 CSR is not prefixed by the node name (hostname)

Only enable on specific username prefix

Hello,

I am trying to use a chart called stackgres on the same cluster as kubelet-csr-approver, but it fails to install because kubelet-csr-approver automatically denies its certificate request.

Revelant log line:

2022-06-11T13:51:08.348Z        INFO    controller.certificatesigningrequest    controller/csr_controller.go:107        Denying kubelet-serving CSR. Reason:CSR Spec.Username is not prefixed with system:node: {"reconciler group": "certificates.k8s.io", "reconciler kind": "CertificateSigningRequest", "name": "stackgres-operator", "namespace": ""}

Would it possible to have an option to only process CSR with a given prefix, like system:node:, and leave others untreated as they may have a different usage pattern?

Thank you

A flag to bypass DNS resolvabilty check

Hello! I'd really appreciate it if you'd add a flag to disable the DNS name resolvability validation.
RegExp alone is probably good enough for the testing needs in absence of properly configured DNS server.
Screen Shot 2021-12-30 at 11 52 29 PM
:)

Several completed and Container status Unknown pods

Hi, for some odd reason I have several kubelet-csr-approver pods in not running state. This only happens for its deployment, all other deployments do not have this behaviour.

image

Any idea what may be causing this ?

deploy/k8s/deployment.yaml wasn't updated

Grabbing https://github.com/postfinance/kubelet-csr-approver/blob/v1.0.4/deploy/k8s/deployment.yaml (note: v1.0.4) will run the image postfinance/kubelet-csr-approver:v1.0.1

Chart.yaml version, appVersion

When pulling this chart from a Git Repo (for situations where a Helm Repo is not available), the Chart.yaml always shows version and appVersion as 0.0.1-dummy instead of i.e. 1.0.7

Could Chart.yaml be updated at release times to correctly state the version?

expirationSeconds checks

  • (Implement and) document checks on the .spec.expirationSeconds field for a kubelet CertificateSigningRequest
    • for example, only allow certificates to be issued with a duration of 86400 seconds (24 hours) by default
    • maybe a command line option to allow issuing certificates that last longer than this?

looks like the image name is wrong in the deployment.yaml

https://github.com/postfinance/kubelet-csr-approver/blob/main/deploy/k8s/deployment.yaml

│   Normal   Pulling    102s (x4 over 3m9s)  kubelet            Pulling image "pf/kubelet-csr-approver:0.1.0"                                                              │
│   Warning  Failed     101s (x4 over 3m7s)  kubelet            Failed to pull image "pf/kubelet-csr-approver:0.1.0": rpc error: code = Unknown desc = Error response from │
│  daemon: pull access denied for pf/kubelet-csr-approver, repository does not exist or may require 'docker login'                                                         │
│   Warning  Failed     101s (x4 over 3m7s)  kubelet            Error: ErrImagePull                                                                                        │
│   Warning  Failed     86s (x6 over 3m7s)   kubelet            Error: ImagePullBackOff                                                                                    │
│   Normal   BackOff    72s (x7 over 3m7s)   kubelet            Back-off pulling image "pf/kubelet-csr-approver:0.1.0"  

Feature request: option to bypass or tune SAN validation

Hi,

could you please add an option to bypass or tune SAN validation?
Currently CSR are being denied with the following reason:

> kubectl get csr csr-zwzjd -ojson | jq '.status.conditions[] | {message,reason,type}' 
{
  "message": "CSR not complying with kubelet-csr-approver validation process. Reason: The x509 Cert Request contains more than 1 DNS name",
  "reason": "kubelet-serving cert denied",
  "type": "Denied"
}

The SAN part of the request looks like:

                X509v3 Subject Alternative Name: 
                    DNS:ec2-1-2-3-4.eu-central-1.compute.amazonaws.com, DNS:ip-192-168-5-6.eu-central-1.compute.internal, IP Address:192.168.5.6, IP Address:1.2.3.4

I am not aware of any way to influence that, even though in my case public names/IPs are not needed. The easiest would be to have an option to bypass this check or tune the allowed value, ie. making it greater than 1.

fix: invalid syntax in ServiceMonitor helm template

helm chart version: 1.0.3

I enabled the serviceMonitor in helm values:

metrics:
  serviceMonitor:
    enabled: true

But when I upgrade the helm release it failed due to invalid syntax in servicemonitor template:

Error from server (BadRequest): error when creating "servicemonitor.yaml": ServiceMonitor in version "v1" cannot be handled as a ServiceMonitor: strict decoding error: unknown field "spec.selector.app.kubernetes.io/instance", unknown field "spec.selector.app.kubernetes.io/name"
The ServiceMonitor "release-name-kubelet-csr-approver" is invalid: spec.endpoints[0].port: Invalid value: "integer": spec.endpoints[0].port in body must be of type string: "integer"

Solve "The SAN DNS Name could not be resolved" without bypassDnsResolution

Hi !

I would like to know if there is a solution to solve the problem "The SAN DNS Name could not be resolved" without using the bypassDnsResolution argument.

This is my entire error : certificate request was not signed: cannot watch on the certificate signing request: certificate signing request is denied, reason: kubelet-serving cert denied, message: CSR not complying with kubelet-csr-approver validation process. Reason: The SAN DNS Name could not be resolved, denying the CSR

Thanks in advance !

extra arbitrary SANs after valid DNS name

hey,

if my assumption is correct after I read the source code, it is possible to add extra SANs to request and only the first one will be verified, technically I can still add auth.company.com into the list of SANs per threat model, amirite?

cheers

Error: chart "kubelet-csr-approver" matching 0.2.5 not found in kubelet-csr-approver index.

Thank you. Great work. I found a problem with helm. Even I try 'helm repo update'.

Error: chart "kubelet-csr-approver" matching 0.2.6 not found in kubelet-csr-approver index. (try 'helm repo update'): no chart version found for kubelet-csr-approver-0.2.6
Error: chart "kubelet-csr-approver" matching 0.2.5 not found in kubelet-csr-approver index. (try 'helm repo update'): no chart version found for kubelet-csr-approver-0.2.5

Some certificates remain in the approved state but not approved,issued.

We have a Kubernetes integration with Datadog 7.44.0 on AWS EKS clusters, to monitor resources and performance of different applications. Everything was working fine in EKS version 1.23 and earlier. However, after upgrading one of the clusters (dev) to EKS version 1.24, the integration stopped working.

Upon investigation, we realized that the problem seemed to be with the certificates generated by Datadog. EKS does not recognize their origin, and as a result, the certificates are left in a "pending" state. Being a development environment, daily it is turned off at night and turned on in the morning, by doing this the integration with Datadog is lost, and the command kubectl get csr | awk '{print $1}' | xargs kubectl certificate approve to manually approve the certificates and restore the integration.

AWS in its documentation indicates that a driver must be developed in order to automate the approval of certificates.
https://docs.aws.amazon.com/eks/latest/userguide/cert-signing.html#csr-considerations

Kubernetes recommends in its documentation to use a ready-built controller.
Third party custom controllers can be used: https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-certs/#kubelet-serving-certs

  1. First Experimentation:
    On the development ('dev') cluster, we had a node with a CSR in a 'Pending' state.
image

Then when installing the driver, the certificate is approved and issued
image

image
  1. Second Experimentation:
    However, if the kubelet-csr-approver controller is already installed on the 'dev' cluster and then a new node is added to the cluster, the controller is able to approve the CSR of the new node, but does not issue the corresponding certificate. In this case, the CSR remains in the 'Approved' state, but does not change to 'Approved, Issued', this causes the integration of the new node with datadog to be unsuccessful.
image

We appreciate any help

Unable to retrieve the complete list of server APIs: certificates.k8s.io/v1 with default deployment

I'm using the default options in deploy/k8s and only overriding the KUBERNETES_SERVICE_{HOST,PORT} environment variables but getting the following error about a minute or so after the pod starts:

E1211 19:49:34.608041       1 leaderelection.go:332]
{
"level":"ERROR",
"ts":"2023-12-11T19:44:49.789Z",
"logger":"controller-runtime.source.EventHandler",
"caller":"source/kind.go:68",
"msg":"failed to get informer from cache",
"error":"failed to get API group resources: 
      unable to retrieve the complete list of server APIs: 
          certificates.k8s.io/v1: 
              Get \"https://API_SERVER:6443/apis/certificates.k8s.io/v1\": 
                 dial tcp: lookup API_SERVER: i/o timeout"
}

I know that pods are able to talk to the api server because I have a running deployment of kube-state-metrics that also overrides the same env vars with the same values.

I'm running kubernetes 1.28.3 if that's helpful.

Never approve CSR if --bypass-dns-resolution is specified

After updating to 1.2.0, the following error message appeared and CSRs were not approved.

Denying kubelet-serving CSR. DNS checks failed. Reason:One of the SAN IP addresses, xxx.xxx.xxx.xxx, is not contained in the set of resolved IP addresses, denying the CSR.

In my environment, the node name cannot be resolved by DNS, so I specify --bypass-dns-resolution.

I checked the source, and the IP addresses of the SAN are checked against resolvedIPSet here, however
resolvedIPSet contains only the IP addresses resolved here by DNS.

So, I think the check will always fail if --bypass-dns-resolution is specified.

Request for an enhancement to support K8's 1.18

Thanks for the custom controller to auto approve the csr's. The current functionality of the project doesn't support older version of K8's v 1.18) as it leverages /v1beta1 k8's apis.

Therefore, I would like to request for an enhancement to optimize the current functionality to support v1beta1 apis.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.