How to restrict internet time-based via iptables?


I tried to restrict the internet for my laptop on a time-based schedule. Here’s what I tried:

sudo iptables -I OUTPUT -p tcp -m owner --uid-owner "$USER" -m time --timestart $(date -u -d @$(date "+%s" -d "14:00") +%H:%M) --timestop $(date -u -d @$(date "+%s" -d "15:00") +%H:%M) -j DROP

as well as:

sudo iptables -I OUTPUT -p tcp -m owner --uid-owner "$USER" -m time --timestart 14:00:00 --timestop 15:00:00 --kerneltz -j DROP

And it looked good:

sudo iptables -L OUTPUT
Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
DROP       tcp  --  anywhere             anywhere             owner UID match MYUSER TIME from 14:00:00 to 15:00:00
DROP       tcp  --  anywhere             anywhere             owner UID match MYUSER TIME from 12:00:00 to 13:00:00 UTC

But I still have Internet access. What am I doing wrong?

I mainly used this soure:

Hi @xps,

According to:

Please note time module is not part of standard kernel, you need to download and apply patch from Patch-O-Matic

Hope this helps!

Is there another way than patching my kernel manually? I guess, this exceeds my capabilities a bit and I would not feel comfortable doing it :see_no_evil:

Yeah. Same.

But, if you know commands to execute and restore it immediately, not time-based rules, you can use systemd timers



The iptables command works, you don’t need to patch anything. Just keep in mind that it will only “block” IPv4. If you have both IPv4 and IPv6, you would need to block both.

Also keep in mind that it is just TCP, depending on how you test your connection, it might looks like it is working. Ping will still work, also DNS and the UDP based QUIC protocol.

You are quoting 15+ years old article.

@xps does the rule work without “-m time …”?

Also, besides what @xabbu wrote, anything running as different user will also keep working.

Why not just completely disconnecting and reconnecting the network adapter(s) via a timer based script?

1 Like

Thanks for pointing that out. I was already wondering why iptables wouldn’t show some sort of error if provided a wrong option/command.

That was the main problem. I really appreciate you saying that. It solved the problem.

That’s fine as I just want to restrict myself from spending the night doing useless stuff on the internet. This should raise the bar high enough and, therefore, should serve the purpose.


1 Like

One last question:

How can I put this into an systemd oneshot service?

I tired

Description=Beschränke das Internet nachts

ExecStart=iptables -N TBNR
ExecStart=iptables -A TBNR -m limit --limit 5/m --limit-burst 10 -j LOG --log-prefix='[TIME-BASED NTWRK BLOCK]'
ExecStart=iptables -A TBNR -j REJECT
ExecStart=ip6tables -N TBNR
ExecStart=ip6tables -A TBNR -m limit --limit 5/m --limit-burst 10 -j LOG --log-prefix='[TIME-BASED NTWRK BLOCK]'
ExecStart=ip6tables -A TBNR -j REJECT
ExecStart=iptables -I OUTPUT -p tcp -m owner --uid-owner "$USER" -m time --timestart $(date -u -d @$(date "+%s" -d "20:35") +%H:%M) -j TBNR
ExecStart=iptables -I OUTPUT -p tcp -m owner --uid-owner "$USER" -m time --timestop $$(date -u -d @$(date "+%s" -d "05:00") +%H:%M) -j TBNR
ExecStart=ip6tables -I OUTPUT -p tcp -m owner --uid-owner "$USER" -m time --timestart $((date -u -d @$(date "+%s" -d "20:35") +%H:%M)) -j TBNR
ExecStart=ip6tables -I OUTPUT -p tcp -m owner --uid-owner "$USER" -m time --timestop $(date -u -d @$(date "+%%s" -d "05:00") +%%H:%%M) -j TBNR


None of the combination above worked. What am I missing/do I need to do to make the bash expansion/substitution work?

If you’re using iptables.service, why not just put them in /etc/iptables/ip(6)tables.rules?

As for your .service, use full path for commands (/usr/bin/iptables). Can’t remember if oneshot supports multiple ExecStarts though. And I don’t think RemainAfterExit=yes makes sense here, but I could be wrong.


What’s gonna prevent you from just disabling these rules when you feel like it? :stuck_out_tongue:

Everything @zbe said and the $USER will not work, specify the username or ID. You can’t use environment variables unless you add them in your systemd service file. But don’t add a $USER it makes no sense in a service file.
And take a look at your date commands, the first looks ok, but the other 3 have all different problems.

But I would also use the files in /etc/iptables and use iptables.service and ip6tables.service ( But of course without $USER, it will not work. Just use the real username or ID)

Also, shouldn’t --timestart and --timestop be in the same rule or else any tcp packet with time later than soonest --timestart until midnight will be matched? (I guess it doesn’t matter in your specific case where you go over midnight anyway.)

Btw, you could just remove default route and you are free of internet. :stuck_out_tongue:

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.