New Feature: Network Policies

For the k8s-aware among you, the name “Network Policies” may induce either a familiar calm or terrified heart palpitations. Here at fly dot eye oh, we aim to induce a more in between contented feeling. To that end we’ve built some minimal tooling that allows you to control network traffic on your machines.

Let’s imagine you are an AI company, running user models and code in a Fly Machine. To combat abuse you want to limit egress traffic only to port 80 and 443. (Ahem, no port 30303, thank you very much). To enforce that, this company (henceforth known as: Dov’s Awesome AI Association) could add this network policy to their app where they run customer vms

curl --location 'http://api.machines.dev/v1/apps/dovsaaa_customer_app/network_policies' \
--header 'Content-Type: application/json' \
--data '{
    "name": "specific-egress",
    "selector": {
      "all": true
    },
    "rules": [
        {
            "action": "allow",
            "direction": "egress",
            "ports": [
                {
                    "protocol": "tcp",
                    "port": 80
                },
                {
                    "protocol": "tcp",
                    "port": 443
                }
            ]
        }
    ]
}'

Let’s break this down:

The selector:

The selectors, when using all of it’s features, looks like this:

{
  "all": true,
  "machines": [
    {
      "id": "abc"
    },
    {
      "id": "def"
    }
  ],
  "metadata" {
    "key": "value",
    "other": "match"
  }
}

This means this selector matches all machines in the app AND (machine ID abc OR machine ID def) AND (metadata key=value OR metadata other=match).

The rules:

If we look at the example rule from above, we can break it down:

{
    "action": "allow",
    "direction": "egress",
    "ports": [
        {
            "protocol": "tcp",
            "port": 80
        },
        {
            "protocol": "tcp",
            "port": 443
        }
    ]
}

This rule has an action allow (valid actions are allow), meaning packets which match the criteria will be allowed. The direction is egress (valid directions are ingress or egress), meaning it applies to packets leaving, a machine. ports is an array of objects, which denote protocol (tcp or udp) and port.

Once you create a rule for a given direction, the default for that direction becomes drop. You will have to explicitly open any ports you want open.

API

POST http://api.machines.dev/v1/apps/app_name/network_policies

{
    "name": string,
    //Pass ID to update an existing policy
    "id": optional<string>,
    // See above
    "selector": ...,
    "rules": [
        ...
    ]
}

GET http://api.machines.dev/v1/apps/:app_name/network_policies/

List for app

DELETE http://api.machines.dev/v1/apps/:app_name/network_policies/:id

Delete network policy

Wrap up

There are probably other, more specific tools to reach for then this first. If you really need this, you’d know. For instance, THIS DOES NOT APPLY TO PROXY TRAFFIC.

FKS will, in fact, gain good ol NetworkPolicy support built on this. There are a bunch of other things that could happen here, port ranges for example. We’d love to hear your ideas. Feel free to ask any questions/suggest any ideas here.

10 Likes

If I want to create an app in my org and only allow it to talk to a subset of the other apps in the org, is a network policy the way to go? The best way I can see to do that is to make sure all the machines in the other apps have a metadata field set. Is there a simpler way currently available or planned?

It think it’s very surprising that the key value pairs values inside a JSON object are ORed - or is it just a mistake in the network policy JSON where it says

  "metadata" {
    "key": "value",
    "other": "match"
  }

and means to say smth like

  "metadata": [
    { "key": "value" },
    { "other": "match" }
  ]

?