1 #!/usr/bin/ruby
   2 # license note
   3 # Copyright (c) 2017, Eliezer Croitoru
   4 # All rights reserved.
   5 #
   6 # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
   7 #
   8 # 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
   9 #
  10 # 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  11 #
  12 # 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
  13 #
  14 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
  15 
  16 require "open-uri"
  17 require "syslog"
  18 require 'resolv'
  19 require 'timeout'
  20 
  21 Signal.trap("TERM") do
  22   STDERR.puts "Terminating..."
  23   Syslog.close
  24   exit 1
  25 end
  26 
  27 #squid external_acl format:
  28 # %URI %METHOD %SRC %PORT %MYPORT
  29 #0 http://askubuntu.com/ 192.168.10.131/- - GET myip=192.168.10.1 myport=3128
  30 #example settings:
  31 #external_acl_type filtering_helper ttl=2 children-startup=2 children-max=10 %URI %METHOD %SRC %PORT %MYPORT /opt/external_acl/run1.rb
  32 #acl filtering_helper_acl external filtering_helper
  33 #http_access allow localnet filtering_helper_acl
  34 
  35 $debug = false
  36 $stderrdebug = false
  37 $dns_db = Resolv::DNS.new(:nameserver_port => [["127.0.0.1", 5300]])
  38 Syslog.open('dnsbl_client.rb', Syslog::LOG_PID)
  39 
  40 def debug(str)
  41   STDERR.print("ERR_filtering_debug: #{str}".inspect + "\n") if $stderrdebug
  42   Syslog.log(Syslog::LOG_ERR, "%s", "ERR_filtering_debug: #{str}")
  43 end
  44 
  45 debug("Started helper")
  46 
  47 STDOUT.sync = true
  48 
  49 def process(line)
  50   answer = "ERR"
  51   rewritten = false
  52   if line.size < 2
  53     debug "line empty or malformed"
  54     puts "ERR line is corrupted"
  55     exit 1
  56     return
  57   end
  58 #0 http://askubuntu.com/ 192.168.10.131/- - GET myip=192.168.10.1 myport=3128
  59   id, url, src, fqdn, method, src, squidport, others = line.split
  60   case url
  61     when /^([\w]+\:\/\/)([\w\d\.\-\_]+)/
  62       begin
  63         uri = URI(url)
  64       rescue URI::InvalidURIError => e
  65         debug("Rescued a wrong uri and resdcaped it!")
  66         uri = URI(URI.encode url)
  67         debug("URL string is: #{uri.to_s}")
  68       rescue => e
  69        debug("rescued URI parsing")
  70       end
  71     when /^([\w\d\.\-\_]+)\:([\d]{1,5})/
  72       uri = URI("CONNECT://#{$1}:#{$2}")
  73     else
  74     STDERR.puts "ELSE"
  75   end
  76   
  77   debug "CONNECT" if method == "CONNECT" if $debug
  78   debug "it's HTTP" if uri.scheme == "http" if $debug
  79   debug "it's HTTPS" if uri.scheme == "https" if $debug
  80   debug "it's FTP" if uri.scheme == "ftp" if $debug
  81   debug "parsed url #{uri.scheme}://#{uri.host}:#{uri.port}#{uri.path}?#{uri.query}" if $debug && method != "CONNECT"
  82   res = []
  83   host = uri.host
  84 
  85   begin
  86     dnsres = 0
  87         Timeout::timeout(3) do
  88           dnsres = $dns_db.getresources(host, Resolv::DNS::Resource::IN::A)
  89         end
  90         if dnsres != 0 && dnsres[0].address.to_s =~ /10\.0\.0\.1/
  91             #unknown
  92             debug("the domain is unknown") if $debug 
  93         elsif dnsres != 0 && dnsres[0].address.to_s =~ /127\.0\.0\.100/
  94             #blacklisted
  95             debug("the domain is blacklisted") if $debug
  96             res << "Blacklisted"
  97     else
  98             #unknown or error
  99             debug("unkown issue") if $debug
 100         end
 101   rescue Exception => e
 102     debug(e)
 103     debug(e.inspect)
 104     case e
 105     when Resolv::ResolvError
 106       debug(": \e[0;32mOK\e[0m\n")
 107     when Timeout::Error
 108       #puts ": \e[0;41mTIMEOUT\e[0m\n"
 109       debug("TIMEOUT DNS taking default action to allow")
 110     when Interrupt
 111       puts "\nCaught signal SIGINT. Exiting..."
 112       exit 1
 113     else
 114       debug("TIMEOUT\ELSE") if $debug
 115     end  
 116   end
 117   
 118   if res && res[0]
 119     answer = "OK url=http://www1.ngtech.co.il/cgi-bin/URLblocked.cgi?category=blocked status=302" 
 120     rewritten = true
 121   end
 122   puts "#{id} #{answer}"
 123 end
 124 
 125 while true
 126   begin
 127     line = gets
 128   rescue => e
 129     debug(e)
 130     debug(e.inspect)
 131   end
 132   if !line
 133     debug("Empty line, Exiting.")
 134     break
 135   end
 136   debug "{ line => \"#{line}\"} line_size => #{line.size}"
 137   if line =~ /^[Qq]/
 138     debug("quitting by user request")
 139     break
 140   end
 141   process(line)
 142 end

EliezerCroitoru/Dnsbl/client_helper (last edited 2017-10-06 01:39:40 by Eliezer Croitoru)