{
    "product": "Cenvero Stratum",
    "generated_at": "2026-10-10T15:58:25+00:00",
    "format": "cenvero-docs-v1",
    "document_count": 1,
    "documents": [
        {
            "slug": "networking/public-addresses",
            "title": "Public Addresses (Routed IPs)",
            "category": "Networking",
            "url": "https://www.stratum.cenvero.com/docs/networking/public-addresses",
            "headings": [
                {
                    "level": 1,
                    "text": "Public Addresses (Routed IPs)"
                },
                {
                    "level": 2,
                    "text": "Before you start"
                },
                {
                    "level": 2,
                    "text": "Adding addresses"
                },
                {
                    "level": 2,
                    "text": "Giving a virtual machine a public address"
                },
                {
                    "level": 2,
                    "text": "What the machine sees"
                },
                {
                    "level": 2,
                    "text": "How traffic reaches it"
                },
                {
                    "level": 2,
                    "text": "What protects the address"
                },
                {
                    "level": 2,
                    "text": "Over the API"
                },
                {
                    "level": 2,
                    "text": "See also"
                }
            ],
            "word_count": 1421,
            "markdown": "# Public Addresses (Routed IPs)\n\nMost dedicated-server providers sell extra public IPv4 addresses — one at a time,\nor as a small block — and **route** them to your server's main address. A node\ncan hand each of those addresses to one virtual machine, so the machine is\nreachable on the internet under its own address, with nothing translated on the\nway.\n\nThis page covers adding the addresses, giving one to a virtual machine, what the\nmachine sees, and what protects the address once it is in use.\n\n> **IPv4 only.** Routed IPv6 addresses are not supported in this version.\n\n> **Virtual machines come with [Stratum Compute](/compute)**, which is not\n> generally available yet. You can add routed addresses on any node; giving one\n> to a virtual machine needs Compute.\n\n## Before you start\n\n- **Your provider must route the addresses to this server.** That is the usual\n  way extra IPs are delivered (\"routed to the main IP\"). If your provider instead\n  expects the server to answer for each address on its own network port — often\n  sold with a \"virtual MAC\" per address — this feature is not the right fit.\n- **Every address you add is usable.** In a routed block every address, including\n  the first and the last, reaches your server. If your provider reserves some of\n  them, add only the ones you may use — single addresses are fine.\n- **Never add the server's own address or its gateway.** The node refuses both,\n  along with private, shared and reserved ranges and anything that overlaps one\n  of your networks.\n- **Addresses the node already uses elsewhere are refused too:** a block that\n  overlaps one of the node's static routes, a prefix it announces over BGP, an\n  overlay (VXLAN) subnet, or the internal target of a port forward. Routing the\n  same addresses to your machines as well would send their traffic two ways at\n  once. The refusal names what is in the way; remove it first, or add only the\n  addresses outside it.\n\n## Adding addresses\n\nAdd one address, or a block of up to 4096 (a `/20`):\n\n```bash\nsudo cenvero-str-ctl routed add 203.0.113.10\nsudo cenvero-str-ctl routed add 203.0.113.16/29 --description \"provider subnet\"\n```\n\nTo keep a block for one customer only, name their tenant. Nobody else can use\nthose addresses, and that tenant's virtual machines take them before any shared\nones:\n\n```bash\nsudo cenvero-str-ctl routed add 203.0.113.32/29 --tenant t-acme\n```\n\nSee what you have and what is in use:\n\n```bash\ncenvero-str-ctl routed list\ncenvero-str-ctl routed list --tenant t-acme\n```\n\n```json\n{\n  \"gateway\": \"169.254.1.1\",\n  \"ranges\": [\n    { \"id\": \"rr-4f0c2a91d3e7\", \"cidr\": \"203.0.113.16/29\", \"tenant_id\": \"\", \"size\": 8, \"used\": 1, \"free\": 7,\n      \"description\": \"provider subnet\" }\n  ],\n  \"addresses\": [\n    { \"ip\": \"203.0.113.16\", \"range_id\": \"rr-4f0c2a91d3e7\", \"tenant_id\": \"t-acme\", \"used_by\": \"vm-3f9a1c2e\",\n      \"mac\": \"02:ce:cb:00:71:10\" }\n  ]\n}\n```\n\nA block is removed with its id or its prefix, once no virtual machine uses any of\nits addresses:\n\n```bash\nsudo cenvero-str-ctl routed remove 203.0.113.16/29\n```\n\n## Giving a virtual machine a public address\n\nAsk for a public address when you create the machine. `auto` takes the next free\none; you can also name a specific address:\n\n```bash\nsudo cenvero-str-ctl vm create --name www --tenant t-acme --image img-3f9a1c2e \\\n  --vcpus 2 --memory 2048 --public-ip auto\n\nsudo cenvero-str-ctl vm create --name mail --tenant t-acme --image img-3f9a1c2e \\\n  --vcpus 2 --memory 2048 --public-ip 203.0.113.17 --network net-acme\n```\n\nThe public address gets a network interface of its own. A machine can have a\npublic address and private networks side by side (up to four interfaces in all).\nWhich interface comes first depends on how you create the machine:\n\n- **`vm create`** puts every `--public-ip` interface first, in the order given,\n  then the `--network` interfaces — so a machine with a public address sees it\n  on its first interface.\n- **The API** creates the interfaces in the order you list them in `networks`,\n  and changes nothing about that order. List the public address first if the\n  machine should see it on its first interface.\n\nEither way, the machine's default route goes through its first interface that\nhas a public address; an interface on a private network then gets no default\nroute. The address belongs to the machine until it is\ndeleted; deleting the machine gives the address back and it is free for the next\none.\n\nA request that cannot be met — the address is in use, reserved for another\ntenant, not one you added, or none is left — is refused before anything is\ncreated.\n\n## What the machine sees\n\nThe machine holds its public address on its own, as a single address (`/32`),\nwith no neighbours on its network. Everything it sends goes through the node,\nwhich it reaches at the fixed gateway **169.254.1.1**. That gateway is\n\"on-link\": the machine sends to it directly even though it is outside the\nmachine's own address.\n\nThe first-boot configuration carries all of this, so a standard cloud image\nconfigures itself:\n\n```yaml\nnic0:\n  match: { macaddress: \"02:ce:cb:00:71:11\" }\n  addresses: [ 203.0.113.17/32 ]\n  routes:\n    - to: default\n      via: 169.254.1.1\n      on-link: true\n```\n\nConfiguring it by hand in a guest that does not read the first-boot\nconfiguration:\n\n```bash\nip addr add 203.0.113.17/32 dev eth0\nip link set eth0 up\nip route add 169.254.1.1 dev eth0\nip route add default via 169.254.1.1 dev eth0\n```\n\nThe gateway address is the same on every node and for every machine, so an\nimage prepared on one node works on any other.\n\n## How traffic reaches it\n\n```\ninternet ─► your provider ─► the server's main address ─► node ─► the machine\nthe machine ─► 169.254.1.1 (the node) ─► your provider ─► internet\n```\n\nYour provider delivers the address to the server; the node routes it to the\nmachine's port. The machine's replies go to its gateway, and the node forwards\nthem out unchanged: **a public address is never translated**, not even when an\noutbound translation rule on the node happens to cover it.\n\n**An address no machine uses leads nowhere.** From the moment you add a block\nuntil you remove it, traffic for any of its addresses that is not in use is\nrefused by the node (\"host unreachable\"). It is never sent back towards your\nprovider, which would only route it to the server again — round and round until\nthe packet expires.\n\n## What protects the address\n\n- **Only its machine can use it.** The address is bound to the machine's hardware\n  address and pinned to the machine's own port: another workload sending from it\n  is dropped. The machine, in turn, can send only from its own addresses — not\n  from any other address, forged or borrowed (see\n  [Tenants & Bandwidth](/docs/tenants#a-workload-sends-only-from-its-own-addresses)).\n- **It counts as its tenant's.** Traffic from the address is the tenant's\n  traffic: it cannot reach another tenant's private networks, it is covered by\n  the tenant's bandwidth limit, it is cut off while the tenant is suspended, and\n  it counts towards the tenant's addresses. The limit and the suspension belong\n  to the tenant, not to the address: when the machine is deleted they come off\n  the address, and the next machine to take it, whichever tenant it belongs\n  to, starts with neither.\n- **It is public.** Anything on the internet can reach it — including other\n  customers' machines on the same node. That is what a public address is for;\n  use the [firewall](/docs/networking/firewall) to decide what may connect.\n- **It comes back after a restart.** The route, the gateway and the protection\n  are put back when the node or its agent restarts, before the machine is started\n  again.\n\nA private network that wants to reach a public address on the same node does so\nthe way it reaches the rest of the internet — through outbound address\ntranslation (see [Gateway NAT](/docs/networking/gateway-nat)). Without it, the\npublic address's reply to the private network is refused like any other\ntenant's traffic.\n\n## Over the API\n\n```bash\n# list (optionally ?tenant_id=)\ncurl -k \"$NODE/api/v1/routed-addresses\" -H \"Authorization: Bearer $TOKEN\"\n\n# add\ncurl -k -X POST \"$NODE/api/v1/routed-addresses\" -H \"Authorization: Bearer $TOKEN\" \\\n  -H \"Content-Type: application/json\" -d '{\"cidr\":\"203.0.113.16/29\",\"description\":\"provider subnet\"}'\n\n# remove, by id or by prefix (write the slash as %2F, or as a dash: 203.0.113.16-29)\ncurl -k -X DELETE \"$NODE/api/v1/routed-addresses/203.0.113.16-29\" -H \"Authorization: Bearer $TOKEN\"\n```\n\nA virtual machine takes an address with `\"public_ip\"` on one of its interfaces.\nThe interfaces are created in the order listed — here the public address is the\nmachine's first interface:\n\n```json\n{ \"name\": \"www\", \"tenant_id\": \"t-acme\", \"image_id\": \"img-3f9a1c2e\", \"vcpus\": 2, \"memory_mib\": 2048,\n  \"networks\": [ { \"public_ip\": \"auto\" }, { \"network_id\": \"net-acme\" } ] }\n```\n\n## See also\n\n- [Networking Overview](/docs/networking/overview) — networks, endpoints and the host gateway.\n- [Gateway NAT](/docs/networking/gateway-nat) — outbound translation for private networks.\n- [Tenants & Bandwidth](/docs/tenants) — what separates one customer from another.\n"
        }
    ]
}