Forum Discussion

paulpatriot_129's avatar
paulpatriot_129
Icon for Nimbostratus rankNimbostratus
Jul 28, 2016
Solved

Need help with irule to attach specific headers on all http methods ?

I have an irule applied to a VIP that SNAT's only when a particular pool is selected that inserts headers. I ran a wireshark and it appears that the POST is the only http method that has the headers attached the GET doesn't. How can I get it to attach the headers on all http methods?

 

Below is the irule currently used: when LB_SELECTED { log local0. "sending to pool: [LB::server pool]" if { [LB::server pool] ends_with {/pool_name} } { snat automap log local0. "releasing request with private headers [HTTP::header Host]:[TCP::local_port clientside] from [IP::remote_addr clientside]" HTTP::header insert {$WSIS} {true} HTTP::header insert {$WSSC} {https} HTTP::header insert {$WSPR} "HTTP/[HTTP::version]" HTTP::header insert {$WSRA} [IP::remote_addr clientside] HTTP::header insert {$WSRH} [IP::remote_addr clientside] HTTP::header insert {$WSSN} [HTTP::header Host] HTTP::header insert {$WSSP} [TCP::local_port clientside] } else { snat none } }

 

  • I present the iRule here with formatting to make it clearer to others that may read this thread:

    when LB_SELECTED {
        log local0. "sending to pool: [LB::server pool]" 
        if { [LB::server pool] ends_with {/pool_name} } { 
            snat automap 
            log local0. "releasing request with private headers [HTTP::header Host]:[TCP::local_port clientside] from [IP::remote_addr clientside]" 
            HTTP::header insert {$WSIS} {true}
            HTTP::header insert {$WSSC} {https}
            HTTP::header insert {$WSPR} "HTTP/[HTTP::version]"
            HTTP::header insert {$WSRA} [IP::remote_addr clientside] 
            HTTP::header insert {$WSRH} [IP::remote_addr clientside] 
            HTTP::header insert {$WSSN} [HTTP::header Host] 
            HTTP::header insert {$WSSP} [TCP::local_port clientside] 
        } else { 
            snat none 
        }
    }
    

    This iRule should function the same regardless of the method. However, LB_SELECTED will fire only once per underlying connection. HTTP typically employs connection keepalives, so multiple requests may be sent over the same underlying connection. In that case, only the first request would have headers inserted (the others would have automap SNAT applied, however, because that actually does operate on the outbound proxied connection).

    I recommend moving the header inserting into HTTP_REQUEST_SEND. Do, however, read the page for it. You'll see that you will need to use the

    clientside
    directive for the inserts. Since HTTP_REQUEST_SEND fires after LB_SELECTED, you can set a variable in LB_SELECTED if the criteria matches for insertion (although
    LB::server
    may be valid in that event):

    when LB_SELECTED {
        set poolmatch 0
        if { [LB::server pool] ends_with {/pool_name} } {
            set poolmatch 1
            snat automap
        }
    }
    
    when HTTP_REQUEST_SEND {
        if { $poolmatch } {
             ... insert your headers here ...
        }
    }
    

    Incidentally, if SNAT is not applied to the Virtual Server, then the

    else
    clause in LB_SELECTED (
    snat none
    ) is not necessary, but will still consume execution cycles on each connection.

4 Replies

  • I present the iRule here with formatting to make it clearer to others that may read this thread:

    when LB_SELECTED {
        log local0. "sending to pool: [LB::server pool]" 
        if { [LB::server pool] ends_with {/pool_name} } { 
            snat automap 
            log local0. "releasing request with private headers [HTTP::header Host]:[TCP::local_port clientside] from [IP::remote_addr clientside]" 
            HTTP::header insert {$WSIS} {true}
            HTTP::header insert {$WSSC} {https}
            HTTP::header insert {$WSPR} "HTTP/[HTTP::version]"
            HTTP::header insert {$WSRA} [IP::remote_addr clientside] 
            HTTP::header insert {$WSRH} [IP::remote_addr clientside] 
            HTTP::header insert {$WSSN} [HTTP::header Host] 
            HTTP::header insert {$WSSP} [TCP::local_port clientside] 
        } else { 
            snat none 
        }
    }
    

    This iRule should function the same regardless of the method. However, LB_SELECTED will fire only once per underlying connection. HTTP typically employs connection keepalives, so multiple requests may be sent over the same underlying connection. In that case, only the first request would have headers inserted (the others would have automap SNAT applied, however, because that actually does operate on the outbound proxied connection).

    I recommend moving the header inserting into HTTP_REQUEST_SEND. Do, however, read the page for it. You'll see that you will need to use the

    clientside
    directive for the inserts. Since HTTP_REQUEST_SEND fires after LB_SELECTED, you can set a variable in LB_SELECTED if the criteria matches for insertion (although
    LB::server
    may be valid in that event):

    when LB_SELECTED {
        set poolmatch 0
        if { [LB::server pool] ends_with {/pool_name} } {
            set poolmatch 1
            snat automap
        }
    }
    
    when HTTP_REQUEST_SEND {
        if { $poolmatch } {
             ... insert your headers here ...
        }
    }
    

    Incidentally, if SNAT is not applied to the Virtual Server, then the

    else
    clause in LB_SELECTED (
    snat none
    ) is not necessary, but will still consume execution cycles on each connection.

  • Vernon_97235's avatar
    Vernon_97235
    Historic F5 Account

    I present the iRule here with formatting to make it clearer to others that may read this thread:

    when LB_SELECTED {
        log local0. "sending to pool: [LB::server pool]" 
        if { [LB::server pool] ends_with {/pool_name} } { 
            snat automap 
            log local0. "releasing request with private headers [HTTP::header Host]:[TCP::local_port clientside] from [IP::remote_addr clientside]" 
            HTTP::header insert {$WSIS} {true}
            HTTP::header insert {$WSSC} {https}
            HTTP::header insert {$WSPR} "HTTP/[HTTP::version]"
            HTTP::header insert {$WSRA} [IP::remote_addr clientside] 
            HTTP::header insert {$WSRH} [IP::remote_addr clientside] 
            HTTP::header insert {$WSSN} [HTTP::header Host] 
            HTTP::header insert {$WSSP} [TCP::local_port clientside] 
        } else { 
            snat none 
        }
    }
    

    This iRule should function the same regardless of the method. However, LB_SELECTED will fire only once per underlying connection. HTTP typically employs connection keepalives, so multiple requests may be sent over the same underlying connection. In that case, only the first request would have headers inserted (the others would have automap SNAT applied, however, because that actually does operate on the outbound proxied connection).

    I recommend moving the header inserting into HTTP_REQUEST_SEND. Do, however, read the page for it. You'll see that you will need to use the

    clientside
    directive for the inserts. Since HTTP_REQUEST_SEND fires after LB_SELECTED, you can set a variable in LB_SELECTED if the criteria matches for insertion (although
    LB::server
    may be valid in that event):

    when LB_SELECTED {
        set poolmatch 0
        if { [LB::server pool] ends_with {/pool_name} } {
            set poolmatch 1
            snat automap
        }
    }
    
    when HTTP_REQUEST_SEND {
        if { $poolmatch } {
             ... insert your headers here ...
        }
    }
    

    Incidentally, if SNAT is not applied to the Virtual Server, then the

    else
    clause in LB_SELECTED (
    snat none
    ) is not necessary, but will still consume execution cycles on each connection.