SomeWhereOverTheRainBow
Part of the Furniture
There are many approaches to this topic and RMerlin's Wiki https://github.com/RMerl/asuswrt-merlin.ng/wiki/Enforce-Safesearch
-briefly delves on the concept using dnsmasq. Instead of reinventing the wheel over and over again with this topic, below is a small script and instructions for users that wish to explore this topic.
simply copy and paste the below script into SSH terminal + Press Enter and everything is taken care of. Before testing it is important to clear/refresh any browsers and/or cache on test devices.
To reduce risk IP changes this script is adapted for using fresh IP addresses:
On a side note for users that want a restrict.youtube.com instead of a lower level restrictmoderate.youtube.com:
Results:
-briefly delves on the concept using dnsmasq. Instead of reinventing the wheel over and over again with this topic, below is a small script and instructions for users that wish to explore this topic.
simply copy and paste the below script into SSH terminal + Press Enter and everything is taken care of. Before testing it is important to clear/refresh any browsers and/or cache on test devices.
To reduce risk IP changes this script is adapted for using fresh IP addresses:
Code:
touch enforcesafe.sh && cat > "enforcesafe.sh" <<'EOF'
#!/bin/sh
URL="https://www.google.com/supported_domains"
FILE="/jffs/configs/dnsmasq.conf.add"
[ ! -f "$FILE" ] && touch "$FILE"
f_nslookup() {
local DOMAIN="$1"
nslookup "${DOMAIN}" 1.1.1.1 2>/dev/null | awk '/^Address[[:space:]][0-9]*\:[[:space:]]/{if($3 ~ /((((25[0-5]|(2[0-4]|1[0-9]|[1-9]|)[0-9])\.){3}(25[0-5]|(2[0-4]|1[0-9]|[1-9]|)[0-9])(\/(1?[0-9]|2?[0-9]|3?[0-2]))?)|(([0-9A-f]{0,4}:){1,7}[0-9A-f]{0,4}:{2}(\/(1?[0-2][0-8]|[0-9][0-9]))?))/ && !/1\.1\.1\.1/)print $3}' | while read -r line; do { if [ "${line%%.*}" = "0" ] || [ -z "${line%%::*}" ]; then continue; elif [ "${line##*:}" = "${line}" ]; then printf "%s " "$line"; else printf "%s " "$line"; fi; }; done
}
{
printf "%s\n" "# Enforced Safe Search:"
DOMAINS="$(curl $URL 2>/dev/null)"
for DOMAIN in $DOMAINS; do
DOMAIN="$(echo $DOMAIN | cut -c 2-)"
printf "%s\n" "local=/www.${DOMAIN}/" \
"cname=www.${DOMAIN},forcesafesearch.google.com"
done
#this version uses restrictmoderate.youtube.com
for DOMAIN in youtube; do
printf "%s\n" "local=/www.${DOMAIN}.com/" \
"cname=www.${DOMAIN}.com,restrictmoderate.${DOMAIN}.com" \
"local=/m.${DOMAIN}.com/" \
"cname=m.${DOMAIN}.com,restrictmoderate.${DOMAIN}.com" \
"local=/${DOMAIN}i.googleapis.com/" \
"cname=${DOMAIN}i.googleapis.com,restrictmoderate.${DOMAIN}.com" \
"local=/${DOMAIN}.googleapis.com/" \
"cname=${DOMAIN}.googleapis.com,restrictmoderate.${DOMAIN}.com" \
"local=/www.${DOMAIN}-nocookie.com/" \
"cname=www.${DOMAIN}-nocookie.com,restrictmoderate.${DOMAIN}.com"
done
for DOMAIN in bing.com; do
printf "%s\n" "local=/${DOMAIN}/www.${DOMAIN}/" \
"cname=${DOMAIN},www.${DOMAIN},strict.${DOMAIN}"
done
for DOMAIN in pixabay.com; do
printf "%s\n" "local=/${DOMAIN}/" \
"cname=${DOMAIN},safesearch.${DOMAIN}"
done
for DOMAIN in duckduckgo.com; do
printf "%s\n" "local=/${DOMAIN}/www.${DOMAIN}/" \
"cname=${DOMAIN},www.${DOMAIN},start.${DOMAIN},safe.${DOMAIN}" \
"local=/duck.com/www.duck.com/" \
"cname=duck.com,www.duck.com,safe.${DOMAIN}"
done
for DOMAIN in qwant.com; do
printf "%s\n" "local=/${DOMAIN}/www.${DOMAIN}/api.${DOMAIN}/" \
"cname=${DOMAIN},www.${DOMAIN},api.${DOMAIN},safeapi.${DOMAIN}" \
"local=/s1.${DOMAIN}/s2.${DOMAIN}/" \
"cname=s1.${DOMAIN},s2.${DOMAIN},safeapi.${DOMAIN}"
done
YANDEX="com ru ua by kz"
for DOMAIN in $YANDEX; do
printf "%s\n" "local=/yandex.${DOMAIN}/www.yandex.${DOMAIN}/" \
"cname=yandex.${DOMAIN},www.yandex.${DOMAIN},familysearch.yandex.ru"
done
for DOMAIN in forcesafesearch.google.com safe.duckduckgo.com restrictmoderate.youtube.com strict.bing.com safesearch.pixabay.com safeapi.qwant.com familysearch.yandex.ru; do
for IPS in $(f_nslookup $DOMAIN); do
if [ "$DOMAIN" = "forcesafesearch.google.com" ]; then
if [ "${IPS##*:}" = "${IPS}" ]; then
printf "%s\n" "host-record=${DOMAIN},restrict.youtube.com,${IPS},::ffff:${IPS}"
else
printf "%s\n" "host-record=${DOMAIN},restrict.youtube.com,${IPS}"
fi
else
if [ "${IPS##*:}" = "${IPS}" ]; then
printf "%s\n" "host-record=${DOMAIN},${IPS},::ffff:${IPS}"
else
printf "%s\n" "host-record=${DOMAIN},${IPS}"
fi
fi
done
done
printf "%s\n" "# End of Enforced Safe Search #"
} >> "${FILE}"
service restart_dnsmasq >/dev/null 2>&1
EOF
sh enforcesafe.sh && rm -rf enforcesafe.sh
Code:
touch enforcesafe.sh && cat > "enforcesafe.sh" <<'EOF'
#!/bin/sh
URL="https://www.google.com/supported_domains"
FILE="/jffs/configs/dnsmasq.conf.add"
[ ! -f "$FILE" ] && touch "$FILE"
f_nslookup() {
local DOMAIN="$1"
nslookup "${DOMAIN}" 1.1.1.1 2>/dev/null | awk '/^Address[[:space:]][0-9]*\:[[:space:]]/{if($3 ~ /((((25[0-5]|(2[0-4]|1[0-9]|[1-9]|)[0-9])\.){3}(25[0-5]|(2[0-4]|1[0-9]|[1-9]|)[0-9])(\/(1?[0-9]|2?[0-9]|3?[0-2]))?)|(([0-9A-f]{0,4}:){1,7}[0-9A-f]{0,4}:{2}(\/(1?[0-2][0-8]|[0-9][0-9]))?))/ && !/1\.1\.1\.1/)print $3}' | while read -r line; do { if [ "${line%%.*}" = "0" ] || [ -z "${line%%::*}" ]; then continue; elif [ "${line##*:}" = "${line}" ]; then printf "%s " "$line"; else printf "%s " "$line"; fi; }; done
}
{
printf "%s\n" "# Enforced Safe Search:"
DOMAINS="$(curl $URL 2>/dev/null)"
for DOMAIN in $DOMAINS; do
DOMAIN="$(echo $DOMAIN | cut -c 2-)"
printf "%s\n" "local=/www.${DOMAIN}/" \
"cname=www.${DOMAIN},forcesafesearch.google.com"
done
#this version uses restrict.youtube.com
for DOMAIN in youtube; do
printf "%s\n" "local=/www.${DOMAIN}.com/" \
"cname=www.${DOMAIN}.com,restrict.${DOMAIN}.com" \
"local=/m.${DOMAIN}.com/" \
"cname=m.${DOMAIN}.com,restrict.${DOMAIN}.com" \
"local=/${DOMAIN}i.googleapis.com/" \
"cname=${DOMAIN}i.googleapis.com,restrict.${DOMAIN}.com" \
"local=/${DOMAIN}.googleapis.com/" \
"cname=${DOMAIN}.googleapis.com,restrict.${DOMAIN}.com" \
"local=/www.${DOMAIN}-nocookie.com/" \
"cname=www.${DOMAIN}-nocookie.com,restrict.${DOMAIN}.com"
done
for DOMAIN in bing.com; do
printf "%s\n" "local=/${DOMAIN}/www.${DOMAIN}/" \
"cname=${DOMAIN},www.${DOMAIN},strict.${DOMAIN}"
done
for DOMAIN in pixabay.com; do
printf "%s\n" "local=/${DOMAIN}/" \
"cname=${DOMAIN},safesearch.${DOMAIN}"
done
for DOMAIN in duckduckgo.com; do
printf "%s\n" "local=/${DOMAIN}/www.${DOMAIN}/" \
"cname=${DOMAIN},www.${DOMAIN},start.${DOMAIN},safe.${DOMAIN}" \
"local=/duck.com/www.duck.com/" \
"cname=duck.com,www.duck.com,safe.${DOMAIN}"
done
for DOMAIN in qwant.com; do
printf "%s\n" "local=/${DOMAIN}/www.${DOMAIN}/api.${DOMAIN}/" \
"cname=${DOMAIN},www.${DOMAIN},api.${DOMAIN},safeapi.${DOMAIN}" \
"local=/s1.${DOMAIN}/s2.${DOMAIN}/" \
"cname=s1.${DOMAIN},s2.${DOMAIN},safeapi.${DOMAIN}"
done
YANDEX="com ru ua by kz"
for DOMAIN in $YANDEX; do
printf "%s\n" "local=/yandex.${DOMAIN}/www.yandex.${DOMAIN}/" \
"cname=yandex.${DOMAIN},www.yandex.${DOMAIN},familysearch.yandex.ru"
done
for DOMAIN in forcesafesearch.google.com safe.duckduckgo.com restrictmoderate.youtube.com strict.bing.com safesearch.pixabay.com safeapi.qwant.com familysearch.yandex.ru; do
for IPS in $(f_nslookup $DOMAIN); do
if [ "$DOMAIN" = "forcesafesearch.google.com" ]; then
if [ "${IPS##*:}" = "${IPS}" ]; then
printf "%s\n" "host-record=${DOMAIN},restrict.youtube.com,${IPS},::ffff:${IPS}"
else
printf "%s\n" "host-record=${DOMAIN},restrict.youtube.com,${IPS}"
fi
else
if [ "${IPS##*:}" = "${IPS}" ]; then
printf "%s\n" "host-record=${DOMAIN},${IPS},::ffff:${IPS}"
else
printf "%s\n" "host-record=${DOMAIN},${IPS}"
fi
fi
done
done
printf "%s\n" "# End of Enforced Safe Search #"
} >> "${FILE}"
service restart_dnsmasq >/dev/null 2>&1
EOF
sh enforcesafe.sh && rm -rf enforcesafe.sh
Code:
#########################################################
/tmp/home/root# dig www.google.com @192.168.1.1
; <<>> DiG 9.16.8 <<>> www.google.com @192.168.1.1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26812
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1280
;; QUESTION SECTION:
;www.google.com. IN A
;; ANSWER SECTION:
www.google.com. 0 IN CNAME forcesafesearch.google.com.
forcesafesearch.google.com. 0 IN A 216.239.38.120
;; Query time: 1 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Sun Jan 31 21:32:53 EST 2021
;; MSG SIZE rcvd: 99
#########################################################
Last edited: