BIG-IP DNS
21 TopicsExport GTM/DNS Virtual Servers Configuration in CSV - tmsh cli script
Problem this snippet solves: This is a simple cli script used to collect all the virtual-servers name, its destination created in a server or ltm server. A sample output would be like below, How to use this snippet: This is similar to my other share - https://devcentral.f5.com/s/articles/Export-GTM-DNS-Configuration-in-CSV-tmsh-cli-script Login to the GTM/DNS, create your script by running the below commands and paste the code provided in snippet, tmsh create cli script gtm-vs Delete the proc blocks, so it looks something like below, create script gtm-vs { ## PASTE THE CODE HERE ## } and paste the code provided in the snippet. Note: When you paste it, the indentation may be realigned, it shouldn't cause any errors, but the list output would show improperly aligned. Feel free to delete the tab spaces in the code snippet & paste it while creating, so indentation is aligned properly. And you can run the script like below, tmsh run cli script gtm-vs > /var/tmp/gtm-vs-output.csv And get the output from the saved file, open it on excel. Format it & use it for audit & reporting. cat /var/tmp/gtm-vs-output.csv Feel free to add more elements as per your requirements. Code : proc script::run {} { puts "Server,Virtual-Server,Destination" foreach { obj } [tmsh::get_config gtm server] { set server [tmsh::get_name $obj] foreach { vss } [tmsh::get_config gtm server $server virtual-servers] { set vs_set [tmsh::get_field_value $vss virtual-servers] foreach vs $vs_set { set vs_name [tmsh::get_name $vs] puts $server,$vs_name,[tmsh::get_field_value $vs destination] } } } } Tested this on version: 13.11.5KViews3likes2CommentsDNS Tunnel Mitigation v2
Problem this snippet solves: (Solution from Pedro Haoa) Due to some people attempt DNS tunneling to pass data frames inside of DNS records to the Internet and the lack of information around here, I'm going to share with you some basic code for DNS Tunnel Mitigation on the BIG-IPs. This irule put some overhead in your CPU so check it with caution. The idea is to improve this code (I'm looking for less overhead) here in DevCentral and try to build a better base solution for the most common techniques. You can use the DNS Protocol Security, DNS Anti-DDoS and IP Intelligence features to get the most comprehensive solution. Remember that there are a lot of DNS Tunneling utilities with a wide range of capabilities and options, so this is one of many forms to mitigate some of the attacks. How to use this snippet: LTM + AFM + DNS Services BIG-IP AFM (Protocol Security) In Security ›› Protocol Security : Security Profiles : DNS ›› Create a New Security Profile and exclude obsolete record types like MD, MF, MAILA, NULL, HINFO, SPF, etc. Then apply to your DNS profile associated with your Listener. BIG-IP DNS (LTM Data Groups and iRule) Creating DNS Tunnel Query type Data Group BIG-IP AFM (Protocol Security) In Security ›› Protocol Security : Security Profiles : DNS ›› Create a New Security Profile and exclude obsolete record types like MD, MF, MAILA, NULL, HINFO, SPF, etc. Then apply to your DNS profile associated with your Listener. BIG-IP DNS (LTM Data Groups and iRule) Creating DNS Tunnel Query type Data Group create ltm data-group internal TunnelType records replace-all-with { CNAME { } } type string modify ltm data-group internal TunnelType records add { TXT { } } modify ltm data-group internal TunnelType records add { SRV { } } modify ltm data-group internal TunnelType records add { KEY { } } Creating Whitelist Data Group create ltm data-group internal Dominios_Lista_Blanca records replace-all-with { facebook.com { data facebook.com } } type string modify ltm data-group internal Dominios_Lista_Blanca records add { instagram.com { data instagram.com } } modify ltm data-group internal Dominios_Lista_Blanca records add { fbcdn.net { data fbcdn.net } } modify ltm data-group internal Dominios_Lista_Blanca records add { google.com { data google.com } } modify ltm data-group internal Dominios_Lista_Blanca records add { googleapis.com { data googleapis.com } } Creating Blacklist Data Group create ltm data-group internal Dominios_Lista_Negra records replace-all-with { dnstunnel.de { data dnstunnel.de } } type string modify ltm data-group internal Dominios_Lista_Negra records add { cutheatergroup.cn { data cutheatergroup.cn } } modify ltm data-group internal Dominios_Lista_Negra records add { demodomain.cz { data demodomain.cz } } modify ltm data-group internal Dominios_Lista_Negra records add { buo.cc { data buo.cc } } modify ltm data-group internal Dominios_Lista_Negra records add { pdk.lcn.cc { data pdk.lcn.cc } } Code : when RULE_INIT { # Max DNS queries during detection period per source IP / destination domain set static::maxq 180 # Detection & Blocking Period set static::btime 60 } when DNS_REQUEST { set srcip [IP::remote_addr] set qtype [DNS::question type] set DomOrigen [domain [DNS::question name] 4] set key "$srcip:$DomOrigen" if { ([class match $qtype equals TunnelType]) and [DNS::len] > 512 } { if {[class match $DomOrigen ends_with Dominios_Lista_Blanca] }{ return } elseif {[class match $DomOrigen ends_with Dominios_Lista_Negra] }{ DNS::drop return } elseif {[table lookup $key] ne ""} { set count [table incr $key] if {$count > $static::maxq} { DNS::drop return } } else { table add $key 1 indef $static::btime } } } Tested this on version: No Version Found2.4KViews2likes6CommentsExport GTM/DNS Configuration in CSV - tmsh cli script
Problem this snippet solves: This is a simple cli script used to collect all the WideIP, LB Method, Status, State, Pool Name, Pool LB, Pool Members, Pool Fall back, Last Resort pool info in CSV format. A sample output would be like below, One can customize the code to extract other fields available too. Check out my other codeshare of LTM report. Note: The codeshare may get multiple version, use the latest version alone. The reason to keep the other versions is for end users to understand & compare, thus helping them to modify to their own requirements. Hope it helps. How to use this snippet: Login to the GTM/DNS, create your script by running the below commands and paste the code provided in snippet, tmsh create cli script gtm-config-parser Delete the proc blocks, so it looks something like below, create script gtm-config-parser { ## PASTE THE CODE HERE ## } and paste the code provided in the snippet. Note: When you paste it, the indentation may be realigned, it shouldn't cause any errors, but the list output would show improperly aligned. Feel free to delete the tab spaces in the code snippet & paste it while creating, so indentation is aligned properly. And you can run the script like below, tmsh run cli script gtm-config-parser > /var/tmp/gtm-config-parser-output.csv And get the output from the saved file, open it on excel. Format it & use it for audit & reporting. cat /var/tmp/gtm-config-parser-output.csv Feel free to add more elements as per your requirements. For version 13.x & higher, there requires a small change in the code. Refer the comments section. Thanks to @azblaster Code : proc script::run {} { puts "WIP,LB-MODE,WIP-STATUS,WIP-STATE,POOL-NAME,POOL-LB,POOL-MEMBERS,POOL-FB,LASTRESORT-POOL" foreach { obj } [tmsh::get_config gtm wideip all-properties] { set wipname [tmsh::get_name $obj] set wippools [tmsh::get_field_value $obj pools] set lbmode [tmsh::get_field_value $obj "pool-lb-mode"] set lastresort [tmsh::get_field_value $obj "last-resort-pool"] foreach { status } [tmsh::get_status gtm wideip $wipname] { set wipstatus [tmsh::get_field_value $status "status.availability-state"] set wipstate [tmsh::get_field_value $status "status.enabled-state"] } foreach wippool $wippools { set pool_name [tmsh::get_name $wippool] set pool_configs [tmsh::get_config /gtm pool $pool_name all-properties] foreach pool_config $pool_configs { set pool_lb [tmsh::get_field_value $pool_config "load-balancing-mode"] set pool_fb [tmsh::get_field_value $pool_config "fallback-mode"] if { [catch { set member_name [tmsh::get_field_value $pool_config "members" ]} err] } { set pool_member $err } else { set pool_member "" set member_name [tmsh::get_field_value $pool_config "members"] foreach member $member_name { append pool_member "[lindex $member 1] " } } puts "$wipname,$lbmode,$wipstatus,$wipstate,$pool_name,$pool_lb,$pool_member,$pool_fb,$lastresort" } } } } Tested this on version: 11.63.7KViews2likes6CommentsGTM return LDNS IP to client
Problem this snippet solves: We do a lot of our load balancing based on topology rules, so it's often very useful to know where the DNS request is actually coming from rather than just the client's IP and the DNS servers they have configured. Especially if they're behind an ADSL router doing NAT or some other similar set up. This rule simply returns the IP address of the LDNS that eventually made the query to the GTM device in the response to a lookup for the WideIP using the rule, as well as logging the response and perceived location. Code : rule "DNS_debug" partition "Common" { when DNS_REQUEST { host [IP::client_addr] log local0.err "Debug address : [IP::client_addr] [whereis [IP::client_addr]]" } }868Views1like2CommentsImplementing Client Subnet DNS Requests
Problem this snippet solves: Update 2018-10-23: As of BIG-IP DNS 14.0 there is now a checkbox feature for edns-client-subnet. Please see: Using Client Subnet in DNS Requests. The following is still useful if you want to customize your responses. Original post: Using an iRule and edns-client-subnet (ECS) we can improve the accuracy of F5 GTM’s topology load balancing. DevCentral Article: Implementing Client Subnet DNS Requests How to use this snippet: There are two different iRules. One is an LTM iRule and the second is a GTM iRule. These should be deployed separately. Code : # # LTM iRule # # comply with draft to respond with ECS when DNS_REQUEST { if { [DNS::edns0 exists] &! [catch { DNS::edns0 subnet address }] } { set ecs_address [DNS::edns0 subnet address] set ecs_source [DNS::edns0 subnet source] set ecs_scope [DNS::edns0 subnet scope] log local0. "Received EDNS request from [IP::client_addr]:$ecs_address/$ecs_source/$ecs_scope" } } when DNS_RESPONSE { if { [info exists ecs_address] } { DNS::edns0 subnet address $ecs_address DNS::edns0 subnet source $ecs_source #DNS::edns0 subnet scope $ecs_scope # hardcode the desired scope to be /24, not sure this is OK DNS::edns0 subnet scope 24 } } # # GTM iRule # when DNS_REQUEST { set ldns [IP::client_addr] log local0. "LDNS LOC: $ldns [whereis $ldns]" if { [DNS::edns0 exists] &! [catch { DNS::edns0 subnet address }] } { set gtm_ecs_address [DNS::edns0 subnet address] set gtm_ecs_source [DNS::edns0 subnet source] set gtm_ecs_scope [DNS::edns0 subnet scope] set ldns $gtm_ecs_address log local0. "ECS LOC: $gtm_ecs_address [whereis $ldns]" } set loc [whereis $ldns] if { $loc contains "NA" } { log local0. "NA" } elseif { $loc contains "AS" } { log local0. "Asia" } elseif { $loc contains "EU" } { log local0. "Europe" } else { log local0. "All other" } } Tested this on version: 11.62.6KViews1like16CommentsGTM Monitors internal LTM, but I need Public IP as Answer
Problem this snippet solves: A WideIP is linked to an LTM Virtual Server that uses Internal IP Addresses. the DNS should reply with External IP addresses. although its possible via gui, its quiet tricky to get the monitors and the translation right. for your convenience , here is an Irule that does just that. How to use this snippet: cut and past this code into a new Irule under DNS->Delivery->Irules->Irule List and then add it to the DNS Listener.this Irule fixes 2 A records. a.a.a.a = internal ip address#1 aaa.aaa.com. = the A record#1 b.b.b.b = external ip address#1 c.c.c.c = internal ip address#2 ccc.ccc.com. = the A record#2 d.d.d.d = external ip address#2 Code : when DNS_RESPONSE { set rrs [DNS::answer] foreach rr $rrs { if { ([DNS::rdata $rr] eq "a.a.a.a")} { DNS::answer clear DNS::answer insert [DNS::rr "aaa.aaa.com. IN A b.b.b.b"] } elseif { ([DNS::rdata $rr] eq "c.c.c.c")} { DNS::answer clear DNS::answer insert [DNS::rr "ccc.ccc.com. IN A d.d.d.d"] } } }802Views1like5Comments