3

The problem -- Translate 10.8.a.b to 10.0.a.b ?

I have a VPN setup to a bastion host. I'm attempting to map 10.8.0.0/17 into 10.0.0.0/17 so that the IP address 10.8.1.1 gets mapped to 10.0.1.1 in my local network.

I imagine the culprit of this problem is

iptables -t nat -A PREROUTING -d 10.8.0.0/17 -j DNAT --to-destination 10.0.0.0-10.0.127.255
                                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
####
# This allows you to DNAT connections in a round-robin way over a given range of destination addresses.
# --to-destination ipaddr-ipaddr
#     Address range to round-robin over. 
# What I Want:
#    10.8.0.1 -> 10.0.0.253 -> 10.0.0.1
# What I Get:
listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes
04:41:15.934726 IP 10.8.255.1 > 10.8.0.1: ICMP echo request, id 93, seq 1, length 64

listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
05:50:27.228399 IP 10.0.0.253 > 10.0.52.24: ICMP echo request, id 93, seq 1, length 64
                                ^^^^^^^^^^
                              Wrong IP Address!!!

How do I write the (first 17 bit/last 15 bits) of the destination into a new destination. A more clear example of what I'm aiming to achieve is 10.8.0.100 in the VPN correlates to 10.0.0.100 in my LAN network.

Note: This is my first time setting up routing between two networks, if there's any obvious mistakes or inconsistency with normal conventions please address it, I'm still learning. IPTables how to nat 10.8.a.b to 10.0.a.b?

Networks

LAN (10.0.0.0/16)

network VPN IP
10.0.0.1 ISP Gateway
10.0.0.253 Home OpenVPN Gateway (10.8.255.2)

VPN (10.8.0.0/16)

network VPN IP
10.8.0.0/16 Reserved Clients (Start at 10.8.128.1)
10.8.0.0/17 IP Forward NAT 10.8.0.0/17 -> 10.0.0.0/17 via 10.8.255.2
10.8.255.1 Cloud Server Gateway
10.8.255.2 Home OpenVPN Gateway (LAN: 10.0.0.253)

VPN Routes

network gateway Notes
10.8.0.0/16 10.8.255.1 Entire network
10.8.0.0/17 10.8.255.2 all IP address should translate the last 15 bits onto the destination (10.8.0.100 -> 10.0.0.100)

IPTables

root@gwhome# iptables -A FORWARD -i tun0 -o eth0 -m conntrack --ctstate NEW -j ACCEPT
root@gwhome# iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
root@gwhome# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
root@gwhome# iptables -t nat -A PREROUTING -d 10.8.0.0/17 -j DNAT --to-destination 10.0.0.0-10.0.127.255

This machine is not the network gateway, so I've seen some people mention the need for SNAT, but I think the need for this should be alleviated by MASQUERADE. A confirmation on this would be appreciated.

ping 10.8.0.1 (LAN: 10.0.0.1)

root@cloud-server# ping 10.8.0.1 -c 3
PING 10.8.0.1 (10.8.0.1) 56(84) bytes of data.

--- 10.8.0.1 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 2078ms

tun0 sniff

root@gwhome# tcpdump -i tun0 icmp
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes
04:41:15.934726 IP 10.8.255.1 > 10.8.0.1: ICMP echo request, id 89, seq 1, length 64
04:41:16.989078 IP 10.8.255.1 > 10.8.0.1: ICMP echo request, id 89, seq 2, length 64
04:41:18.013008 IP 10.8.255.1 > 10.8.0.1: ICMP echo request, id 89, seq 3, length 64
^C
3 packets captured
3 packets received by filter
0 packets dropped by kernel

eth0 sniff

root@gwhome# tcpdump -i eth0 icmp
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
05:50:27.228399 IP 10.0.0.253 > 10.0.52.24: ICMP echo request, id 93, seq 1, length 64
05:50:28.234007 IP 10.0.0.253 > 10.0.52.24: ICMP echo request, id 93, seq 2, length 64
05:50:29.257588 IP 10.0.0.253 > 10.0.52.24: ICMP echo request, id 93, seq 3, length 64
^C
3 packets captured
3 packets received by filter
0 packets dropped by kernel
2
  • 1
    Although this is easy to achieve in iptables, why do you want to perform this kind of NAT in the first place, instead of directly routing 10.0.0.0/16 via the VPN gateway? Commented Nov 16, 2022 at 13:51
  • @user1686 Thank you for your time, My home network is on 10.0.0.0/16, and my office also uses 10.0.0.0/16, this VPN is to enter my home network from my office, so I'll need to have the address translated to avoid overlapping IP addresses.
    – Christian
    Commented Nov 16, 2022 at 13:54

3 Answers 3

4

The DNAT target won't work here; it translates everything to one host or to a randomly selected host from the specified range. (Basically it is meant to be used when matching one destination host, i.e. -d foo/32.)

For prefix translation you'd be looking for the NETMAP target:

  • iptables:
    -d 10.8.0.0/16 -j NETMAP --to 10.0.0.0/16

  • nftables (new):
    ip daddr 10.8.0.0/16 dnat ip prefix to ip daddr map { 10.8.0.0/16 : 10.0.0.0/16 }

  • nftables (all versions):
    ip daddr 10.8.0.0/16 dnat to ip addr & 0.0.255.255 | 10.8.0.0

(Other than that, NETMAP is still a form of DNAT and uses the same iptables NAT/conntrack infrastructure as DNAT does.)

This machine is not the network gateway, so I've seen some people mention the need for SNAT, but I think the need for this should be alleviated by MASQUERADE. A confirmation on this would be appreciated.

Yes, MASQUERADE is also SNAT, except it automatically chooses the new source address from the outbound interface while the SNAT target requires it to be specified manually.

Even if you cannot configure routes for the VPN on your LAN gateway, you can still (partially) avoid the need for SNAT by configuring the same route directly on each host (e.g. using route -p add on Windows, or DHCP option 121). This isn't something you can do on all devices, but may be enough if you only want to access a PC or a server.

5

The IPTables target you want is NETMAP:

This target allows you to statically map a whole network of addresses onto another network of addresses. It can only be used from rules in the nat table.

--to address[/mask]
    Network address to map to. The resulting address will be constructed in the following way: All 'one' bits in the mask are filled in from the new `address'. All bits that are zero in the mask are filled in from the original address. IPv6 support available since Linux kernels >= 3.7.

Also keep in mind that your local hosts (in 10.0.0.0/17) MUST direct their response traffic to the VPN.

0

Another workable solution is to go through the one-time pain of renumbering your home network to something more unique.

Instead of picking the common networks, renumber with a block out of 172.16.0.0/12 which goes up to 172.31.255.255.

This may be as little as re-configuring your router's LAN port and DHCP scope, and updating any device with a static DHCP reservation or static local IP config. You may have to reconfigure network printers or cameras too.

A good candidate is 172.27.0.0 /16 or a smaller netblock if you don't need that many IPs.

192.168.(something between 100 and 254) /24 would be useful too. The blocks in 192.168.0 and 1 and 10 tend to be over-used.

Other uncommon RFC1918 blocks might include subnets from 198.18.0.0/15 There's a full list at https://en.wikipedia.org/wiki/Reserved_IP_addresses#IPv4 though your results might vary with some of the specialty networks.

Choose wisely and you'll never have to do this again.

3
  • 3
    I realise this doesn't answer the question as posted, but does resolve the underlying issue of conflicting network blocks while also decreasing complexity. Adding NAT never simplifies things and should be a last resort.
    – Criggie
    Commented Nov 16, 2022 at 23:58
  • 1
    Good idea, though 172.16/12 is also a minefield. Used in some corporate networks and many(!) virtualization/containerization solutions. IMHO, good old 192.168/16 is the way to go for home networks.
    – Daniel B
    Commented Nov 17, 2022 at 9:28
  • @DanielB fair call - though 192.168.200-through-250.x would be less-used in my guess rather than the 192.168.0 or 1 or 10 or 20 or 100 ranges.
    – Criggie
    Commented Nov 17, 2022 at 18:14

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .