DNSmasq as default cache and lookup.



  • For use with Squid and dnsmasq.

    By default the dnsforwarder "dnsmasq" sort of works.
    On clients it will resolve the mentioned malwaredomains to whatever IP you've setup, using nslookup in a windows client for example.
    But it doesn't resolve blackhole DNSes to the harmless IP when using a squid proxy with the default dnsforwarder as dnsresolver. (Dangerous to clients!!!)

    Clients use "pfsense" as a dnslookup and cache. (good!)
    Squid / Proxy uses local resolve as dnslookup (ISP DNSes, when using dhcp on WAN). (unsafe for clients, BAD!!!)

    Setup without blackholeDNS:
    Setting dnsmasq to be the default cache and lookup for your pfsense box is much safer for squid and other clients.
    only requires a mod of the "/etc/resolve.conf" and the creation of "/usr/local/etc/dnsmasq.conf" and "/var/etc/resolv.dsnmasq".

    /var/etc/resolv.dnsmasq (doesn't exist on standard install of pfsense, go and CREATE)

    
    nameserver 127.0.0.1
    
    

    new symbolic link for "/etc/resolv.conf (Needs CHANGE)

    
    /var/etc/resolv.dnsmasq (your can "edit links" via WinSCP)
    
    

    /usr/local/etc/dnsmasq.conf (doesn't exist on standard install of pfsense, go and CREATE)

    
    # increase DNS cache size
    cache-size=10000
    #
    # LAN domain lookups (used differently on pfSense, commented some for now)
    # local=/local/
    # domain=local
    expand-hosts 
    #
    # Give local DHCPleases names. (used differently on pfSense, comment for now)
    # dhcp-leasefile=/var/dhcpd/var/db/dhcpd.leases
    #
    # Resolve(generated from WAN DHCP)
    resolv-file=/var/etc/resolv.conf
    #
    # Extra : Blackhole DNS adresses. (NO blackholeDNS, comment next line)
    # conf-file=/etc/blackhole.conf
    #
    
    

    restart dnsfowarder via WebGUI. (press save)
    restart proxy via WebGUI. (press save)

    FULL Setup with blackholeDNS:
    I don't know about license for blackhole.pl perl script!! (modified it to work in pfSense)
    You can skip "blackhole.pl" and create the conf-file by hand using excel and upload it manually to your pfsensebox.

    List of files involved:

    /etc/resolv.conf (symbolic link, to /var/etc/resolv.conf. Needs change later on.)
    /var/etc/resolv.conf (created when WAN gets DHCP, or other setup)
    /var/etc/resolv.dnsmasq (NEW!, create yourself)
    /usr/local/etc/dnsmasq.conf (NEW!, create yourself)
    /usr/local/bin/blackhole.pl (NEW!, create yourself, requires PERL also installed when using a squid package!)

    /usr/local/bin/blackhole.pl (chmod 0700) (doesn't exist on standard install of pfsense, go and CREATE)

    
    #!/usr/bin/perl
    #-----------------------------------------------------------------------------------#
    #   Group: Front Matter
    #
    #       Script: blackhole.pl
    #       ___________________________________________________________________________
    #
    #       Version 0.07
    #
    #       About: Author
    #
    #           Kurt Kincaid
    #           Email: perl -e "($_='tjgvlvsuAzbipp/dpn')=~s/(.)/chr(ord($1)-1)/ge;print"
    #
    #       Copyright (C) 2005 Kurt Kincaid
    #
    #
    #       About: License
    #
    #          This script is licensed under the GPL license.
    #
    #          This script may be modified and/or redistributed under the same
    #          conditions as SmoothWall Express itself.
    #          Modified for use on a pfSense 1.2.1 RC1\. (HELP! I don't KNOW licenses!!!)
    #
    #      Topic: Description
    #
    #          Updates dnsmasq with malwaredomains.com info
    #
    #      Topic: Dates
    #
    #          Creation and modification dates
    #
    #          Date Written:
    #
    #             08-Nov-2005 03:02:46 PM
    #
    #          Last Modified:
    #
    #             25-Aug-2008 07:10 PM (for use on pfSense Box)
    #
    #      Topic: Required Modules
    #
    #          - strict
    #          - Getopt::Long
    #          - IO::Socket
    #
    #   Group: Installation, Configuration, and Usage
    #
    #       Topic: Installation
    #
    #          Copy the script onto your pfSense box as /usr/local/bin/blackhole.pl. Make sure
    #          to set the permissions like so:
    #
    #>         chmod 700 /usr/local/bin/blackhole.pl
    #
    #          Finally, at the bottom of your /usr/local/etc/dnsmasq.conf file, add this line:
    #
    #>         conf-file=/etc/blackhole.conf
    #
    #       Topic: Configuration
    #
    #          As it is written, the script uses the Spyware Listening Post IP address as explained
    #          in the documentation at doc.bleedingthreats.net. If, however, you prefer to have your
    #          spyware redirected to another address (127.0.0.1, for example), change the value
    #          of $redirect accordingly. The host, port, and actual destination of the zones file
    #          are easily modified in the event that the URL should change or in the event that
    #          you prefer to use a different source.
    #
    #       Topic: Usage
    #
    #          The script may be run by hand, as a cron job, or both. Each time the script it run, it grabs
    #          the lastest spywaredomains.zones file, modifies /etc/blackhole.conf accordingly, and
    #          restarts dnsmasq. 
    #          !!!!(YOU have to restart VIA WEBConfigurator on your PFSENSE BOX)!!!
    #
    #################################################
    # Script includes a fix to automatically reload dnsmasq with the additional blackhole entries.
    # Changes by Kevin Hughes www.kphonline.co.uk
    # Script includes changes made by cheesman to allow the use of an ignore file.
    # BEngEE 21.11.07 -
    # Script no longer overwrites /etc/blackhole.conf with zero byte file if source data is not found, e.g. if server goes down
    # BEngEE 28.11.07 -
    # Skip over entries that have an invalid space in the address name e.g. "botnet C&C"
    # BEngEE 28.12.07 -
    # Bleedingthreats is considered dead, a new server location malwaredomains.com has beed added. Thier policy is
    # of purely identifying malware sites rather than the spyware, ad servers and malware approach of BT.
    # No listening port exists yet, emergingthreats are onto that issue (in the meantime use 127.0.0.1).
    # So that we all have same stats, /etc/blackhole.cnt is now retrieved number of rules and no longer incl. custom
    # Therefore, /etc/blackholecustom.cnt is a new file for the number of custom rules.
    # BEngEE 29.12.07 -
    # malwaredomains.com probably wont be incorporating the rules from bleedingthreats, therefore, for those that
    # have the last available list, i have done a very crude merge.
    # /etc/blackholebt.cnt is a new file for the count of bleedingthreats legacy rules.
    # Newly created ignores are taken into account with legacy BT data.
    # Notes: Those using legacy BT data will notice duplicates exist between it and the malware lists, its no biggy. You
    # can always opt out of using the BT file by renaming the /etc/blackhole.conf_BT to something else. However, the
    # malware list is currently at 17K plus, where BT data ended at around 80K.
    # I am releasing this now as there are are few bad boys on the block as i observed earlier today via a spam email
    #-----------------------------------------------------------------------------------#
    
    use strict;
    use IO::Socket;
    
    our( $sock, $host, $port, $list, $redirect, $get, $ignorefile, $customfile );
    $host       = "www.malwaredomains.com"; #"docs.bleedingthreats.net"; #"www.bleedingthreats.net"; #"www.bleedingsnort.com";
    $redirect   = "64.34.209.132"; #"127.0.0.1"; #"64.34.209.132"; #"216.81.78.3";
    $port       = 80;
    $get        = "/files/spywaredomains.zones"; #"/pub/Main/SnortConfSamples/blackhole.conf"; #"/blackhole-dns/files/spywaredomains.zones";
    $ignorefile = "/etc/blackhole.ignore";
    $customfile = "/etc/blackhole.custom";
    
    unless ( $sock = new IO::Socket::INET( PeerAddr => $host, PeerPort => $port, Proto => 'tcp', Timeout => 5 ) ) {
      print( "Error: Could not connect to $host. Aborting.\n" );
      exit;
    }
    print $sock "GET $get HTTP/1.1\r\nHost: $host\r\nConnection: close\r\n\r\n";
    $list .= $_ while <$sock>;
    close( $sock );
    my @lines = split( /\n/, $list );
    unless ( scalar @lines ) {
      print( "Error: Unable to retrieve spywaredomains.zones data from www.malwaredomains.com/files. Aborting.\n" );
      exit;
    }
    
    #create ignore file if it doesnt exist
    unless ( -e $ignorefile ) {
       system ('/usr/bin/touch', $ignorefile);
       system ("/usr/sbin/chown root $ignorefile");
    }
    #create custom block file if it doesnt exist
    unless ( -e $customfile ) {
       system ('/usr/bin/touch', $customfile);
       system ("/usr/sbin/chown root $customfile");
    }
    #Backup last ever bleedingthreats list for those that have it
    unless ( -e "/etc/blackhole.conf_BT" ) {
      system('/usr/bin/touch -t 0712280001 /tmp/BT');
      system('find /etc/blackhole.conf -type f ! -newer /tmp/BT -exec cp {} /etc/blackhole.conf_BT \;');
      system('rm -f /tmp/BT');
    }
    
    my %ignore;
    if ( -e $ignorefile ) {
      open( IGNORE, $ignorefile );
      while (<ignore>) {
        chomp;
        next if (/\#/);  #skip comments
        next if (/^\s*$/); # and blank lines
        $ignore{$_} = 1;
      }
      close( IGNORE );
    }
    
    #open ( OUT, ">/etc/blackhole.conf" );
    open( OUT, ">/tmp/blackhole.conf" ); #create file in /tmp rather than the final resting place
    my $linesRead = 0;
    foreach my $line ( @lines ) {
       next unless $line =~ /^zone "(.*?)"/;
    #  next unless $line =~ /^zone\s+"([a-zA-Z0-9.\-]+)"/;
    #  next unless $line =~ /^address=\/(.*)\/.*/;
      next if $ignore{$1};
      #skip over entries that have a space in them (causes dnsmasq to fail otherwise)
      next if $1 =~ /.*\ .*/;
      $linesRead = $linesRead + 1;
      print OUT ( "address=/$1/$redirect\n" );
    }
    close( OUT );
    if ( $linesRead != 0 ) { #we have at more than 1 rules therefore let's use this file
      if (-e "/etc/blackhole.conf") {
      system("mv -f /etc/blackhole.conf /etc/blackhole.conf_old"); #create backup just in case something goes wrong
      }
      # Count number of retrieved addresses
      system("cat /tmp/blackhole.conf | wc -l > /tmp/blackhole.cnt");
      system("tr '\n' ' ' < /tmp/blackhole.cnt | sed 's/[ ]*//' | sed 's/[ ]*\$//' > /tmp/blackhole.cnt"); #trim the text
      # Count number of custom addresses
      system("cat $customfile | wc -l > /tmp/blackholecustom.cnt");
      system("tr '\n' ' ' < /tmp/blackholecustom.cnt | sed 's/[ ]*//' | sed 's/[ ]*\$//' > /tmp/blackholecustom.cnt"); #trim the text
      # Append custom address blocks to the retrieved addresses
      system("cat $customfile >> /tmp/blackhole.conf");
      # Merge existing legacy bleedingthreats list if any
      if ( -e "/etc/blackhole.conf_BT" ) {
        # Count number of BT addresses
        system("cat '/etc/blackhole.conf_BT' | wc -l > /tmp/blackholebt.cnt");
        system("tr '\n' ' ' < /tmp/blackholebt.cnt | sed 's/[ ]*//' | sed 's/[ ]*\$//' > /tmp/blackholebt.cnt"); #trim the text
        system("mv -f /tmp/blackholebt.cnt /etc/blackholebt.cnt"); #use this somewhere to display number of legacy bleedingthreat rules
        #open bt file, print each line not ignored to mainfile
        open( OUT, ">>/tmp/blackhole.conf" );
        open( BTLEGACY, "/etc/blackhole.conf_BT");
        print OUT ( "\n#Legacy Bleedingthreats & custom section\n" );
        while (<btlegacy>) {
          chomp;
          next if (/\#/);  #skip comments
          next if (/^\s*$/); # and blank lines
          next unless (/^address=\/(.*)\/.*/);
          next if $ignore{$1};
          print OUT ( "address=/$1/$redirect\n" );
        }
        close( BTLEGACY );
        close( OUT );
      }
      # Place address list and counter files in main location
      system("mv -f /tmp/blackhole.conf /etc/blackhole.conf");
      system("mv -f /tmp/blackhole.cnt /etc/blackhole.cnt");  #use this somewhere to display retrieved number of rules
      system("mv -f /tmp/blackholecustom.cnt /etc/blackholecustom.cnt"); #use this somewhere to display number of custom rules
    }</btlegacy></ignore>
    

    files created by "blackhole.pl"
    /etc/blackhole.cnt (contains the number of lines of "blackhole.conf", use for statistics? and test : download has more than 1 line)
    /etc/blackhole.conf (this is the main list of malware sites and their preferred harmless ip. p.s. 127.0.0.1 won't work here!)
    /etc/blackhole.conf_old (backup, of previous downloaded update)
    /etc/blackhole.custom (custom file for custom modifications, leave empty)
    /etc/blackhole.ignore (list of ignore addresses, leave empty)
    /etc/blackholecustom.cnt (contains the number of lines of "blackhole.custom" )

    /etc/blackhole.conf  (partial example format, what blackhole.pl does for you!)

    address=/007arcadegames.com/64.34.209.132
    address=/008i.com/64.34.209.132
    address=/008k.com/64.34.209.132
    address=/00hq.com/64.34.209.132
    address=/010402.com/64.34.209.132
    address=/0190-dialer.com/64.34.209.132
    address=/0-29.com/64.34.209.132
    address=/0-2u.com/64.34.209.132
    address=/05p.com/64.34.209.132
    

    /var/etc/resolv.conf (do nothing manually, example content only)

    
    domain local
    nameserver 213.xx.xxx.xx (your ISP's DNSes)
    nameserver 213.xxx.xxx.xxx
    nameserver 213.xx.xxx.xx
    
    

    /var/etc/resolv.dnsmasq (doesn't exist on standard install of pfsense, go and CREATE)

    
    nameserver 127.0.0.1
    
    

    new symbolic link for "/etc/resolv.conf (Needs CHANGE)

    
    /var/etc/resolv.dnsmasq (your can "edit links" via WinSCP)
    
    

    /usr/local/etc/dnsmasq.conf (doesn't exist on standard install of pfsense, go and CREATE)

    
    # increase DNS cache size
    cache-size=10000
    #
    # LAN domain lookups (used differently on pfSense, commented some for now)
    # local=/local/
    # domain=local
    expand-hosts 
    #
    # Give local DHCPleases names. (used differently on pfSense, comment for now)
    # dhcp-leasefile=/var/dhcpd/var/db/dhcpd.leases
    #
    # Resolve(generated from WAN DHCP)
    resolv-file=/var/etc/resolv.conf
    #
    # Extra : Blackhole DNS adresses.
    conf-file=/etc/blackhole.conf
    #
    
    

    First run:
    Execute manually /usr/local/bin/blackhole.pl : to create blackhole.conf for the fist time
    Restart (dnsforwarder) dsnmasq via WebGUI. (check system log afterwards)
    Restart squid proxy via WebGUI.
    (may need to clear cache too, squid and browser of the client)
    Test it!!! Surf to any malware domain mentioned in "/etc/blackhole.conf", ikena.com 2020search.com for example.
    It will display "1", because that is what "http://64.34.209.132/" shows you.

    After any update of blackhole.pl, restart both dnsforwarder and squid.

    To undo this modification:
    edit symboliclink of /etc/resolv.conf back to /var/etc/resolv.conf
    remove /usr/local/etc/dnsmasq.conf
    remove /var/etc/resolv.dnsmasq
    remove /usr/local/bin/blackhole.pl
    remove /etc/blackhole*
    restart dnsforwarder via webgui (or reboot machine.)
    restart squid proxy via webgui

    edited: missing uninstall info (cutting and pasting all over the place doesn't do wonders with spelling and grammar, cleaned up some type-o's)



  • I've stumbled upon a small hick-up during an snapshot update and reboot with my previous modifications.
    After a system reboot the boot-time-update-check won't find an ntpserver ip because of the dsnmasq "localhost" modifications done earlier.
    Time update check is done before dnsmasq has loaded. So I "restored" the original symlink before time update check is run.
    Didn't try moving dnsmasq startup before time update check though, so I don't know if that will work too.

    Symbolic links are not "repaired" when the exist…
    /etc/rc only checks if the links exist and recreates them if they are missing, it does not repair them like the comments state...

    the following is only a small part of /etc/rc :

    echo -n "Creating symlinks..."
    # Make sure symlink is correct on embedded
    if [ "$PLATFORM" = "embedded" ] ; then
    	rm /conf
    	ln -s /cf/conf/ /conf
    fi
    
    # Repair symlinks if they are broken
    if [ ! -L /etc/syslog.conf ]; then
    	rm -rf /etc/syslog.conf
    	ln -s /var/etc/syslog.conf /etc/syslog.conf
    fi
    
    # Repair symlinks if they are broken
    if [ ! -L /etc/hosts ]; then
    	rm -rf /etc/hosts
    	ln -s /var/etc/hosts /etc/hosts
    fi
    
    # Repair symlinks period!!!
    if [ ! -L /etc/resolv.conf]; then
        rm -rf /etc/resolv.conf
        ln -s /var/etc/resolv.conf /etc/resolv.conf
    else
        #make sure the link is pointing to the right conf file for startup reasons ( -f )
        ln -f -s /var/etc/resolv.conf /etc/resolv.conf
    fi
    
    

    the following is only a small part of /etc/rc.bootup :

    	/* start DHCP service */
    	services_dhcpd_configure();
    
        /* create correct symbolic link for using dnsmasq as forwarder and local cache!!! */
        mwexec("/bin/ln -f -s /var/etc/resolv.dnsmasq /etc/resolv.conf");
    
    	/* start dnsmasq service */
    	services_dnsmasq_configure();
    
    

    side note, people who want OpenDNS and ISP's DNSservers (dhcp) add two lines in to /etc/inc/system.inc like so:

    function system_resolvconf_generate($dynupdate = false) {
    	global $config, $g;
    	if(isset($config['system']['developerspew'])) {
    		$mt = microtime();
    		echo "system_resolvconf_generate() being called $mt\n";
    	}
    
            $syscfg = $config['system'];
    
            $fd = fopen("{$g['varetc_path']}/resolv.conf", "w");
            if (!$fd) {
                    printf("Error: cannot open resolv.conf in system_resolvconf_generate().\n");
                    return 1;
            }
    
            $resolvconf = "domain {$syscfg['domain']}\n";
            /* Add OpenDNS to the list of nameservers */
            $resolvconf .= "nameserver 208.67.222.222\n";
            $resolvconf .= "nameserver 208.67.220.220\n";
    
            $havedns = false;
    
            if (isset($syscfg['dnsallowoverride'])) {
                    /* get dynamically assigned DNS servers (if any) */
    		$ns = array_unique(get_nameservers());
    		foreach($ns as $nameserver) {
    			if($nameserver) {
    				$resolvconf .= "nameserver $nameserver\n";
    				$havedns = true;
    			}
    		}
            }
            if (!$havedns && is_array($syscfg['dnsserver'])) {
                    foreach ($syscfg['dnsserver'] as $ns) {
                            if ($ns) {
                                    $resolvconf .= "nameserver $ns\n";
    				$havedns = true;
    			}
                    }
            }
    
            fwrite($fd, $resolvconf);
            fclose($fd);
    
    

Log in to reply