You will need a combination of DNAT and SNAT, and you need ip_forwarding active.
First, check ip_forwarding:
cat /proc/sys/net/ipv4/ip_forward
If it is 1 (enabled), go ahead. If not, you will have to put net.ipv4.ip_forward=1
on /etc/sysctl.conf
and run sysctl -p
.
The first rule is DNAT (assume 8.8.8.8
as the external IP and 192.168.0.10
as the internal):
iptables -t nat -A PREROUTING -d 8.8.8.8 -j DNAT --to-destination 192.168.0.10
When a external system (e.g. 200.100.50.25
) sends a packet reaching 8.8.8.8 will have the DESTINATION
changed to 192.168.0.10
, and sent away. But the source will be 200.100.50.25
, the packet will be processed and the response packet can:
Be dropped by 192.168.0.10 that may not know how to route it. Not desirable.
Be sent by 192.168.0.10 to the default gateway and to internet. As soon as it reaches 200.100.50.25
, this system will had never heard of 192.168.0.10
and will drop the packet. Not good.
Be dropped on the first hop, as 192.168.0.10
is a private address and not routeable on Internet.
To solve this, you need the second rule, SNAT:
iptables -t nat -A POSTROUTING -s 192.168.0.10 -j SNAT --to-source 8.8.8.8
With this rule, every packet that comes from 192.168.0.10
will have the source changed to 8.8.8.8
and sent away.
The collateral effect is that every log on 192.168.0.10
will show 8.8.8.8
as the client, not the real client. Tracking abusers will be a little harder.
You could install ufw
on your devices. It has support for defining apps through configuration files (you tell it which ports to open in the file) and then you can enable them (make the firewall take it into account) by running a command.
Make your packages depend on ufw
, drop a file in /etc/ufw/applications.d
and then using a post-install hook run ufw allow <app name>
to enable the rules.
Shorewall seems to be an even advanced front-end for IPtables and I'm sure it would support what you are trying to do. I recommend you check out its documentation and see if it would be a better fit.
Best Answer
IPTables isn't made for this kind of work, where lots and lots of packets need to be analyzed to make these decisions. IPTables is partly the answer though!
The real answer to this is the awesome and underused traffic control facilities in Linux. Note that mucking around with this without knowing what is going on may lead to you losing network connectivity to the machine! You have been warned!
Assuming eth0 is the outgoing device you will need to create a class-based traffic control queue which will by default output most traffic through the 'fast' queue and put a specific list of people into the 'slow' queue.
The beauty of this is you can create a situation whereby you allow lots of outbound traffic for the slow user unless an overriding class wants the bandwidth, but this example does not do this (will always provide 10kbps to the slow users). The queuing system will look something like this:
To do this, first you'll need to setup the queuing discipline in the kernel. The following will do this for you.. you must run this as one whole script
The "default 11" is important as it tells the kernel what to do with traffic not classified.
Once this is done, you can then setup an iptables rule to classify packets that match a certain criteria. If you plan on putting lots and lots of people into this slow rule an ipset rule is more appropriate (which should be available on rhel6 I believe).
So, create an ipset database to do the matching against...
Then create the iptables rule to do the match..
This instructs the kernel that if you match the destination IP with the source port from the set, classify it into the slow queue you setup with traffic control.
Now, finally whenever you want to slow an IP down you can use the ipset command to add the ip to the set such as this:
You can test it works using the command "tc -s class show dev eth0" and you will see stats in there indicating packets being redirected to the slow queue.
Note the only real downside to this is making it survive reboots. I don't think there are any init scripts available to create the ipsets from dumps on reboot (and they also must be created before iptables rules) and I'm certain there's no init scripts to resetup traffic control rules on reboot. If your not bothered, you can just recreate the whole thing from invoking a script in rc.local.