What's new

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.

  • SNBForums Code of Conduct

    SNBForums is a community for everyone, no matter what their level of experience.

    Please be tolerant and patient of others, especially newcomers. We are all here to share and learn!

    The rules are simple: Be patient, be nice, be helpful or be gone!

Daxx123

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?
 
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.
 
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.

Capture.JPG
 
I have a suggestion.

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

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

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

# add/remove barrier to the nodes
grep '192.168.9.100/32' /tmp/timer_list.txt
if [ "$?" -ne 0 ];then
    iptables -t nat -A PREROUTING -s 192.168.9.100/32 -p tcp -m multiport --dport http,https -j DNAT --to-destination 192.168.9.1:4444
else
    iptables -t nat -D PREROUTING -s 192.168.9.100/32 -p tcp -m multiport --dport http,https -j DNAT --to-destination 192.168.9.1:4444
else
fi
3. Sampling every minutes, if packet counts increased, subtracting 1-minute
*/1 * * * * /jffs/scripts/activity.sh
4. If remaining minutes equals to 0, replace iptables target IP with `reject-with icmp-host-prohibited`
sudo iptables -I INPUT -s 192.168.9.100/32 -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.

Interception
sudo iptables -t nat -A PREROUTING -s 192.168.9.100/32 -p tcp -m multiport --dport http,https -j DNAT --to-destination 192.168.9.1:4444
Poor man's HTTP server
socat -d TCP4-LISTEN:9444,reuseaddr,fork,crlf SYSTEM:./httpd.sh,pipes
Bash:
#!/bin/bash
# -----------------------------------
# socat -d TCP4-LISTEN:4444,reuseaddr,fork,crlf SYSTEM:./httpd.sh,pipes
# curl http://127.0.0.1:4444
# -----------------------------------
is_debug=0

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

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

# -----------------------------------
echoerr() { echo "$@" 1>&2; }

# -----------------------------------
echoheader() {
    headers="$headers$@\n"
    echo "$@" 1>&2;
}

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

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

    RESPONSE_CODE="$1"
    echo "$RESPONSE_CODE" 1>&2;

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

    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"
    txtBody="${txtBody//%/%%}"
    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
    <html>
    <Body>
    [info_msg]
    </Body></html>
EOM

# ---------------------------------------------------
D_SPACE="Time is up!"
html_body=${html_body//\[info_msg\]/$D_SPACE}

echobody "$html_body"
endheader "200 OK"
 
Last edited:
Nice script. How can the iptables entry be disabled / removed again to enable access?

The -D will do.
Bash:
iptables -D INPUT -s 192.168.9.100/32 -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.
Bash:
ipset -exist create clients_ipv4 hash:net counters
ipset -exist add clients_ipv4 192.168.9.100/32
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
Bash:
ipset -exist del clients_ipv4 192.168.9.100/32
ipset -exist del clients_ipv6 fec0::100/128
 
Last edited:

Similar threads

Support SNBForums w/ Amazon

If you'd like to support SNBForums, just use this link and buy anything on Amazon. Thanks!

Sign Up For SNBForums Daily Digest

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