What you will set up
Each Melonslab server is isolated from the other servers on its local network, so that no other customer's server can reach yours directly. Your server still believes the other addresses in its network are next door, and tries to reach them directly. That fails: two servers in the same network cannot reach each other until their traffic goes through the gateway, the router every server already uses for the internet.
You only need this between two Melonslab servers in the same network. A server elsewhere, or a Melonslab server in another network, goes through the gateway already.
Every step below was run on two fresh Melonslab servers with Debian 13:
- Before the change, every IPv4 connection between them failed with
No route to host. Over IPv6, most failed withNo route to hostorTLS handshake timeout. - After the change, 60 pings in a row and 20 connections in a row succeeded, over both IPv4 and IPv6, in both directions.
- Both servers kept reaching their gateway and the internet, and everything still worked after a reboot.
Before you start
You need two Melonslab servers with Debian 13, and root access to both. Do every step on both servers.
The examples use 203.0.113.10 and 2001:db8:0:10::a for one server, 203.0.113.20 and 2001:db8:0:20::a for the other, and 203.0.113.1 for the gateway. Replace them with your own.
1. Find your network and gateway
ip -4 route
default via 203.0.113.1 dev eth0 onlink
203.0.113.0/24 dev eth0 proto kernel scope link src 203.0.113.10
The second line is your server's local network, 203.0.113.0/24, which it tries to reach directly. The first line names the gateway, 203.0.113.1. If the other server's IPv4 address is not in the same network, IPv4 needs no change, and you can go to step 3.
2. Send IPv4 through the gateway
On a Melonslab server, the network is set up by Debian's ifupdown, from a file that cloud-init writes, /etc/network/interfaces.d/50-cloud-init. Its first line warns that changes to it may not last, so leave it alone. ifupdown also runs every script in /etc/network/if-up.d each time a network connection comes up. Create /etc/network/if-up.d/via-gateway, with your network and gateway:
#!/bin/sh
# Melonslab isolates servers from each other on the local network:
# send traffic for the rest of the /24 through the gateway.
[ "$IFACE" = eth0 ] && [ "$ADDRFAM" = inet ] || exit 0
ip route replace 203.0.113.0/24 via 203.0.113.1 dev eth0 onlink
This replaces the route for the whole network, so every server in it, now and later, is reached through the gateway. A route for each single address would work too, but you would have to add one on both servers for each new server. The gateway itself stays reachable: onlink tells the server it is next door, as the default route already does.
Make it executable, and run it once now:
chmod 755 /etc/network/if-up.d/via-gateway
IFACE=eth0 ADDRFAM=inet /etc/network/if-up.d/via-gateway
ip -4 route
default via 203.0.113.1 dev eth0 onlink
203.0.113.0/24 via 203.0.113.1 dev eth0 onlink
3. Send IPv6 through the gateway
Each Melonslab server has an IPv6 network of its own, so IPv6 already goes through the gateway, and needs no route. But the gateway sends the servers a message, called a redirect, telling them to talk to each other directly, which fails again. Tell the server to ignore redirects. Create /etc/sysctl.d/60-no-redirects.conf:
# Send traffic to other servers in the same network through the router.
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0
net.ipv6.conf.eth0.accept_redirects = 0
The eth0 line is needed: without it, the setting was back on for eth0 after a reboot. Apply it, and forget the redirects the server has already received:
sysctl --system
ip -6 route flush cache
Ignoring redirects is also a common recommendation for hardening a server. IPv4 needed no such setting in our test, once the route from step 2 was in place.
4. Test it
After doing steps 2 and 3 on both servers, from the first server:
ping -c 3 203.0.113.20
ping -c 3 2001:db8:0:20::a
3 packets transmitted, 3 received, 0% packet loss, time 2050ms
Then the same from the second server to the first. To see which way the server sends traffic:
ip route get 203.0.113.20
203.0.113.20 via 203.0.113.1 dev eth0 src 203.0.113.10 uid 0
via 203.0.113.1 means it goes through the gateway. Restart both servers once, and run the test again: the route and the setting come back by themselves.
Troubleshooting
No route to host, or Destination Host Unreachable, between two Melonslab servers. The traffic does not go through the gateway. Check ip route get from step 4 on both servers: the answer must say via and the gateway. A reply has to find its way back, so both servers need the change.
IPv6 works for a while, then fails with No route to host or TLS handshake timeout. The server has accepted a redirect. Check that sysctl net.ipv6.conf.eth0.accept_redirects shows 0, and run ip -6 route flush cache.
The route is gone after a reboot. The script is not executable, or its name contains a dot, which makes ifupdown skip it. Check with ls -l /etc/network/if-up.d/via-gateway.