Bandwidth throttling in OS X
posted in the early afternoon by Constantinos. Filed under Code, OS X, TerminalThis post was originally published in 2008
The tips and techniques explained may be outdated.
It’s been a while since my last post, and that’s because I’ve been busy with coursework, so I haven’t had time to mess around with OS X. However there was one feature I needed to figure out out of necessity if anything else. I have certain files I wish to freely share with some friends of mine, and the easiest way for me to do that was put them on my local web server and serve them over http. The only problem with this approach, is that the university has a weekly data transfer limit of 5Gb per week during peak hours, those being between 6pm and midnight. Additionally, local traffic doesn’t count towards that limit, and if that limit is exceeded then my Internet would be blocked and limited to only the local network for the remainder of that week.
Therefore, the solution I was looking for would not require me to turn off my web server (as I’d like to still access it locally), and would ideally simply limit the outgoing traffic automatically between those two times.
One aspect that made this particular solution usable, was the fact that port 80 is firewalled from the external world. This means that if I want to run a web server on my local machine accessible from the outside, I have to do it on a different port. Therefore I use port 80 to access the web server locally, and port 8080 to access it from the outside. This gives me a dedicated point of entry for the traffic that I wish to limit the bandwidth.
The solution is fairly simple, and involves only two tools: cron
, for enabling and disabling the filter at specific times, and ipfw
for actually setting up the filters. The idea is this: create a pipe
using ipfw
that limits outgoing traffic on port 8080 to a specified rate (let’s say 15KByte/s), and using a cron job add the pipe to my network interface at 6pm, and delete it at midnight. That’s it! Theoretically you only have to create the pipe once, but in order to have this survive across restarts, I added another cron job at 5:59pm that re-creates the pipe. The full contents of the crontab file (located at /etc/crontab
) are as follows:
# Set the bandwidth limit at 5:59pm 59 17 * * * root /sbin/ipfw pipe 1 config bw 15KByte/s # Add the bandwidth limit to the specified port at 6:00pm 0 18 * * * root /sbin/ipfw add 1 pipe 1 src-port 8080 # Lift the bandwidth limit at 12:00am 0 0 * * * root /sbin/ipfw delete 1 |
The problem with this is if the computer boots up or reboots after 6pm and before midnight, the filters will not be set. The solution is to use anacron
for executing the ipfw commands, But as I rarely shut down or reboot my computer, it wasn’t worth it for me to make that happen. If I do make those modifications, I will post an update here. Also note that the ipfw commands need to be executed as root.