On off internet

Q I'm trying to restrict internet access (Wi-Fi) on one of my laptops, but only at set periods during the day and night. I presume it can be done as a Cron job, but I'm not quite sure of the syntax to set out the time frame and if I need to edit Cron as a user or via the root. Let's say the laptop can only access the internet from 08.00 until 17.00, then from 20.00 to 22.30 on Sunday-Thursday (school nights) but on Friday or Saturday it can connect from 08.00 until 23.00. Could it be done in a couple of lines, or do I have to run one command for each day of the week and the off times? Also, how do I stop all internet traffic, both Wi-Fi and Ethernet?

A This can be done with Iptables, the program that controls the Linux kernel's firewall abilities. You can use this to block all outgoing traffic, but a cleaner solution is to block all traffic that's not destined for your local network. That way your child's computer can still access any shared directories or local servers, but outside internet access is prevented. The following command will allow connections to the 192.168.0.* network, but block everything else.

iptables -I OUTPUT ! -d 192.168.1.0/24 -j DROP

The -I OUTPUT part (that's a capital letter i) inserts the rule at the start of the output chain. Firewall rules are processed in order, with the first match used, so you want this to come before anything else you may have. This is important if you're already running firewall software, since that's normally set to allow outgoing connections and you want to override it. The d 192.168.1.0/24 part matches any traffic heading for the 192.168.1.* network, but the preceding ! inverts this, so any traffic not for your network matches. The final part, -j, tells Iptables what to do with this data - in this case, discard it. Since this rule doesn't specify an interface, it will block regardless of whether you're using a wireless or wired connection. You could put this command into a Cron task, and add the corresponding rule to remove the restriction

iptables -D OUTPUT ! -d 192.168.1.0/24 -j DROP

where the -I (insert) is replaced by -D to delete the rule and that would effectively switch on and off the computer's internet connection at the specified times. For example, by putting this in /etc/cron.d/firewall

0 8 * * * root /sbin/iptables -D OUTPUT ! -d
192.168.1.0/24 -j DROP &>/dev/null
0 17 * * 0-4 root /sbin/iptables -I OUTPUT ! -d
192.168.1.0/24 -j DROP &>/dev/null
0 20 * * 0-4 root /sbin/iptables -D OUTPUT ! -d
192.168.1.0/24 -j DROP &>/dev/null
30 22 * * 0-4 root /sbin/iptables -I OUTPUT !
-d 192.168.1.0/24 -j DROP &>/dev/null
0 23 * * 5-6 root /sbin/iptables -I OUTPUT ! -d
192.168.1.0/24 -j DROP &>/dev/null

The first rule turns the filtering off at 8am every day, the next three turn on at 5pm, off at 8pm and on again at 10.30pm on Sunday to Thursday (days 0 to 4 in Cron terms). The final line turns on filtering at the later time for weekend use. There is one serious flaw with this approach: the computer has to be turned on for the Cron task to activate, so resetting it will cause the rule to disappear. One solution is a shell script that checks the time and sets the rules accordingly, which you can run from /etc/rc.local.

#!/bin/sh
DAY=$(( $(date +%u) % 7 ))
HOUR=$(date +%H)
if  $DAY -lt 2 ; then
if  $HOUR -ge 8  &&  $HOUR -lt 23
then
/sbin/iptables -D OUTPUT ! -d
192.168.1.0/24 -j DROP
else
/sbin/iptables -I OUTPUT ! -d 192.168.1.0/24
-j DROP
fi
else
if  $HOUR -ge 8  &&  $HOUR -lt 17
then
/sbin/iptables -D OUTPUT ! -d
192.168.1.0/24 -j DROP
elif  $HOUR -ge 20  &&  $HOUR -lt 22
then
/sbin/iptables -D OUTPUT ! -d
192.168.1.0/24 -j DROP
else
/sbin/iptables -I OUTPUT ! -d 192.168.1.0/24
-j DROP
fi
fi

This may look complicated, but all it does is retrieve the day and hour from the date command and make decisions about whether to turn filtering on or off based on this. You may want to tweak it to suit your needs, but it's a good starting point.

Follow us on Identi.ca or Twitter

Username:   Password:
Create Account | About TuxRadar