diff --git a/urlfilter/Makefile b/urlfilter/Makefile index 5b9c59e83..aa335cb76 100644 --- a/urlfilter/Makefile +++ b/urlfilter/Makefile @@ -61,6 +61,8 @@ define Package/urlfilter/install $(INSTALL_DIR) $(1)/etc/uci-defaults $(INSTALL_DATA) ./files/etc/uci-defaults/95-firewall_parentalcontrol.ucidefaults $(1)/etc/uci-defaults/ $(INSTALL_DATA) ./files/etc/uci-defaults/95-migrate_urlfilter.ucidefaults $(1)/etc/uci-defaults/ + + $(BBFDM_INSTALL_CORE_PLUGIN) ./files/etc/urlfilter/X_IOPSYS_EU_ParentalControl.json $(1) parental_control endef $(eval $(call BuildPackage,urlfilter)) diff --git a/urlfilter/files/etc/firewall.parentalcontrol b/urlfilter/files/etc/firewall.parentalcontrol index 2ab856577..05410754f 100644 --- a/urlfilter/files/etc/firewall.parentalcontrol +++ b/urlfilter/files/etc/firewall.parentalcontrol @@ -1,41 +1,16 @@ #!/bin/sh -. /lib/functions.sh . /lib/parentalcontrol/parentalcontrol.sh -add_iptables_nfqueue_rules() { - iptables -w -nL FORWARD|grep -iqE "NFQUEUE" - if [ "$?" -ne 0 ]; then - # setup netfilter queue 0, use queue bypass so that if no application is - # listening to this queue then traffic is unaffected. - iptables -w -I FORWARD 1 -p tcp --match multiport --ports 80,443,53 -j NFQUEUE --queue-num 0 --queue-bypass - iptables -w -I FORWARD 1 -p udp --match multiport --ports 80,443,53 -j NFQUEUE --queue-num 0 --queue-bypass - - iptables -w -I INPUT 1 -p tcp --match multiport --ports 80,443,53 -j NFQUEUE --queue-num 0 --queue-bypass - iptables -w -I INPUT 1 -p udp --match multiport --ports 80,443,53 -j NFQUEUE --queue-num 0 --queue-bypass - - # 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 - - ip6tables -w -nL FORWARD|grep -iqE "NFQUEUE" - if [ "$?" -ne 0 ]; then - #ip6table rules - ip6tables -w -I FORWARD 1 -p tcp --match multiport --ports 80,443,53 -j NFQUEUE --queue-num 0 --queue-bypass - ip6tables -w -I FORWARD 1 -p udp --match multiport --ports 80,443,53 -j NFQUEUE --queue-num 0 --queue-bypass - - ip6tables -w -I INPUT 1 -p tcp --match multiport --ports 80,443,53 -j NFQUEUE --queue-num 0 --queue-bypass - ip6tables -w -I INPUT 1 -p udp --match multiport --ports 80,443,53 -j NFQUEUE --queue-num 0 --queue-bypass - - # 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 -} - -add_iptables_nfqueue_rules - -handle_internet_schedule +# if parentalcontrol is enabled, add the rules, else remove them +if [ "$(uci -q get parentalcontrol.globals.enable)" == "1" ]; then + # this is for urlfilter daemon + add_iptables_nfqueue_rules + # this for internet_access and profile_bedtime_schedule sections + add_internet_schedule_rules +else + # remove urlfilter daemon rules + remove_iptables_nfqueue_rules + # remove internet_access and profile_bedtime_schedule rules + remove_internet_schedule_rules +fi diff --git a/urlfilter/files/etc/init.d/urlfilter b/urlfilter/files/etc/init.d/urlfilter index b6b48fae0..b2aeb88e1 100755 --- a/urlfilter/files/etc/init.d/urlfilter +++ b/urlfilter/files/etc/init.d/urlfilter @@ -6,8 +6,9 @@ STOP=10 USE_PROCD=1 PROG=/usr/sbin/urlfilter -start_service() { +. /lib/parentalcontrol/parentalcontrol.sh +start_service() { if [ "$(uci -q get parentalcontrol.globals.enable)" == "1" ]; then procd_open_instance urlfilter procd_set_param command ${PROG} @@ -21,12 +22,20 @@ start_service() { conntrack -F fi - . /lib/parentalcontrol/parentalcontrol.sh - - handle_internet_schedule + # this is for urlfilter daemon + add_iptables_nfqueue_rules + # this for internet_access and profile_bedtime_schedule sections + add_internet_schedule_rules fi } +stop_service() { + # remove urlfilter daemon rules + remove_iptables_nfqueue_rules + # remove internet_access and profile_bedtime_schedule rules + remove_internet_schedule_rules +} + reload_service() { stop start diff --git a/urlfilter/files/etc/urlfilter/X_IOPSYS_EU_ParentalControl.json b/urlfilter/files/etc/urlfilter/X_IOPSYS_EU_ParentalControl.json new file mode 100644 index 000000000..75b71472a --- /dev/null +++ b/urlfilter/files/etc/urlfilter/X_IOPSYS_EU_ParentalControl.json @@ -0,0 +1,716 @@ +{ + "json_plugin_version": 2, + "Device.{BBF_VENDOR_PREFIX}ParentalControl.": { + "type": "object", + "protocols": [ + "cwmp", + "usp" + ], + "access": false, + "description": "This object contains the information about all parental control features.", + "array": false, + "Enable": { + "type": "boolean", + "read": true, + "write": true, + "protocols": [ + "cwmp", + "usp" + ], + "datatype": "boolean", + "description": "Enable or disable ParentalControl on the CPE.", + "mapping": [ + { + "type" : "uci", + "uci" : { + "file" : "parentalcontrol", + "section" : { + "type": "globals", + "name": "globals" + }, + "option" : { + "name" : "enable" + } + } + } + ] + }, + "ProfileNumberOfEntries": { + "type": "unsignedInt", + "read": true, + "write": false, + "protocols": [ + "cwmp", + "usp" + ], + "datatype": "unsignedInt", + "description": "<>", + "mapping": [ + { + "type": "uci", + "uci": { + "file": "parentalcontrol", + "section": { + "type": "profile" + }, + "option": { + "name": "@Count" + } + } + } + ] + }, + "URLBundleNumberOfEntries": { + "type": "unsignedInt", + "read": true, + "write": false, + "protocols": [ + "cwmp", + "usp" + ], + "datatype": "unsignedInt", + "description": "<>", + "mapping": [ + { + "type": "uci", + "uci": { + "file": "parentalcontrol", + "section": { + "type": "urlbundle" + }, + "option": { + "name": "@Count" + } + } + } + ] + }, + "Device.{BBF_VENDOR_PREFIX}ParentalControl.URLBundle.{i}.": { + "type": "object", + "protocols": [ + "cwmp", + "usp" + ], + "access": true, + "array": true, + "mapping": [ + { + "type": "uci", + "uci": { + "file": "parentalcontrol", + "section": { + "type": "urlbundle" + }, + "dmmapfile": "dmmap_parentalcontrol" + } + } + ], + "Name": { + "type": "string", + "read": true, + "write": true, + "protocols": [ + "cwmp", + "usp" + ], + "description": "Uniquely identifiable name of the URL bundle instance.", + "datatype": "string", + "range": [ + { + "max": 32 + } + ], + "flags": [ + "Unique", + "Linker" + ], + "mapping": [ + { + "data": "@Parent", + "type": "uci_sec", + "key": "name" + } + ] + }, + "DownloadURL": { + "type": "string", + "read": true, + "write": true, + "protocols": [ + "cwmp", + "usp" + ], + "datatype": "string", + "mapping": [ + { + "data": "@Parent", + "type": "uci_sec", + "key": "download_url" + } + ] + }, + "CustomURL": { + "type": "string", + "read": true, + "write": true, + "protocols": [ + "cwmp", + "usp" + ], + "description": "Comma separated list of URLs.", + "list": { + "datatype": "string" + }, + "mapping": [ + { + "data": "@Parent", + "type": "uci_sec", + "list": "custom_url" + } + ] + } + }, + "Device.{BBF_VENDOR_PREFIX}ParentalControl.Profile.{i}.": { + "type": "object", + "protocols": [ + "cwmp", + "usp" + ], + "description": "Table contain details of the access profiles.", + "uniqueKeys": [ + "Name" + ], + "access": true, + "array": true, + "mapping": [ + { + "type": "uci", + "uci": { + "file": "parentalcontrol", + "section": { + "type": "profile" + }, + "dmmapfile": "dmmap_parentalcontrol" + } + } + ], + "Alias": { + "type": "string", + "read": true, + "write": true, + "protocols": [ + "cwmp", + "usp" + ], + "datatype": "Alias", + "range": [ + { + "max": 64 + } + ], + "flags": [ + "unique" + ], + "mapping": [ + { + "data": "@Parent", + "type": "uci_sec", + "key": "alias" + } + ] + }, + "Name": { + "type": "string", + "read": true, + "write": true, + "protocols": [ + "cwmp", + "usp" + ], + "datatype": "string", + "range": [ + { + "max": 64 + } + ], + "mapping": [ + { + "data": "@Parent", + "type": "uci_sec", + "key": "name" + } + ] + }, + "IconName": { + "type": "string", + "read": true, + "write": true, + "protocols": [ + "cwmp", + "usp" + ], + "datatype": "string", + "range": [ + { + "max": 32 + } + ], + "mapping": [ + { + "data": "@Parent", + "type": "uci_sec", + "key": "icon_name" + } + ] + }, + "HostList": { + "type": "string", + "read": true, + "write": true, + "protocols": [ + "cwmp", + "usp" + ], + "description": "Comma separated list of hostnames or MAC addresses.", + "list": { + "datatype": "string" + }, + "mapping": [ + { + "data": "@Parent", + "type": "uci_sec", + "list": "host" + } + ] + }, + "URLFilterNumberOfEntries": { + "type": "unsignedInt", + "read": true, + "write": false, + "protocols": [ + "cwmp", + "usp" + ], + "datatype": "unsignedInt", + "description": "<>", + "mapping": [ + { + "type": "uci", + "uci": { + "file": "parentalcontrol", + "section": { + "type": "profile_urlfilter" + }, + "option": { + "name": "@Count" + } + } + } + ] + }, + "Device.{BBF_VENDOR_PREFIX}ParentalControl.Profile.{i}.URLFilter.{i}.": { + "type": "object", + "protocols": [ + "cwmp", + "usp" + ], + "access": true, + "array": true, + "mapping": [ + { + "type": "uci", + "uci": { + "file": "parentalcontrol", + "section": { + "type": "profile_urlfilter" + }, + "dmmapfile": "dmmap_parentalcontrol" + } + } + ], + "Enable": { + "type": "boolean", + "read": true, + "write": true, + "protocols": [ + "cwmp", + "usp" + ], + "datatype": "boolean", + "description": "Enable or disable this filter instance on the CPE.", + "mapping": [ + { + "data": "@Parent", + "type": "uci_sec", + "key": "enable" + } + ] + }, + "AccessPolicy": { + "type": "string", + "read": true, + "write": true, + "protocols": [ + "cwmp", + "usp" + ], + "datatype": "string", + "default": "Allow", + "enumerations": [ + "Allow", + "Deny" + ], + "mapping": [ + { + "data": "@Parent", + "type": "uci_sec", + "key": "access" + } + ] + }, + "Order": { + "type": "unsignedInt", + "read": true, + "write": true, + "protocols": [ + "cwmp", + "usp" + ], + "description": "Priority order of applying the policy", + "datatype": "unsignedInt", + "mapping": [ + { + "data": "@Parent", + "type": "uci_sec", + "key": "order" + } + ] + }, + "FilterText": { + "type": "string", + "read": true, + "write": true, + "protocols": [ + "cwmp", + "usp" + ], + "description": "Comma separated list of URL or sub-part of the URL used for filter", + "list": { + "datatype": "string" + }, + "mapping": [ + { + "data": "@Parent", + "type": "uci_sec", + "list": "filter_text" + } + ] + }, + "URLBundleRef": { + "type": "string", + "read": true, + "write": true, + "protocols": [ + "cwmp", + "usp" + ], + "flags": [ + "Reference" + ], + "description": "Reference to URLBundle which has list of URLs defined based on Category", + "mapping": [ + { + "data": "@Parent", + "type": "uci_sec", + "key": "profile_urlbundle", + "linker_obj": "Device.{BBF_VENDOR_PREFIX}ParentalControl.URLBundle.*.Name" + } + ] + }, + "ScheduleRef": { + "type": "string", + "read": true, + "write": true, + "protocols": [ + "cwmp", + "usp" + ], + "flags": [ + "Reference" + ], + "list": { + "datatype": "string" + }, + "description": "Comma separated list of references to the Schedules object", + "mapping": [ + { + "data": "@Parent", + "type": "uci_sec", + "list": "profile_urlfilter_schedule", + "linker_obj": "Device.Schedules.Schedule.[Alias==@list]" + } + ] + } + }, + "Device.{BBF_VENDOR_PREFIX}ParentalControl.Profile.{i}.BedTime.": { + "type": "object", + "protocols": [ + "cwmp", + "usp" + ], + "access": false, + "array": false, + "Enable": { + "type": "boolean", + "read": true, + "write": true, + "protocols": [ + "cwmp", + "usp" + ], + "datatype": "boolean", + "mapping": [ + { + "data": "@Parent", + "type": "uci_sec", + "key": "bedtime_enable" + } + ] + }, + "ScheduleNumberOfEntries": { + "type": "unsignedInt", + "read": true, + "write": false, + "protocols": [ + "cwmp", + "usp" + ], + "datatype": "unsignedInt", + "mapping": [ + { + "type": "uci", + "uci": { + "file": "parentalcontrol", + "section": { + "type": "profile_bedtime_schedule" + }, + "option": { + "name": "@Count" + } + } + } + ] + }, + "Device.{BBF_VENDOR_PREFIX}ParentalControl.Profile.{i}.BedTime.Schedule.{i}.": { + "type": "object", + "protocols": [ + "cwmp", + "usp" + ], + "access": true, + "array": true, + "mapping": [ + { + "type": "uci", + "uci": { + "file": "parentalcontrol", + "section": { + "type": "profile_bedtime_schedule" + }, + "dmmapfile": "dmmap_parentalcontrol" + } + } + ], + "Alias": { + "type": "string", + "read": true, + "write": true, + "protocols": [ + "cwmp", + "usp" + ], + "datatype": "Alias", + "range": [ + { + "max": 64 + } + ], + "flags": [ + "unique" + ], + "mapping": [ + { + "data": "@Parent", + "type": "uci_sec", + "key": "alias" + } + ] + }, + "Name": { + "type": "string", + "read": true, + "write": true, + "protocols": [ + "cwmp", + "usp" + ], + "description": "Name of this schedule instance.", + "mapping": [ + { + "data": "@Parent", + "type": "uci_sec", + "key": "name" + } + ] + }, + "Days": { + "type": "string", + "read": true, + "write": true, + "protocols": [ + "cwmp", + "usp" + ], + "list": { + "datatype": "string", + "enumerations": [ + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday", + "Sunday" + ] + }, + "mapping": [ + { + "data": "@Parent", + "type": "uci_sec", + "list": "day" + } + ] + }, + "StartTime": { + "type": "string", + "read": true, + "write": true, + "protocols": [ + "cwmp", + "usp" + ], + "datatype": "string", + "range": [ + { + "max": 5 + } + ], + "mapping": [ + { + "data": "@Parent", + "type": "uci_sec", + "key": "start_time" + } + ] + }, + "EndTime": { + "type": "string", + "read": true, + "write": true, + "protocols": [ + "cwmp", + "usp" + ], + "datatype": "string", + "range": [ + { + "max": 5 + } + ], + "mapping": [ + { + "data": "@Parent", + "type": "uci_sec", + "key": "end_time" + } + ] + } + } + }, + "Device.{BBF_VENDOR_PREFIX}ParentalControl.Profile.{i}.InternetAccess.": { + "type": "object", + "protocols": [ + "cwmp", + "usp" + ], + "access": false, + "array": false, + "Enable": { + "type": "boolean", + "read": true, + "write": true, + "protocols": [ + "cwmp", + "usp" + ], + "datatype": "boolean", + "mapping": [ + { + "data": "@Parent", + "type": "uci_sec", + "key": "internet_access_enable" + } + ] + }, + "AccessPolicy": { + "type": "string", + "read": true, + "write": true, + "protocols": [ + "cwmp", + "usp" + ], + "description": "Set Deny to stop internet access, set Allow to allow access based on Schedule", + "datatype": "string", + "default": "Allow", + "enumerations": [ + "Allow", + "Deny" + ], + "mapping": [ + { + "data": "@Parent", + "type": "uci_sec", + "key": "internet_access_policy" + } + ] + }, + "ScheduleRef": { + "type": "string", + "read": true, + "write": true, + "protocols": [ + "cwmp", + "usp" + ], + "flags": [ + "Reference" + ], + "list": { + "datatype": "string" + }, + "description": "Comma separated list of references to the Schedules object", + "mapping": [ + { + "data": "@Parent", + "type": "uci_sec", + "list": "internet_access_schedule", + "linker_obj": "Device.Schedules.Schedule.[Alias==@list]" + } + ] + } + } + } + } +} + diff --git a/urlfilter/files/lib/parentalcontrol/parentalcontrol.sh b/urlfilter/files/lib/parentalcontrol/parentalcontrol.sh index 37d85f9a3..ed44faba6 100644 --- a/urlfilter/files/lib/parentalcontrol/parentalcontrol.sh +++ b/urlfilter/files/lib/parentalcontrol/parentalcontrol.sh @@ -385,7 +385,7 @@ handle_profile() { } -handle_internet_schedule() { +add_internet_schedule_rules() { ACL_FILE="/tmp/parentalcontrol_access_control/access_control.rules" rm -f $ACL_FILE @@ -417,3 +417,79 @@ handle_internet_schedule() { # apply the rules sh $ACL_FILE } + +add_iptables_nfqueue_rules() { + iptables -w -nL FORWARD|grep -iqE "NFQUEUE" + if [ "$?" -ne 0 ]; then + # setup netfilter queue 0, use queue bypass so that if no application is + # listening to this queue then traffic is unaffected. + iptables -w -I FORWARD 1 -p tcp --match multiport --ports 80,443,53 -j NFQUEUE --queue-num 0 --queue-bypass + iptables -w -I FORWARD 1 -p udp --match multiport --ports 80,443,53 -j NFQUEUE --queue-num 0 --queue-bypass + + iptables -w -I INPUT 1 -p tcp --match multiport --ports 80,443,53 -j NFQUEUE --queue-num 0 --queue-bypass + iptables -w -I INPUT 1 -p udp --match multiport --ports 80,443,53 -j NFQUEUE --queue-num 0 --queue-bypass + + # 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 + + ip6tables -w -nL FORWARD|grep -iqE "NFQUEUE" + if [ "$?" -ne 0 ]; then + #ip6table rules + ip6tables -w -I FORWARD 1 -p tcp --match multiport --ports 80,443,53 -j NFQUEUE --queue-num 0 --queue-bypass + ip6tables -w -I FORWARD 1 -p udp --match multiport --ports 80,443,53 -j NFQUEUE --queue-num 0 --queue-bypass + + ip6tables -w -I INPUT 1 -p tcp --match multiport --ports 80,443,53 -j NFQUEUE --queue-num 0 --queue-bypass + ip6tables -w -I INPUT 1 -p udp --match multiport --ports 80,443,53 -j NFQUEUE --queue-num 0 --queue-bypass + + # 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 +} + +remove_iptables_nfqueue_rules() { + iptables -w -nL FORWARD|grep -iqE "NFQUEUE" + if [ "$?" -eq 0 ]; then + iptables -w -D FORWARD -p tcp --match multiport --ports 80,443,53 -j NFQUEUE --queue-num 0 --queue-bypass + iptables -w -D FORWARD -p udp --match multiport --ports 80,443,53 -j NFQUEUE --queue-num 0 --queue-bypass + + iptables -w -D INPUT -p tcp --match multiport --ports 80,443,53 -j NFQUEUE --queue-num 0 --queue-bypass + iptables -w -D INPUT -p udp --match multiport --ports 80,443,53 -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 + fi + ip6tables -w -nL FORWARD|grep -iqE "NFQUEUE" + if [ "$?" -eq 0 ]; then + #ip6table rules + ip6tables -w -D FORWARD -p tcp --match multiport --ports 80,443,53 -j NFQUEUE --queue-num 0 --queue-bypass + ip6tables -w -D FORWARD -p udp --match multiport --ports 80,443,53 -j NFQUEUE --queue-num 0 --queue-bypass + + ip6tables -w -D INPUT -p tcp --match multiport --ports 80,443,53 -j NFQUEUE --queue-num 0 --queue-bypass + ip6tables -w -D INPUT -p udp --match multiport --ports 80,443,53 -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 +} + +remove_internet_schedule_rules() { + # remove from iptables, if chain exists + if iptables -w -nL FORWARD|grep -iqE "parentalcontrol_forward"; then + iptables -w -t filter -D FORWARD -j parentalcontrol_forward + iptables -w -F parentalcontrol_forward + iptables -w -X parentalcontrol_forward + fi + # remove from ip6tables, if chain exists + if ip6tables -w -nL FORWARD|grep -iqE "parentalcontrol_forward"; then + ip6tables -w -t filter -D FORWARD -j parentalcontrol_forward + ip6tables -w -F parentalcontrol_forward + ip6tables -w -X parentalcontrol_forward + fi +}