GithubHelp home page GithubHelp logo

ukhomeoffice / policy-admission Goto Github PK

View Code? Open in Web Editor NEW
17.0 17.0 5.0 442 KB

Kubernetes admission controller

Makefile 1.36% Go 95.85% JavaScript 2.57% Dockerfile 0.22%
kubernetes admission-controllers security

policy-admission's Introduction

Kubernetes Policy Admission Controller

The policy-admission is a custom admission controller used to enforce a collection of security and administrative policies across our kubernetes clusters. Each of the authorizers (https://github.com/UKHomeOffice/policy-admission/tree/master/pkg/authorize) are enabled individually via the command option --authorizer=NAME:CONFIG_PATH (note if no configuration path is given we use the default configuration for that authorizer).

$ bin/policy-admission --help
NAME:
   policy-admission - is a service used to enforce security policy within a cluster

USAGE:
    [global options] command [command options] [arguments...]

VERSION:
   v0.1.0 (git+sha: fa934ac)

AUTHOR:
   Rohith Jayawardene <[email protected]>

COMMANDS:
     help, h  Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --listen INTERFACE      network interface the service should listen on INTERFACE (default: ":8443") [$LISTEN]
   --tls-cert PATH         path to a file containing the tls certificate PATH [$TLS_CERT]
   --tls-key PATH          path to a file containing the tls key PATH [$TLS_KEY]
   --authorizer value      enable an admission authorizer, the format is name=config_path (i.e images=config.yaml)
   --cluster NAME          the name of the kubernetes cluster we are running NAME [$KUBE_CLUSTER]
   --namespace NAME        namespace to create denial events (optional as we can try and discover) NAME (default: "kube-admission") [$KUBE_NAMESPACE]
   --slack-webhook URL     slack webhook to send the events to URL [$SLACK_WEBHOOK]
   --controller-name NAME  controller name also used as prefix in annotations NAME (default: "policy-admission.acp.homeoffice.gov.uk") [$CONTROLLER_NAME]
   --enable-logging BOOL   indicates you wish to log the admission requests for debugging BOOL [$ENABLE_LOGGING]
   --enable-metrics BOOL   indicates you wish to expose the prometheus metrics BOOL [$ENABLE_METRICS]
   --enable-events BOOL    indicates you wish to log kubernetes events on denials BOOL [$ENABLE_EVENTS]
   --rate-limit DURATION   the time duration to attempt to wrap up duplicate events DURATION (default: 1m30s) [$RATE_LIMIT]
   --verbose BOOL          indicates you wish for verbose logging BOOL [$VERBOSE]
   --help, -h              show help
   --version, -v           print the version

Note, the configuration is auto-reloaded, so you can chunk the configuration files in the configmap and on changes the authorizer will automatically pick on the changes.

Prometheus Metrics

The admission controller on /metrics on the listening port produce a series of metrics related to request approvals and denial and a breakdown of the latency per authorizer and request. The feature is enabled via --enable-metrics (albeit defaulting to true).

Slack Integration

The admission controller along with creating kubernetes events in specified namespace (via the --enable-events command line option) can also publish denial to a slack channel. Simply pass the --slack-webhook or inject the SLACK_WEBHOOK environment variable. This event will detail Kind, Name, Namespace, Username and the denial message in the event.

Authorizers

An authorizer is enabled via the command line switch --authorizer=name=config_file_path i.e. --authorizer=images=/config/images.yml. The configuration as well as the defaults for all of these can be found in the doc.go in each of the authorizer folders. Each of the authorizer's can be configured to ignore certain namespaces.

Initially the project started off with a series of authorizer's however when the scripts authorizer was added most of coded authorizer's could be replaced with a script.

- Scripts Authorizer

The scripts authorizer (--authorizer=scripts=config) provides an embedded javascript runtime via github.com/robertkrimen/otto. Both the object and namespace it derives is inject into the script as a javascript object. An explain before for an Ingress resource

function isFiltering(o) {
  if (o.kind != "Ingress") {
    return false
  }
  annotations = o.metadata.annotations
  if (annotations["ingress.kubernetes.io/class"] != "default") {
    return false
  }

  return true
}

if (isFiltering(object)) {
  // do some logic
  provider = object.metadata.annotations["ingress.kubernetes.io/provider"]
  if (provider != "http") {
    deny("metadata.annotations[ingress.kubernetes.io/provider]", "you must use a http provider", provider)
  }
}

You can find a few more examples in the features folder. By default everyone is allowed, if you wish to deny and object, you can call the deny method, passing the field and reason for denial.

- Images

Images provides a means to control which container images are permitted to run within the environment. Applied to both the initContainers and containers of any pods which are created. The configuration for authorizer contains a series of regex's, which are taken as the default policy, however it will also read the annotation policy-admission.acp.homeoffice.gov.uk/images on the pod namespace; a comma separated list of regex's which can add on top of the default policies.

apiVersion: v1
kind: Namespace
metadata:
  name: test
  annotations:
    policy-admission.acp.homeoffice.gov.uk/images: ^docker.io/ukhomehomeoffice/.*$, quay.io/ukhomehomeoffice/.*$

- Domains

The domains authorizer provides one a means to control which hostname's / site are permitted via ingress resources and to control those at a namespace level, ensuring pods from another namespace can't take over a URL from another hosted site. Namespaces are annotated with the policy-admission.acp.homeoffice.gov.uk/domains tag, which is a comma separated list of domains this namespace can create ingress resources for. This hostname's themselves may contain a single wildcard i.e. *.example.com

- Kube Cert Manager

This authorizer is fairly bespoke, it was added as a number of users were getting the configuration wrong and causing the kube cert manager to fail and hit Letsencrypt limits. The authorizer performs a series of checks against a ingress resource which has been labelled to consume certificates from Letencrypt. This is broken down depending on internal or external ingress ELB's.

For internal:

  • we ensure it's not trying to use HTTP as the challenge and has selected dns.
  • we ensure the domain name is hosted by us and thus kube-cert-manager can add the TXT record.

For External:

  • we ensure the ingress is not attached to an internal ELB.
  • we ensure the resource if using DNS the zone is hosted by us.
  • we ensure if it's using HTTP that the hostname is a CNAME to our ingress ELB.

- Services

Services provides a means to control the kubernetes service types a namespace can use. In general we don't want anyone to be able to open NodePorts or LoadBalancer services. The authorizer takes the default configuration which is ClusterIP only and also reads the policy-admission.acp.homeoffice.gov.uk/services annotation from the namespace to see if anything else is permitted.

- Values

The values is generic authorizer used to match one or more attributes targeted via jsonpath and regex the values against a regexp. It can be used to enforce certain labels or annotation's i.e. a namespace must have a contact label etc. The configuration is as below

filter-on: Ingress
matches:
- path: metadata.annotations
  key-filter: ingress.kubernetes.io/provider
  value: ^http$
## OR on a namespace
filter-on: Namespace
matches:
- path: metadata.annotations
  key-filter: maintainers
  value: ^.*$
  required: true

- Toleration's & Taints

The current pod tolerations admission gave more headache then features so we combined the enforcement into an authorizer. The behaviors is as such.

  • Check the pod tolerations against the default whitelist defined in the configuration.
  • If an annotation exists on the namespace, check the pod against the whitelist

The configuration for the authorizer is

// Config is the configuration for the taint authorizer
type Config struct {
	// IgnoreNamespaces is list of namespace to
	IgnoreNamespaces []string `yaml:"ignored-namespaces" json:"ignored-namespaces"`
	// DefaultWhitelist is default whitelist applied to all unless a namespace has one
	DefaultWhitelist []core.Toleration `yaml:"default-whitelist" json:"default-whitelist"`
}

An example configuration is;

ignored-namespaces:
- kube-admission
- kube-system
- logging
- sysdig-agent
default-whitelist:
- key: node.alpha.kubernetes.io/notReady
  operator: '*'
  value: '*'
  effect: '*'
- key: node.alpha.kubernetes.io/unreachable
  operator: '*'
  value: '*'
  effect: '*'
- key: dedicated
  operator: '*'
  value: backend
  effect: '*'
- key: dedicated
  operator: '*'
  value: liberal
  effect: '*'
- key: dedicated
  operator: '*'
  value: strict
  effect: '*'

For the namespace whitelist annotation the tolerations must be specified in json for:

apiVersion: v1
kind: Namespace
metadata:
  name: test
  annotations:
    policy-admission.acp.homeoffice.gov.uk/tolerations: |
      [
        {
          "key": "dedicated",
          "operator": "*",
          "value": "compute",
          "effect": "*"
        },
        {
          "key": "dedicated",
          "operator": "*",
          "value": "liberal",
          "effect": "*"
        },
        {
          "key": "dedicated",
          "operator": "*",
          "value": "strict",
          "effect": "*"
        }
      ]

Controller Name

You can alter the controller prefix by using the --controller-name option which sets the prefix for the annotations across all the authorizers.

policy-admission's People

Contributors

chej-hod avatar gambol99 avatar kashifsaadat avatar nefischer avatar tasharnvb avatar vjremotegithub avatar

Stargazers

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

Watchers

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

policy-admission's Issues

Switch to an informer

The current implementation grab resources direct from the api or cache .. it make's more sense to use an informer and update an internal cache.

support dry run

$ kustomize build . | kubectl diff -f -
Error from server (BadRequest): admission webhook "policy-admission.acp.homeoffice.gov.uk" does not support dry run

Would be awesome to be able to provide diffs for PRs (and my sanity)

Fail when we can't register the webhook

We don't get any failure notification during deployment or after from Monitoring as the service will continue to run after failing to register:

$ kubectl -n kube-admission logs policy-admission-5d98dc5b47-j56p5
...

...
echo: http: TLS handshake error from 10.244.2.0:50290: remote error: tls: bad certificate
echo: http: TLS handshake error from 10.244.2.0:50446: remote error: tls: bad certificate
echo: http: TLS handshake error from 10.244.2.0:50492: remote error: tls: bad certificate
^C

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.