From c89816ac60bece63f5362a3629ea28ba4f7cf047 Mon Sep 17 00:00:00 2001 From: Mohd Husaam Mehdi Date: Thu, 25 Sep 2025 20:07:35 +0530 Subject: [PATCH] parental-control: config option for nfqueue number --- parental-control/Makefile | 4 +- .../files/etc/init.d/parentalcontrol | 13 +- .../lib/parentalcontrol/parentalcontrol.sh | 174 ++++++++++-------- 3 files changed, 107 insertions(+), 84 deletions(-) diff --git a/parental-control/Makefile b/parental-control/Makefile index 44197447b..bfa6e7529 100644 --- a/parental-control/Makefile +++ b/parental-control/Makefile @@ -5,13 +5,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=parental-control -PKG_VERSION:=1.3.2 +PKG_VERSION:=1.4.0 LOCAL_DEV:=0 ifneq ($(LOCAL_DEV),1) PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://dev.iopsys.eu/network/parental-control.git -PKG_SOURCE_VERSION:=7ae6eaa6cc946ed05693bc84c61edbb16b1727bd +PKG_SOURCE_VERSION:=7fd56a198612166de682121d4970a82616840b8a PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz PKG_MIRROR_HASH:=skip endif diff --git a/parental-control/files/etc/init.d/parentalcontrol b/parental-control/files/etc/init.d/parentalcontrol index 92bc23cda..d096183fa 100755 --- a/parental-control/files/etc/init.d/parentalcontrol +++ b/parental-control/files/etc/init.d/parentalcontrol @@ -12,6 +12,7 @@ validate_global_section() { uci_validate_section parentalcontrol globals globals \ 'enable:bool:1' \ 'loglevel:uinteger:3' \ + 'queue_num:uinteger:53' \ 'bundle_path:string' \ 'urlfilter:bool' } @@ -24,11 +25,12 @@ remove_fw_rules() { } configure_fw_rules() { - local enable urlfilter + local enable urlfilter queue_num config_load parentalcontrol config_get_bool enable globals enable 0 config_get_bool urlfilter globals urlfilter 0 + config_get queue_num globals queue_num 53 remove_fw_rules @@ -37,6 +39,11 @@ configure_fw_rules() { return 0 fi + if [ "${queue_num}" -lt 0 ] || [ "${queue_num}" -gt 65535 ]; then + log "ERROR: queue_num not in 0-65535" + return 1 + fi + if [ "${urlfilter}" -eq "1" ]; then if [ ! -f "${OVERRIDE_JSON}" ]; then # throw error @@ -52,7 +59,7 @@ configure_fw_rules() { fi # this is for urlfilter daemon - add_iptables_nfqueue_rules + add_iptables_nfqueue_rules "$queue_num" fi fi @@ -107,7 +114,7 @@ start_service() { procd_open_instance "parentalcontrol" procd_set_param command nice -n 10 "${PROG}" # Lower priority - procd_append_param command -l ${loglevel} + procd_append_param command -l "${loglevel}" procd_set_param respawn procd_close_instance } diff --git a/parental-control/files/lib/parentalcontrol/parentalcontrol.sh b/parental-control/files/lib/parentalcontrol/parentalcontrol.sh index 13452cdf0..ef0db1def 100644 --- a/parental-control/files/lib/parentalcontrol/parentalcontrol.sh +++ b/parental-control/files/lib/parentalcontrol/parentalcontrol.sh @@ -438,102 +438,118 @@ add_internet_schedule_rules() { } add_iptables_nfqueue_rules() { - local filter_used + local queue_num="$1" - # Check if urlfilter used - if ! uci show parentalcontrol | grep -q profile_urlfilter; then - return - fi + # Check if urlfilter used + if ! uci show parentalcontrol | grep -q profile_urlfilter; then + return + fi - # IPv4 rules - iptables -w -nL FORWARD | grep -iqE "NFQUEUE" - if [ "$?" -ne 0 ]; then - # capture DNS responses (UDP/TCP sport 53) in FORWARD - iptables -w -I FORWARD 1 -p tcp --sport 53 -j NFQUEUE --queue-num 0 --queue-bypass - iptables -w -I FORWARD 1 -p udp --sport 53 -j NFQUEUE --queue-num 0 --queue-bypass + # IPv4 + # FORWARD + if ! iptables -w -nL | grep -q "URLFILTER_FORWARD"; then + iptables -w -N URLFILTER_FORWARD + iptables -w -I FORWARD 1 -j URLFILTER_FORWARD - # INPUT: DNS replies to router, skip loopback - iptables -w -I INPUT 1 -p tcp --sport 53 ! -i lo -j NFQUEUE --queue-num 0 --queue-bypass - iptables -w -I INPUT 1 -p udp --sport 53 ! -i lo -j NFQUEUE --queue-num 0 --queue-bypass + # capture DNS responses (sport 53) + iptables -w -A URLFILTER_FORWARD -p tcp --sport 53 -j NFQUEUE --queue-num $queue_num --queue-bypass + iptables -w -A URLFILTER_FORWARD -p udp --sport 53 -j NFQUEUE --queue-num $queue_num --queue-bypass - # OUTPUT: DNS replies from router, skip loopback - iptables -w -I OUTPUT 1 -p tcp --sport 53 ! -o lo -j NFQUEUE --queue-num 0 --queue-bypass - iptables -w -I OUTPUT 1 -p udp --sport 53 ! -o lo -j NFQUEUE --queue-num 0 --queue-bypass + # HTTP/HTTPS flows + iptables -w -A URLFILTER_FORWARD -p tcp --match multiport --ports 80,443 -j NFQUEUE --queue-num $queue_num --queue-bypass + iptables -w -A URLFILTER_FORWARD -p udp --match multiport --ports 80,443 -j NFQUEUE --queue-num $queue_num --queue-bypass + fi - # HTTP/HTTPS flows for urlfilter - iptables -w -I FORWARD 1 -p tcp --match multiport --ports 80,443 -j NFQUEUE --queue-num 0 --queue-bypass - iptables -w -I FORWARD 1 -p udp --match multiport --ports 80,443 -j NFQUEUE --queue-num 0 --queue-bypass + # INPUT + if ! iptables -w -nL | grep -q "URLFILTER_INPUT"; then + iptables -w -N URLFILTER_INPUT + iptables -w -I INPUT 1 -j URLFILTER_INPUT - # disable acceleration for https packet so that they can be read by urlfilter - ebtables --concurrent -A FORWARD -p ip --ip-protocol 6 --ip-destination-port 443 -j SKIPLOG 2> /dev/null - ebtables --concurrent -A FORWARD -p ip --ip-protocol 6 --ip-source-port 53 -j SKIPLOG 2> /dev/null - ebtables --concurrent -A FORWARD -p ip --ip-protocol 17 --ip-source-port 53 -j SKIPLOG 2> /dev/null - fi + iptables -w -A URLFILTER_INPUT -p tcp --sport 53 ! -i lo -j NFQUEUE --queue-num $queue_num --queue-bypass + iptables -w -A URLFILTER_INPUT -p udp --sport 53 ! -i lo -j NFQUEUE --queue-num $queue_num --queue-bypass + fi - # IPv6 rules - ip6tables -w -nL FORWARD | grep -iqE "NFQUEUE" - if [ "$?" -ne 0 ]; then - # capture DNS responses (UDP/TCP sport 53) in FORWARD - ip6tables -w -I FORWARD 1 -p tcp --sport 53 -j NFQUEUE --queue-num 0 --queue-bypass - ip6tables -w -I FORWARD 1 -p udp --sport 53 -j NFQUEUE --queue-num 0 --queue-bypass + # OUTPUT + if ! iptables -w -nL | grep -q "URLFILTER_OUTPUT"; then + iptables -w -N URLFILTER_OUTPUT + iptables -w -I OUTPUT 1 -j URLFILTER_OUTPUT - # INPUT: DNS replies to router, skip loopback - ip6tables -w -I INPUT 1 -p tcp --sport 53 ! -i lo -j NFQUEUE --queue-num 0 --queue-bypass - ip6tables -w -I INPUT 1 -p udp --sport 53 ! -i lo -j NFQUEUE --queue-num 0 --queue-bypass + iptables -w -A URLFILTER_OUTPUT -p tcp --sport 53 ! -o lo -j NFQUEUE --queue-num $queue_num --queue-bypass + iptables -w -A URLFILTER_OUTPUT -p udp --sport 53 ! -o lo -j NFQUEUE --queue-num $queue_num --queue-bypass + fi - # OUTPUT: DNS replies from router, skip loopback - ip6tables -w -I OUTPUT 1 -p tcp --sport 53 ! -o lo -j NFQUEUE --queue-num 0 --queue-bypass - ip6tables -w -I OUTPUT 1 -p udp --sport 53 ! -o lo -j NFQUEUE --queue-num 0 --queue-bypass + # ebtables bypass for IPv4 + ebtables --concurrent -A FORWARD -p ip --ip-protocol 6 --ip-destination-port 443 -j SKIPLOG 2>/dev/null + ebtables --concurrent -A FORWARD -p ip --ip-protocol 6 --ip-source-port 53 -j SKIPLOG 2>/dev/null + ebtables --concurrent -A FORWARD -p ip --ip-protocol 17 --ip-source-port 53 -j SKIPLOG 2>/dev/null - # HTTP/HTTPS flows for urlfilter - ip6tables -w -I FORWARD 1 -p tcp --match multiport --ports 80,443 -j NFQUEUE --queue-num 0 --queue-bypass - ip6tables -w -I FORWARD 1 -p udp --match multiport --ports 80,443 -j NFQUEUE --queue-num 0 --queue-bypass + # IPv6 + # FORWARD + if ! ip6tables -w -nL | grep -q "URLFILTER_FORWARD6"; then + ip6tables -w -N URLFILTER_FORWARD6 + ip6tables -w -I FORWARD 1 -j URLFILTER_FORWARD6 - # disable acceleration for https packet so that they can be read by urlfilter - ebtables --concurrent -A FORWARD -p ip6 --ip6-protocol 6 --ip6-destination-port 443 -j SKIPLOG 2> /dev/null - ebtables --concurrent -A FORWARD -p ip6 --ip6-protocol 6 --ip6-source-port 53 -j SKIPLOG 2> /dev/null - ebtables --concurrent -A FORWARD -p ip6 --ip6-protocol 17 --ip6-source-port 53 -j SKIPLOG 2> /dev/null - fi + ip6tables -w -A URLFILTER_FORWARD6 -p tcp --sport 53 -j NFQUEUE --queue-num $queue_num --queue-bypass + ip6tables -w -A URLFILTER_FORWARD6 -p udp --sport 53 -j NFQUEUE --queue-num $queue_num --queue-bypass + + ip6tables -w -A URLFILTER_FORWARD6 -p tcp --match multiport --ports 80,443 -j NFQUEUE --queue-num $queue_num --queue-bypass + ip6tables -w -A URLFILTER_FORWARD6 -p udp --match multiport --ports 80,443 -j NFQUEUE --queue-num $queue_num --queue-bypass + fi + + # INPUT + if ! ip6tables -w -nL | grep -q "URLFILTER_INPUT6"; then + ip6tables -w -N URLFILTER_INPUT6 + ip6tables -w -I INPUT 1 -j URLFILTER_INPUT6 + + ip6tables -w -A URLFILTER_INPUT6 -p tcp --sport 53 ! -i lo -j NFQUEUE --queue-num $queue_num --queue-bypass + ip6tables -w -A URLFILTER_INPUT6 -p udp --sport 53 ! -i lo -j NFQUEUE --queue-num $queue_num --queue-bypass + fi + + # OUTPUT + if ! ip6tables -w -nL | grep -q "URLFILTER_OUTPUT6"; then + ip6tables -w -N URLFILTER_OUTPUT6 + ip6tables -w -I OUTPUT 1 -j URLFILTER_OUTPUT6 + + ip6tables -w -A URLFILTER_OUTPUT6 -p tcp --sport 53 ! -o lo -j NFQUEUE --queue-num $queue_num --queue-bypass + ip6tables -w -A URLFILTER_OUTPUT6 -p udp --sport 53 ! -o lo -j NFQUEUE --queue-num $queue_num --queue-bypass + fi + + # ebtables bypass for IPv6 + ebtables --concurrent -A FORWARD -p ip6 --ip6-protocol 6 --ip6-destination-port 443 -j SKIPLOG 2>/dev/null + ebtables --concurrent -A FORWARD -p ip6 --ip6-protocol 6 --ip6-source-port 53 -j SKIPLOG 2>/dev/null + ebtables --concurrent -A FORWARD -p ip6 --ip6-protocol 17 --ip6-source-port 53 -j SKIPLOG 2>/dev/null } remove_iptables_nfqueue_rules() { - iptables -w -nL FORWARD | grep -iqE "NFQUEUE" - if [ "$?" -eq 0 ]; then - # DNS response rules - iptables -w -D FORWARD -p tcp --sport 53 -j NFQUEUE --queue-num 0 --queue-bypass - iptables -w -D FORWARD -p udp --sport 53 -j NFQUEUE --queue-num 0 --queue-bypass - iptables -w -D INPUT -p tcp --sport 53 ! -i lo -j NFQUEUE --queue-num 0 --queue-bypass - iptables -w -D INPUT -p udp --sport 53 ! -i lo -j NFQUEUE --queue-num 0 --queue-bypass - iptables -w -D OUTPUT -p tcp --sport 53 ! -o lo -j NFQUEUE --queue-num 0 --queue-bypass - iptables -w -D OUTPUT -p udp --sport 53 ! -o lo -j NFQUEUE --queue-num 0 --queue-bypass + # IPv4 + for chain in URLFILTER_FORWARD URLFILTER_INPUT URLFILTER_OUTPUT; do + if iptables -w -nL | grep -q "$chain"; then + iptables -w -D FORWARD -j $chain 2>/dev/null + iptables -w -D INPUT -j $chain 2>/dev/null + iptables -w -D OUTPUT -j $chain 2>/dev/null + iptables -w -F $chain + iptables -w -X $chain + fi + done - # HTTP/HTTPS - iptables -w -D FORWARD -p tcp --match multiport --ports 80,443 -j NFQUEUE --queue-num 0 --queue-bypass - iptables -w -D FORWARD -p udp --match multiport --ports 80,443 -j NFQUEUE --queue-num 0 --queue-bypass + ebtables --concurrent -D FORWARD -p ip --ip-protocol 6 --ip-destination-port 443 -j SKIPLOG 2>/dev/null + ebtables --concurrent -D FORWARD -p ip --ip-protocol 6 --ip-source-port 53 -j SKIPLOG 2>/dev/null + ebtables --concurrent -D FORWARD -p ip --ip-protocol 17 --ip-source-port 53 -j SKIPLOG 2>/dev/null - ebtables --concurrent -D FORWARD -p ip --ip-protocol 6 --ip-destination-port 443 -j SKIPLOG 2> /dev/null - ebtables --concurrent -D FORWARD -p ip --ip-protocol 6 --ip-source-port 53 -j SKIPLOG 2> /dev/null - ebtables --concurrent -D FORWARD -p ip --ip-protocol 17 --ip-source-port 53 -j SKIPLOG 2> /dev/null - fi + # IPv6 + for chain in URLFILTER_FORWARD6 URLFILTER_INPUT6 URLFILTER_OUTPUT6; do + if ip6tables -w -nL | grep -q "$chain"; then + ip6tables -w -D FORWARD -j $chain 2>/dev/null + ip6tables -w -D INPUT -j $chain 2>/dev/null + ip6tables -w -D OUTPUT -j $chain 2>/dev/null + ip6tables -w -F $chain + ip6tables -w -X $chain + fi + done - ip6tables -w -nL FORWARD | grep -iqE "NFQUEUE" - if [ "$?" -eq 0 ]; then - # DNS response rules - ip6tables -w -D FORWARD -p tcp --sport 53 -j NFQUEUE --queue-num 0 --queue-bypass - ip6tables -w -D FORWARD -p udp --sport 53 -j NFQUEUE --queue-num 0 --queue-bypass - ip6tables -w -D INPUT -p tcp --sport 53 ! -i lo -j NFQUEUE --queue-num 0 --queue-bypass - ip6tables -w -D INPUT -p udp --sport 53 ! -i lo -j NFQUEUE --queue-num 0 --queue-bypass - ip6tables -w -D OUTPUT -p tcp --sport 53 ! -o lo -j NFQUEUE --queue-num 0 --queue-bypass - ip6tables -w -D OUTPUT -p udp --sport 53 ! -o lo -j NFQUEUE --queue-num 0 --queue-bypass - - # HTTP/HTTPS - ip6tables -w -D FORWARD -p tcp --match multiport --ports 80,443 -j NFQUEUE --queue-num 0 --queue-bypass - ip6tables -w -D FORWARD -p udp --match multiport --ports 80,443 -j NFQUEUE --queue-num 0 --queue-bypass - - ebtables --concurrent -D FORWARD -p ip6 --ip6-protocol 6 --ip6-destination-port 443 -j SKIPLOG 2> /dev/null - ebtables --concurrent -D FORWARD -p ip6 --ip6-protocol 6 --ip6-source-port 53 -j SKIPLOG 2> /dev/null - ebtables --concurrent -D FORWARD -p ip6 --ip6-protocol 17 --ip6-source-port 53 -j SKIPLOG 2> /dev/null - fi + ebtables --concurrent -D FORWARD -p ip6 --ip6-protocol 6 --ip6-destination-port 443 -j SKIPLOG 2>/dev/null + ebtables --concurrent -D FORWARD -p ip6 --ip6-protocol 6 --ip6-source-port 53 -j SKIPLOG 2>/dev/null + ebtables --concurrent -D FORWARD -p ip6 --ip6-protocol 17 --ip6-source-port 53 -j SKIPLOG 2>/dev/null } remove_internet_schedule_rules() {