Skip to contentSkip to conversation

iptables DNAT algorithm -- another way?

DISCUSSION John Miller 3 participants 8 messages Dec 12, 2014 – Dec 14, 2014

lore
Share & tools
lore
#0 lore raw

Hi folks,

We're running a server that scan local systems for installed SSL certificates. Problem is, the tool truly means local -- RFC1918 private ranges only, please. Being a university, we have quite a few things located in public IP space that aren't necessarily world-accessible (development servers and the like).

My solution thus far has been to use DNAT to trick our scanning program into thinking it's using local addresses.

iptables -t nat -A OUTPUT -d 172.16.x.y -j DNAT \
    --to-destination 129.64.x.y

Trouble is that I want a direct correspondence: the third and fourth octets need to be the same for source and destination. I can certainly set ranges for initial and final destination address, but the NAT algorithm picks the destination at random. Is there a way to accomplish this in iptables? With another netfilter tool? I'd like to avoid running

#!/bin/sh
for third_octet in {0..255}; do

    for fourth_octet in {0..255}; do
        iptables -t nat -A OUTPUT \
            -d 172.16.${third_octet}.${fourth_octet} -j DNAT \
            --to-destination 129.64.${third_octet}.${fourth_octet}
    done

done

and ending up with 2^16 separate iptables rules.

John

Signature · 4 lines
John Miller
Systems Engineer
Brandeis University
[email protected]
#1 lore raw
Quoted 8 lines · John Miller

Hi folks,

We're running a server that scan local systems for installed SSL certificates. Problem is, the tool truly means local -- RFC1918 private ranges only, please. Being a university, we have quite a few things located in public IP space that aren't necessarily world-accessible (development servers and the like).

Quoted 5 lines

My solution thus far has been to use DNAT to trick our scanning program into thinking it's using local addresses.

iptables -t nat -A OUTPUT -d 172.16.x.y -j DNAT \
     --to-destination 129.64.x.y

This might point you in the right direction:

iptables -t nat -A PREROUTING -s 172.16.0.0/16 \
-j DNAT --to-destination 129.64.0.0-129.64.255.255

But I don't know if it provides predictable 1:1 mapping.

#2 lore raw
Quoted 12 lines · Neal Murphy
Quoted 11 lines · John Miller

Hi folks,

We're running a server that scan local systems for installed SSL certificates. Problem is, the tool truly means local -- RFC1918 private ranges only, please. Being a university, we have quite a few things located in public IP space that aren't necessarily world-accessible (development servers and the like).

My solution thus far has been to use DNAT to trick our scanning program into thinking it's using local addresses.

Quoted 7 lines
Quoted 2 lines
iptables -t nat -A OUTPUT -d 172.16.x.y -j DNAT \
     --to-destination 129.64.x.y

This might point you in the right direction:

iptables -t nat -A PREROUTING -s 172.16.0.0/16 \
-j DNAT --to-destination 129.64.0.0-129.64.255.255

Thanks for your response, Neal. These are for TCP streams that I'm initiating, so I'm pretty sure the OUTPUT chain is what I want here. As for the range in --to-destination, it's as you say: mappings aren't predictable. Was hoping someone on the list knew the innards of the DNAT target and whether there were other options besides --to-destination. Alternatively, was wondering if the mangle table might be able to do what I'm looking for. Definitely open to suggestions!

John

#3 lore raw
Quoted 1 line · John Miller

On Fri, Dec 12, 2014 at 7:50 PM, Neal Murphy <[email protected]>

Quoted 31 lines · wrote:
Quoted 14 lines · John Miller
Quoted 13 lines

Hi folks,

We're running a server that scan local systems for installed SSL certificates. Problem is, the tool truly means local -- RFC1918 private ranges only, please. Being a university, we have quite a few things located in public IP space that aren't necessarily world-accessible (development servers and the like).

My solution thus far has been to use DNAT to trick our scanning program into thinking it's using local addresses.

iptables -t nat -A OUTPUT -d 172.16.x.y -j DNAT \

Quoted 7 lines
Quoted 1 line
     --to-destination 129.64.x.y

This might point you in the right direction:

iptables -t nat -A PREROUTING -s 172.16.0.0/16 \

  -j DNAT --to-destination 129.64.0.0-129.64.255.255

Thanks for your response, Neal. These are for TCP streams that I'm initiating, so I'm pretty sure the OUTPUT chain is what I want here. As for the range in --to-destination, it's as you say: mappings aren't predictable. Was hoping someone on the list knew the innards of the DNAT target and whether there were other options besides --to-destination. Alternatively, was wondering if the mangle table might be able to do what I'm looking for. Definitely open to suggestions!

Quoted 1 line

John

Traditionally, DNAT must be done in the nat table in PREROUTING (change the destination address before any routing decisions are made). Likewise, SNAT must be done in the nat table in POSTROUTING (change the source address after all routing decisions are made).

Things might've changed with recent versions of netfilter and iptables.

#4 lore raw
In reply to Neal Murphy

Hello,

Quoted 8 lines · Neal Murphy
Quoted 6 lines · John Miller

My solution thus far has been to use DNAT to trick our scanning program into thinking it's using local addresses.

iptables -t nat -A OUTPUT -d 172.16.x.y -j DNAT \
     --to-destination 129.64.x.y
Quoted 6 lines

This might point you in the right direction:

iptables -t nat -A PREROUTING -s 172.16.0.0/16 \
-j DNAT --to-destination 129.64.0.0-129.64.255.255

But I don't know if it provides predictable 1:1 mapping.

It doesn't. You want to use NETMAP instead of DNAT.

Quoted 2 lines

Traditionally, DNAT must be done in the nat table in PREROUTING (change the destination address before any routing decisions are made).

That's for incoming packets. For locally-generated outgoing packets, you want to use the OUTPUT chain.

#5 lore raw
Quoted 11 lines · Pascal Hambourg

Hello,

Neal Murphy a écrit :

Quoted 8 lines · John Miller
Quoted 6 lines

My solution thus far has been to use DNAT to trick our scanning program into thinking it's using local addresses.

iptables -t nat -A OUTPUT -d 172.16.x.y -j DNAT \
     --to-destination 129.64.x.y
Quoted 8 lines
Quoted 6 lines

This might point you in the right direction:

iptables -t nat -A PREROUTING -s 172.16.0.0/16 \
-j DNAT --to-destination 129.64.0.0-129.64.255.255

But I don't know if it provides predictable 1:1 mapping.

It doesn't. You want to use NETMAP instead of DNAT.

Beautiful! That's exactly what I was looking for. Thank you!

Sounds like

iptables -t mangle -A OUTPUT -d 172.16.0.0/16 -j NETMAP --to 129.64.0.0/16

will do the trick.

John

#6 lore raw
Quoted 2 lines · John Miller

iptables -t mangle -A OUTPUT -d 172.16.0.0/16 -j NETMAP --to 129.64.0.0/16

The NETMAP target is valid only in the nat table.

#7 lore raw
Quoted 5 lines · Pascal Hambourg

John Miller a écrit :

Quoted 2 lines

iptables -t mangle -A OUTPUT -d 172.16.0.0/16 -j NETMAP --to 129.64.0.0/16

The NETMAP target is valid only in the nat table.

Just had a look at the iptables-extensions(8) manpage. You're definitely correct:

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.

Looks like the Frozentux tutorial
(https://www.frozentux.net/iptables-tutorial/iptables-tutorial.html#NETMAPTARGET)
made a typo in its example. The nat table definitely makes more sense; the mangle table wouldn't keep track of TCP streams, which is the whole point.

I thank you for your correction and help: because of it, I've learned more about iptables than I had in quite a while.

John