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