In this post I will explain a way to get multiple public IPs for an OpenWRT router and configuring it so that you can have several servers behind NAT with overlapping ports.

⚠️ WARNING: The solution presented here may not adhere to best practices.
The following method is kinda a dirty hack and requires a lot of manual configuration. Also this doesn’t provide any firewall so if one of your servers gets hacked, your whole LAN is exposed to the compromised machine.

Install kmod-macvlan

This is required for creating a virtual device that the DHCP server assigns our new IP address.

Create a MACVLAN device and an interface for it

In LuCI, navigate to Network > Interfaces > Devices and create a device with the following configurations:

Setting Value
Device type MACVLAN
Name srv_macvlan in this guide
Existing device interface facing WAN, usually eth0.2
MAC address something unique

Then head to the Interfaces tab. Create new interface:

Setting Value
Name srv_wan in this guide
Device srv_macvlan
Protocol DHCP client

After creating, open advanced settings and tick Use default gateway off. Save and apply. Note down the IP your ISP gave to srv_wan. We will refer to it as srv_wan_ip.

Forward desired ports

Let srv_lan_ip be the server’s IP in LAN that you want to add.

Now that we have more than one public IP, we need to specify which public IP maps to which local IP. Configure the port forwards as you want but all traffic intended for srv_lan_ip should be matched with srv_wan_ip.

Create a response routing table for server

Now your server has a reachable IP srv_wan_ip, but it doesn’t have any way to respond due to lack of default gateway. Because the current default gateway would make your server answer with different public IP than srv_wan_ip, we need to manually configure routes for your server.

Navigate to Network > Static Routes and add for your server:

  • A default gateway:

    Setting Value
    Interface srv_wan
    IPv4-Gateway the gateway that srv_wan is connected to
    Route table rtable_nb in this guide
  • Route to your router’s neighbors:

    Setting Value
    Interface srv_wan
    Target subnet that srv_wan is in (CIDR notation)
    Route table rtable_nb
  • Route to your LAN:

    Setting Value
    Interface your LAN interface
    Target subnet that your LAN interface is in (CIDR notation)
    Route table rtable_nb

Apply the routing table

The last step is to redirect all the traffic from your server to the routing table created. This is easily done, but it requires modifying the config files directly.

SSH to the router and open /etc/config/network in editor. Append:

config rule
	option src 'srv_lan_ip/32'
	option lookup 'rtable_nb'

to the end of file. Then restart some interface or reload network config some other way. Issue command ip rules show to make sure your rule was added. You should now have a working system.