typhoon/docs/topics/security.md
Dalton Hubble fd044ee117 Enable Kubelet TLS bootstrap and NodeRestriction
* Enable bootstrap token authentication on kube-apiserver
* Generate the bootstrap.kubernetes.io/token Secret that
may be used as a bootstrap token
* Generate a bootstrap kubeconfig (with a bootstrap token)
to be securely distributed to nodes. Each Kubelet will use
the bootstrap kubeconfig to authenticate to kube-apiserver
as `system:bootstrappers` and send a node-unique CSR for
kube-controller-manager to automatically approve to issue
a Kubelet certificate and kubeconfig (expires in 72 hours)
* Add ClusterRoleBinding for bootstrap token subjects
(`system:bootstrappers`) to have the `system:node-bootstrapper`
ClusterRole
* Add ClusterRoleBinding for bootstrap token subjects
(`system:bootstrappers`) to have the csr nodeclient ClusterRole
* Add ClusterRoleBinding for bootstrap token subjects
(`system:bootstrappers`) to have the csr selfnodeclient ClusterRole
* Enable NodeRestriction admission controller to limit the
scope of Node or Pod objects a Kubelet can modify to those of
the node itself
* Ability for a Kubelet to delete its Node object is retained
as preemptible nodes or those in auto-scaling instance groups
need to be able to remove themselves on shutdown. This need
continues to have precedence over any risk of a node deleting
itself maliciously

Security notes:

1. Issued Kubelet certificates authenticate as user `system:node:NAME`
and group `system:nodes` and are limited in their authorization
to perform API operations by Node authorization and NodeRestriction
admission. Previously, a Kubelet's authorization was broader. This
is the primary security motivation.

2. The bootstrap kubeconfig credential has the same sensitivity
as the previous generated TLS client-certificate kubeconfig.
It must be distributed securely to nodes. Its compromise still
allows an attacker to obtain a Kubelet kubeconfig

3. Bootstrapping Kubelet kubeconfig's with a limited lifetime offers
a slight security improvement.
  * An attacker who obtains the kubeconfig can likely obtain the
  bootstrap kubeconfig as well, to obtain the ability to renew
  their access
  * A compromised bootstrap kubeconfig could plausibly be handled
  by replacing the bootstrap token Secret, distributing the token
  to new nodes, and expiration. Whereas a compromised TLS-client
  certificate kubeconfig can't be revoked (no CRL). However,
  replacing a bootstrap token can be impractical in real cluster
  environments, so the limited lifetime is mostly a theoretical
  benefit.
  * Cluster CSR objects are visible via kubectl which is nice

4. Bootstrapping node-unique Kubelet kubeconfigs means Kubelet
clients have more identity information, which can improve the
utility of audits and future features

Rel: https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/
Rel: https://github.com/poseidon/terraform-render-bootstrap/pull/185
2020-04-28 19:35:33 -07:00

2.8 KiB

Security

Typhoon aims to be minimal and secure. We're running it ourselves after all.

Overview

Kubernetes

  • etcd with peer-to-peer and client-auth TLS
  • Kubelets TLS bootstrap certificates (72 hours)
  • Generated TLS certificate (365 days) for admin kubeconfig
  • NodeRestriction is enabled to limit Kubelet authorization
  • Role-Based Access Control is enabled. Apps must define RBAC policies for API access
  • Workloads run on worker nodes only, unless they tolerate the master taint
  • Kubernetes Network Policy and Calico NetworkPolicy support 1

Hosts

  • Container Linux auto-updates are enabled
  • Hosts limit logins to SSH key-based auth (user "core")

Platform

  • Cloud firewalls limit access to ssh, kube-apiserver, and ingress
  • No cluster credentials are stored in Matchbox (used for bare-metal)
  • No cluster credentials are stored in Digital Ocean metadata
  • Cluster credentials are stored in AWS metadata (for ASGs)
  • Cluster credentials are stored in Azure metadata (for scale sets)
  • Cluster credentials are stored in Google Cloud metadata (for managed instance groups)
  • No account credentials are available to Digital Ocean droplets
  • No account credentials are available to AWS EC2 instances (no IAM permissions)
  • No account credentials are available to Azure instances (no IAM permissions)
  • No account credentials are available to Google Cloud instances (no IAM permissions)

Precautions

Typhoon limits exposure to many security threats, but it is not a silver bullet. As usual,

  • Do not run untrusted images or accept manifests from strangers
  • Do not give untrusted users a shell behind your firewall
  • Define network policies for your namespaces

Container Images

Typhoon uses upstream container images (where possible) and upstream binaries.

!!! note Kubernetes releases kubelet as a binary for distros to package, either as a DEB/RPM on traditional distros or as a container image for container-optimized operating systems.

Typhoon packages the upstream Kubelet and its dependencies as a container image for use in Typhoon. The upstream Kubelet binary is checksummed and packaged directly. Quay automated builds provide verifiability and confidence in image contents.

Disclosures

If you find security issues, please email dghubble at gmail. If the issue lies in upstream Kubernetes, please inform upstream Kubernetes as well.


  1. Requires networking = "calico". Calico is the default on all platforms (AWS, Azure, bare-metal, DigitalOcean, and Google Cloud). ↩︎