9

I have a Linux machine (RHEL 6.7) with 2 IP's configured on a single NIC (eth1). The primary address, and therefore the address that all traffic appears to come from, is 10.0.0.23. The other is 10.0.0.160.

I am looking for a way to use iptables to change the source IP based on the destination address of a packet. Normally the traffic will 'go out on' 10.0.0.23, but say my packet is destined for 10.0.0.1, I want that packet to 'go out on' 10.0.0.160.

The reason for this is firewalls on the network that are out of my control. There are rules in place allowing traffic from 10.0.0.160 to 10.0.0.1, but not from 10.0.0.23 to 10.0.0.1.

I don't want all traffic to originate from 10.0.0.160, only that destined for 10.0.0.1.

I was looking at using the nat table and maybe a prerouting rule, but don't see a way to change the source address. If it would help I could create an alias for eth1 (so there would be eth1 and eth1:0) but would like to see if there's a solution in the current config.

Thanks in advance for any advice.

1
  • Is there a particular reason for wanting to do this with iptables? The behaviour you described is easily achieved by modifying the routing table. Nov 17 '15 at 19:59
11

Here are two different methods of achieving the desired behaviour:

1. Using iptables

The SNAT target in iptables allows the source address to be modified as you requested. The man page for iptables-extensions has this to say about SNAT:

This target is only valid in the nat table, in the POSTROUTING and INPUT chains, and user-defined chains which are only called from those chains. It specifies that the source address of the packet should be modified (and all future packets in this connection will also be mangled), and rules should cease being examined.

Based on your question, the following rule will change the source address of packets destined for 10.0.0.1 to 10.0.0.160:

$ iptables -t nat -A POSTROUTING --destination 10.0.0.1/32 -j SNAT --to-source 10.0.0.160

2. Using a static route

Alternatively, instead of an iptables rule, add a static route for the destination host to the routing table, using the following syntax:

$ ip route add <destination>/32 via <gateway> src <alias>

Based on the information you provided, you would use:

$ ip route add 10.0.0.1/32 via <gateway> src 10.0.0.160

Replace <gateway> with the actual IP address of your gateway, as this wasn't provided in your question.

Traffic destined for 10.0.0.1 will now originate from 10.0.0.160. Any other traffic takes the default route, originating from 10.0.0.23.

9
  • soulcake - there is no particular reason why I want to use iptables to accomplish this. Your option one works just fine, thank you. Your option two is not working for me, when I add your rule I can no longer ping my destination. So you have solved my problem, but I don't think I should mark the question answered since the rule doesn't work for me. Either way, many thanks.
    – eliszka
    Nov 18 '15 at 18:19
  • @eliszka If you could post the output of ip addr for the interface you're working with I could possibly help you with the static route method. Other than that, I think the answer specifically addresses what you were requesting, and likely deserves an upvote at least? Nov 18 '15 at 18:41
  • I will mark it answered since, if you remove 'iptables' from the title it is in fact answered. Your routing solution works for me but the iptables rule does not.
    – eliszka
    Nov 18 '15 at 20:29
  • @eliszka I misunderstood in that case. In your first comment you mentioned 'option two is not working', which I took to refer to the static route as this was labelled as the second option. You could try running tcpdump -i <interface> 'icmp[icmptype] = icmp-echo' on host 10.0.0.1, and then run ping 10.0.0.1 from host 10.0.0.160. The tcpdump command will show you whether your ICMP request packets are at least reaching the host. Can you confirm? It could be the case that this traffic isn't making it through your firewall. Nov 18 '15 at 20:52
  • After applying your iptables rule I get 100% packet loss pinging 10.0.0.1 from 10.0.0.160, however the packets are making it to 10.0.0.1 per the ICMP echo request output I see running your tcpdump command on 10.0.0.1.
    – eliszka
    Nov 19 '15 at 21:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.