Static IPs for Serverless Containers
modal.com
modal.com
As a serverless platform we hit a bit of a tricky tradeoff: we run multi-tenant user workloads on machines around the world, and each serverless function is an autoscaling container pool. How do you let users give their functions static IPs, but also decouple them from compute resource flexibility?
We needed a high-availability VPN proxy for containers and didn't find one, so we built our own on top of WireGuard and open-sourced it at https://github.com/modal-labs/vprox
Let us know if you have thoughts! I'm relatively new to low-level container networking, and we (me + my coworkers Luis and Jeffrey + others) have enjoyed working on this.
It's also used by Google Kubernetes Engine, OpenAI, and Cloudflare among others to run untrusted code.
- You are using a container orchestrator like Kubernetes
- You are using gVisor as a container runtime
- Two applications from different users, containerized, are scheduled on the same node.
Then, which of the following are true?
(1) Both have shared access to an NVIDIA GPU
(2) Both share access to the NVIDIA GPU via CUDA MPS
(3) If there were 2 or more MIGs on the node with a MIG-supporting GPU, the NVIDIA container toolkit shim assigned a distinct MIG to each application
If you'd like to learn more, you can check out our docs here: https://modal.com/docs/guide/gpu
Re not using Kubernetes, we have our own custom container runtime in Rust with optimizations like lazy loading of content-addressed file systems. https://www.youtube.com/watch?v=SlkEW4C2kd4
(I work at Modal.)
E.g. it came up in this thread: https://news.ycombinator.com/item?id=41672168
Modal is actually a happy customer of Tailscale (but for other purposes). :D
an unfinished project I worked on (https://github.com/redpwn/rvpn) was a bit more ambitious with a global control plane and I quickly learned supporting multiple clients especially anything networking related is a tarpit. the focus on linux / aws specifically here and the results achievable from it are nice to see.
networking is challenging and this was a nice deep dive into some networking internals, thanks for sharing the details :)
Controlling our worker environment (like `net.ipv4.conf.all.rp_filter` sysctl) is a big help for us since it means we don't have to deal with the fullness of all possible network configurations.
It's not quite a zero-trust solution though due to the CA chain of trust.
mTLS is security at a different layer though than IP source whitelisting. I'd say that a lot of companies we spoke to would want both as a defense-in-depth measure. Even with mTLS, network whitelisting is relevant. If your certificate were to be exposed for instance, an attacker would still need to be able to forge a source IP address to start a connection.
This (and more) is exactly what we (I work on it) built with open source OpenZiti, a zero trust networking platform. Bonus points, it includes SDKs so you can embed ZTN into the serverless function, a colleague demonstrated it with a Python workload on AWS - https://blog.openziti.io/my-intern-assignment-call-a-dark-we....
Or, you use a broker like Vault to which you authenticate with that JWT, and which generates a just in time ephemeral username/password for your database, which gets rotated at some point.
Authentication is only part of the problem, networks are firewalled (with dedicated appliances) and segmented to prevent lateral movement in the event of a compromise
But if I have firewall policies that allow connections only to specific services I need a destination address and port (yes, some firewalls allow host names but there's drawbacks to that)
> IP addresses aren't authenticated, they can be spoofed
For anything bidirectional you'd need the client to have a route back to you for that address, which would require you compromising some routers and advertising it via BGP etc.
You can spoof addresses all you want but it will generally not do much for a stateful protocol
Lol. Of course they do. In fact, it's the only viable way to authenticate servers in Current Year. Unlike ssh host keys, of which literally nobody on this planet takes seriously, or https certificates which is just make-work security theater.
Unfortunately they are! I’ve seen up whitelistijg used as the only means of authentication over the WAN several times
Looks like Modal hosts workloads in Containers, not VMs. How do you enforce secure isolation with this design? A single kernel vulnerability could lead to remote execution on the host, impacting all workloads . Am I missing anything?
It's also used by Google Kubernetes Engine, OpenAI, and Cloudflare among others to run untrusted code.
Disclaimer: I'm an SRE on the GCP Serverless products.
Even longer for QUIC/H3.
The architecture of vprox is pretty generic though and could support IPv6 as well.
In a perfect world I'd also be asking whether you considered NAT64, but unfortunately I'm well aware that's a giant world of pain to get to work on Linux (involving either out-of-tree Jool, or full-on VPP)
Glad to know that IPv6-only is working well for you. "In a perfect world…" :)
(FTR, it works for us because our CI is relatively self-contained. And we have local git mirrors… f***ing github…)
(I would already have expected this to be quite effective in forcing IPv6, but tbh I'm still surprised just how effective.)
The other features that were hard requirements for us were multi-tenancy and high availability / failover.
By the way, fck-nat is just a basic shell script that sets the `ip_forward` and `rp_filter` sysctls and adds an IP masquerade rule. If you look at vprox, we also do this but build a lot on top of it. https://github.com/modal-labs/vprox