Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl -Tw
- # build_iptables.pl domain_list [ domain_list... ]
- #
- # Create a firewall ruleset in iptables-restore format to create a layer 4 DNS
- # proxy using NAT that filters domains from given lists.
- # In this example:
- # - 123.123.123.158 is the proxy address.
- # - 123.123.123.{152,154,156} are the real DNS resolvers.
- # Copyright (c) 2009 Terry Burton
- #
- # http://www.terryburton.co.uk
- #
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
- # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
- # THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
- # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- # DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- # CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- # IN THE SOFTWARE.
- use strict;
- die "Usage: $0 domain_list [ domain_list... ]" unless $#ARGV>=0;
- my @doms=();
- foreach my $filename (@ARGV) {
- open(FILE,"<$filename") or die("Unable to open file");
- @_=<FILE>;
- close(FILE);
- map {chomp} @_;
- push @doms,@_;
- }
- print <<'EOF';
- *mangle
- :PREROUTING ACCEPT [0:0]
- -A PREROUTING -d 123.123.123.158 -p udp -m udp --dport 53 -m statistic --mode nth --every 3 --packet 0 -m state --state new -j CONNMARK --set-mark 1
- -A PREROUTING -d 123.123.123.158 -p udp -m udp --dport 53 -m statistic --mode nth --every 3 --packet 1 -m state --state new -j CONNMARK --set-mark 2
- -A PREROUTING -d 123.123.123.158 -p udp -m udp --dport 53 -m statistic --mode nth --every 3 --packet 2 -m state --state new -j CONNMARK --set-mark 3
- -A PREROUTING -d 123.123.123.158 -p tcp -m tcp --dport 53 -m statistic --mode random --probability 0.333333 -m state --state new -j CONNMARK --set-mark 1
- -A PREROUTING -d 123.123.123.158 -p tcp -m tcp --dport 53 -m statistic --mode random --probability 0.5 -m state --state new -j CONNMARK --set-mark 2
- -A PREROUTING -d 123.123.123.158 -p tcp -m tcp --dport 53 -m state --state new -j CONNMARK --set-mark 3
- COMMIT
- *nat
- :PREROUTING ACCEPT [0:0]
- :POSTROUTING ACCEPT [0:0]
- -A PREROUTING -m connmark --mark 1 -j DNAT --to-destination 123.123.123.152
- -A PREROUTING -m connmark --mark 2 -j DNAT --to-destination 123.123.123.154
- -A PREROUTING -m connmark --mark 3 -j DNAT --to-destination 123.123.123.156
- -A POSTROUTING -m connmark --mark 1 -j SNAT --to-destination 123.123.123.158
- -A POSTROUTING -m connmark --mark 2 -j SNAT --to-destination 123.123.123.158
- -A POSTROUTING -m connmark --mark 3 -j SNAT --to-destination 123.123.123.158
- COMMIT
- *filter
- :LOGDROP - [0:0]
- -A LOGDROP -m limit --limit 1/second --limit-burst 100 -j LOG
- -A LOGDROP -j DROP
- :DNSCHECK - [0:0]
- :FORWARD ACCEPT [0:0]
- -A FORWARD -s 123.123.0.0/16 -p udp --dport 53 -m u32 --u32 "0>>22&0x3C@8>>15&0x01=0" -j DNSCHECK
- -A FORWARD -s 123.123.0.0/16 -p udp --dport 53 -j ACCEPT
- -A FORWARD -s 123.123.0.0/16 -p tcp --dport 53 -j ACCEPT
- -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
- -A FORWARD -j LOGDROP
- EOF
- my $last_prefix='';
- foreach my $dom (sort @doms) {
- (my $prefix,my $suffix)=$dom=~/^(..)(.*)$/;
- if ($prefix ne $last_prefix) {
- $last_prefix=$prefix;
- print ":DNSCHECK$prefix - [0:0]\n";
- if ($prefix=~/^.\./) {
- my $hex=sprintf("01%02lx", ord substr($prefix,0,1));
- print "-A DNSCHECK -m u32 --u32 \"0>>22&0x3C\@18&0xffff=0x$hex\" -j DNSCHECK$prefix\n";
- } else {
- (my $hex=$prefix)=~s/(.)/sprintf("%02lx", ord $1)/eg;
- print "-A DNSCHECK -m u32 --u32 \"0>>22&0x3C\@19&0xffff=0x$hex\" -j DNSCHECK$prefix\n";
- }
- }
- my $enc=''; my $offset=40;
- foreach (split /\./, $dom) {
- $enc.='|'.(sprintf '%02x', length)."|$_";
- $offset+=(length $_)+1;
- }
- print "-A DNSCHECK$prefix -m string --from 40 --to $offset --hex-string \"$enc|00|\" --algo bm -j LOGDROP\n";
- }
- print <<'EOF'
- COMMIT
- EOF
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement