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 sudo access.
  • 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 addr and ip 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:

PlaceholderMeaningExample
host_primary_ipMain IP of the dedicated server198.51.100.10
host_prefixPrefix length of the main IP24
host_gatewayUpstream gateway of the dedicated server198.51.100.1
additional_ip_1, additional_ip_2Additional IPs you will give to VMs203.0.113.25, 203.0.113.26
eno1Host's physical uplink interfaceeno1, enp1s0f0

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

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.