on 16-Mar-2015 15:42
Problem this snippet solves:
This iRule performs a reverse DNS lookup on the client IP address and blocks any which don't match a specific top level domain. This specific example sends an HTTP response. But you could also send a TCP reset using reject.
Note that due to a bug ( BZ 340659 ) with RESOLV::lookup's handling of PTR records, we use the older NAME::lookup command. See the RESOLV::lookup wiki page for details on the issue.
Code :
when CLIENT_ACCEPTED { # Trigger a name lookup for new connections set do_lookup 1 log local0. "[IP::client_addr]:[TCP::client_port]: New connection to [IP::local_addr]:[TCP::local_port]" } when HTTP_REQUEST { # Check if we haven't done a lookup already on this connection if { $do_lookup }{ log local0. "[IP::client_addr]:[TCP::client_port]: Collecting HTTP for new lookup" # Hold HTTP data until client IP address is resolved HTTP::collect # Start a name resolution on the client IP address NAME::lookup -ptr [IP::client_addr] } } when NAME_RESOLVED { # FQDN of client IP address set ptr [string tolower [NAME::response]] log local0. "[IP::client_addr]:[TCP::client_port]: Lookup result: $ptr" # Check if ptr record ends with .mil if { $ptr ends_with ".mil" } { # Release HTTP data for .mil addresses and track that we've done a lookup for this connection log local0. "[IP::client_addr]:[TCP::client_port]: Valid ptr, releasing HTTP" set do_lookup 0 HTTP::release } else { # PTR record does not end with ".mil", reject the connection log local0. "[IP::client_addr]:[TCP::client_port]: Invalid PTR, blocking HTTP request." HTTP::respond 403 content "Invalid PTR!\r\n" TCP::close } }
Thank you, John, this is exactly the snippet I needed to get the lookup to work
For anyone else needing this snippet I've formatted it as code
Not certain I've inserted all the new lines needed.
when RULE_INIT {
# Set debug to 0 for no logging
# Set debug to 1 to just log blocks
# Set debug to 2 to log blocks and valid requests
set static::debug 1
#Ensure this points to your Data Group
set static::domain_blacklist_dg "domain_block_blacklist"
#Set IP for your DNS Server
set static::my_dns 192.168.10.1
#Set name of VS if using a local Virtual Server
#set static::my_dns my_dns_vs
}
when CLIENT_ACCEPTED {
set do_lookup 1
set is_blocked 0
set full_domain ""
set base_domain ""
if { $static::debug > 1 } { log local0. "Connection Accepted from IP_Addr:[IP::remote_addr]" }
}
when HTTP_REQUEST {
if { $static::debug > 1 } {
log local0. "Processing Request from IP_Addr:[IP::remote_addr]"
log local0. "Do Lookup: $do_lookup Is Blocked: $is_blocked"
log local0. "My_DNS: $static::my_dns"
}
if { $do_lookup } {
# grab the client base domain reverse lookup of IP Address
set full_domain [RESOLV::lookup @$static::my_dns inet -ptr [IP::remote_addr]]
#grab the base domain (top level plus subdomain) from full_domain
set base_domain [join [lrange [split $full_domain .] end-1 end] .]
set do_lookup 0
}
if { $is_blocked } {
if { $static::debug > 0 } {
log local0. "IP_Addr:[IP::remote_addr] Reverse_Lookup:$base_domain blacklisted (Already Blocked)"
log local0. "Full Domain: $full_domain" } send a TCP reset reject
} else {
if { [class match $base_domain contains $static::domain_blacklist_dg] } {
if { $static::debug > 0 } {
log local0. "IP_Addr:[IP::remote_addr] Reverse_Lookup:$base_domain blacklisted (Blocked)"
log local0. "Full Domian: $full_domain"
}
set is_blocked 1
#send a TCP reset
reject
} else {
if { $static::debug > 1 } {
log local0. "IP_Addr:[IP::remote_addr] Reverse_Lookup:$base_domain $full_domain Accepted"
}
}
}
}