Use BIG-IP LTM Virtual Server & iRule for an internal "What's My IP" website

Code is community submitted, community supported, and recognized as ‘Use At Your Own Risk’.

Short Description

This article describes how to use an F5 BIG-IP LTM iRule attached to a virtual server as an internal "What's My IP" website.

Various online information, people, and ChatGPT helped get various aspects of this iRule working so a big thanks to all who helped!!

Problem solved by this Code Snippet

Allows end-users to go to an internal website fully hosted on an F5 BIG-IP LTM appliance to determine their device's internal IP address as well as how they are connected to the network.

How to use this Code Snippet

  1. This article assumes you have the knowledge to set up a basic F5 BIG-IP virtual server (http or https w/ client SSL profile), the correct DNS record(s) to access by fully qualified domain name, and allow the BIG-IP to query your DNS server(s).
  2. Configure BIG-IP DNS resolvers (reference: K12140128: Overview of the DNS resolver )
  3. On your BIG-IP LTM, configure the "DNS Resolvers" by going to Network > DNS Resolvers > Create
  4. Name > Internal_DNS_Resolvers (name can be changed)
  5. Leave all other settings at default and optionally uncheck the "Use IPv6" setting if applicable.
  6. Finished
  7. From the DNS Resolvers List, click Internal_DNS_Resolvers, then go to the Forward Zones tab.
  8. Click Add
  9. In the Name field enter a period .
  10. In the address field enter each internal DNS server, then click add until all DNS servers are in the Nameservers field.
  11. Finished
  12. Create iRule from code snippet below, and then apply the iRule to the virtual server.
  13. Additional 'elseif' statements can be added to accomodate more granular responses and CIDR blocks changed to reflect your specific networks.
  14. Change the wording in between the quotation marks to your liking for the 'set locate_me' & 'set vpn_server' variables.

Code Snippet Meta Information

  1. Version: BIG-IP 16.1
  2. Coding Language: F5 BIG-IP iRule with HTML for the response.
  3. This code has only been tested with IPv4 and not IPv6.

Full Code Snippet

 

 

 

 

#############################################################################
##                                                                         ##
## Proc to reverse the IP octets to build the ptr record format            ##
## Downwards compatibility to 8.4: https://wiki.tcl-lang.org/page/lreverse ##
##                                                                         ##
#############################################################################
proc lreverse list {
  set res {}
  set i [llength $list]
  while {$i} {
    lappend res [lindex $list [incr i -1]]
  }
  set res
}

  when CLIENT_ACCEPTED {
  set client_ip [IP::client_addr]
  # Format the ptr record so the RESOLVER::name_lookup will work properly for a ptr lookup
  set ptr [join [call lreverse [split $client_ip .]] .].in-addr.arpa
  set result [RESOLVER::name_lookup "/Common/Internal_DNS_Resolvers" $ptr ptr]
  set response_record "<div class=\"paragraph\">The internal DNS servers were unable to determine your device's hostname.<br>&nbsp;</div>" ;# Default message

  foreach record [RESOLVER::summarize $result] {
    set resolved_hostname [lindex $record 4]
    if {[string length $resolved_hostname] > 0} {
      # A fully qualified domain name is returned, set it as the response_record
      set response_record "<div class=\"paragraph\">Your hostname resolved to <strong>$resolved_hostname</strong> by the internal DNS servers.<br>&nbsp;</div>"
      break ;# Exit the loop as we have a valid response
    }
  }
    ####################################################################################################################
    ##                                                                                                                ##
    ## The if/elseif statements below are used to create the variable 'locate_me' and 'vpn_server'that is the used in ## 
    ## the HTTP_REQUEST portion of the iRule to display which method of connectivity is being used by the end user    ##
    ##                                                                                                                ##
    ####################################################################################################################
    if { [IP::addr [IP::client_addr] equals 10.1.1.0/24] } then {
        set locate_me "You are connected to VPN appliance"
        set vpn_server "vpn1" }
    elseif { [IP::addr [IP::client_addr] equals 10.2.2.0/24] } then {
        set locate_me "You are connected to VPN appliance"
        set vpn_server "vpn2" }
    elseif { [IP::addr [IP::client_addr] equals 10.3.3.0/24] } then {
        set locate_me "You are connected to the Wireless network,"
        set vpn_server "and not connected via VPN"}
    elseif { [IP::addr [IP::client_addr] equals 10.4.4.0/24] } then {
        set locate_me "You are connected to the wired network,"
        set vpn_server "and not connected via VPN" }
    elseif { [IP::addr [IP::client_addr] equals 10.0.0.0/8] } then {
        set locate_me "You are connected to wireless network."
        set vpn_server ",and not connected via VPN"}
    elseif { [IP::addr [IP::client_addr] equals 172.16.0.0/12] } then {
        set locate_me "You are connected to a partner network."
        set vpn_server ",and not connected via VPN"}
    elseif { [IP::addr [IP::client_addr] equals 192.168.0.0/16] } then {
        set locate_me "You are connected to a wired network."
        set vpn_server ",and not connected via VPN"}
}

when HTTP_REQUEST {
   HTTP::respond 200 content "<!DOCTYPE html>
<html>
<head>
<title>What's My IP (NYC bigip01)</title>
<style>
  body {
    background-color: #154733;
    font-family: Arial, sans-serif;
    text-align: center;
    color: white;
  }
  
  .container {
    margin: 50px auto;
    padding: 20px;
    max-width: 1000px;
    background-color: rgba(255, 255, 255, 0.1);
    border-radius: 10px;
  }
  
  .header {
    font-size: 36px;
    margin-bottom: 20px;
  }
  
  .paragraph {
    font-size: 28px;
    margin-bottom: 10px;
  }
  
  strong {
    color: yellow;
    font-size: 30px; /* Increased font size */
  }

</style>
</head>
<body>
<div class=\"container\">
  <div class=\"paragraph\">Your IP address is <strong>[IP::client_addr]</strong></div>
  $response_record
  <div class=\"paragraph\">$locate_me <strong>$vpn_server</strong>.</div>
  <div class=\"paragraph\">RCC F5 BIG-IP virtual server IP address <strong>[IP::local_addr]</strong> responded to this request.<br>&nbsp;</div>
  <div class=\"paragraph\">This website is brought to you by YOUR TEAM NAME HERE.<br>&nbsp;</div>
  <div class=\"paragraph\">Click the email link to send feedback <a href=\"mailto:email@yourdomain.com?subject=WhatsMyIP Website Feedback\"><strong>email@yourdomain.com</strong></a>.</div>
</div>
</body>
</html>"
}

 

 

 

 

Updated Sep 05, 2023
Version 2.0

Was this article helpful?