Learn F5 Technologies, Get Answers & Share Community Solutions Join DevCentral

Filter by:
  • Solution
  • Technology
Answers

HOST and partial path rewrite

Hi I am new to F5 and am trying to do a URL rewrite a chunk of the URL. I think I am on the right track but I just cannot make it work. Any help is really appreciated.

I just want to replace any request that contains the below retaining the remainder of the URL represented by *

https://my.server.net/info/*

with

http://10.10.10.10:9000/files/*

He is my effort at achieving this.

when HTTP_REQUEST { if { [HTTP::uri] starts_with "/info"}{ HTTP::redirect "http://[string map {https://my.server.net/info http://10.10.10.10:9000/jenkins_files} [string tolower[HTTP::host]][HTTP::uri]]" } }

0
Rate this Question

Answers to this Question

placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

Hi,

to do it, no need to create irules.

there is a profile named "rewrite profile" which can do it. create one rewrite profile in URI translation mode, then create one rule with:

1
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

Hello CraigyB, Try using the following iRule.

when HTTP_REQUEST {
if { ( [string tolower [HTTP::uri]] starts_with "/info" ) } {
    set uri [HTTP::uri [string map {"/info" "/files"} [HTTP::uri]]]
    HTTP::redirect "https://[HTTP::host]$uri"
}
}
0
Comments on this Answer
Comment made 5 months ago by CraigyB 1

Hi Kolom, appreciate your input, which parts do i replace with destination host name and port number?

0
Comment made 5 months ago by kolom 242

i've tested the following and it's working fine.

when HTTP_REQUEST 
if { ( [string tolower [HTTP::uri]] starts_with "/info" ) } {
set newUri [string map [list "info" "files"] [HTTP::uri]]
HTTP::redirect "http://[HTTP::host]$newUri"
}

if you want to replace the host/port , change the redirection part from HTTP::redirect "http://[HTTP::host]$newUri" to HTTP::redirect "http://10.10.10.10:9000$newUri"

0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

You can try this iRule - I've written it without the redirect as I presume you want to rewrite the header and URI on the fly - a redirect to a private IP may cause issues if accessing over the internet? Please correct me if not. I've also rewritten the host header using the selected back-end server IP and port you connect to, rather than hard code the IP addresses - this can be changed if needs be Let me know how you get on

when HTTP_REQUEST {
    if {[HTTP::uri] starts_with "/info"} {
        set newUri [string map [list "info" "files"] [HTTP::uri]]
        HTTP::header replace Host "[LB::server addr]:[LB::server port]"
        HTTP::uri $newUri   
    }
}

Cheers Lee

0
Comments on this Answer
Comment made 5 months ago by CraigyB 1

Thanks for your response Lee,

Unfortunately I'm getting an undefined procedure error on the two LB entries

[undefined procedure: LB::9000][LB::9000]

Could this be a version issue i'm on BIG-IP 12.1.1

0
Comment made 5 months ago by MrPlastic 1647

It's probably erroring as the server has not been selected for load balancing yet in the HTTP_REQUEST event. Try hard coding it first, if it works we can maybe re-write the header in a server side event context, maybe LB_SELECTED

when HTTP_REQUEST {
    if {[HTTP::uri] starts_with "/info"} {
        set newUri [string map [list "info" "files"] [HTTP::uri]]
        HTTP::header replace Host "10.10.10.10:9000"
        HTTP::uri $newUri   
    }
}
0
Comment made 5 months ago by CraigyB 1

No dice i get file not found in the browser like the host redirect is not happening but replacing info with file is.

0
Comment made 5 months ago by MrPlastic 1647

Can you explain your requirement a bit more, e.g. why do you need to replace the host header? Do you want a redirect to 10.10.10.10:9000 (visible to the user) or do you need to rewrite it as the request comes in so the pool member can understand the request (invisible to the user).

It may be you need to re-write the HTTP responses so a Stream expression may be required.

0
Comment made 5 months ago by CraigyB 1

basically we have a server that is hosting a Jenkins instance. The F5 is currently doing http to https redirect and SSL off loading for jenkins VIP

On the same jenkins server we have an apache webserver (on port 9000) that is hosting some reporting content and jenkins files. I just need to redirect / rewwrite requests that come in to F5-VIP-Jenkins/info to jenkins-server:9000/jenkins_info. while still persisting any additional path that is supplied. So F5-VIP-Jenkins/info/project1 would redirect to jenkins-server:9000/jenkins_info/project1. There is no problem making the URL visable.

I hope this helps

0
Comment made 5 months ago by MrPlastic 1647

Thanks, that made a lot of sense. In that case, reformatting the URI and redirecting to HTTP should do the trick:

when HTTP_REQUEST {
    if {[HTTP::uri] starts_with "/info"} {
        set newUri [string map [list "info" "files"] [HTTP::uri]]
        HTTP::uri $newUri 
        HTTP::redirect http://10.10.10.10:9000[HTTP::uri]
    }
}

Also worth looking at the solution Stanislas Piron has suggested by using a rewrite profile. It may be easier to maintain and probably more efficient that iRules

0
Comment made 5 months ago by Stanislas Piron 8395

@CraigyB, in HTTP, redirect is a specific word which means to send a response to the client asking to request the new URL. MrPlastic las solution changes based because you used this word.

Do you want the browser request the internal URL?

if not, the issue is to rewrite the response to change every references of http://10.10.10.10:9000 by https://my.server.net/info/ which is more difficult with an irule in any pages.

try the rewrite profile, if it doesn't work, We can help you with an irule.

0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

I just need to redirect / rewwrite requests that come in to F5-VIP-Jenkins/info to jenkins-server:9000/jenkins_info. while still persisting any additional path that is supplied. So F5-VIP-Jenkins/info/project1 would redirect to jenkins-server:9000/jenkins_info/project1.

just another example

e.g.

// config

root@(ve13a)(cfg-sync In Sync)(Active)(/Common)(tmos)# list ltm virtual bar
ltm virtual bar {
    destination 172.28.24.10:80
    ip-protocol tcp
    mask 255.255.255.255
    pool foo
    profiles {
        http { }
        tcp { }
    }
    rules {
        qux
    }
    source 0.0.0.0/0
    source-address-translation {
        type automap
    }
    translate-address enabled
    translate-port enabled
    vs-index 17
}
root@(ve13a)(cfg-sync In Sync)(Active)(/Common)(tmos)# list ltm pool foo
ltm pool foo {
    members {
        200.200.200.101:9000 {
            address 200.200.200.101
        }
    }
}
root@(ve13a)(cfg-sync In Sync)(Active)(/Common)(tmos)# list ltm rule qux
ltm rule qux {
when HTTP_REQUEST_RELEASE {
  if { [HTTP::uri] starts_with "/info/" } {
    HTTP::host "[LB::server addr]:[LB::server port]"
    HTTP::uri [string map {"/info/" "/jenkins_info/"} [HTTP::uri]]
  }
}
}

// test

[root@ve13a:Active:In Sync] config # ssldump -Aed -nni 0.0 port 80 or port 9000
New TCP connection #1: 172.28.24.1(42574) <-> 172.28.24.10(80)
1515777465.5177 (0.0006)  C>S
---------------------------------------------------------------
GET /info/project1/helloworld HTTP/1.1
User-Agent: curl/7.29.0
Host: 172.28.24.10
Accept: */*

---------------------------------------------------------------

New TCP connection #2: 200.200.200.14(3889) <-> 200.200.200.101(9000)
1515777465.5189 (0.0011)  C>S
---------------------------------------------------------------
GET /jenkins_info/project1/helloworld HTTP/1.1
User-Agent: curl/7.29.0
Host: 200.200.200.101:9000
Accept: */*

---------------------------------------------------------------
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

Check out F5's LTM > Policies instead of creating an iRule. You can do all this in the GUI.

Create a new policy, name it, then create a rule within the policy "Create policy" button, do all your rules here. URI and redirect changes. Then go to your VIP, resource tab, apply the policy.

0