How can I limit a clients total internet time per day on the router without using scheduling? For example, 4 hours to use whenever they want.


Occasional Visitor
I have an RT-AC86U running with 386.7-2 Merlin. How can I go about limiting a client's total time usage per 24 hour period? I would like a client to have 4 hours of usage per day but not tied to any time schedule, free to use 4 hours whenever, and turns off when they go over the limit. I don't see this option in Asuswrt-Merlin, but can it be done?


Part of the Furniture
I don’t think there’s any inherent way for a router to manage a time budget. There are byte quotas or fixed time windows via iptables, but it isn’t practical for the router to track a client‘s elapsed wall clock time spent online. Would the router only count time spent sending or receiving packets to that client? It may take 5 seconds to download a big webpage, but take 30 minutes to read. Does that count as 5 seconds or 30 minutes?

The task is better suited to some parental control software residing on the client, if that’s the type of scenario you’re after.


Occasional Visitor
Here is how a different router brand handles what I'm trying to accomplish. It seems possible, just not sure how on the Asus since it's not built into the GUI.



Regular Contributor
I have a suggestion.

This can be done with a shell script and crontab.
Assuming is the router IP, is the device IP.

1. Make DHCP binding to the MAC address.
echo ",60" >> /tmp/timer_list.txt
2. Use iptables to monitor the either INPUT or OUTPUT packet counts(activity) of target device(ip)
# count down
iptables -nvL -Z INPUT | grep | grep -iPo '^\s*\d+[KM]?'
if [ "$?" -ne 0 ];then
   awk -F',' '{printf("%s\t%d\n",$1,$2-1)}' /tmp/timer_list.txt

# remove time-up nodes
sed -ir '/.+?,0/d' /tmp/timer_list.txt

# add/remove barrier to the nodes
grep '' /tmp/timer_list.txt
if [ "$?" -ne 0 ];then
    iptables -t nat -A PREROUTING -s -p tcp -m multiport --dport http,https -j DNAT --to-destination
    iptables -t nat -D PREROUTING -s -p tcp -m multiport --dport http,https -j DNAT --to-destination
3. Sampling every minutes, if packet counts increased, subtracting 1-minute
*/1 * * * * /jffs/scripts/
4. If remaining minutes equals to 0, replace iptables target IP with `reject-with icmp-host-prohibited`
sudo iptables -I INPUT -s -j REJECT --reject-with icmp-host-prohibited
or even better you may intercept the HTTP requests to your pre-defined http web hosted by local socat based on poor man's http server, and warn the time-upped user.

sudo iptables -t nat -A PREROUTING -s -p tcp -m multiport --dport http,https -j DNAT --to-destination
Poor man's HTTP server
socat -d TCP4-LISTEN:9444,reuseaddr,fork,crlf SYSTEM:./,pipes
# -----------------------------------
# socat -d TCP4-LISTEN:4444,reuseaddr,fork,crlf SYSTEM:./,pipes
# curl
# -----------------------------------

# -----------------------------------
tmp=$(mktemp -td)

# -----------------------------------
function finish() {
    printf -- '-%.0s' {1..20}  1>&2
    echo ""  1>&2
    rm -rf "$tmp"
# -----------------------------------
trap finish EXIT

# -----------------------------------
echoerr() { echo "[email protected]" 1>&2; }

# -----------------------------------
echoheader() {
    headers="[email protected]\n"
    echo "[email protected]" 1>&2;

# -----------------------------------
echobody() {
    txtBody="[email protected]\n"
    [ "$is_debug" -gt 0 ] && echo "[email protected]" 1>&2;

# -----------------------------------
endheader() {

    echo "$RESPONSE_CODE" 1>&2;

    if [ -z "$CONTEN_TYPE" ];then
        CONTEN_TYPE="text/html; charset=utf-8"

    printf "HTTP/1.0 $RESPONSE_CODE\n"
    printf "Cache-Control: no-store,no-cache\n"
    printf "Content-Type: $CONTEN_TYPE\n"
    byteCNT=$(echo -en "$txtBody" | wc -c)
    LineCNT=$(echo -en "$txtBody" | wc -l)
    totalCNT=`expr $byteCNT + $LineCNT`
    printf "Content-Length: $totalCNT\n"
    printf "$headers\n"
    printf "$txtBody\n"

    d=`date '+%m-%d %T'`
    echoerr "[ ] $RESPONSE_CODE $LineCNT lines $byteCNT|$totalCNT bytes | $HTTP_DEBUG"
    echoerr ""
    echoerr ""
    sleep 0.1
    exit 0;

# ---------------------------------------------------
read -r -d '' html_body <<- EOM

# ---------------------------------------------------
D_SPACE="Time is up!"

echobody "$html_body"
endheader "200 OK"
Last edited:


Part of the Furniture
Here is how a different router brand handles what

This looks like TP-Link GUI, but may I ask what model has this feature included?


Regular Contributor
Nice script. How can the iptables entry be disabled / removed again to enable access?

The -D will do.
iptables -D INPUT -s -j REJECT --reject-with icmp-host-prohibited

Or you may prefer to ipset, then you can keep the iptables unchanged, just add/remove items in ipset.
ipset -exist create clients_ipv4 hash:net counters
ipset -exist add clients_ipv4
iptables -I INPUT -i ${ip4if} -m set --match-set clients_ipv4 src -j ACCEPT
iptables -A INPUT -i ${ip4if} -j REJECT --reject-with icmp-host-prohibited"

ipset -exist create clients_ipv6 hash:net counters family inet6
ipset -exist add clients_ipv6 fec0::100/128
ip6tables -I INPUT -i ${ip6if} -m set --match-set clients_ipv6 src -j ACCEPT
ip6tables -A INPUT -i ${ip6if} -j REJECT --reject-with icmp6-adm-prohibited

Remove IPs
ipset -exist del clients_ipv4
ipset -exist del clients_ipv6 fec0::100/128
Last edited:

Similar threads

Latest threads

Sign Up For SNBForums Daily Digest

Get an update of what's new every day delivered to your mailbox. Sign up here!