Unbound SafeSearchEnforcement with unbound.

  • ATTENTION! You'll notice a Prefix dropdown when you create a thread. If your post applies to one of the topics listed, please use that Prefix for your post. When browsing the thread list you can use the Prefix to filter the view.
  • ATTENTION! As of November 1, 2020, you are not able to reply to threads 6 months after the thread is opened if there are more than 500 posts in the thread.
    Threads will not be locked, so posts may still be edited by their authors.
    Just start a new thread on the topic to post if you get an error message when trying to reply to a thread.

SomeWhereOverTheRainBow

Very Senior Member
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.
echo "server:" > "${file}"
domains="$(curl $url 2>/dev/null)"
for domain in $domains; do
    dom=$(echo $domain | cut -c 2-)
    printf 'local-zone: "%s" redirect \n' "$dom" >> "${file}"
    printf 'local-data: "%s CNAME forcesafesearch.google.com" \n' "$dom" >> "${file}"
    printf 'local-zone: "www.%s" redirect \n' "$dom" >> "${file}"
    printf 'local-data: "www.%s CNAME forcesafesearch.google.com" \n' "$dom" >> "${file}"
done
printf 'local-zone: "duckduckgo.com" redirect \n' >> "${file}"
printf 'local-data: "duckduckgo.com CNAME safe.duckduckgo.com" \n' >> "${file}"
printf 'local-zone: "www.duckduckgo.com" redirect \n' >> "${file}"
printf 'local-data: "www.duckduckgo.com CNAME safe.duckduckgo.com" \n' >> "${file}"
printf 'local-zone: "start.duckduckgo.com" redirect \n' >> "${file}"
printf 'local-data: "start.duckduckgo.com CNAME safe.duckduckgo.com" \n' >> "${file}"
printf 'local-zone: "duck.com" redirect \n' >> "${file}"
printf 'local-data: "duck.com CNAME safe.duckduckgo.com" \n' >> "${file}"
printf 'local-zone: "www.duck.com" redirect \n' >> "${file}"
printf 'local-data: "www.duck.com CNAME safe.duckduckgo.com" \n' >> "${file}"
printf 'local-zone: "bing.com" redirect \n' >> "${file}"
printf 'local-data: "bing.com CNAME strict.bing.com" \n' >> "${file}"
printf 'local-zone: "www.bing.com" redirect \n' >> "${file}"
printf 'local-data: "www.bing.com CNAME strict.bing.com" \n' >> "${file}"
printf 'local-zone: "pixabay.com" redirect \n' >> "${file}"
printf 'local-data: "pixabay.com CNAME safesearch.pixabay.com" \n' >> "${file}"
printf 'local-zone: "www.youtube.com" redirect \n' >> "${file}"
printf 'local-data: "www.youtube.com CNAME restrictmoderate.youtube.com" \n' >> "${file}"
printf 'local-zone: "m.youtube.com" redirect \n' >> "${file}"
printf 'local-data: "m.youtube.com CNAME restrictmoderate.youtube.com" \n' >> "${file}"
printf 'local-zone: "youtubei.googleapis.com" redirect \n' >> "${file}"
printf 'local-data: "youtubei.googleapis.com CNAME restrictmoderate.youtube.com" \n' >> "${file}"
printf 'local-zone: "youtube.googleapis.com" redirect \n' >> "${file}"
printf 'local-data: "youtube.googleapis.com CNAME restrictmoderate.youtube.com" \n' >> "${file}"
printf 'local-zone: "www.youtube-nocookie.com" redirect \n' >> "${file}"
printf 'local-data: "www.youtube-nocookie.com CNAME restrictmoderate.youtube.com" \n' >> "${file}"
printf 'local-zone: "yandex.com" redirect \n' >> "${file}"
printf 'local-data: "yandex.com CNAME familysearch.yandex.ru" \n' >> "${file}"
printf 'local-zone: "yandex.ru" redirect \n' >> "${file}"
printf 'local-data: "yandex.ru CNAME familysearch.yandex.ru" \n' >> "${file}"
printf 'local-zone: "yandex.ua" redirect \n' >> "${file}"
printf 'local-data: "yandex.ua CNAME familysearch.yandex.ru" \n' >> "${file}"
printf 'local-zone: "yandex.by" redirect \n' >> "${file}"
printf 'local-data: "yandex.by CNAME familysearch.yandex.ru" \n' >> "${file}"
printf 'local-zone: "yandex.kz" redirect \n' >> "${file}"
printf 'local-data: "yandex.kz CNAME familysearch.yandex.ru" \n' >> "${file}"
printf 'local-zone: "www.yandex.com" redirect \n' >> "${file}"
printf 'local-data: "www.yandex.com CNAME familysearch.yandex.ru" \n' >> "${file}"
printf 'local-zone: "www.yandex.ru" redirect \n' >> "${file}"
printf 'local-data: "www.yandex.ru CNAME familysearch.yandex.ru" \n' >> "${file}"
printf 'local-zone: "www.yandex.ua" redirect \n' >> "${file}"
printf 'local-data: "www.yandex.ua CNAME familysearch.yandex.ru" \n' >> "${file}"
printf 'local-zone: "www.yandex.by" redirect \n' >> "${file}"
printf 'local-data: "www.yandex.by CNAME familysearch.yandex.ru" \n' >> "${file}"
printf 'local-zone: "www.yandex.kz" redirect \n' >> "${file}"
printf 'local-data: "www.yandex.kz CNAME familysearch.yandex.ru" \n' >> "${file}"
 
Last edited:

ColinTaylor

Part of the Furniture
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.
 

dave14305

Part of the Furniture
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}"
 

SomeWhereOverTheRainBow

Very Senior Member
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:.
 

SomeWhereOverTheRainBow

Very Senior Member
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.
 

Jack Yaz

Part of the Furniture
I’m only claiming the high road after recently converting many echos to printf. :D
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.
 

ColinTaylor

Part of the Furniture
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.
 

steelskinz

Regular Contributor
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
 

sturmstar

Occasional Visitor
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...
 

Martineau

Part of the Furniture
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:

sturmstar

Occasional Visitor
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
 

L&LD

Part of the Furniture
@ugandy, maybe some of the older kids too! :)
 

SomeWhereOverTheRainBow

Very Senior Member
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

Part of the Furniture
@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.
 

BreakingDad

Senior Member
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 :)
 
Top