Jump to content
Welcome to our new Citrix community!

F5 Irules to Netscaler migration..Inserting XFF requests


Recommended Posts

Here is the details being requested for building header for i rules :

In the below i am able to implement the preflight request .But i want to know how to implement the X-Forwarded header in entirety .

Please find advise on the highted part .

 

ltm rule /Common/staging_qa {
when HTTP_REQUEST {
    #Configure the following 2 variables
    set allowed_origins "exo.com"
    #Uncomment out this line if the cookie name is the default
    #set cookie_name "BIGIPServer[getfield [LB::server pool] "/" 3]" 
    #Comment out the set cookie_name if using the default value
    #Change the following line only if the session
    # persistent cookie name is not the default value
    #The cookie_name must be the same on all servers  
    set cookie_name SERVERID
    #####
    set cors_acah [HTTP::header "Access-Control-Request-Headers"]
    set webappName [getfield [HTTP::uri] "/" 2]
    #log local0. "Origin: "[HTTP::header "Origin"]" Request-Method:"[HTTP::header "Access-Control-Request-Method"]
##
## Manage and handle the CORS preflight requests completely
## within the load balancer itself. The HTTP::respond does not 
## return a new load balancer cookie as the request is not sent
## to a backend pool member.
##
## CORS preflight requests are made completely credential and
## cookie free. If these requests were allowed to be handled by 
## the backend pool members the returned new session persistence
## cookie would overwrite the existing one causing intermittent 
## failures in the end user browser or native client sessions
##

    if { [HTTP::header Origin] ends_with $allowed_origins } {
        if { ( [HTTP::method] equals "OPTIONS" ) and ( [HTTP::header exists "Access-Control-Request-Method"] ) } {
            # CORS preflight request - return response immediately
            HTTP::respond 204 "Access-Control-Allow-Origin" [HTTP::header "Origin"] \
                              "Access-Control-Allow-Methods" "GET, POST, OPTIONS, HEAD, PUT, DELETE, PATCH" \
                              "Access-Control-Allow-Headers" [HTTP::header "Access-Control-Request-Headers"] \
                              "Access-Control-Max-Age" "600" \
                              "Vary" "Origin" \
                              "Access-Control-Allow-Credentials" "true"
            return
        } else {
            # CORS GET/POST requests - set cors_origin variable
            set cors_origin [HTTP::header "Origin"]
        }
    }

##
## Insert the mandatory X-Forwarded-XXX headers into the request
## stream for the backend pool members to process. These headers
## allow the back-end applications to properly construct a URL
## for a client to return back to same vanity URL. 
##
    HTTP::header insert "X-Forwarded-For" [getfield [IP::client_addr] "%" 1]
    HTTP::header replace "Host" [HTTP::host]
    HTTP::header insert "X-Forwarded-Host" [HTTP::host]
    HTTP::header insert "X-Forwarded-Hostname" [getfield [HTTP::host] ":" 1]
    HTTP::header insert "X-Forwarded-Port" [TCP::local_port]
    HTTP::header insert "X-Forwarded-ContextPath" /$webappName
    HTTP::header insert "X-Forwarded-Proto" "https"
    # Create the Forward header to be compliant with RFC7239
    #  set string "for="[IP::client_addr]";proto="$proto";by="[TCP::local_host]";host="[HTTP::host]";contextpath="$webappName
    #  HTTP::header insert "Forwarded" string

####SRN2#####Persist JSESSIONID if it exists    
####SRN2####if { [HTTP::cookie exists "JSESSIONID"] } { 
####SRN2#### persist uie [HTTP::cookie "JSESSIONID"] 1800 
####SRN2#### } else { 
####SRN2#### set jsess [findstr [HTTP::uri] "JSESSIONID" 11 ";"] 
####SRN2#### if { $jsess != "" } { 
####SRN2#### persist uie $jsess 1800
####SRN2#### }
####SRN2#### }
}

##
## This section allows the F5 to send to the back-end
## application the exact same cookie name and value the 
## F5 will be creating for the client. This allows the 
## application to have the information even on the initial
## request 
##
##
when LB_SELECTED {
    #following 3 lines could determine persistence cookie name being used if not manually set in the previous line
    #if {not [info exists cookie_name]} {
    #    if { [set cookie_name [PROFILE::persist mode cookie cookie_name]] eq "" } { set cookie_name "BIGIPServer"[getfield [LB::server pool] "/" 3] }
    #}
    #Next function is here to forge the persistence cookie value when it doesn't exist yet (because it's the first hit)
    if { [set COOKIE [HTTP::cookie value $cookie_name]] == "" } {
        scan [LB::server addr] {%d.%d.%d.%d} a b c d
        #Forging the cookie value based on sol6917
        set ADDR [expr { $a + $b * 256 + $c * 65536 + $d * 16777216 }]
        set PORT [ntohs [LB::server port]]
        set COOKIE "${ADDR}.${PORT}.0000"
        #log local0. "$cookie_name = $COOKIE created for [HTTP::uri]"
        unset a b c d ADDR PORT
    }
    HTTP::header insert "X-dsp-client-node" $COOKIE

Link to comment
Share on other sites

NetScaler Load Balancing Services > Settings have a checkbox for Insert Client IP Address and field to enter the Header Name (X-Forwarded-For).

 

For the other headers, you'll need to configure Rewrite policies/actions of type INSERT_HTTP_HEADER and bind the Rewrite policies to the Request bank.

Link to comment
Share on other sites

Hi!

 

Here are some examples that you might use :

 

X-Forwarded-For:

add rewrite action act_insertxff insert_http_header X-Forwarded-For CLIENT.IP.SRC
add rewrite policy pol_insertxff HTTP.REQ.IS_VALID rw_act_insertxff

 

X-Forwarded-Host:

add rewrite action act_insertxfh insert_http_header X-Forwarded-Host "HTTP.REQ.HEADER(\"Host\")"
add rewrite policy pol_insertxfh HTTP.REQ.IS_VALID rw_act_insertxfh

 

X-Forwarded-Proto:
add rewrite action act_insertxfp insert_http_header X-Forwarded-Proto "\"https\""
add rewrite policy pol_insertxfp HTTP.REQ.IS_VALID rw_act_insertxfp

Link to comment
Share on other sites

On 4/3/2019 at 4:04 PM, Mihai Cziraki1709160741 said:

Hi!

 

Here are some examples that you might use :

 

X-Forwarded-For:

add rewrite action act_insertxff insert_http_header X-Forwarded-For CLIENT.IP.SRC
add rewrite policy pol_insertxff HTTP.REQ.IS_VALID rw_act_insertxff

 

X-Forwarded-Host:

add rewrite action act_insertxfh insert_http_header X-Forwarded-Host "HTTP.REQ.HEADER(\"Host\")"
add rewrite policy pol_insertxfh HTTP.REQ.IS_VALID rw_act_insertxfh

 

X-Forwarded-Proto:
add rewrite action act_insertxfp insert_http_header X-Forwarded-Proto "\"https\""
add rewrite policy pol_insertxfp HTTP.REQ.IS_VALID rw_act_insertxfp

Hello Mihai ,

 

Thanks for the response ...Yes i have made these changes already .

All i am concerned is the big Cookie expression as to how i should make that happen .

Secondly what is the difference between host and hostname in the expression so that i can make necessary changes .

 

Link to comment
Share on other sites

17 hours ago, Mihai Cziraki1709160741 said:

HTTP.REQ.HEADER(\"Host\") takes the content of the host header an puts it in a new http header  X-Forwarded-Host .

 

http.REQ.HOSTNAME.SERVER  returns the host name that it find in the request

for http://www.example.com/test/index.html

Hostname is : www.example.com

I created the following rewrite for   HTTP::header insert "X-Forwarded-Hostname" [getfield [HTTP::host] ":" 1] .

I used expression http.REQ.HOSTNAME not http.REQ.HOSTNAME.SERVER , so does that also return the hostname or i have to use a different expression for rewriting this i rule  HTTP::header insert "X-Forwarded-Hostname" [getfield [HTTP::host] ":" 1] . 

 

Please advise asap as i am close to finish the complete request but stuck with few things .

Link to comment
Share on other sites

All I am concerned is for below lines :

If possible please help me with below policies .

 

 HTTP::header replace "Host" [HTTP::host]    ( How i can rewrite this one ????)
  HTTP::header insert "X-Forwarded-Host" [HTTP::host] ( created this one )
  HTTP::header insert "X-Forwarded-Hostname" [getfield [HTTP::host] ":" 1] ( created this one but doubtful as i used expression http.REQ.HOSTNAME not http.REQ.HOSTNAME.Server )

 

 

 

Link to comment
Share on other sites

HTTP::host   - returns the value contained in the Host header of an HTTP request.

 

So  this :  HTTP::header replace "Host" [HTTP::host]   does not make sense to me. As it replaces the content of the Host http header with the same content.

 

getfield [HTTP::host] ":" 1  takes the first part of a hostname . The hostname can have the port part, like this  : www.example.com:8080.   The F5 rules takes the first part without the port.

 

X-Forwarded-Hostname:

add rewrite action act_inserthostname insert_http_header  X-Forwarded-Hostname http.REQ.HOSTNAME.SERVER
add rewrite policy pol_insertxfh HTTP.REQ.IS_VALID rw_act_inserthostname

 

 

If you use http.REQ.HOSTNAME  , ithe hostname part might include the port also.   like this : www.example.com:8080.

 

 

 

 

Link to comment
Share on other sites

1 hour ago, Mihai Cziraki1709160741 said:

HTTP::host   - returns the value contained in the Host header of an HTTP request.

 

So  this :  HTTP::header replace "Host" [HTTP::host]   does not make sense to me. As it replaces the content of the Host http header with the same content.

 

getfield [HTTP::host] ":" 1  takes the first part of a hostname . The hostname can have the port part, like this  : www.example.com:8080.   The F5 rules takes the first part without the port.

 

X-Forwarded-Hostname:

add rewrite action act_inserthostname insert_http_header  X-Forwarded-Hostname http.REQ.HOSTNAME.SERVER
add rewrite policy pol_insertxfh HTTP.REQ.IS_VALID rw_act_inserthostname

 

 

If you use http.REQ.HOSTNAME  , ithe hostname part might include the port also.   like this : www.example.com:8080.

 

 

 

 

Thanks a lot for the explanation .When i am using HTTP.REQ.HEADER(\"Host\") for X-Forwarded-Host , I am getting this as it is in the header insertion .I am attaching the packet capture screen shot here .Is that the required output ?

Capture.JPG

Link to comment
Share on other sites

1 hour ago, Mihai Cziraki1709160741 said:

somethink is not ok. 

Can you share the policy you are using (CLI or GUI)? looks like there might be something wrong

 

It should look something like this:

 

add rewrite action act_insertxfh insert_http_header X-Forwarded-Host "HTTP.REQ.HEADER(\"Host\")"

 

 

Please find the screen shot of the configuration from GUI

Capture2.JPG

Link to comment
Share on other sites

Yes now it is getting through successfully thanks..

The only thing left is the below expression for cookies which is quite complex .

====================

## This section allows the F5 to send to the back-end
## application the exact same cookie name and value the 
## F5 will be creating for the client. This allows the 
## application to have the information even on the initial
## request 
##
##
when LB_SELECTED {
    #following 3 lines could determine persistence cookie name being used if not manually set in the previous line
    #if {not [info exists cookie_name]} {
    #    if { [set cookie_name [PROFILE::persist mode cookie cookie_name]] eq "" } { set cookie_name "BIGIPServer"[getfield [LB::server pool] "/" 3] }
    #}
    #Next function is here to forge the persistence cookie value when it doesn't exist yet (because it's the first hit)
    if { [set COOKIE [HTTP::cookie value $cookie_name]] == "" } {
        scan [LB::server addr] {%d.%d.%d.%d} a b c d
        #Forging the cookie value based on sol6917
        set ADDR [expr { $a + $b * 256 + $c * 65536 + $d * 16777216 }]
        set PORT [ntohs [LB::server port]]
        set COOKIE "${ADDR}.${PORT}.0000"
        #log local0. "$cookie_name = $COOKIE created for [HTTP::uri]"
        unset a b c d ADDR PORT
    }
    HTTP::header insert "X-dsp-client-node" $COOKIE

 

Can someone please put some lights for these expression ?

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...