Enforce Google Safesearch



  • @bilbo:

    Thanks for the replies. I have an all in one adsl modem wirlesss router so cannot put pfsense in the middle at the moment, is it possible to get this to work in transparent mode without putting pfsense in the middle? Clients will be connecting to the wireless.

    Would it be some variation of this: http://forum.pfsense.org/index.php?topic=46351.0

    I do have two interfaces in the box I will be using.

    Would I haved dhcp specify pfsense as the gateway and pfsenses gateway would be the all in one router, all devices on same subnet?

    internet    <===  allin one adsl modem router  wired/ wireless ====Pfsense
                                          ||
                                          ||
                                Wireless Clients

    I can set router to only allow internet access from a single ip, eg pfsense.

    I had my home network setup this way for a while - it works, but it results in an extra hop. First, you need to create a rule on the adsl router to forward outbound port 80 requests from the wireless clients to the Pfsense box (IP address of pfsense and port of dansguardian - depens on the router for how you would create this rule). Then, (as you suggested) create a rule to only allow the Pfsense box outbound. The other thing you will need to do is set the wireless clients to use pfsense for DNS resolution (to force nosslsearch) or figure out how to override resolution of "google.com" in the DNS settings on your router (perhaps set it to use the pfsense box as the dns server?).

    While the steps above should work - what I'd recommend is to shut off wireless on the adsl router then go adsl –> Pfsense --> wireless access point --> wireless clients (i.e. what you said you couldn't do - pfsense in the middle). Of course this approach has a cost - you would need to purchase and setup a wireless access point.



  • Squidguard has an option to force safe search, you can also set it on a per computer basis where some computers can have it forced, some can turn it off, and some can leave it off.



  • @rountrey:

    Squidguard has an option to force safe search, you can also set it on a per computer basis where some computers can have it forced, some can turn it off, and some can leave it off.

    I assume it works the same way as dansguardian though - i.e. it rewrites the query string. If so, you would still need to force non-SSL search. If you are doing SSL search, you don't have visibility into (or ability to change) the query string.



  • Unfortunately it is a netgear dgnd3700 adsl router on which you cannot confgure a great deal but it has a great wireless ap built in, darn. I understand the squidguard / dansguardian and dns no ssl option bits.

    Its the can it be done with the existing devices I have I would like to know, will gateway options not do it by sending outbound tarffic to pfsense?

    So pfsense is 192.168.0.2, dhcp gives this out to clients as the gateway, pfsense gateway is 192.168.0.1 that of the router and thus forwards traffic to and from the internet enabling it proxy transparently or does pfsense HAVE to physically sit in between? Thank you.



  • I put in an installation with "all-in-one" ADSL router/WiFi in front of a pfSense last week - see http://forum.pfsense.org/index.php/topic,54650.0.html
    Basically I did:

    • turn off DHCP on the "all-in-one" device.
    • setup pfSense WAN allowing everything on the local WAN subnet, giving out DHCP on WAN (then clients get pfSense as their gateway, DNS server etc.)
    • pfSense WAN gateway is the "all-in-one" device
    • all the wired and WiFi devices end up on the pfSense WAN (which is the "all-in-one" device LAN)
    • nothing plugged into the pfSense LAN
    • enable manual NAT. Make packets come from the WAN clients be NATted by pfSense on the way out to the "all-in-one" device. This hides the real IP address of the local clients. Packets returning back from the internet/all-in-one device are always sent back to pfSense to be unNaTted and forwarded back on WAN to the clients. Avoids any asymmetric routing issues, and that pfSense gets to see everything to and from the internet. Thus you can do whatever filtering/caching etc that you want with pfSense.

    In a way, the clients that are in front of the pfSense, on its WAN, act a lot like clients that could be behind the pfSense, on its LAN. They get NATted out, and have all their packets go through pfSense.

    For my case, the install was in a remote area with solar. I wanted to minimise power consumption, and the ADSL already had WiFi. This config avoided adding an extra WiFi device behind pfSense.



  • Thank you, when I get round to building no doubt I'll be askin for more help.  :)



  • Great tutorial phil.davis  :)



  • @phil.davis:

    I put in an installation with "all-in-one" ADSL router/WiFi in front of a pfSense last week - see http://forum.pfsense.org/index.php/topic,54650.0.html
    Basically I did:

    • turn off DHCP on the "all-in-one" device.
    • setup pfSense WAN allowing everything on the local WAN subnet, giving out DHCP on WAN (then clients get pfSense as their gateway, DNS server etc.)
    • pfSense WAN gateway is the "all-in-one" device
    • all the wired and WiFi devices end up on the pfSense WAN (which is the "all-in-one" device LAN)
    • nothing plugged into the pfSense LAN
    • enable manual NAT. Make packets come from the WAN clients be NATted by pfSense on the way out to the "all-in-one" device. This hides the real IP address of the local clients. Packets returning back from the internet/all-in-one device are always sent back to pfSense to be unNaTted and forwarded back on WAN to the clients. Avoids any asymmetric routing issues, and that pfSense gets to see everything to and from the internet. Thus you can do whatever filtering/caching etc that you want with pfSense.

    In a way, the clients that are in front of the pfSense, on its WAN, act a lot like clients that could be behind the pfSense, on its LAN. They get NATted out, and have all their packets go through pfSense.

    For my case, the install was in a remote area with solar. I wanted to minimise power consumption, and the ADSL already had WiFi. This config avoided adding an extra WiFi device behind pfSense.

    Didn't think about setting it up that way - but it seems like a great way to solve the problem…



  • Phil, I think I have set up as you have (minus the lan interface).
    Clients are getting internet okay.
    I have installed squid and squidguard, so I can force safeserach, is there anything special I need to do in this configuration as I cant get it to work at the moment.

    Edit: Working! Now to figure how to block google ssl



  • how to do this? Or best to use suggestion above?

    To utilize the no SSL option for your network, configure the DNS entry for www.google.com to be a CNAME for nosslsearch.google.com.

    We will not serve SSL search results for requests that we receive on this VIP. If we receive a search request over port 443, the certificate handshake will complete successfully, but we will then redirect the user to a non-SSL search experience along with an initial message explaining so.



  • @bilbo:

    how to do this? Or best to use suggestion above?

    To utilize the no SSL option for your network, configure the DNS entry for www.google.com to be a CNAME for nosslsearch.google.com.

    We will not serve SSL search results for requests that we receive on this VIP. If we receive a search request over port 443, the certificate handshake will complete successfully, but we will then redirect the user to a non-SSL search experience along with an initial message explaining so.

    OK… in theory, you should be able to do this with with the tiny DNS package. I never actually tried it, but I read a number of posts that gave me concern about whether it would work correctly (and whether tiny DNS supported it). That's why I went with just adding the overrides in the DNS forward settings... BTW, I think all the host override setting does under the covers is add the entry to the /etc/hosts file.



  • Could tell me how to setup the cron job, I have got the overide working now, sweet.

    Hopefully no more accidents when the kids are searching on google!



  • Screenshot attached…

    Earlier I said that I have a script to update the IP addresses of nosslsearch.google.com. The way the script works is that it will actually update any IP address into the override list based on specific text in the description field. It looks for the "ip=..." in the description field. If it finds it, then it tries to resolve the host after the "=" and updates it into the override ip address (if it is different from the address that is already there). The script runs every 30 minutes from cron with the intent of updating the address of nosslsearch.google.com if google would change where it resolves...

    /*
            update_hosts.php
    
    Process the config settings of the dnsmasq service and set the host override
    IP addresses to values that we lookup using nslookup.
    
    If the description in the host override contains the string
    ip=domain (such as ip=nosslsearch.google.com) then lookup
    the domain value and put it into the ip address field
    */
    
    require("config.inc");
    require_once("functions.inc");
    require_once("filter.inc");
    require_once("shaper.inc");
    
    if (!is_array($config['dnsmasq']['hosts']))
            $config['dnsmasq']['hosts'] = array();
    
    if (!is_array($config['dnsmasq']['domainoverrides']))
            $config['dnsmasq']['domainoverrides'] = array();
    
    $a_hosts = &$config['dnsmasq']['hosts'];
    $a_domainOverrides = &$config['dnsmasq']['domainoverrides'];
    
    $write_it = 0;
    $i = 0;
    foreach ($a_hosts as $hostent) {
    
            /* If the description starts with "ip=", then we want to lookup the
               domain specified
            */
            $descr=ltrim(strtolower($hostent['descr']));
            $str_part=explode("=",$descr);
            if ( $str_part[0] == "ip" ) {
    
                    /* Pull the domain out (second part of 'ip=domain')
                    */
                    $ret_val=0;
                    $out_array=array();
                    $check_domain=$str_part[1];
    
                    echo "Checking override address for {$hostent['domain']}\n";
                    echo "should be set to resolution of {$check_domain}\n";
    
                    /* Try to lookup the domain and get an address back for it
                    */
                    $tmp=exec("nslookup -timeout=2 " . $check_domain, $out_array, $ret_val);
                    $str_part=explode(" ", $out_array[4]);
                    if ($str_part[0] == "Address:") {
                            $lookup_addr=$str_part[1];
                            echo "nslookup of {$check_domain} returned {$lookup_addr}\n";
    
                            /* If the address is different than the IP alread stored for this
                               override record, then update it
                            */
                            if ($lookup_addr != $hostent['ip']) {
                                    echo "{$hostent[ip]} != {$lookup_addr}\n";
                                    echo "updating address {$hostent['ip']} ---> {$lookup_addr}\n\n";
    
                                    $hostent['ip']=$lookup_addr;
                                    $a_hosts[$i]=$hostent;
                                    $write_it=1;
                            }
                            else {
                                    echo "{$hostent[ip]} == {$lookup_addr}\n";
                                    echo "skipping address update...\n\n";
                            }
                    }
                    else {
                            echo "unable to resolve {$check_domain}\n";
                            echo "skipping address update...\n\n";
                    }
            }
            $i++;
    }
    
    /* Only rewrite things if something actually changed
    */
    if ($write_it > 0) {
            echo "writing config\n";
            write_config();
            $retval = services_dnsmasq_configure();
    
            /* Relaod filter (we might need to sync to CARP hosts)
               don't know if this is really necessary or not
            */
            filter_configure();
    }
    
    




  • Thanks rj, I'll try this later and thanks phil, the setup seems to be working well. I see what you meant about the nat rule which I had not applied properly at first , internet worked but ssh connections etc kept bombing out till I applied it correctly.



  • @bilbo:

    Thanks rj, I'll try this later and thanks phil, the setup seems to be working well. I see what you meant about the nat rule which I had not applied properly at first , internet worked but ssh connections etc kept bombing out till I applied it correctly.

    BTW… If you use the script I provided, you might want to check that it works correctly. The return values from nslookup were different on my home router versus a VM I was playing with. You might need to change the line:

    $str_part=explode(" ", $out_array[4]);
    to be
                    $str_part=explode(" ", $out_array[5]);

    My cron entry looks like this…
    */30 * * * * root /usr/local/bin/php -q /usr/local/ip_updater/ip_updater.php > /var/log/ip_updater/ip_updater.log

    Obviously I copied the script to /usr/local/ip_updater and named it ip_updater.php. You can use the cron package within pfsense to create your cron entries.

    Also... just as an aside. If you are concerned about your kids internet experience I'm a big fan of dansguardian. It does blacklist filter as you can do with squidgaurd but also allows content based filtering. In my opinion, content based filtering is key. Blacklists are only as good as they are maintained and keeping them up to date is a nearly impossible task. I'm very happy with my current setup and I use three different things to ensure a safe web experience:
      1. OpenDNS as my DNS servers
      2. Dansguardian blacklists
      3. Dansguardian content filtering

    Just my unsolicited two cents...



  • Many thanks again for the tip, I actually already use opendns its pretty good. I will have a look at dansguardian.

    Is it possible to redirect the standard opendns blocked page http://blocked-website.com to a standard simple custom page somehow?

    I suppose there is the dns forwarder option again, or maybe squidguard/dansguardian could do it? How to go about hosting the web page?

    Maybe I could create a squid rule to block http://blocked-website.com and somehow edit the inbuilt pfsense block page, dya reckon this is possible?



  • I am trying to get dansguardian to work but struggling, is there something special I need to do give the setup above?

    I removed squidguard so just have squid and dansguardian.



  • I think its the forwarding rule that needs tweaking to 8080.

    I have Dansguardian listening on the wan and parent proxy defaults 127.0.0.1 3128

    My one and only subnet the one the wan is one is 192.168.0.1/24

    I tried to create  a rule to forward traffic from wan subnet to 8080 but it does not work and the internet breaks.



  • Going back to squidguard for now then!

    But another issue the int error page does not work, nor any of the other block page options. The actual block works but I get a no response from 127.0.0.1 error page in my browser instead og the block page.

    Is this because I only have a WAN interface?



  • @bilbo:

    Going back to squidguard for now then!

    But another issue the int error page does not work, nor any of the other block page options. The actual block works but I get a no response from 127.0.0.1 error page in my browser instead og the block page.

    Is this because I only have a WAN interface?

    Sorry… wasn't watching the forums for a while.

    For DG... In a normal setup it should be listening on the LAN interface port 8080. The setup would then be as follows:
    1. DG connects to Squid running on the loopback (or LAN) port 3128 (setup in the DG config).
    2. Configure squid to listen on the loopback and port 3128.
    3. Configure the browser to go to the pfsense box port 8080 as the proxy sever.

    The only thing you need a rule for is if you want to make the proxy transparent. In that case, you forward all port 80 requests to 8080. I'm not sure how you would modify the above config to work in your situation.

    Hope that make sense...



  • Many thanks for the respsonse, I think this is why I am having issues due to only having a wan interface, I tried all I can do isget them to listen on the WAN which does not work.



  • @bilbo:

    Could tell me how to setup the cron job, I have got the overide working now, sweet.

    Hopefully no more accidents when the kids are searching on google!

    Thought you might be interested in something I figured out this weekend… The override for "encrypted.google.com" does not work if someone browses to "https://encrypted.google.com". Not 100% sure of all the reasons why but I was able to figure out two options for solving the problem...

    1.) You can block outbound access on port 443 to the IP addresses that encrypted.google.com resolves to. Unfortunately, this is a pretty long list so it's better to use an alias in your firewall rule.
    2.) You can use the dns override and forward encrypted.google.com to a different ip address. It doesn't really block encrypted.google.com, but it sends the user to another site you trust - for example the address of opendns.com

    To block using option #1, I ended up using the url table feature of the alias. It will read a text file at a URL and block all the IP addresses or networks that are listed. The nice thing is that there is a built-in cron job that re-reads the text file daily and updates the table in your firewall rules. In order to make sure the addresses were up to date in the text file, I wrote another little shell script the does an nslookup of whatever names you want (in this case encrypted.google.com) and writes their resolved ip addresses to a text file. I place the text file in my /usr/local/www directory so that it can be referenced by url in the alias.  I just run my script 5 minutes before the built-in url update job runs.

    This got me going on another track though... It seems that there are several encrypted search engines available that also provide image search capabilities. The ones I found were duckduckgo.com, ixquick.com and startpage.com. Unfortunately, these sites presented challenges with block option #1 because (for whatever reason) nslookup only returns one address for them - but it doesn't always return the same address! For example, you can do an nslookup multiple times in a 10 minute period and get multiple addresses back for ixquick.com! Because of that issue, I used option #2 to prevent access to these sites. Option #2 isn't perfect though - it would not stop someone if they were able to figure out one of the ip addresses of the site and browse there directly (via the ip address).


Log in to reply