├── README.md └── unbound-block-hosts /README.md: -------------------------------------------------------------------------------- 1 | # NAME 2 | 3 | unbound-block-hosts - a script to convert Dan Pollock's ad blocking hosts file 4 | into Unbound local-data 5 | 6 | # SYNOPSIS 7 | 8 | unbound-block-hosts [OPTIONS] 9 | 10 | # INTRODUCTION 11 | 12 | Dan Pollock (http://someonewhocares.org/) maintains a hosts file that can be 13 | used by individual users to block hosts that contain advertisements, spyware, 14 | web trackers and other unpleasant, annoying or malicious content. 15 | 16 | This script converts this file into a format that can be loaded into the Unbound 17 | DNS server, allowing this list to be consumed by an entire network, or by 18 | devices (such as smart phones and tablets) which don't support a local hosts 19 | file. 20 | 21 | # USAGE 22 | 23 | unbound-block-hosts supports the following arguments: 24 | 25 | - `--address=ADDRESS` 26 | 27 | The IP address to resolve to. This is `127.0.0.1` by default. 28 | 29 | - `--v6address=ADDRESS` 30 | 31 | The IPv6 address to resolve to. This is `::1` by default. 32 | 33 | - `--url=URL` 34 | 35 | The URL to retrieve. This is [http://someonewhocares.org/hosts/hosts](http://someonewhocares.org/hosts/hosts) by default. 36 | 37 | - `--file=FILE` 38 | 39 | The file to write. This is `/var/unbound/local-blocking-data.conf` by default. 40 | 41 | - `--SECTION` 42 | 43 | The source file contains a number of sections, which can be enabled or disabled 44 | as required. By default, all sections are enabled except for `shock-sites` and 45 | `maybe-spy`. 46 | 47 | This script will compare the modification time of the local file to that on the 48 | remote server, and won't request the file if it hasn't been updated. 49 | 50 | # INTEGRATING INTO UNBOUND 51 | 52 | To use the output of this file with Unbound, use the `include` directive within 53 | the `server` block, like so: 54 | 55 | server: 56 | access-control: 0.0.0.0/8 allow 57 | include: /var/unbound/local-blocking-data.conf 58 | 59 | # COPYRIGHT 60 | 61 | Copyright 2015 Gavin Brown <gavin.brown@uk.com> 62 | 63 | This program is Free Software, you can use it and/or modify it under the same 64 | terms as Perl itself. 65 | 66 | # SEE ALSO 67 | 68 | - [https://github.com/jodrell/unbound-block-hosts](https://github.com/jodrell/unbound-block-hosts) 69 | - [http://someonewhocares.org/hosts/](http://someonewhocares.org/hosts/) 70 | -------------------------------------------------------------------------------- /unbound-block-hosts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | # Copyright 2013 Gavin Brown 3 | # This program is Free Software, you can use it and/or modify it under the same 4 | # terms as Perl itself. 5 | use LWP; 6 | use HTTP::Request::Common; 7 | use HTTP::Date; 8 | use Getopt::Long; 9 | use Pod::Usage; 10 | use strict; 11 | 12 | my $opt = { 13 | # addresses to resolve the hosts to: 14 | 'address' => '127.0.0.1', 15 | 'v6address' => '::1', 16 | 17 | # url we pull from: 18 | 'url' => 'http://someonewhocares.org/hosts/hosts', 19 | 20 | # file we write to: 21 | 'file' => '/etc/unbound/local-blocking-data.conf', 22 | 23 | 'help' => 0, 24 | 25 | # categories that aren't blocked by default: 26 | 'shock-sites' => undef, 27 | 'maybe-spy' => undef, 28 | 29 | # categories that are blocked by default: 30 | 'hijack-sites' => 1, 31 | 'spyware-sites' => 1, 32 | 'malware-sites' => 1, 33 | 'doubleclick-sites' => 1, 34 | 'intellitxt-sites' => 1, 35 | 'red-sheriff-sites' => 1, 36 | 'cydoor-sites' => 1, 37 | '2o7-sites' => 1, 38 | 'maybe-ads' => 1, 39 | 'ad-sites' => 1, 40 | 'canvass-fingerprinting-sites' => 1, 41 | 'evercookies-sites' => 1, 42 | 'yahoo-ad-sites' => 1, 43 | 'hitbox-sites' => 1, 44 | 'extreme-dm-sites' => 1, 45 | 'realmedia-sites' => 1, 46 | 'fastclick-sites' => 1, 47 | 'belo-interactive-sites' => 1, 48 | 'popup-traps' => 1, 49 | 'ecard-scam-sites' => 1, 50 | 'IVW-sites' => 1, 51 | 'oewabox-sites' => 1, 52 | 'wiki-spam-sites' => 1, 53 | 'Phorm-sites' => 1, 54 | 'Windows10' => 1, 55 | 'local-data' => 1, # if you create your own custom file, make sure to enclose its contents in tags with this name 56 | }; 57 | my @args = map { length($opt->{$_}) > 0 ? $_.'=s' : $_ } keys(%{$opt}); 58 | push(@args, 'help'); 59 | GetOptions($opt, @args); 60 | 61 | if ($opt->{'help'}) { 62 | pod2usage('-verbose' => 99, '-sections' => 'SYNOPSIS|USAGE|INTEGRATING INTO UNBOUND'); 63 | exit; 64 | } 65 | 66 | my $req = GET($opt->{'url'}); 67 | $req->header('If-Modified-Since' => time2str((stat($opt->{'file'}))[9])) if (-e $opt->{'file'}); 68 | 69 | my $ua = LWP::UserAgent->new; 70 | my $res = $ua->request($req); 71 | 72 | if ($res->is_error) { 73 | printf(STDERR "Error: %s\n", $res->message); 74 | exit(1); 75 | 76 | } elsif (!$res->is_success) { 77 | if ($res->code(304)) { 78 | printf(STDOUT "(%s)\n", $res->message); 79 | 80 | } else { 81 | printf(STDERR "(%s)\n", $res->message); 82 | 83 | } 84 | exit; 85 | 86 | } 87 | 88 | if (!open(FILE, '>'.$opt->{'file'})) { 89 | printf(STDERR "Error: cannot open %s: %s\n", $opt->{'file'}, $!); 90 | exit(1); 91 | } 92 | 93 | my @names; 94 | my @sections; 95 | my $name; 96 | my $discarded = 0; 97 | foreach my $line (split("\n", $res->content)) { 98 | if ($line =~ /^\#<\/(.+?)>/) { 99 | pop(@sections); 100 | 101 | } elsif ($line =~ /^\#<(.+?)>/) { 102 | push(@sections, $1); 103 | 104 | } elsif ($line !~ /^\s*\#/ && $line !~ /^\s*$/) { 105 | my $section = $sections[-1]; 106 | if (!$section) { 107 | $discarded++; 108 | 109 | } elsif ($opt->{$section}) { 110 | $line =~ s/\s*\#.+$//; 111 | (undef, $name) = split(/\s+/, $line, 2); 112 | push(@names, $name); 113 | } 114 | } 115 | } 116 | 117 | printf(STDERR "Warning: discarded %u lines that were found outside section tags\n", $discarded) if ($discarded > 0); 118 | 119 | map { 120 | printf(FILE "local-data: \"%s A %s\"\n", $_, $opt->{'address'}); 121 | printf(FILE "local-data: \"%s AAAA %s\"\n", $_, $opt->{'v6address'}); 122 | } @names; 123 | 124 | close(FILE); 125 | 126 | exit; 127 | 128 | __END__ 129 | 130 | =pod 131 | 132 | =head1 NAME 133 | 134 | unbound-block-hosts - a script to convert Dan Pollock's ad blocking hosts file 135 | into Unbound local-data 136 | 137 | =head1 SYNOPSIS 138 | 139 | unbound-block-hosts [OPTIONS] 140 | 141 | =head1 INTRODUCTION 142 | 143 | Dan Pollock (http://someonewhocares.org/) maintains a hosts file that can be 144 | used by individual users to block hosts that contain advertisements, spyware, 145 | web trackers and other unpleasant, annoying or malicious content. 146 | 147 | This script converts this file into a format that can be loaded into the Unbound 148 | DNS server, allowing this list to be consumed by an entire network, or by 149 | devices (such as smart phones and tablets) which don't support a local hosts 150 | file. 151 | 152 | =head1 USAGE 153 | 154 | unbound-block-hosts supports the following arguments: 155 | 156 | =over 157 | 158 | =item C<--address=ADDRESS> 159 | 160 | The IP address to resolve to. This is C<127.0.0.1> by default. 161 | 162 | =item C<--v6address=ADDRESS> 163 | 164 | The IPv6 address to resolve to. This is C<::1> by default. 165 | 166 | =item C<--url=URL> 167 | 168 | The URL to retrieve. This is L by default. 169 | 170 | =item C<--file=FILE> 171 | 172 | The file to write. This is C by default. 173 | 174 | =item C<--SECTION> 175 | 176 | The source file contains a number of sections, which can be enabled or disabled 177 | as required. By default, all sections are enabled except for C and 178 | C. 179 | 180 | =back 181 | 182 | This script will compare the modification time of the local file to that on the 183 | remote server, and won't request the file if it hasn't been updated. 184 | 185 | =head1 INTEGRATING INTO UNBOUND 186 | 187 | To use the output of this file with Unbound, use the C directive within 188 | the C block, like so: 189 | 190 | server: 191 | access-control: 0.0.0.0/8 allow 192 | include: /var/unbound/local-blocking-data.conf 193 | 194 | =head1 COPYRIGHT 195 | 196 | Copyright 2015 Gavin Brown 197 | 198 | This program is Free Software, you can use it and/or modify it under the same 199 | terms as Perl itself. 200 | 201 | =head1 SEE ALSO 202 | 203 | =over 204 | 205 | =item L 206 | 207 | =item L 208 | 209 | =back 210 | 211 | =cut 212 | --------------------------------------------------------------------------------