Signed-off-by: Gregory L. Dietsche <gregory.dietsche@cuw.edu>lilik-openwrt-22.03
@ -0,0 +1,56 @@ | |||
# | |||
# Copyright (c) 2020 Gregory L. Dietsche <Gregory.Dietsche@cuw.edu> | |||
# This is free software, licensed under the MIT License | |||
# | |||
include $(TOPDIR)/rules.mk | |||
PKG_NAME:=family-dns | |||
PKG_VERSION:=1.0.0 | |||
PKG_RELEASE:=1 | |||
PKG_LICENSE:=MIT | |||
PKG_MAINTAINER:=Gregory L. Dietsche <Gregory.Dietsche@cuw.edu> | |||
include $(INCLUDE_DIR)/package.mk | |||
define Package/family-dns | |||
SECTION:=net | |||
CATEGORY:=Network | |||
TITLE:=Family DNS | |||
PKGARCH:=all | |||
endef | |||
define Package/family-dns/description | |||
This package configures your router to block adult websites. | |||
The default settings are designed to be appropriate for most businesses, | |||
schools and families. | |||
endef | |||
define Package/family-dns/conffiles | |||
/etc/config/family-dns | |||
endef | |||
define Build/Compile | |||
endef | |||
define Package/family-dns/install | |||
$(INSTALL_DIR) $(1)/etc/uci-defaults | |||
$(INSTALL_DATA) ./files/family-dns.uci-defaults $(1)/etc/uci-defaults/family-dns | |||
$(INSTALL_DIR) $(1)/etc/config | |||
$(INSTALL_CONF) ./files/family-dns.conf $(1)/etc/config/family-dns | |||
$(INSTALL_DIR) $(1)/usr/sbin | |||
$(INSTALL_BIN) ./files/family-dns-update $(1)/usr/sbin/family-dns-update | |||
$(INSTALL_BIN) ./files/test-family-dns $(1)/usr/sbin/test-family-dns | |||
endef | |||
define Package/family-dns/prerm | |||
#!/bin/sh | |||
if [ -z "$${IPGK_INSTROOT}" ]; then | |||
/usr/sbin/family-dns-update uninstall | |||
fi | |||
exit 0 | |||
endef | |||
$(eval $(call BuildPackage,family-dns)) |
@ -0,0 +1,21 @@ | |||
# Package: net/family-dns | |||
This package configures your router to block access to adult websites. | |||
The default settings are designed to be appropriate for most businesses, schools, and families. | |||
Enabled and disable Family DNS by editing /etc/config/family-dns. To make | |||
your changes active, run family-dns-update. | |||
- Default DNS Filter | |||
- CleanBrowsing.org Adult Filter | |||
- https://cleanbrowsing.org/filters#adult | |||
- Blocks access to all adult, pornographic and explicit sites. It does not block proxy or VPNs, nor mixed-content sites. Sites like Reddit are allowed. Google and Bing are set to the Safe Mode. Malicious and Phishing domains are blocked. | |||
- Alternate DNS Filters: | |||
- CleanBrowsing.org Family Filter | |||
- https://cleanbrowsing.org/filters#family | |||
- Blocks access to all adult, pornographic and explicit sites. It also blocks proxy and VPN domains that are used to bypass the filters. Mixed content sites (like Reddit) are also blocked. Google, Bing and Youtube are set to the Safe Mode. Malicious and Phishing domains are blocked. | |||
- Cisco Family Shield | |||
- https://www.opendns.com/home-internet-security/ | |||
- https://www.opendns.com/setupguide/#familyshield | |||
- FamilyShield will block domains that are categorized as: Tasteless, Proxy/Anonymizer, Sexuality and Pornography. |
@ -0,0 +1,95 @@ | |||
#!/bin/sh | |||
# | |||
# Copyright (c) 2020 Gregory L. Dietsche <Gregory.Dietsche@cuw.edu> | |||
# This is free software, licensed under the MIT License | |||
# | |||
. /lib/functions.sh | |||
config_load 'family-dns' | |||
config_get_bool enabled default enabled 0 | |||
config_get_bool redirect_dns default redirect_dns 0 | |||
config_get dns default dns default | |||
#uninstall and disable are designed to be equivalent. | |||
if [ "$1" = "uninstall" ] ; then | |||
enabled=0 | |||
fi | |||
# Set OpenWrt Defaults | |||
uci -q batch <<-EOT | |||
set network.wan.peerdns='1' | |||
set network.wan6.peerdns='1' | |||
delete network.wan.dns | |||
delete network.wan6.dns | |||
delete firewall.family_dns_lan | |||
EOT | |||
if [ "$enabled" -ne 1 ] ; then | |||
echo 'Activating Default ISP DNS server(s)' | |||
else | |||
# We don't want to use ISP DNS servers because they don't filter queries | |||
uci set network.wan.peerdns='0' | |||
uci set network.wan6.peerdns='0' | |||
# Configure the DNS server(s) that will handle filtering. | |||
echo "Activating $dns" | |||
case $dns in | |||
cleanbrowsing-adult-filter) | |||
uci add_list network.wan.dns=185.228.168.10 | |||
uci add_list network.wan.dns=185.228.169.11 | |||
uci add_list network.wan6.dns=2a0d:2a00:1::1 | |||
uci add_list network.wan6.dns=2a0d:2a00:2::1 | |||
;; | |||
cleanbrowsing-family-filter) | |||
uci add_list network.wan.dns=185.228.168.168 | |||
uci add_list network.wan.dns=185.228.169.168 | |||
uci add_list network.wan6.dns=2a0d:2a00:1:: | |||
uci add_list network.wan6.dns=2a0d:2a00:2:: | |||
;; | |||
cloudflare-malware-and-adult-content) | |||
uci add_list network.wan.dns=1.1.1.3 | |||
uci add_list network.wan.dns=1.0.0.3 | |||
uci add_list network.wan6.dns=2606:4700:4700::1113 | |||
uci add_list network.wan6.dns=2606:4700:4700::1003 | |||
;; | |||
cisco-family-shield) | |||
uci add_list network.wan.dns=208.67.222.123 | |||
uci add_list network.wan.dns=208.67.220.123 | |||
uci add_list network.wan6.dns=::ffff:d043:de7b | |||
uci add_list network.wan6.dns=::ffff:d043:dc7b | |||
;; | |||
*) | |||
echo "$dns" is not supported. | |||
uci revert network | |||
redirect_dns=0 | |||
;; | |||
esac | |||
if [ "$redirect_dns" -eq 1 ] ; then | |||
echo Activating DNS redirect | |||
zone=lan | |||
ip=$(uci get network.$zone.ipaddr) | |||
uci -q batch <<-EOT | |||
set firewall.family_dns_lan=redirect | |||
add_list firewall.family_dns_lan.proto='tcp' | |||
add_list firewall.family_dns_lan.proto='udp' | |||
set firewall.family_dns_lan.src_dport='53' | |||
set firewall.family_dns_lan.dest_ip='$ip' | |||
set firewall.family_dns_lan.target='DNAT' | |||
set firewall.family_dns_lan.src='$zone' | |||
set firewall.family_dns_lan.dest='$zone' | |||
set firewall.family_dns_lan.name='family-dns redirect for $zone zone' | |||
EOT | |||
fi | |||
fi | |||
uci -q batch <<-EOT | |||
commit network | |||
commit firewall | |||
EOT | |||
/etc/init.d/network reload | |||
/etc/init.d/dnsmasq reload | |||
/etc/init.d/firewall reload 2>/dev/null | |||
@ -0,0 +1,14 @@ | |||
# Copyright (c) 2020 Gregory L. Dietsche | |||
# This is free software, licensed under the MIT License | |||
# | |||
# run family-dns-update after making configuration changes. | |||
# | |||
config family-dns default | |||
option enabled 1 | |||
option redirect_dns 1 | |||
option dns 'cleanbrowsing-adult-filter' | |||
#option dns 'cleanbrowsing-family-filter' | |||
#option dns 'cloudflare-malware-and-adult-content' | |||
#option dns 'cisco-family-shield' | |||
@ -0,0 +1,9 @@ | |||
#!/bin/sh | |||
# | |||
# Copyright (c) 2020 Gregory L. Dietsche <Gregory.Dietsche@cuw.edu> | |||
# This is free software, licensed under the MIT License | |||
# | |||
/usr/sbin/family-dns-update | |||
exit 0 |
@ -0,0 +1,124 @@ | |||
#!/bin/sh | |||
# | |||
# Copyright (c) 2020 Gregory L. Dietsche <Gregory.Dietsche@cuw.edu> | |||
# This is free software, licensed under the MIT License | |||
# | |||
######################## | |||
#Yucky global variables# | |||
######################## | |||
global_result=0 | |||
# A list of adult websites that support both IPv4 and IPv6 | |||
IPv4andIPv6EnabledSiteList="https://xhamster.com https://www.watchmyexgf.net https://gaymaletube.com" | |||
expect_not_safe(){ | |||
title=$1 | |||
size=$2 | |||
web=$3 | |||
actual=$(wget -4 -O - "$web" | wc -l) 2> /dev/null | |||
if [ "$actual" -gt "$size" ] ; then | |||
echo "$title: IPv4: $size/$actual. NOT SAFE" | |||
else | |||
echo "$title: IPv4: SAFE. $actual (expected not safe!) ***************" | |||
global_result=1 | |||
fi | |||
actual=$(wget -6 -O - "$web" | wc -l) 2> /dev/null | |||
if [ "$actual" -gt "$size" ] ; then | |||
echo "$title: IPv6: $size/$actual. NOT SAFE" | |||
else | |||
echo "$title: IPv6: SAFE. $actual (expected not safe!) ***************" | |||
global_result=1 | |||
fi | |||
return $global_result | |||
} | |||
expect_safe(){ | |||
title=$1 | |||
size=$2 | |||
web=$3 | |||
actual=$(wget -4 -O - "$web" | wc -l) 2> /dev/null | |||
if [ "$actual" -gt "$size" ] ; then | |||
echo "$title: IPv4: $size/$actual. NOT SAFE ******************" | |||
global_result=1 | |||
else | |||
echo "$title: IPv4: SAFE. $actual" | |||
fi | |||
actual=$(wget -6 -O - "$web" | wc -l) 2> /dev/null | |||
if [ "$actual" -gt "$size" ] ; then | |||
echo "$title: IPv6: $size/$actual. NOT SAFE ******************" | |||
global_result=1 | |||
else | |||
echo "$title: IPv6: SAFE. $actual" | |||
fi | |||
} | |||
test_not_safe(){ | |||
uci set family-dns.default.enabled=0 | |||
uci commit family-dns | |||
family-dns-update | |||
echo "******************************" | |||
echo "Testing Without Protection ***" | |||
echo "******************************" | |||
c=0 | |||
for site in ${IPv4andIPv6EnabledSiteList}; do | |||
expect_not_safe "Site $c" 500 "$site" | |||
c=$((c+1)) | |||
done | |||
uci set family-dns.default.enabled=1 | |||
uci commit family-dns | |||
family-dns-update | |||
echo | |||
} | |||
test_filter(){ | |||
echo "******************************" | |||
echo "Testing With Protection ***" | |||
echo "******************************" | |||
echo testing "$1" | |||
uci set family-dns.default.dns="$1" | |||
uci commit family-dns | |||
family-dns-update | |||
c=0 | |||
for site in ${IPv4andIPv6EnabledSiteList}; do | |||
expect_safe "Testing Site $c" 500 "$site" | |||
c=$((c+1)) | |||
done | |||
echo | |||
} | |||
############################################# | |||
## Main Tests ## | |||
############################################# | |||
test_not_safe | |||
test_filter cisco-family-shield | |||
test_filter cloudflare-malware-and-adult-content | |||
test_filter cleanbrowsing-family-filter | |||
test_filter cleanbrowsing-adult-filter | |||
# with cleanbrowsing-adult-filter on, run this test on a different device (not the router) | |||
# the result should be 0 when redirect_dns=1 and the result should be 1 when redirect_dns=0 | |||
#count=$(nslookup -query=A www.sex.com 8.8.8.8 | grep NXDOMAIN | wc -l) | |||
#if [ $count -eq 1 ]; then | |||
# echo Clean Browsing returned NXDOMAIN. This is expected. | |||
#else | |||
# echo Clean Browsing did not return NXDOMAIN. This is NOT expected. | |||
#fi | |||
if [ $global_result -ne 0 ]; then | |||
echo '************ Test(s) failed! ********************************************************' | |||
fi | |||
exit $global_result |