Time Based Firewall Rules

I would like to see a time based firewall rules page. I.E. Block ebay.com on Friday from 10 PM till Saturday at 5 AM, Saturday at 10 PM till Sunday 5 AM, Sunday 10 PM till Monday 5 AM.

Go to LuCi -->Network–>Firewall–>Traffic Rules

Add a new rule to it New forward rule:

Give it a “name” click on "add and edit"

Scroll down to Destination Address

click on Custom

copy and paste this address (for ebay.com in this case) 23.211.155.210 To know certain ipaddress of a dns. Use ping command.

root@K-Router:~# ping www.ebay.com
PING www.ebay.com (23.211.155.210): 56 data bytes
64 bytes from 23.211.155.210: seq=0 ttl=54 time=89.993 ms
64 bytes from 23.211.155.210: seq=1 ttl=54 time=75.248 ms
64 bytes from 23.211.155.210: seq=2 ttl=54 time=62.035 ms
^C
--- www.ebay.com ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 62.035/75.758/89.993 ms

Action on reject

Fill in week days…month days…time etc.

Do let me know if it works, i haven’t tried it myself.

Now if we could do this with DNS, since eBay has at least 10 netblocks (http://ipinfo.io/AS11643).

I haven’t used it myself to be honest, so my knowledge goes up to here.

So with the firewall, it was blocking when it should have been. Also with ebay and other site - the use caching from external companies, so they don’t fall into place with the netblocks.

There seems to be a problem with time based rules: When the time for blocking has come - any connections there were already established before the block will be allowed to continue. This appears to be due to the following:

root@turris:~# iptables -L delegate_forward --line-numbers
Chain delegate_forward (1 references)
num  target     prot opt source               destination
1    forwarding_rule  all  --  anywhere             anywhere             /* user chain for forwarding */
2    ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
3    zone_wan_dest_REJECT  tcp  --  anywhere             anywhere             MAC 28:6A:BA:DF:BD:C9 TIME from 01:00:00 to 05:00:00 UTC /* Angelikas-iPad */
4    zone_wan_dest_REJECT  udp  --  anywhere             anywhere             MAC 28:6A:BA:DF:BD:C9 TIME from 01:00:00 to 05:00:00 UTC /* Angelikas-iPad */
5    zone_wan_dest_REJECT  tcp  --  anywhere             anywhere             MAC 1C:91:48:6E:98:44 TIME from 01:00:00 to 05:00:00 UTC /* Angelikas-iPhoneSE */
6    zone_wan_dest_REJECT  udp  --  anywhere             anywhere             MAC 1C:91:48:6E:98:44 TIME from 01:00:00 to 05:00:00 UTC /* Angelikas-iPhoneSE */
7    zone_wan_dest_REJECT  tcp  --  anywhere             anywhere             MAC B8:8D:12:12:78:08 TIME from 01:00:00 to 05:00:00 UTC /* Angelikas-Mac */
8    zone_wan_dest_REJECT  udp  --  anywhere             anywhere             MAC B8:8D:12:12:78:08 TIME from 01:00:00 to 05:00:00 UTC /* Angelikas-Mac */
9    zone_lan_forward  all  --  anywhere             anywhere
10   zone_wan_forward  all  --  anywhere             anywhere
11   zone_guest_forward  all  --  anywhere             anywhere
12   reject     all  --  anywhere             anywhere

You see here that the blocking rules (#3-8) are added to the firewall AFTER the “ctstate RELATED,ESTABLISHED” rule (#2). This means that any established connections are allowed to continue during the blocked time.

How do I move these blocking rules to before rule #2?

I’m sure IPTables are probably saved somewhere - would just have to juggle things around in that text file…

Did You already solved problem with already established connections? I am looking forward to time limited internet access too and I am observing the same behavior.

I couldn’t get it working with the time based rules in the web UI so I solved the problem in the following way (all in /etc/firewall.user):

First mark packets from the devices to affect in the “nat” table:

iptables -t nat -A prerouting_rule -m mac --mac-source 1c:91:48:xx:xx:xx -j MARK --set-mark 0x0A -m comment --comment "iPhone SE"

Then filter the marked packets in the appropriate chain:

iptables -A forwarding_rule -m mark --mark 0xA -m time --timestart 00:00:00 --timestop 04:00:00 -j REJECT -m comment --comment "Reject Kid's packets"

Because the custom chain “forwarding_rule” is evaluated before the default RELATED,ESTABLISHED rules in the delegate_forward chain, this works fine.

This can also be done without marking any packets but since I have these rules apply to several devices, it suits my purposes (only one time based rule needed). I’m also doing a few more things that I explain in this blog post (limiting speed after a certain number of MB has been used): https://gerco.tweakblogs.net/blog/14655/openwrt-iptables-download-rate-limiting

I’m interested in implementing something similar to download-rate limit my streaming obsessed teenagers who tend to hog our limited bandwidth. Could you share the Python script that you mention in your blogpost?

No problem. I’ll clean it up a little so it’s usable for other people than just me and let you know in the next few days.

Excellent - thank you!

I uploaded the Python script - you can find it at countbw.py · GitHub

To use it:

  1. Save the script as /root/countbw.py and make it executable

  2. Customize the groups in the script:

    groups = { '1c:91:48:xx:xx:xx': 'a', 'f0:dc:e2:xx:xx:xx': 'a', 'b8:8d:12:xx:xx:xx': 'b', '28:6a:ba:xx:xx:xx': 'b' }

  3. And the limits for those groups or individual clients:

    limits = { 'a': { 'dn': 512 * mega }, 'b': { 'up': 10*mega, 'dn': 100*mega } }

  4. Then add the script into /etc/cron.d (I called my file quota). This will cause the firewall to be restarted whenever one of the configured limits is exceeded. The bandwidth will be counted every 5 minutes and cached. There is no point in counting more frequently because majordomo only persists its store every 5 minutes anyway.

    MAILTO="" */5 * * * * root /root/countbw.py update --on-limits-changed "/etc/init.d/firewall restart"

  5. Now that we can restart the firewall when needed, the actual rules need to be applied for the correct groups. Add something like the following in /etc/firewall.user (to add on to the rules above, since this uses the packet marks). Make sure to follow [my blog post] (https://gerco.tweakblogs.net/blog/14655/openwrt-iptables-download-rate-limiting) to enable save/restore of packets marks using conntrack otherwise the rate limiting will only apply to upload traffic!

    # Rate limiting after quota exceeded if ! /root/countbw.py check --group a; then iptables -A forwarding_rule -m mark --mark 0xA -m conntrack --ctstate ESTABLISHED,RELATED -m hashlimit --hashlimit-name "over quota" --hashlimit-above 24kb/s -j DROP ip6tables -A forwarding_rule -m mark --mark 0xA -m conntrack --ctstate ESTABLISHED,RELATED -m hashlimit --hashlimit-name "over quota" --hashlimit-above 24kb/s -j DROP fi

The firewall will only be restarted if one of the configured limits has changed (from false to true or the other way around) so it won’t restart every 5 minutes. Because of the way Majordomo works, this will automatically reset to 0 and remove all limits at midnight. You can change this to use monthly or hourly limits by changing the majordomo files the script reads at the very top of the Python script.

If you have vague problems if it you have changed any of the configured groups or limits, you may need to delete the cache file (/tmp/countbw.cache) and recache “/root/countbw.py update” to get it to work again. I’m sure there are many edge cases this does not take in to account. If you are using non-Apple devices you may also want to change the exclusions in the script to make sure software updates and/or backups to whatever services matter to you are excluded from bandwidth caps. In my case I excluded iCloud backups, App Store, etc from counting.

Just for completeness, here is my /etc/firewall.user, which does contain some irrelevant stuff related to Tor - just ignore that.

Thank you very much, you are a star!! :relaxed:

I’m glad this topic is active. I had to replace my Omnia because of the poor IPv6 support.