Fair NAT 0.80
Fair NAT is a script for configuring NAT on dedicated Linux routers.
You have a certain number of Clients (User A - User N) in your LAN which are connected by a Switch (or a Hub or BNC) to the Linux Router which is supposed to act as a gateway to the internet. The trouble now is, User B has a lot of downloads running and User C uploads stuff day and night, which leaves User A who only wants to use an interactive SSH shell in the rain, since B and C already use up all bandwidth the internet connection offers.
What we need to do is to share available bandwidth fairly among clients. In order to achieve this, I first tried several searches at Google and Freshmeat. This turned up quite a lot of results, like the Linux Advanced Routing & Traffic Control HOWTO which is a must-read and also contains great scripts, like the Wondershaper for single users. Another great general purpose script I found was HTB.init, which doesn't do anything by default, but gives you an easy way to setup HTB queues. In case you prefer CBQ, there's a CBQ.init too. If you don't know what I'm talking about, read the HOWTO above or continue reading here.
Since I never found a script that did exactly what I wanted, I decided to write my own. It's designed to be an all-I-need script, therefore it does not just setup Traffic Shaping, but Masquerading and Port Forwarding too. In short, it does everything that has to do with IPTables and Traffic Control. I use HTB (Hierarchical Token Bucket) to share bandwidth among clients (one class per client). On top of that I added a PRIO queue to prioritize interactive traffic on a per-user basis. On top of PRIO I set SFQ to treat connections fairly. In version 0.72, experimental support for IPP2P to recognize peer-to-peer traffic was added.
This is the simplified scheme for routing:
HTB class (for bandwidth sharing)
-- PRIO (for prioritizing interactive traffic)
--- Interactive: SFQ (to treat concurrent connections fairly)
--- Normal: SFQ
--- High-Traffic: SFQ
[ --- P2P: SFQ (if IPP2P support is enabled only) ]
I bet this can still be improved and I'm always interested in ways to do so. In case you want another class structure, this can be done by replacing the parent_class and user_class functions in the script. See CLASS_MODE in Configuration section and the function documentation in the script for details. Feel free to send me your own functions with a short explanation, if you want me to make them available for everybody.
Here's a "real" graphic, which shows the complete qdisc/class structure on $DEV_LAN if you use the unmodified example configuration file. This graphic was created using a hacked version of Stef Coene's show.pl script and GraphViz. Click here to see it, but I warn you: it's quite big. Here's a similar picture, which includes IPP2P support. Note that there are more filter rules (the blue arrows) now which put the filesharing traffic into the user's prio band 4.
Here are some key features of "FairNAT":
· This is a variable with a space-separated list of features that should be enabled. Default is all enabled if you dont set this variable.
· Allow Fair NAT to change some system variables in /proc, like setting /proc/sys/net/ipv4/ip_forward to 1.
· Try to load kernel modules for QoS first.
· Fair NAT will replace all existing iptables rules with a very basic (empty) configuration. Not healthy for firewalls. You can disable this feature to keep the original rules in place. See Firewall Support below.
· Allow Fair NAT to configure NAT. You could disable this if you prefer to set this up yourself / let your firewall do it.
· Allow Fair NAT to configure Port Forwarding. Same as NAT, you can disable this if you don't need it.
· Shape download traffic. If you know a little bit about traffic shaping and believe that download shaping is completely useless, feel free to disable this.
· Shaping upload traffic can be disabled also. If you disable this and QOS_DOWN also, you could use Fair NAT for setting up NAT and Port Forwarding only, although that's not really the purpose of the script ;-)
· Allow Fair NAT to modify the TOS (type-of-service) field of packets. Right now, Fair NAT relies on this TOS field for shaping, so using this feature is highly recommended.
For this script, you need iptables, tc and a QoS-enabled kernel. All these binaries must support HTB (usually the case unless you got a really old installation, in which case you ought to update anyway). I also use several kernel patches, none of which are actually required (unless if you want P2P shaping and some other Hacks). See README.patches in the tarball.