Using Two Public IPs from DHCP
Using Two Public IPs from DHCP
Section titled “Using Two Public IPs from DHCP”Overview
Section titled “Overview”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 Model | RouterOS Approach |
|---|---|
| One DHCP lease + a routed extra IP or subnet | One DHCP client; add second IP as a static address |
| One DHCP lease + one additional static /32 | One 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.
Prerequisites
Section titled “Prerequisites”- 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
Configuration
Section titled “Configuration”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-clientadd interface=ether1 add-default-route=yes use-peer-dns=no disabled=no
# Add second public IP delivered statically by ISP/ip addressadd 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 vlanadd name=wan1 interface=ether1 vlan-id=10add 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-clientadd interface=wan1 add-default-route=no use-peer-dns=no disabled=noadd interface=wan2 add-default-route=no use-peer-dns=no disabled=noNote: “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.
DHCP Client-ID (ISP identity binding)
Section titled “DHCP Client-ID (ISP identity binding)”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 optionadd 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-clientset [find interface=wan1] dhcp-options=circuit-Aset [find interface=wan2] dhcp-options=circuit-BIf 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.
Using Both Public IPs
Section titled “Using Both Public IPs”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 tableadd name=to_pub1 fibadd name=to_pub2 fib
# Default routes per table (same ISP gateway if both IPs share one WAN)/ip routeadd dst-address=0.0.0.0/0 gateway=203.0.113.1 routing-table=to_pub1add dst-address=0.0.0.0/0 gateway=203.0.113.1 routing-table=to_pub2add 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 mangleadd 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 natadd 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 tabledoes not exist. Userouting-mark=in/ip route adddirectly 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.
# 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/50add 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 marksadd 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 natadd chain=srcnat out-interface=ether1 connection-mark=conn_pub1 \ action=src-nat to-addresses=203.0.113.10add chain=srcnat out-interface=ether1 connection-mark=conn_pub2 \ action=src-nat to-addresses=203.0.113.11Inbound 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 natadd 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"Verification
Section titled “Verification”Confirm addresses are assigned
Section titled “Confirm addresses are assigned”/ip address printBoth public IPs should appear on the WAN interface (or VLAN sub-interfaces) with the correct prefix lengths.
Check DHCP client status
Section titled “Check DHCP client status”/ip dhcp-client print detailEach DHCP client entry should show status: bound with the leased address and
gateway.
Verify routing tables (RouterOS v7)
Section titled “Verify routing tables (RouterOS v7)”/routing table print/ip route print where routing-table~"pub"Each named table should have a default route pointing to the ISP gateway.
Test outbound path per public IP
Section titled “Test outbound path per public IP”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=userOr 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=3Check NAT translations
Section titled “Check NAT translations”/ip firewall nat print stats/ip firewall connection printConfirm counters increment on the correct src-nat rule for each public IP.
Check mangle rule hits
Section titled “Check mangle rule hits”/ip firewall mangle print statsRouting-mark rules should show packet counts when LAN hosts generate traffic.
Troubleshooting
Section titled “Troubleshooting”Both LAN hosts appear to use the same public IP
- Confirm mangle rules are in the
preroutingchain and thatpassthrough=nois set on mark-routing rules so they stop further processing. - Verify specific
src-natrules 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=yeson both and manage default routes manually; two competing default routes atdistance=1cause 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=30If 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-clientset [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-arpif 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
masqueraderule with explicitsrc-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.
See Also
Section titled “See Also”- DHCP Client — DHCP client configuration reference
- Policy Routing — routing marks and routing tables
- Firewall Mangle — packet marking with PCC and connection marks
- NAT — src-nat, dst-nat, and masquerade
- Load Balancing with PCC — full PCC dual-WAN guide