When you run your own virtual machines on a CubePath dedicated server, the additional IPv4 addresses you order for that server can be given to individual VMs. The most reliable way to do this is a routed setup: the host keeps its primary IP, forwards traffic for each additional IP to a local bridge, and every VM uses its additional IP as a /32 with the host's primary IP as its gateway. In this tutorial you will configure the host (Proxmox VE or any Debian 12 based hypervisor using /etc/network/interfaces) and then the guests (Ubuntu 24.04 with Netplan, and Debian 12 with ifupdown).
Prerequisites
To follow this guide you need:
- A CubePath dedicated server running Proxmox VE 8 or Debian 12 with a hypervisor (KVM) installed, and root or
sudoaccess. - One or more additional IPv4 addresses assigned to that dedicated server in the CubePath panel.
- The host's primary IP, its prefix length and its gateway, as shown in the panel or in the output of
ip -4 addrandip route. - At least one virtual machine running Ubuntu 24.04 or Debian 12, with access to its console through the hypervisor (you will change its network configuration, so SSH may drop).
- Out-of-band access to the host (IPMI/KVM console) in case a network change on the host locks you out.
Throughout the guide these placeholders are used. Replace them with your own values:
| Placeholder | Meaning | Example |
|---|---|---|
host_primary_ip | Main IP of the dedicated server | 198.51.100.10 |
host_prefix | Prefix length of the main IP | 24 |
host_gateway | Upstream gateway of the dedicated server | 198.51.100.1 |
additional_ip_1, additional_ip_2 | Additional IPs you will give to VMs | 203.0.113.25, 203.0.113.26 |
eno1 | Host's physical uplink interface | eno1, enp1s0f0 |
NoteDo not add the additional IPs to the host's own interface as aliases. If the host owns them, it answers for them itself and the traffic never reaches the VMs.
Step 1 - Identifying the host's network settings
Log in to the dedicated server and find the uplink interface, the primary IP and the default gateway:
ip -4 addr show
ip route show default
2: eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
inet 198.51.100.10/24 scope global eno1
default via 198.51.100.1 dev eno1 proto kernel onlink
Write down the interface name (eno1 in this example), the address with its prefix and the gateway. On Proxmox VE the primary IP is usually configured on a bridge such as vmbr0 with eno1 as its port. In that case, keep that bridge as your uplink and create the routed bridge under a different name (for example vmbr1) in the next step.
Before editing anything, back up the current configuration:
sudo cp /etc/network/interfaces /etc/network/interfaces.bak
Step 2 - Enabling IP forwarding on the host
The host has to forward packets between the uplink and the VM bridge. Create a dedicated sysctl file so the setting survives reboots:
sudo nano /etc/sysctl.d/99-routed-ips.conf
net.ipv4.ip_forward = 1
Load it and check the value:
sudo sysctl --system
sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1
Step 3 - Creating a routed bridge for the VMs
Now add a bridge with no physical ports. The host gives this bridge its own primary IP as a /32, so the VMs see the host's primary IP as their gateway, and a host route is added for each additional IP pointing to the bridge. Proxy ARP on the uplink makes the host answer ARP requests for the additional IPs, so the setup works whether the upstream router delivers them routed to your primary IP or expects them on the link.
Open the network configuration:
sudo nano /etc/network/interfaces
Leave the loopback and uplink stanzas as they are, add the post-up line to the uplink stanza, and append the new bridge. The complete relevant part looks like this:
auto lo
iface lo inet loopback
auto eno1
iface eno1 inet static
address host_primary_ip/host_prefix
gateway host_gateway
post-up echo 1 > /proc/sys/net/ipv4/conf/eno1/proxy_arp
auto vmbr1
iface vmbr1 inet static
address host_primary_ip/32
bridge-ports none
bridge-stp off
bridge-fd 0
up ip route add additional_ip_1/32 dev vmbr1
up ip route add additional_ip_2/32 dev vmbr1
If your primary IP lives on a Proxmox bridge (vmbr0 with bridge-ports eno1), put the post-up ... proxy_arp line in the vmbr0 stanza instead and use vmbr0 in the path. Add one up ip route add line for every additional IP you want to hand to a VM.
Apply the configuration. Proxmox VE and most modern Debian hypervisors use ifupdown2, which can reload without restarting the whole network:
sudo ifreload -a
On a plain Debian 12 host with classic ifupdown, bring up only the new bridge instead:
sudo ifup vmbr1
Verify that the bridge exists and the host routes are in place:
ip -4 addr show vmbr1
ip route show dev vmbr1
5: vmbr1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
inet 198.51.100.10/32 scope global vmbr1
203.0.113.25 scope link
203.0.113.26 scope link
Also confirm proxy ARP is enabled on the uplink:
cat /proc/sys/net/ipv4/conf/eno1/proxy_arp
1
NoteIf the host uses a firewall that filters forwarded traffic (for example the Proxmox VE firewall or nftables rules with a
forwardchain), allow traffic between the uplink andvmbr1, or the VMs will not be reachable.
Step 4 - Attaching the VM to the routed bridge
Connect the VM's network card to vmbr1. In the Proxmox VE web interface, open the VM, go to Hardware, edit the Network Device and set Bridge to vmbr1. From the host shell you can do the same with qm, replacing 100 with your VM ID:
sudo qm set 100 --net0 virtio,bridge=vmbr1
With plain libvirt/KVM, edit the VM with sudo virsh edit vm_name and set the interface source bridge to vmbr1.
The MAC address of the VM does not matter in a routed setup, because the host, not the upstream router, delivers the packets to the VM.
Step 5 - Configuring an Ubuntu 24.04 guest with Netplan
Open the VM's console from the hypervisor and log in. First find the name of its network interface:
ip link
On Proxmox VE with VirtIO it is usually ens18. On cloud images, cloud-init may rewrite the network configuration on boot. Disable that so your static configuration is kept:
sudo nano /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg
network: {config: disabled}
Move any existing Netplan file out of the way (the name varies, check with ls /etc/netplan/):
sudo mv /etc/netplan/50-cloud-init.yaml /root/50-cloud-init.yaml.bak
Create a new Netplan file:
sudo nano /etc/netplan/60-routed-ip.yaml
network:
version: 2
ethernets:
ens18:
addresses:
- additional_ip_1/32
routes:
- to: default
via: host_primary_ip
on-link: true
nameservers:
addresses:
- 1.1.1.1
- 9.9.9.9
The on-link: true option is what makes this work: it tells the kernel the gateway is directly reachable on ens18 even though it is outside the /32 subnet.
Restrict the file permissions (Netplan warns about world-readable files) and test the configuration. netplan try rolls back automatically after 120 seconds if you do not confirm:
sudo chmod 600 /etc/netplan/60-routed-ip.yaml
sudo netplan try
Press Enter to accept once you confirm connectivity in the next step.
Step 6 - Configuring a Debian 12 guest with ifupdown
On a Debian 12 VM, edit /etc/network/interfaces (replace ens18 with the name shown by ip link):
sudo nano /etc/network/interfaces
auto lo
iface lo inet loopback
auto ens18
iface ens18 inet static
address additional_ip_2/32
gateway host_primary_ip
pointopoint host_primary_ip
dns-nameservers 1.1.1.1 9.9.9.9
The pointopoint option adds a direct route to the host, so the gateway outside the /32 is reachable. The dns-nameservers line only takes effect if the resolvconf package is installed; otherwise put the resolvers in /etc/resolv.conf.
If the file contains a source /etc/network/interfaces.d/* line and a cloud-init file exists there (for example 50-cloud-init), remove the duplicate ens18 stanza from that file and disable cloud-init networking as shown in Step 5. Then apply the change from the VM console:
sudo systemctl restart networking
Step 7 - Verifying the configuration
Inside the VM, check the address and the routing table:
ip -4 addr show ens18
ip route
2: ens18: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
inet 203.0.113.25/32 scope global ens18
default via 198.51.100.10 dev ens18 proto static onlink
Test outbound connectivity and confirm the public address the VM uses:
ping -c 4 1.1.1.1
curl -4 https://ifconfig.me
203.0.113.25
Finally, from a machine outside the server (your workstation), check that the VM answers on its additional IP:
ping -c 4 additional_ip_1
ssh your_user@additional_ip_1
If you used netplan try, confirm the change now so it is not rolled back.
Troubleshooting
The VM cannot reach its gateway. Check on the host that vmbr1 has the host's primary IP as /32 and that the VM's NIC is attached to vmbr1. In the VM, make sure the default route shows onlink; without on-link: true (Netplan) or pointopoint (ifupdown) the kernel rejects the gateway.
The VM reaches the host but not the internet. Verify sysctl net.ipv4.ip_forward returns 1 on the host and that ip route show dev vmbr1 contains a route for the VM's IP. Look for a host firewall dropping forwarded packets.
Outbound works but the IP is not reachable from outside. Confirm proxy_arp is 1 on the uplink interface (or on vmbr0 if the primary IP lives there) and that the additional IP is really assigned to this dedicated server in the CubePath panel.
The configuration is lost after a VM reboot. Cloud-init regenerated the network files. Create /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg as shown in Step 5.
Conclusion
Your dedicated server now routes each additional IP to a virtual machine through a routed bridge, with every VM using a /32 address and the host's primary IP as gateway. To add another IP later, add an up ip route add line to vmbr1, reload the host network and configure the new VM the same way. As next steps, set up a firewall inside each VM with UFW, and configure reverse DNS for the new addresses in the CubePath panel if you run mail or other services that depend on it.
