LTM DNS Blackhole
Problem this snippet solves:
DNS Black Hole from LTM with DNS Services
Code :
Author: Hugh O'Donnell, F5 Consulting when RULE_INIT { Set IPV4 address that is returned for Blackhole matches for A records set static::blackhole_reply_IPV4 "10.10.20.50" Set IPV6 address that is returned for Blackhole matches for AAAA records set static::blackhole_reply_IPV6 "2001:19b8:101:2::f5f5:1d" Set TTL used for all Blackhole replies set static::blackhole_ttl "300" when DNS_REQUEST { #debugging statement see all questions and request details # log -noname local0. "Client: [IP::client_addr] Question:[DNS::question name] Type:[DNS::question type] Class:[DNS::question class] Origin:[DNS::origin]" # Blackhole_Match is used to track when a Query matches the blackhole list # Ensure it is always set to 0 or false at beginning of the DNS request set Blackhole_Match 0 # Blackhole_Type is used to track why this FQDN was added to the Blackhole_Class set Blackhole_Type "" # When the FQDN from the DNS Query is checked against the Blackhole class, the FQDN must start with a # period. This ensures we match a FQDN and all names to the left of it. This prevents against # malware that dynamically prepends characters to the domain name in order to bypass exact matches if {!([DNS::question name] == ".")} { set fqdn_name .[DNS::question name] } if { [class match $fqdn_name ends_with Blackhole_Class] } { # Client made a DNS request for a Blackhole site. set Blackhole_Match 1 set Blackhole_Type [class match -value $fqdn_name ends_with Blackhole_Class ] # Prevent processing by GTM, DNS Express, BIND and GTM Listener's pool. # Want to ensure we don't request a prohibited site and allow their server to identify or track the GTM source IP. DNS::return } } when DNS_RESPONSE { # debugging statement to see all questions and request details # log -noname local0. "Request: $fqdn_name Answer: [DNS::answer] Origin:[DNS::origin] Status: [DNS::header rcode] Flags: RD [DNS::header rd] RA [DNS::header ra]" if { $Blackhole_Match } { # This DNS request was for a Blackhole FQDN. Take different actions based on the request type. switch [DNS::question type] { "A" { # Clear out any DNS responses and insert the custom response. RA header = recursive answer DNS::answer clear DNS::answer insert "[DNS::question name]. $static::blackhole_ttl [DNS::question class] [DNS::question type] $static::blackhole_reply_IPV4" DNS::header ra "1" # log example: Apr 3 14:54:23 local/tmm info tmm[4694]: # Blackhole: 10.1.1.148#4902 requested foo.com query type: A class IN A-response: 10.1.1.60 log -noname local0. "Blackhole: [IP::client_addr]#[UDP::client_port] requested [DNS::question name] query type: [DNS::question type] class [DNS::question class] A-response: $static::blackhole_reply_IPV4 BH type: $Blackhole_Type" } "AAAA" { # Clear out any DNS responses and insert the custom response. RA header = recursive answer DNS::answer clear DNS::answer insert "[DNS::question name]. $static::blackhole_ttl [DNS::question class] [DNS::question type] $static::blackhole_reply_IPV6" DNS::header ra "1" # log example: Apr 3 14:54:23 local/tmm info tmm[4694]: # Blackhole: 10.1.1.148#4902 requested foo.com query type: A class IN AAAA-response: 2001:19b8:101:2::f5f5:1d log -noname local0. "Blackhole: [IP::client_addr]#[UDP::client_port] requested [DNS::question name] query type: [DNS::question type] class [DNS::question class] AAAA-response: $static::blackhole_reply_IPV6 BH type: $Blackhole_Type" } default { # For other record types, e.g. MX, NS, TXT, etc, provide a blank NOERROR response DNS::last_act reject # log example: Apr 3 14:54:23 local/tmm info tmm[4694]: # Blackhole: 10.1.1.148#4902 requested foo.com query type: A class IN unable to respond log -noname local0. "Blackhole: [IP::client_addr]#[UDP::client_port] requested [DNS::question name] query type: [DNS::question type] class [DNS::question class] unable to respond BH type: $Blackhole_Type" } } } } ######----RESPONSE PAGE IRULE---------- # Author: Hugh O.Donnell, F5 Consulting when HTTP_REQUEST { # the static HTML pages include the logo that is referenced in HTML as corp-logo.gif # intercept requests for this and reply with the image that is stored in an iFile defined in RULE_INIT below if {[HTTP::uri] ends_with "/_maintenance-page/corp-logo.png" } { # Present HTTP::respond 200 content $static::corp_logo } else { # Request for Blackhole webpage. Identify what type of block was in place switch -glob [class match -value ".]HTTP::host[" ends_with Blackhole_Class ] { "virus" { set block_reason "Virus site" } "phishing" { set block_reason "Phishing site" } "generic" { set block_reason "Unacceptable Usage" } default { set block_reason "Denied Per Policy - Other Sites" } } # Log details about the blackhole request to the remote syslog server log -noname local0. "Blackhole: From [IP::client_addr]:[TCP::client_port] \ to [IP::local_addr]:[TCP::local_port], [HTTP::request_num], \ [HTTP::method],[HTTP::uri],[HTTP::version], [HTTP::host], [HTTP::header value Referer], \ [HTTP::header User-Agent], [HTTP::header names],[HTTP::cookie names], BH category: $block_reason," # Send an HTML page to the user. The page is defined in the RULE_INIT event below HTTP::respond 200 content "$static::block_page [HTTP::host][HTTP::uri] $static::after_url $block_reason $static::after_block_reason " } } when RULE_INIT { # load the logo that was stored as an iFile set static::corp_logo [ifile get "/Common/f5ball"] # Beginning of the block page set static::block_page "Web Access Denied - Enterprise Network Operations Center " }
Your request was denied because it is blacklisted in DNS. Blacklist category: " set static::after_block_reason " Access has been denied. URL: " set static::after_url "
The Internet Gateways are for official use only. Misuse violates policy. If you believe that this site is categorized incorrectly, and that you have a valid business reason for access to this site please contact your manager for approval and the Enterprise Network Operations Center via E-mail: enoc@example.com Please use the Web Access Request Form and include a business justification. Only e-mail that originates from valid internal e-mail addresses will be processed. If you do not have a valid e-mail address, your manager will need to submit a request on your behalf.
Generated by bigip1.f5.com.