Block requests by reverse DNS record
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
}
}Published Mar 16, 2015
Version 1.0hoolio
Cirrostratus
VP of Solutions at WorldTech IThoolio
Cirrostratus
VP of Solutions at WorldTech IT3 Comments
- John_Beckmann
Employee
The bug ( BZ 340659 ) https://support.f5.com/kb/en-us/solutions/public/12000/300/sol12378.html was resolved in 10.2.2, so I am sharing an updated iRule to do this in 11.x ========================================================================== 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" } } } } ========================================================================== - Heinrichm5
Altocumulus
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" } } } } - THE_BLUE
Cirrostratus
so does this will help me to check PTR as anti spam does?
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)