Page MenuHomePhabricator

[Epic] Improve defense in depth for higher-risk payloads running on kubernetes
Open, HighPublic

Description

We have several services and tools that accept either arbitrary binary input, or what amounts to some form of code (be it a DSL, as in the case of the easytimeline or score extensions, or directly code as in the case of wikifunctions or the shellbox-constraints service), from basically any user on the internet.

Up to now, we have mostly relied on container-level isolation to ensure separation of such payloads from the rest of our infrastructure. The rising frequency of LPEs on Linux, and thus the risk of container escape, makes us want to improve the level of isolation of such payloads, so that a compromise of a payload doesn't easily result in a physical host compromise; with the only exception being wikifunctions, that uses WASM to sandbox the application code.

There's a couple of solutions for this, gvisor and kata-containers. gVisor is basically a user-space simulated kernel which only reproduces a subset of the linux syscalls and adds a sentry layer to it, while kata-containers spawn a VM in which the containers are executed. gVisor provides a smaller footprint in terms of memory/cpu overhead, and faster startuptimes, at the expense of a slightly higher runtime overhead. Kata-containers, especially on hardware that supports hardware virtualization, have a lower performance overhead at the cost of added complexity and more resource consumption.

It is probably a good idea long-term to consider the strenghts of both approaches, but for now, we don't need both.

Specifically, given none of the deployments we consider critical from a security POV have very strict latency requirements, the simplicity and resource frugality of gVisor seem to make it the better candidate for our goals.

This umbrella task should spawn all the tasks needed to introduce gvisor as a runtime for our kubernetes clusters.

In order to run gvisor and make it available for our kubernetes clusters, we need to do the following:

  • Ensure we import the right gvisor sets of packages
  • Conditionally configure containerd to be able to run one or more runsc-based runtimes
  • Automatically label nodes that are configured to run gvisor-based payloads
  • Configure said runtimes according to different risk profiles we want to run
  • Create the corresponding RuntimeClass objects
  • Add validating admission policies to ensure high-risk payloads only run with the aforementioned runtimeclasses
  • Add the needed annotations to the deployments to ensure they can work under gvisor (for instance, we use shared pod volumes for php-fpm and apache to communicate via unix sockets)

Event Timeline

Restricted Application added a subscriber: Aklapper. · View Herald Transcript

Thanks for filing this! Couple of questions:

  1. "none of the deployments we consider critical from a security POV have very strict latency requirements" - to challenge the future use cases a bit, are we considering only Wikikube here or should we also consider the other clusters?
  2. Do we want (and do we need) to pilot this on a small scale to measure the various overhead and assess if they are reasonable before scaling?
  3. Timeline-wise, is there an ongoing project (possibly APP) which depends on this?
  1. "none of the deployments we consider critical from a security POV have very strict latency requirements" - to challenge the future use cases a bit, are we considering only Wikikube here or should we also consider the other clusters?

Wikikube is actually the one cluster where a latency increase of say 15% matters the most. It might be true to a degree for inference models as well, but in that case we have bigger issues with running in gvisor - if we ever need stronger isolation on kubernetes workers with GPUs, we'll have to look into kata-containers because GPU support in gvisor is somewhat limited.

  1. Do we want (and do we need) to pilot this on a small scale to measure the various overhead and assess if they are reasonable before scaling?

Once the technical capabilities are baked into our codebases, the natural followup would be to test it out on staging, then to pick a specific deployment for further testing.

A few reports from successfully running shellbox for EasyTimeline in gVisor:

  • runsc only works correctly on trixie hosts; probably related to the containerd version
  • the performance penalty is quite steep - so we might want to enable virtualization support in hardware and switch to kvm as the platform for runsc if we are to support more expensive or time-sensitive payloads
MLechvien-WMF moved this task from Next quarter to Radar (Awareness) on the ServiceOps board.
MLechvien-WMF edited projects, added: ServiceOps; removed: ServiceOps (Next quarter).