I am looking to start up a new open-source mirror for my enterprise, but would also be interested in opening it up for external clients as well. However, for obvious reasons, I would like to limit the outgoing bandwidth to anyone not in one of my local subnets (e.g. traffic headed for one of the border routers).

I was originally looking at apache mod_bw, however there will likely be FTP access to this mirror as well. I've seen a number of promising options using 'tc', however that looks like it will match a pattern based on subnet. But I want the negation of that -- I have a list of a few (5 or 6) internal subnets which should have no restrictions, and everything else should go through the traffic shaper. Complicating things somewhat is I'll also need to match both v4 and v6 subnets.

I was experimenting with this, but again, I basically need the inverse of that, so "don't shape these subnets; apply policy to everything else". Perhaps 2 classes, one with a rate limiter and one which doesn't? I'm still unclear though on how the processing order goes with 'tc' -- is processing terminated after a match is found, or will it continue until the end? (e.g., will a catch-all at the end truly catch everything, or just what hasn't been matched yet?)


As far as I know, 'tc match' can't be used with ipv6. You will have to use iptables with '-j CLASSIFY'.

With iptables, processing continue after a match is found. With tc though, flowid redirect the packet to the class and stop the processing.

About the tree, I think what you want is:

  • root qdisc
  • class with all the bandwidth (this way leaf classes can borrow)
  • two classes, with eg 20% (external) and 80% (internal) of the bandwidth as guaranteed, and 100% as maximum : you can't have more than 100% as guaranteed
  • one leaf qdisc (pfifo, fq, fq_codel) per class

Although, I don't know your architecture. If you are using NAT, you will have to be accurate (no range) in your iptables rules. If you are using a reverse proxy, you won't be able to differenciate internal and external traffic.

If you have a reverse proxy, alternatives are:

  1. Shape at level 7 (with mod_bw and equivalent for ftp), because you will be able to look at X-Forwarded-For header
  2. Setup the shaper on your border router / Firewall (the one with a public IP), because you will be able to look at the public IP (remember you are always working on upload link)

Depending on your ability to do this, the best option is the second one, because you will be able to shape accurately, based on your WAN bandwidth and not the 1 or 10Gb NIC on your web server. It is your best option even without a reverse proxy.

About the class choice, you should use htb or hfsc for a better use of dynamic bandwidth and the 'default' option in the root qdisc.

  • The machine in question has an internet-routable IP, so no NAT. And its interface (1Gb) is also the slowest link between it and the border router. While there is no reverse proxy set up on the machine, that could be possible with some creative VirtualHost port assignments, though seems like a long end-around to employ what seems should be a relatively simple issue. I could always disable listening on IPv6 until the 'tc match' code is updated to be compliant with both protocols.... – ereisch Apr 22 '16 at 15:46
  • It's ok for you to shape on the server so. Match the traffic with "iptables -t mangle -A POSTROUTING -s <range>/<CIDR> -j CLASSIFY --set-class 1:10 && iptables -t mangle -A POSTROUTING ! -s <range>/<CIDR> -j CLASSIFY --set-class 1:20" then create your qdisc and classes with tc. You don't need to disable ipv6, do the same as above with ip6tables to match the ipv6 traffic. – Sanael Apr 24 '16 at 10:12

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.