Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Securing Containerized Applications: A Primer


Published on

A talk given at Devoxx Morocco on Wednesday, November 13, 2019. In this talk a very insecure sample (demo) application is used to explain the various security principles application developers can apply when using containers and Kubernetes--from image sourcing, content, scanning to resource controls, attack surface mitigation, and reducing privilege for containers.

Published in: Software
  • Be the first to comment

  • Be the first to like this

Securing Containerized Applications: A Primer

  1. 1. @estesp Securing Container Applications: A PrimerPhil Estes Distinguished Engineer, Container Strategy Office of the CTO, IBM Cloud
  2. 2. @estesp Container Security Scope (hint: it’s big) > Management/Control plane > Networking > Host OS > Image security, provenance > Runtime security/isolation
  3. 3. @estesp What We Won’t Cover Hardening your host OS Hardening your cluster Configuring container runtimes Securing network traffic
  4. 4. @estesp Your Awesome Application - Secure coding practices - Protect against exploits - No embedded secrets/keys $ docker build -t myawesomeapp . Host OS container runtime AppArmor SECCOMP Capabilities Process isolation Filesystem isolation Network isolation ...
  5. 5. @estesp Container Application Security Tools, configuration, and runtime capabilities provided via the container ecosystem used to wrap an existing security-focused application to provide more isolation, protection, and overall security for your code running inside a container.
  6. 6. @estesp Images: Contents ● NO secrets ○ passwords, API keys, tokens, private keys ● FROM what? ● Minimize content ● Use “FROM SCRATCH” if possible
  7. 7. @estesp Images: Runtime ● Image Signing ○ Notary/TUF/DCT; RedHat PGP ● Image Scanning - CI/CD pipelines ● Don’t run as root!
  8. 8. @estesp 01 RESOURCES 02 ATTACK SURFACE 03 PRIVILEGES As limited as is feasible. As small as is possible. The least amount necessary. Runtime Security
  9. 9. @estesp Runtime Security: Limiting Resources > CPU controls are in the OCI runtime spec. > Process limit (how many can I create) are part of the OCI spec. > Memory limits are a part of the OCI runtime spec. > Kubernetes exposes them in a less complex way. > Disk bandwidth limits are in the OCI runtime spec. > Kubernetes does not enable them, but has ephemeral disk limits. > Quota-enabled filesystem is possible (advanced topic).
  10. 10. @estesp Runtime Security: Limiting Attack Surface Linux capabilities: > Collections of similar system calls. > Names like CAP_NET_RAW and CAP_SYS_ADMIN. > Some are fine grained and some, like CAP_SYS_ADMIN, might as well be “the new root” Linux Security Modules (LSMs) like AppArmor: > provide a “language” to describe a wide-ranging set of permissions for processes > container runtimes use a custom profile written for you to limit what containers can do on the system. SECCOMP stands for “Secure Computing”: > Allows a profile to be associated with a process to allow or deny specific Linux system calls for that process. > Container runtimes have a default seccomp profile; custom ones are allowed. Capabilities AppArmor Seccomp
  11. 11. @estesp Runtime Security: Reducing Privilege Don’t run privileged containers. Don’t run containers as root or elevate privileges. > All security controls/limits are disabled when you run with privileged mode. > Find the specific required privilege and only enable that feature/access. > Rarely do your containerized applications truly need root privileges so don’t use it. > User namespaces are a Linux feature in container runtimes but not yet in Kubernetes. > Exposing the Docker socket or K8s API into your container may allow escalation to root!
  12. 12. @estesp Kubernetes: Controlling Resource Limits apiVersion: v1 kind: Pod metadata: name: frontend spec: containers: - name: db image: mysql resources: limits: memory: "128Mi" cpu: "500m" - name: wp image: wordpress resources: limits: memory: "128Mi" cpu: "500m" ● Resource Limits ○ Set per-container in the Pod yaml ○ Note that not all OCI spec memory/CPU options are exposed in the K8s API specification ● Limit Processes ○ Still alpha as of Kubernetes 1.16 ○ Cluster operator must enable feature gate SupportPodPidsLimit=true, and then pass a --pod-max-pids integer to kubelet ○ Limit is fixed per-pod; no customization possible ● I/O Bandwidth Limits ○ The cgroups i/o settings are not exposed here to be set per container. ○ K8s does offer resource quotas, and QoS features—related but not the same features
  13. 13. @estesp Kubernetes: Limiting Attack Surface apiVersion: v1 kind: Pod metadata: name: hello-apparmor annotations: localhost/deny-write spec: containers: - name: hello ● Capabilities ○ Set per-container via securityContext ; can add/drop caps by name ● AppArmor ○ Annotations are used to identify AppArmor profiles in Kubernetes ○ Operator must install them on worker nodes; developing new profiles? Tools TBD ● Seccomp ○ Also set via annotation, but on PodSecurityPolicy; see upcoming example; not default
  14. 14. @estesp Kubernetes: Reducing Privilege apiVersion: v1 kind: Pod metadata: name: security-context-demo spec: securityContext: runAsUser: 1000 runAsGroup: 3000 fsGroup: 2000 containers: - name: sec-ctx-demo image: busybox command: [ "sh", "-c", "sleep 1h" ] securityContext: allowPrivilegeEscalation: false runAsUser: 2000 capabilities: add: ["NET_ADMIN", "SYS_TIME"] ● Non-root user ○ Use securityContext for containers and pod-level control ○ Use PodSecurityPolicy to enforce restrictions cluster-wide ● Capabilities (privilege related) ○ Also in securityContext; see example
  15. 15. @estesp Kubernetes: Cluster Security Enforcement apiVersion: policy/v1beta1 kind: PodSecurityPolicy metadata: name: restricted annotations: 'runtime/default' 'runtime/default' 'runtime/default' 'runtime/default' spec: privileged: false allowPrivilegeEscalation: false # This is redundant with non-root + disallow privilege escalation: requiredDropCapabilities: - ALL hostNetwork: false hostIPC: false hostPID: false runAsUser: # Require the container to run without root privileges. rule: 'MustRunAsNonRoot'
  16. 16. @estesp Kubernetes: Applying Container Security ● PodSecurityPolicy: enforce many good practices cluster-wide! OpenShift is a good example of a Kubernetes distribution with strong defaults out of the box ● Use the Kubernetes secrets implementation to protect sensitive keys, tokens, materials. Vendor tools available as well (Hashicorp Vault), and potentially from your cloud provider ● Don’t circumvent security to make your code “easy”: e.g. K8s API access with admin role; mounting container runtime (e.g. Docker) API with full privilege ● Have a unique workload requirement (multi-tenancy, untrusted code)? Take a look at RuntimeClass features in Kubernetes to allow custom isolators (gVisor, Kata, Firecracker, Nabla, etc.) ● Remember that you need visibility and not simply fire-and-forget security! Logging, audit, vendor tools/open source projects for runtime protection, anomaly detection, etc.
  17. 17. @estesp BUT...Container Security is Hard!! ● Use a cloud provider ○ Managed Kubernetes services many times can be created with a set of default tools and policies for strong controls pre-configured for you ○ Many managed services integrate with popular vendor tooling ■ e.g. Twistlock, Snyk, Aqua, Datadog, Sysdig, LogDNA and many others ● Use recommended guides and profiles publicly available (CIS, NIST, DockerBench, etc.) ● Try out emerging tooling ○ Generate seccomp profiles by running your application with BPF tracing:
  18. 18. @estesp Resources PodSecurityPolicy: Kubernetes Security Concepts: AppArmor documentation: SELinux documentation: Resource controls: Complete list of Linux capabilities:
  19. 19. @estesp Thank you! Demos located at: