Forum Discussion

Martin182's avatar
Martin182
Icon for Cirrus rankCirrus
Feb 11, 2025
Solved

iRule for host rewriting between nodes

Hello,
 
I have a virtual server that offers 4 services on the same nodes in openshift:
 
service1.dns.com >> A Record (Virtual Server IP 192.168.1.200)
service2.dns.com >> A Record (Virtual Server IP 192.168.1.200)
service3.dns.com >> A Record (Virtual Server IP 192.168.1.200)
service4.dns.com >> A Record (Virtual Server IP 192.168.1.200)
 
* Virtual Server IP 192.168.1.200
          - Pool 
               / Node 1 - 192.168.50.100
               / Node 2 - 192.168.50.101
 
Relevant configuration > SSL Profile Client, SSL Profile Server, iRule (Host rewrite)
 
---
 
In the given iRule, I must rewrite the external DNS host to a host that Openshift is able to handle to avoid 404 errors. If it balances on node1 it must be rewritten in one way, and if it balances on node2 it will be rewritten in another way.
A first configuration has been made with the following definition, but the headers are not being rewritten correctly:
 
 
when LB_SELECTED {
    switch -glob [string tolower [HTTP::host]] {
        "service1.dns.com" {
            if { [LB::server addr] eq "192.168.50.100" } {
                HTTP::header replace Host "service1.ocp.site1.com"
            } elseif { [LB::server addr] eq "192.168.50.101" } {
                HTTP::header replace Host "service1.ocp.site2.com"
            }
        }
        "service2.dns.com" {
            if { [LB::server addr] eq "192.168.50.100" } {
                HTTP::header replace Host "service2.ocp.site1.com"
            } elseif { [LB::server addr] eq "192.168.50.101" } {
                HTTP::header replace Host "service2.ocp.site2.com"
            }
        }
        "service3.dns.com" {
            if { [LB::server addr] eq "192.168.50.100" } {
                HTTP::header replace Host "service3.ocp.site1.com"
            } elseif { [LB::server addr] eq "192.168.50.101" } {
                HTTP::header replace Host "service3.ocp.site2.com"
            }
        }
        "service4.dns.com" {
            if { [LB::server addr] eq "192.168.50.100" } {
                HTTP::header replace Host "service4.ocp.site1.com"
            } elseif { [LB::server addr] eq "192.168.50.101" } {
                HTTP::header replace Host "service4.ocp.site2.com"
            }
        }
    }
}
 
 
Any help is appreciated
Best regards
  • Finally it works ok with the Data group + iRule solution.

    Thanks to all of you!

  • Yes, I have tested both events, but it seems that the fact that there is an SSL Profile Server makes the rewrite not behave correctly.
    However, if I disable the SSL Profile Server it seems to be working correctly. It seems to be some incompatibility between my code and the existence of encryption F5 <> Nodes.

    • Martin182's avatar
      Martin182
      Icon for Cirrus rankCirrus

      Both the virtual server and the nodes listen to port 443

  • I have found another possible approach, using data groups combined with iRule. 

     

    https://community.f5.com/discussions/technicalforum/rewrite-host-header-to-specific-pool-member/152235 

    https://community.f5.com/discussions/technicalforum/change-host-header-for-each-node-in-a-pool/190532

     

    I may try it out during the day.

  • Finally it works ok with the Data group + iRule solution.

    Thanks to all of you!

  • Hi Martin,

     

    You can try add logging statements to your iRule to capture the selected server and the rewritten Host header. This will help you verify that the iRule is executing as expected.

    Adding logging can help debug the issue:

    when LB_SELECTED {

        log local0. "Selected server: [LB::server addr], Host: [HTTP::host]"

        switch -glob [string tolower [HTTP::host]] {

            "service1.dns.com" {

                if { [LB::server addr] eq "192.168.50.100" } {

                    log local0. "Rewriting Host to service1.ocp.site1.com"

                    HTTP::header replace Host "service1.ocp.site1.com"

                } elseif { [LB::server addr] eq "192.168.50.101" } {

                    log local0. "Rewriting Host to service1.ocp.site2.com"

                    HTTP::header replace Host "service1.ocp.site2.com"

                }

            }

            "service2.dns.com" {

                if { [LB::server addr] eq "192.168.50.100" } {

                    log local0. "Rewriting Host to service2.ocp.site1.com"

                    HTTP::header replace Host "service2.ocp.site1.com"

                } elseif { [LB::server addr] eq "192.168.50.101" } {

                    log local0. "Rewriting Host to service2.ocp.site2.com"

                    HTTP::header replace Host "service2.ocp.site2.com"

                }

            }

            "service3.dns.com" {

                if { [LB::server addr] eq "192.168.50.100" } {

                    log local0. "Rewriting Host to service3.ocp.site1.com"

                    HTTP::header replace Host "service3.ocp.site1.com"

                } elseif { [LB::server addr] eq "192.168.50.101" } {

                    log local0. "Rewriting Host to service3.ocp.site2.com"

                    HTTP::header replace Host "service3.ocp.site2.com"

                }

            }

            "service4.dns.com" {

                if { [LB::server addr] eq "192.168.50.100" } {

                    log local0. "Rewriting Host to service4.ocp.site1.com"

                    HTTP::header replace Host "service4.ocp.site1.com"

                } elseif { [LB::server addr] eq "192.168.50.101" } {

                    log local0. "Rewriting Host to service4.ocp.site2.com"

                    HTTP::header replace Host "service4.ocp.site2.com"

                }

            }

        }

    }

    This will log the selected server and the host header, helping you verify if the conditions are being met and the headers are being rewritten correctly.

     

    Use a tool like curl or a web browser to generate traffic to your virtual server. For example:

    curl -H "Host: service1.dns.com" http://192.168.50.100

    curl -H "Host: service2.dns.com" http://192.168.50.100

    curl -H "Host: service3.dns.com" http://192.168.50.100

    curl -H "Host: service4.dns.com" http://192.168.50.100

    curl -H "Host: service1.dns.com" http://192.168.50.101

    curl -H "Host: service2.dns.com" http://192.168.50.101

    curl -H "Host: service3.dns.com" http://192.168.50.101

    curl -H "Host: service4.dns.com" http://192.168.50.101



    When you run the command curl -H "Host: service1.dns.com" http://192.168.1.100, you are making an HTTP request to the server at 192.168.50.100 and setting the Host header to service1.dns.com. This simulates a request as if it were coming from a client trying to access service1.dns.com, allowing you to test how your iRule handles this specific host.

    Check Logs:

    Review the logs on your F5 load balancer to verify that the iRule is executing correctly. Look for the log entries you added to confirm that the Host header is being rewritten as expected.

    Ensure that the applications on OpenShift are receiving the correct Host headers and responding appropriately. Check for any 404 errors or other issues.

    Monitor the traffic and logs to ensure the iRule continues to function correctly. Make any necessary adjustments based on your observations.

     Use tools like grep to filter and view specific log entries. For example:

    grep "Selected server" /var/log/ltm

    grep "Rewriting Host" /var/log/ltm

     

    HTH

    Best Regards

    F5 Design Engineer