What's new

Unbound SafeSearchEnforcement with unbound.

  • 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!

SomeWhereOverTheRainBow

Part of the Furniture
For those who want to enforce safe search with unbound.....
Code:
#!/bin/sh

URL="https://www.google.com/supported_domains"
FILE="/etc/unbound/unbound.conf.d/safesearch.conf" #this can be where-ever your unbound config storage is. You will have to use include: option inside the main unbound.conf though.

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 "server:\n" > "${FILE}"
{
DOMAINS="$(curl $URL 2>/dev/null)"
for DOMAIN in $DOMAINS; do
    DOMAIN=$(printf "%s\n" "$DOMAIN" | cut -c 2-)
    printf 'local-zone: "www.%s." transparent\n' "$DOMAIN"
    printf 'local-data: "www.%s. CNAME forcesafesearch.google.com."\n' "$DOMAIN"
done
for DOMAIN in duckduckgo.com; do
    printf 'local-zone: "%s." transparent\n' "$DOMAIN"
    printf 'local-data: "%s. CNAME safe.%s."\n' "$DOMAIN" "$DOMAIN"
    printf 'local-zone: "www.%s." transparent\n' "$DOMAIN"
    printf 'local-data: "www.%s. CNAME safe.%s."\n' "$DOMAIN" "$DOMAIN"
    printf 'local-zone: "start.%s." transparent\n' "$DOMAIN"
    printf 'local-data: "start.%s. CNAME safe.%s."\n' "$DOMAIN" "$DOMAIN"
    printf 'local-zone: "duck.com." transparent\n'
    printf 'local-data: "duck.com. CNAME safe.%s."\n' "$DOMAIN"
    printf 'local-zone: "www.duck.com." transparent\n'
    printf 'local-data: "www.duck.com. CNAME safe.%s."\n' "$DOMAIN"
done
for DOMAIN in bing.com; do
    printf 'local-zone: "%s." transparent\n' "$DOMAIN"
    printf 'local-data: "%s. CNAME strict.%s."\n' "$DOMAIN" "$DOMAIN"
    printf 'local-zone: "www.%s." transparent\n' "$DOMAIN"
    printf 'local-data: "www.%s. CNAME strict.%s."\n' "$DOMAIN" "$DOMAIN"
done
for DOMAIN in qwant.com; do
    printf 'local-zone: "api.%s." transparent\n' "$DOMAIN"
    printf 'local-data: "api.%s. CNAME safeapi.%s."\n' "$DOMAIN" "$DOMAIN"
    printf 'local-zone: "www.%s." transparent\n' "$DOMAIN"
    printf 'local-data: "www.%s. CNAME safeapi.%s."\n' "$DOMAIN" "$DOMAIN"
    printf 'local-zone: "%s." transparent\n' "$DOMAIN"
    printf 'local-data: "%s. CNAME safeapi.%s."\n' "$DOMAIN" "$DOMAIN"
    printf 'local-zone: "s1.%s." transparent\n' "$DOMAIN"
    printf 'local-data: "s1.%s. CNAME safeapi.%s."\n' "$DOMAIN" "$DOMAIN"
    printf 'local-zone: "s2.%s." transparent\n' "$DOMAIN"
    printf 'local-data: "s2.%s. CNAME safeapi.%s."\n' "$DOMAIN" "$DOMAIN"
done
for DOMAIN in pixabay.com; do
    printf 'local-zone: "%s." transparent\n' "$DOMAIN"
    printf 'local-data: "%s. CNAME safesearch.%s."\n' "$DOMAIN" "$DOMAIN"
done
for DOMAIN in youtube; do
    printf 'local-zone: "www.%s.com." transparent\n' "$DOMAIN"
    printf 'local-data: "www.%s.com. CNAME restrictmoderate.%s.com."\n' "$DOMAIN" "$DOMAIN"
    printf 'local-zone: "m.%s.com." transparent\n' "$DOMAIN"
    printf 'local-data: "m.%s.com. CNAME restrictmoderate.%s.com."\n' "$DOMAIN" "$DOMAIN"
    printf 'local-zone: "%si.googleapis.com." transparent\n' "$DOMAIN"
    printf 'local-data: "%si.googleapis.com. CNAME restrictmoderate.%s.com."\n' "$DOMAIN" "$DOMAIN"
    printf 'local-zone: "%s.googleapis.com." transparent\n' "$DOMAIN"
    printf 'local-data: "%s.googleapis.com. CNAME restrictmoderate.%s.com."\n' "$DOMAIN" "$DOMAIN"
    printf 'local-zone: "www.%s-nocookie.com." transparent\n' "$DOMAIN"
    printf 'local-data: "www.%s-nocookie.com. CNAME restrictmoderate.%s.com."\n' "$DOMAIN" "$DOMAIN"
done
for YANDEX in com ru ua by kz; do
    printf 'local-zone: "yandex.%s." transparent\n' "$YANDEX"
    printf 'local-data: "yandex.%s. CNAME familysearch.yandex.ru."\n' "$YANDEX"
    printf 'local-zone: "www.yandex.%s." transparent\n' "$YANDEX"
    printf 'local-data: "www.yandex.%s. CNAME familysearch.yandex.ru."\n' "$YANDEX"
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" 'local-data: "'${DOMAIN}'. A '${IPS}'"'
                printf "%s\n" 'local-data: "'${DOMAIN}'. AAAA ::ffff:'${IPS}'"'
                printf "%s\n" 'local-data: "restrict.youtube.com. A '${IPS}'"'
                printf "%s\n" 'local-data: "restrict.youtube.com. AAAA ::ffff:'${IPS}'"'
            else
                printf "%s\n" 'local-data: "'${DOMAIN}'. AAAA '${IPS}'"'
                printf "%s\n" 'local-data: "restrict.youtube.com. AAAA '${IPS}'"'
            fi
        else
            if [ "${IPS##*:}" = "${IPS}" ]; then
                printf "%s\n" 'local-data: "'${DOMAIN}'. A '${IPS}'"'
                printf "%s\n" 'local-data: "'${DOMAIN}'. AAAA ::ffff:'${IPS}'"'
            else
                printf "%s\n" 'local-data: "'${DOMAIN}'. AAAA '${IPS}'"'
            fi
        fi
    done
done
} >> "${FILE}"
 
Last edited:
Is that a bash array (domains[@])?
Might I suggest this instead:
Code:
echo "server:" > "${file}"
and
Code:
    domains="$(curl $url 2>/dev/null)"
    for domain in $domains; do
        dom=$(echo $domain | cut -c 2-)
        printf 'local-data: "'$dom' cname forcesafesearch.google.com" \n' >> "${file}"
        printf 'local-data: "www.'${dom}' cname forcesafesearch.google.com" \n' >> "${file}"
    done
It's not ideal to use word lists like that IMHO but at least it runs.
 
Might I suggest this instead:
Code:
echo "server:" > "${file}"
and
Code:
    domains="$(curl $url 2>/dev/null)"
    for domain in $domains; do
        dom=$(echo $domain | cut -c 2-)
        printf 'local-data: "'$dom' cname forcesafesearch.google.com" \n' >> "${file}"
        printf 'local-data: "www.'${dom}' cname forcesafesearch.google.com" \n' >> "${file}"
    done
It's not ideal to use word lists like that IMHO but at least it runs.

And better to have the $dom variable outside the printf format string.
Code:
printf 'local-data: "%s cname forcesafesearch.google.com" \n' $dom >> "${file}"
printf 'local-data: "www.%s cname forcesafesearch.google.com" \n' $dom >> "${file}"
Thanks it is a rough draft like anything else I think of at work on my downtime. I really appreciate the feedback. You should see stacks of lines I originally was going to pass with echo :eek:.
 
I’m only claiming the high road after recently converting many echos to printf. :D
I put up my final version. From my test seems to be the "quickest" and least problematic. Let me know if you try it out. Tell me if you come up with a better arrangement etc.. etc..
You are one of the gurus for finding the path of least resistance.
 
should $dom not be quoted? shellcheck says so :D
Code:
printf 'local-data: "www.%s cname forcesafesearch.google.com" \n' $dom >> "${file}"
                                                                    ^-- SC2086: Double quote to prevent globbing and word splitting.
Depends on how far your want to go with that. Shellcheck seems to want you to quote everything. My view is if your understand your own code and what the variables may contain (even in error conditions) you can make a value judgement on whether it needs to be quoted or not.

I would say you don't need to use "${file}" but could just use $file as the contents of the variable are hard coded and unambiguous.
 
Thanks. I'm not sure pixabay still as a safesearch. I tried a lot of time to apply a safe search but it's not working with dns
 
Hi! I don't get it. What do I do with this script? Save it as .sh and execute it? Sorry for this propably really stupid question...
 
Hi! I don't get it. What do I do with this script? Save it as .sh and execute it? Sorry for this propably really stupid question...
If you wish to try unbound_manager Beta v3.22b4 v3.22b5 v3.22b6 (EDIT: v3.22b4 doesn't auto populate the domains file; v3.22b5 only allows safesearch* commands in Advanced Menu mode)
Code:
e  = Exit Script [?]

A:Option ==> uf dev

    unbound_manager.sh downloaded successfully Github 'dev/development' branch

unbound Manager UPDATE Complete! f215ba4853c609fb2c3c2bdb53a22309


+======================================================================+
|  Welcome to the unbound Manager/Installation script (Asuswrt-Merlin) |
|                                                                      |
|                      Version 3.22b6 by Martineau                     |
|                                                                      |
+======================================================================+
you will be able to use the following command
Code:
safesearch [disable]

1610306191032.png


and to either VIEW or manually EDIT the safesearch configuration file, the following commands are available:
Code:
safesearchv

safesearchx

1610306121236.png

NOTE: If you need to revert back to the current stable unbound_manager v3.21
Code:
e  = Exit Script [?]

A:Option ==> uf

Forced Update


    unbound_manager.sh downloaded successfully

unbound Manager UPDATE Complete! f215ba4853c609fb2c3c2bdb53a22309

+======================================================================+
|  Welcome to the unbound Manager/Installation script (Asuswrt-Merlin) |
|                                                                      |
|                      Version 3.21 by Martineau                       |
|                                                                      |
+======================================================================+
 
Last edited:
If you wish to try unbound_manager Beta v3.22b4
Code:
e  = Exit Script [?]

A:Option ==> uf dev

    unbound_manager.sh downloaded successfully Github 'dev/development' branch

unbound Manager UPDATE Complete! f215ba4853c609fb2c3c2bdb53a22309

+======================================================================+
|  Welcome to the unbound Manager/Installation script (Asuswrt-Merlin) |
|                                                                      |
|                      Version 3.22b4 by Martineau                       |
|                                                                      |
+======================================================================+
you will be able to use the following command
Code:
safesearch [disable]
and to either VIEW or manually EDIT the safesearch configuration file, the following commands are available:
Code:
safesearchv

safesearchx
NOTE: If you need to revert back to the current stable unbound_manager v3.21
Code:
e  = Exit Script [?]

A:Option ==> uf

Forced Update


    unbound_manager.sh downloaded successfully

unbound Manager UPDATE Complete! f215ba4853c609fb2c3c2bdb53a22309

+======================================================================+
|  Welcome to the unbound Manager/Installation script (Asuswrt-Merlin) |
|                                                                      |
|                      Version 3.21 by Martineau                       |
|                                                                      |
+======================================================================+

Hi! Thank you - I will try that tonight. Are there any plans or ways to specify targets (clients, subnets ...) - I'm asking because I want to get rid of my extra raspberry with Adguard-Home (which is working really good - but I don't want a extra device) - with adguard-home it's possible to enforce safesearch on client-basis.

thanks and best regards
 
@ugandy, maybe some of the older kids too! :)
 
If you wish to try unbound_manager Beta v3.22b4v3.22b5 (EDIT: v3.22b4 doesn't auto populate the domains file)
Code:
e  = Exit Script [?]

A:Option ==> uf dev

    unbound_manager.sh downloaded successfully Github 'dev/development' branch

unbound Manager UPDATE Complete! f215ba4853c609fb2c3c2bdb53a22309

+======================================================================+
|  Welcome to the unbound Manager/Installation script (Asuswrt-Merlin) |
|                                                                      |
|                      Version 3.22b4 by Martineau                       |
|                                                                      |
+======================================================================+
you will be able to use the following command
Code:
safesearch [disable]

View attachment 29323

and to either VIEW or manually EDIT the safesearch configuration file, the following commands are available:
Code:
safesearchv

safesearchx

View attachment 29322
NOTE: If you need to revert back to the current stable unbound_manager v3.21
Code:
e  = Exit Script [?]

A:Option ==> uf

Forced Update


    unbound_manager.sh downloaded successfully

unbound Manager UPDATE Complete! f215ba4853c609fb2c3c2bdb53a22309

+======================================================================+
|  Welcome to the unbound Manager/Installation script (Asuswrt-Merlin) |
|                                                                      |
|                      Version 3.21 by Martineau                       |
|                                                                      |
+======================================================================+
@Martineau ,I am glad you decided to incorporate such a feature. I will have to give it a test run at some point. Keep up the awesome work.
 
@Martineau ,I am glad you decided to incorporate such a feature. I will have to give it a test run at some point. Keep up the awesome work.
Safesearch hadn't been discussed in the forums for quite a while until you restarted the discussion, and having been previously snidely criticised for implementing perceived unwanted feature-bloat to unbound_manager, I was reluctant to include the option to auto-generate the necessary domain directives.

However, rather than expect novices to delve into esoteric scripting using your script (or use vi/nano to edit 'unbounf.conf') I decided back in November that perhaps someone may benefit from the Safesearch feature inclusion in the proposed Beta.
 
Alternatively use pi hole https://github.com/jaykepeters/PSS

Or if someone can make this into an easy addon, I would be very interested. Imagine the glory you coders :)
 

Similar threads

Latest 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!

Staff online

Top