DNSBL - Look up IPs in DNS blacklists

When a user connects to your bouncer it can automatically check his/her IP against several customizable databases of open proxies and similar.

The sourcecode below is barely tested, so it is not recommended to enable the suspension of positive reports until you have been using it successfully for a while.

  • For settings see /sbnc set.
  • Usage: /dnsbl [user|ip|host]
  • Made for sBNC 1.2-1082 (a bug in misc.tcl's dnslookup proc made it fail due to a bad regexp fixed in revision 1082).
  • Still contain a lot of redundant code and silly workarounds. This development version was simply “made to work”.
  • Credit for the data goes to the respective DNSBL providers used.

Source

#
# @name       dnsbl - Look up IPs in DNS blacklists
# @version    Build 1 (????-??-??)
# @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
# @author     David Lorentsen <zyberdog@quakenet.org>
# @www        http://wiki.zyberdog.dk/sbnc:dnsbl
#
 
if {[namespace exists ::dnsbl]} {
    namespace delete ::dnsbl
}
 
namespace eval ::dnsbl {
 
    # Configuration
    variable servers
    array set servers {
        problems.dnsbl.sorbs.net {127.0.0.2 127.0.0.3 127.0.0.4}
        ircbl.ahbl.org {}
        tor.dnsbl.sectoor.de {127.0.0.1}
    }
 
    variable default
    array set default {
        auto 0
        report 1
        suspend 0
        warning "You appear to be connecting from an untrustworthy IP (\$ip). If this is a mistake please contact us in #channel"
        reason "Suspected of using an open proxy. \$ip was found positive by \$site"
    }
 
    # End of Configuration
 
    # Binds
    internalbind attach [namespace current]::attach
    internalbind command [namespace current]::commands
 
    # Procedures
    proc attach {client} {
        if {[getconf "dnsbl.auto"] && ![getbncuser $client "admin"]} {
            checktarget [getbncuser $client "client"] $client
        }
    }
 
    proc commands {client params} {
        if {![getbncuser $client "admin"]} { return }
        set command [string tolower [lindex $params 0]]
 
        switch $command {
            "help" {
                bncaddcommand dnsbl admin "check connecting users against lists of open proxys and similar" "Check connecting users against lists of open proxys."
            }
 
            "set" {
                if {[llength $params] < 3} {
                    set replyset [list]
 
                    set cur1 [getconf "dnsbl.auto"]
                    switch $cur1 {
                        0 { lappend replyset "dnsbl.auto - 0 (no)" }
                        1 { lappend replyset "dnsbl.auto - 1 (users are checked when connecting)" }
                    }
 
                    set cur2 [getconf "dnsbl.report"]
                    switch $cur2 {
                        0 { lappend replyset "dnsbl.report - 0 (no)" }
                        1 { lappend replyset "dnsbl.report - 1 (hits are reported to mainlog)" }
                    }
 
                    set cur4 [getconf "dnsbl.suspend"]
                    switch $cur4 {
                        0 { lappend replyset "dnsbl.suspend - 0 (no)" }
                        1 { lappend replyset "dnsbl.suspend - 1 (users are suspended when reported positive)" }
                    }
 
                    set cur5 [getconf "dnsbl.warning"]
                    lappend replyset "dnsbl.warning - $cur5"
 
                    set cur6 [getconf "dnsbl.reason"]
                    lappend replyset "dnsbl.reason - $cur6"
 
                    internaltimer 0 0 [namespace current]::replyset [list $client $replyset]
 
                } else {
                    set t [string tolower [lindex $params 1]]
                    set v [lindex $params 2]
 
                    switch $t {
                        "dnsbl.auto" { 
                            if {($v eq "0") || ($v eq "1")} {
                                bncsetglobaltag $t $v
                                bncreply "Done."
                            } else {
                                bncreply "Error: Invalid value - must be 0 or 1"
                            }
                            haltoutput
                        }
                        "dnsbl.report" {
                            if {($v eq "0") || ($v eq "1")} {
                                bncsetglobaltag $t $v
                                bncreply "Done."
                            } else {
                                bncreply "Error: Invalid value - must be 0 or 1"
                            }
                            haltoutput
                        }
                        "dnsbl.suspend" {
                            if {($v eq "0") || ($v eq "1")} {
                                bncsetglobaltag $t $v
                                bncreply "Done."
                            } else {
                                bncreply "Error: Invalid value - must be 0 or 1"
                            }
                            haltoutput
                        }
                        "dnsbl.warning" {
                            bncsetglobaltag $t [join [lrange $params 2 end]]
                            bncreply "Done."
                            haltoutput
                        }
                        "dnsbl.reason" {
                            bncsetglobaltag $t [join [lrange $params 2 end]]
                            bncreply "Done."
                            haltoutput
                        }
                    }
 
                }
            }
            "dnsbl" {
                if {[llength $params] > 1} {
                    set t [lindex $params 1]
                    if {[lsearch [bncuserlist] $t] eq "-1"} {
                        bncreply "Checking $t - You will only recieve a reply for positive hits."
                        checktarget $t -none
                    } elseif {[getbncuser $t "hasclient"]} {
                        bncreply "Checking $t - You will only recieve a reply for positive hits."
                        checktarget [getbncuser $t "client"] $t
                    } else {
                        bncreply "$t does not have a client connected to check."
                    }
                } else {
                    bncreply "Checking all currently connected users. Only positive hits are reacted to. Might take a while."
                    foreach user [bncuserlist] {
                        if {![getbncuser $user "admin"] && [getbncuser $user "hasclient"]} {
                            set host [getbncuser $user "client"]
                            if {[regexp {\d+\.\d+\.\d+\.\d+} $host]} {
                                set rip [reverse $host]
                                variable servers
 
                                foreach server [array names servers] {
                                    checkip $server $rip $user
                                }
                            } else {
                                dnslookup $host [namespace current]::checkhost $user
                            }
                        }
                    }
                }
 
                haltoutput
            }
        }
    }
 
    proc convert {ip host} {
        set provider [join [lrange [split $host "."] 4 end] "."]
        if {$provider eq "problems.dnsbl.sorbs.net"} {
            switch $ip {
                "127.0.0.2" { return "Open HTTP proxy" }
                "127.0.0.3" { return "Open SOCKS proxy" }
                "127.0.0.4" { return "Open proxy" }
                "127.0.0.5" { return "Open SMTP relay" }
                "127.0.0.7" { return "Abusable vulnerabilities" }
                "127.0.0.9" { return "Zombie" }
                default { return "Other ($ip)" }
            }
        } elseif {$provider eq "ircbl.ahbl.org"} {
            switch $ip {
                "127.0.0.2" { return "Open SMTP relay" }
                "127.0.0.3" { return "Open proxy" }
                "127.0.0.4" { return "Spam source" }
                "127.0.0.10" { return "Shoot on sight" }
                default { return "Other ($ip)" }
            }
        } elseif {$provider eq "tor.dnsbl.sectoor.de"} {
            switch $ip {
                "127.0.0.1" { return "Tor exit node" }
                default { return "Other ($ip)" }
            }
        }
    }
 
    proc getconf {setting} {
        variable default
 
        set c [bncgetglobaltag $setting]
        if {$c eq ""} { set c $default([lindex [split $setting "."] 1]) }
 
        return $c
    }
 
    proc replyset {params} {
        setctx [lindex $params 0]
        foreach r [lindex $params 1] {
            bncreply $r
        }
    }
 
    proc checktarget {host user} {
        if {[regexp {\d+\.\d+\.\d+\.\d+} $host]} {
            set rip [reverse $host]
            variable servers
 
            foreach server [array names servers] {
                checkip $server $rip $user
            }
        } else {
            dnslookup $host [namespace current]::checkhost $user
        }       
    }
 
    proc checkip {server rip user} {
        dnslookup $rip.$server [namespace current]::callback $user
    }
 
    proc checkhost {ip host status user} {
        if {[string equal $status 1]} {
            variable servers
 
            set rip [reverse $ip]
 
            foreach server [array names servers] {
                checkip $server $rip $user
            }
        }
 
    }
 
    proc reverse {ip} {
        set sip [split $ip "."]
        set rev {}
        foreach d $sip {
            set rev [linsert $rev -1 $d]
        }
        return [join $rev "."]
    }
 
    proc callback {cip host status user} {
        variable servers
        if {$status eq "1"} {
            set ip [reverse [join [lrange [split $host "."] 0 3] "."]]
            set site [join [lrange [split $host "."] 4 end] "."]
            if {$user eq "-none"} {
                putlog "\[DNSBL\] $ip is detected as: [convert $cip $host] on $site"
            } elseif {[getconf "dnsbl.report"] eq "1"} {
                if {[getconf "dnsbl.suspend"] eq "1"} {
                    set reason [getconf "dnsbl.reason"]
                    set warning [getconf "dnsbl.warning"]
                    setbncuser $user suspendreason [subst $reason]
                    setbncuser $user lock 1     
                    set curctx [getctx]
                    setctx $user
                    bncreply [subst $warning]
                    bnckill [subst $reason]
                    setctx $curctx            
                    putmainlog "\[DNSBL\] User $user from $ip is detected as: [convert $cip $host] on $site - SUSPENDED!"
                } else {
                    putmainlog "\[DNSBL\] User $user from $ip is detected as: [convert $cip $host] on $site"
                }
            }
        }
    }
}
sbnc/dnsbl.txt · Last modified: 2008/01/12 18:15 by zyberdog