Forum Discussion

InquisitiveMai's avatar
Jan 29, 2023
Solved

Filtering traffic based on client ip address and URL

Let's say I have a setup with  same destination ip address(DNS ) for multiple URLs . This is accessed by multiple clients and there traffic is only separated at the pool level. Can we do any restriction on the GTM, so  that client A cannot access client B if they type client B port number. Can we do something using Client A URL , their Source address and destination port number. If it's not possible onGTM, is it possible on LTM using traffic policies?  Is there any better way to do this restriction in F5 LTM and GTM

  • InquisitiveMai Is the port number in the clients request or on the server side.

    *** DNS records ***
    client1.example.com 300 IN A 1.1.1.1
    client2.example.com 300 IN A 1.1.1.1

    *** Clients side request example with port ***
    https://client1.example.com:49152 -> F5 VS listening on 1.1.1.1:49152 -> pool members listening on <private_IP>:443
    https://client2.example.com:49153 -> F5 VS listening on 1.1.1.1:49153 -> pool members listening on <private_IP>:443

    *** Server side request example with port ***
    https://client1.example.com -> F5 VS listening on 1.1.1.1:443 -> pool member listening on <private_IP>:49152
    https://client2.example.com -> F5 VS listening on 1.1.1.1:443 -> pool member listening on <private_IP>:49153

    In either of the client situation you can create an iRule that drops all hosts requests that are not for that specific client which will prevent from using the incorrect port for the associated client FQDN. In the second example if the client defined an alternate port the traffic would timeout because the F5 isn't listening on that port and it's the servers that are listening on the respective port behind the F5. You can create an iRule that says if host X comes in send them to pool X and if host Y comes in send them to pool Y. The irules would be the following, first the client and second the server.

    # This is the iRule for client1.example.com Virtual Server
    when CLIENT_ACCEPTED priority 500 {
    
        set DEFAULT_POOL [LB::server pool]
    
    }
    
    when HTTP_REQUEST priority 500 {
    
        set HOST [HTTP::uri]
    
        if { ${HOST} != "client1.example.com" } {
            drop
        }
    
    }
    # This is the iRule for client2.example.com Virtual Server
    when CLIENT_ACCEPTED priority 500 {
    
        set DEFAULT_POOL [LB::server pool]
    
    }
    
    when HTTP_REQUEST priority 500 {
    
        set HOST [HTTP::uri]
    
        if { ${HOST} != "client2.example.com" } {
            drop
        }
    
    }
    # This is the iRule for combine Virtual Server listening on 443
    when CLIENT_ACCEPTED priority 500 {
    
        set DEFAULT_POOL [LB::server pool]
    
    }
    
    when HTTP_REQUEST priority 500 {
    
        set HOST [HTTP::uri]
    
        switch --glob ${HOST} {
            "client1.example.com {
                pool POOL_client1_49152
            }
            "client2.example.com {
                pool POOL_client2_49153
            }
            default {
                # This is used if you have a generic website configured to direct clients to you for services
                pool ${DEFAULT_POOL}
            }
        }
    
    }

    If you can provide additional detail on the example communication flow we should be able to come up with a better iRule that will work for you. Please also keep in mind that when dealing with HTTPS communication this iRule would require that you are perform SSL termination on the F5.

4 Replies

  • InquisitiveMai Is the port number in the clients request or on the server side.

    *** DNS records ***
    client1.example.com 300 IN A 1.1.1.1
    client2.example.com 300 IN A 1.1.1.1

    *** Clients side request example with port ***
    https://client1.example.com:49152 -> F5 VS listening on 1.1.1.1:49152 -> pool members listening on <private_IP>:443
    https://client2.example.com:49153 -> F5 VS listening on 1.1.1.1:49153 -> pool members listening on <private_IP>:443

    *** Server side request example with port ***
    https://client1.example.com -> F5 VS listening on 1.1.1.1:443 -> pool member listening on <private_IP>:49152
    https://client2.example.com -> F5 VS listening on 1.1.1.1:443 -> pool member listening on <private_IP>:49153

    In either of the client situation you can create an iRule that drops all hosts requests that are not for that specific client which will prevent from using the incorrect port for the associated client FQDN. In the second example if the client defined an alternate port the traffic would timeout because the F5 isn't listening on that port and it's the servers that are listening on the respective port behind the F5. You can create an iRule that says if host X comes in send them to pool X and if host Y comes in send them to pool Y. The irules would be the following, first the client and second the server.

    # This is the iRule for client1.example.com Virtual Server
    when CLIENT_ACCEPTED priority 500 {
    
        set DEFAULT_POOL [LB::server pool]
    
    }
    
    when HTTP_REQUEST priority 500 {
    
        set HOST [HTTP::uri]
    
        if { ${HOST} != "client1.example.com" } {
            drop
        }
    
    }
    # This is the iRule for client2.example.com Virtual Server
    when CLIENT_ACCEPTED priority 500 {
    
        set DEFAULT_POOL [LB::server pool]
    
    }
    
    when HTTP_REQUEST priority 500 {
    
        set HOST [HTTP::uri]
    
        if { ${HOST} != "client2.example.com" } {
            drop
        }
    
    }
    # This is the iRule for combine Virtual Server listening on 443
    when CLIENT_ACCEPTED priority 500 {
    
        set DEFAULT_POOL [LB::server pool]
    
    }
    
    when HTTP_REQUEST priority 500 {
    
        set HOST [HTTP::uri]
    
        switch --glob ${HOST} {
            "client1.example.com {
                pool POOL_client1_49152
            }
            "client2.example.com {
                pool POOL_client2_49153
            }
            default {
                # This is used if you have a generic website configured to direct clients to you for services
                pool ${DEFAULT_POOL}
            }
        }
    
    }

    If you can provide additional detail on the example communication flow we should be able to come up with a better iRule that will work for you. Please also keep in mind that when dealing with HTTPS communication this iRule would require that you are perform SSL termination on the F5.

    • It is server side connection i.e request comes on https and then it hits a datagroup with a string of url and goes to the pool listening on ex: 49152 for client 1 and 49153 for client 2. Can we do something using traffic policies.

      Option 1) Getting out of the datagroups and Creating a traffic policy with the filtreing based on client and URL

      Option 2) Can we use anything along with the datagroup to filter traffic based on the client and URL and drop other clients who are not eligible to access the URL

      • Paulius's avatar
        Paulius
        Icon for MVP rankMVP

        InquisitiveMai I do not know how to configure the traffic policy equivalent but the following is the iRule that you can use most likely.

        when CLIENT_ACCEPTED  priority 500 {
        
            set DEFAULT_POOL [LB::server pool]
        
        }
        
        when HTTP_REQUEST priority 500 {
        
            set HOST [HTTP::host]
        
            if { [class match -- ${HOST} == CLASS-customer-sites] } {
        
                set TEMP_POOL [class match --value ${HOST} == CLASS-customer-sites]
        
                pool ${TEMP_POOL}
        
            } else {
                pool ${DEFAULT_POOL}
            }
        
        }

        This one is what the data-group should look like.

        ltm data-group internal CLASS-customer-sites {
            records {
                client1.example.com {
                    data POOL_client1_49152
                }
                client2.example.com {
                    data POOL_client2_49153
                }
            }
            type string
        }
  • InquisitiveMai - did the iRule Paulius shared help you out, or are you still trying to find a solution? If it helped, can you please hit the Solution Accepted button on his post so future users with the same challenge can easily find the answer?