Skip to content

Using Two Public IPs from DHCP

RouterOS can work with two public IP addresses assigned by your ISP, but the exact approach depends on how the ISP provisions them. There are three common models:

ISP Provisioning ModelRouterOS Approach
One DHCP lease + a routed extra IP or subnetOne DHCP client; add second IP as a static address
One DHCP lease + one additional static /32One DHCP client; add second IP with /ip address add
Two separate DHCP sessions (VLAN-separated)Two VLAN sub-interfaces, one DHCP client each

Confirming the provisioning model with your ISP before configuring is essential. Attempting to run two DHCP clients on the same L2 interface will not reliably produce two independent public IP leases.


  • RouterOS 6.x or 7.x
  • A WAN interface connected to the ISP (e.g., ether1)
  • Knowledge of the ISP’s provisioning model (routed extra IP, static /32, or separate DHCP sessions per VLAN)
  • Administrator access

Option A — ISP Provides a Routed Extra IP (most common)

Section titled “Option A — ISP Provides a Routed Extra IP (most common)”

The ISP routes an additional IP (or subnet) to your primary leased address. Run a single DHCP client and add the second IP statically.

# Primary WAN DHCP client
/ip dhcp-client
add interface=ether1 add-default-route=yes use-peer-dns=no disabled=no
# Add second public IP delivered statically by ISP
/ip address
add address=203.0.113.11/32 interface=ether1 comment="2nd public IP from ISP"

If the ISP routes an entire subnet (e.g., a /29), add the usable host addresses to the WAN interface (or a loopback) as instructed by the ISP.


Option B — ISP Requires Two Separate DHCP Sessions (VLAN-separated)

Section titled “Option B — ISP Requires Two Separate DHCP Sessions (VLAN-separated)”

Only applicable when the ISP differentiates sessions by VLAN tag or separate physical port. Create two VLAN sub-interfaces on the WAN port, then attach one DHCP client to each.

# VLAN sub-interfaces on the WAN port
/interface vlan
add name=wan1 interface=ether1 vlan-id=10
add name=wan2 interface=ether1 vlan-id=20
# One DHCP client per logical interface; disable default-route installation
# here and manage routes manually (see below)
/ip dhcp-client
add interface=wan1 add-default-route=no use-peer-dns=no disabled=no
add interface=wan2 add-default-route=no use-peer-dns=no disabled=no

Note: “Interface aliasing” (adding a secondary address to the same physical interface) does not create a second independent DHCP session. Separate logical L2 interfaces are required.

Some ISPs bind leases to a DHCP Client-ID (option 61) rather than (or in addition to) the MAC address. In RouterOS 7, client-id is configured through the /ip dhcp-client option system — define a named option with code 61, then reference it in the client entry via dhcp-options.

# Define named options for option 61 (client identifier)
/ip dhcp-client option
add name=circuit-A code=61 value="'circuit-A'"
add name=circuit-B code=61 value="'circuit-B'"
# Apply to each DHCP client entry
/ip dhcp-client
set [find interface=wan1] dhcp-options=circuit-A
set [find interface=wan2] dhcp-options=circuit-B

If no custom option is set, RouterOS sends the interface MAC address as the client identifier by default (clientid option). Confirm expected identifiers with your ISP before changing this value.


src-nat — bind specific LAN hosts or subnets to each public IP

Section titled “src-nat — bind specific LAN hosts or subnets to each public IP”

Use explicit src-nat rules (not masquerade). Masquerade auto-picks the interface address and behaves unpredictably when multiple IPs are assigned.

# RouterOS v7: create named routing tables
/routing table
add name=to_pub1 fib
add name=to_pub2 fib
# Default routes per table (same ISP gateway if both IPs share one WAN)
/ip route
add dst-address=0.0.0.0/0 gateway=203.0.113.1 routing-table=to_pub1
add dst-address=0.0.0.0/0 gateway=203.0.113.1 routing-table=to_pub2
add dst-address=0.0.0.0/0 gateway=203.0.113.1 distance=1 comment="main fallback"
# Mangle: pin specific LAN hosts to a routing table
/ip firewall mangle
add chain=prerouting src-address=192.168.88.10 action=mark-routing \
new-routing-mark=to_pub1 passthrough=no comment="Host .10 exits via Public1"
add chain=prerouting src-address=192.168.88.20 action=mark-routing \
new-routing-mark=to_pub2 passthrough=no comment="Host .20 exits via Public2"
# NAT: translate each host to its designated public IP
/ip firewall nat
add chain=srcnat src-address=192.168.88.10 out-interface=ether1 \
action=src-nat to-addresses=203.0.113.10 comment="public1-nat"
add chain=srcnat src-address=192.168.88.20 out-interface=ether1 \
action=src-nat to-addresses=203.0.113.11 comment="public2-nat"

RouterOS v6: /routing table does not exist. Use routing-mark= in /ip route add directly instead of named routing tables.

PCC load balancing — split all connections 50/50

Section titled “PCC load balancing — split all connections 50/50”

Per-Connection Classifier distributes new connections across both public IPs without pinning specific hosts.

203.0.113.10
# Assumptions:
# ISP gateway: 203.0.113.1 Public IP 2: 203.0.113.11
# LAN: 192.168.88.0/24
/ip firewall mangle
# Step 1: classify new connections 50/50
add chain=prerouting in-interface-list=LAN connection-mark=no-mark \
dst-address-type=!local \
per-connection-classifier=both-addresses-and-ports:2/0 \
action=mark-connection new-connection-mark=conn_pub1 passthrough=yes
add chain=prerouting in-interface-list=LAN connection-mark=no-mark \
dst-address-type=!local \
per-connection-classifier=both-addresses-and-ports:2/1 \
action=mark-connection new-connection-mark=conn_pub2 passthrough=yes
# Step 2: apply routing marks from connection marks
add chain=prerouting in-interface-list=LAN connection-mark=conn_pub1 \
action=mark-routing new-routing-mark=to_pub1 passthrough=no
add chain=prerouting in-interface-list=LAN connection-mark=conn_pub2 \
action=mark-routing new-routing-mark=to_pub2 passthrough=no
# NAT: translate by connection mark
/ip firewall nat
add chain=srcnat out-interface=ether1 connection-mark=conn_pub1 \
action=src-nat to-addresses=203.0.113.10
add chain=srcnat out-interface=ether1 connection-mark=conn_pub2 \
action=src-nat to-addresses=203.0.113.11

Inbound port-forwards (dst-nat) per public IP

Section titled “Inbound port-forwards (dst-nat) per public IP”

Bind inbound services explicitly to the target public IP:

/ip firewall nat
add chain=dstnat dst-address=203.0.113.10 dst-port=80 protocol=tcp \
action=dst-nat to-addresses=192.168.88.100 to-ports=80 \
comment="Web server via Public1"
add chain=dstnat dst-address=203.0.113.11 dst-port=25 protocol=tcp \
action=dst-nat to-addresses=192.168.88.101 to-ports=25 \
comment="Mail server via Public2"

/ip address print

Both public IPs should appear on the WAN interface (or VLAN sub-interfaces) with the correct prefix lengths.

/ip dhcp-client print detail

Each DHCP client entry should show status: bound with the leased address and gateway.

/routing table print
/ip route print where routing-table~"pub"

Each named table should have a default route pointing to the ISP gateway.

From a host pinned to Public1 (e.g., 192.168.88.10), confirm the source IP used for outbound traffic:

/tool fetch url="https://api.ipify.org" mode=https output=user

Or run from two different LAN hosts and compare the reported IPs.

Ping an external host explicitly from each public IP to verify reachability for both addresses independently:

/tool ping 8.8.8.8 src-address=203.0.113.10 count=3
/tool ping 8.8.8.8 src-address=203.0.113.11 count=3
/ip firewall nat print stats
/ip firewall connection print

Confirm counters increment on the correct src-nat rule for each public IP.

/ip firewall mangle print stats

Routing-mark rules should show packet counts when LAN hosts generate traffic.


Both LAN hosts appear to use the same public IP

  • Confirm mangle rules are in the prerouting chain and that passthrough=no is set on mark-routing rules so they stop further processing.
  • Verify specific src-nat rules appear before any catch-all masquerade rule in the NAT chain: /ip firewall nat print.
  • Check that routing table entries exist: /ip route print where routing-table=to_pub1.

Connections to Internet drop or reset intermittently

  • Asymmetric routing breaks stateful NAT. Ensure connection marks are applied so that reply packets follow the same path as the initial packet.
  • If using two DHCP clients, disable add-default-route=yes on both and manage default routes manually; two competing default routes at distance=1 cause flapping.

Second DHCP client does not obtain a lease

  • Confirm the ISP requires two separate DHCP sessions (VLAN-based); most ISPs do not.

  • Verify VLAN IDs match what the ISP expects.

  • Check interface names: /interface vlan print.

  • Capture DHCP packets on the WAN interface to confirm whether the ISP sends a second Offer at all:

    /tool sniffer quick port=67,68 interface=ether1 duration=30

    If no second Offer arrives, the ISP is not provisioning dual leases via DHCP and you need to use Option A (routed extra IP) instead.

ISP rejects traffic from second public IP

  • Some ISPs enforce per-port IP assignments (uRPF or MAC binding). Confirm with the ISP that both IPs are legitimate on the same WAN port.
  • If using VLAN sub-interfaces, ensure the source MAC on each VLAN matches what the ISP expects.

DHCP-provided gateway is unreachable (off-subnet gateway)

Some ISPs deliver an option-3 gateway that is outside the offered subnet (e.g., IP /32 with a gateway in a different block). RouterOS requires a directly connected route to reach a gateway. Add a /32 host route as a lease script:

/ip dhcp-client
set [find interface=ether1] script={
:if ($bound=1) do={
/ip route add dst-address=($"gateway") gateway="" distance=1
}
}

Replace the empty gateway= with the literal ISP gateway address if known, or use a script variable ($"gateway") populated from the lease. Without this host route, default-route installation fails silently and the WAN stays disconnected.

One of the two public IPs is unreachable from upstream (ARP issue)

When two public IPs share the same physical WAN port, some ISPs only ARP-resolve the MAC they originally learned from the DHCP handshake. If the second IP (added statically or via a secondary VLAN) uses a different MAC or the ISP uses strict MAC/IP binding, upstream traffic to the second IP is dropped.

  • Verify the MAC visible to the ISP matches expectations: /interface print detail.
  • Try setting the WAN interface ARP mode to proxy-arp if the upstream switch expects to see ARP replies for all public IPs from the same port: /interface ethernet set ether1 arp=proxy-arp.
  • Contact the ISP to confirm whether MAC/IP binding is enforced.

masquerade rule not translating to the correct public IP

  • Replace the masquerade rule with explicit src-nat to-addresses= rules for each public IP. Masquerade auto-selects the primary interface address and is unreliable when multiple IPs are configured on the same interface.