Forum Discussion
Replacing hostname in HTTP RESPONSE header using stream profile and/or Irule
We are trying to allow access from the internet into an internal webserver running on port 8010. The webserver is coded with its internal hostname (host15.mycompany.com:8010) which is only resolvable within the company. We have assigned a public DNS name for the LTM Virtual Server (public.mycompany.com:443) which will terminate SSL and send traffic to the internal pool member of host15.mycompany.com:8010. Since the webserver's HTTP responses all refer to the internal hostname, external users on the internet are unable to resolve the name. Based on my research, it appears that we will need both a STREAM profile for the hostname find/replace as well as an HTTP profile (for SSL, etc). With a simple STREAM profile with the find/replace in the target field and no HTTP profile, the response to the client seems to be properly replaced, but generates a chunking error at the client. Applying an HTTP profile with the Rechunk option, the find/replace stops working, probably due to the fact that the entire TCP segment is no longer being scanned (only the HTTP payload). Is this assumption correct and if so, what are our options ? We have seen several iRule examples and applied the one below along with a HTTP profile with Rechunking, but the client gets a 504 errror despite the fact that the hostame replace seems to be successful. Any ideas ? This is version 10.2
when HTTP_RESPONSE {
set internal_host "host15.mycompany.com:8010"
set external_host "public.mycompany.com:443"
Disable the stream filter by default
STREAM::disable
Check if we're potentially rewriting this response
if {$internal_host ne ""}{
Rewrite the Location header for redirects
if {[HTTP::is_redirect]}{
if {[HTTP::header Location] contains "$internal_hostname"}{
HTTP::header replace Location [string map "$internal_hostname $external_hostname" [HTTP::header Location]]
}
}
Rewrite the response content using a stream profile if it is text
if {[HTTP::header Content-Type] contains "text"}{
Set the stream expression with the find/replace strings
STREAM::expression "@$internal_hostname@$external_hostname@"
Enable the stream filter
STREAM::enable
}
}
}
5 Replies
- Mike_61663
Cirrus
Maybe just a typo, but I notice the first two variable assignments in the code above show internal_host and external_host whereas most of the variable references that follow instead refer to internal_hostname and external_hostname.
- Kevin_Stewart
Employee
A few additional things:
-
You definitely need an HTTP profile for this, as the HTTP header replace logic requires it, and you specifically only want to capture and replace HTTP traffic anyway (not anything below HTTP).
-
I would leave the request chunking option at Preserve.
-
Would users actually reference the URL with the included port (ie. https://public.mycompany.com:443 vs. https://public.mycompany.com)?
when HTTP_REQUEST { Disable the stream filter for requests STREAM::disable Remove this header to prevent server from compression response HTTP::header remove Accept-Encoding } when HTTP_RESPONSE { set internal_host "host15.mycompany.com:8010" set external_host "public.mycompany.com" Rewrite the Location header for redirects if { [HTTP::header exists Location] }{ HTTP::header replace Location [string map "$internal_host $external_host" [HTTP::header Location]] } Rewrite the response content using a stream profile if it is text if { [HTTP::header Content-Type] contains "text" } { Set the stream expression with the find/replace strings STREAM::expression "@$internal_host@$external_host@" Enable the stream filter STREAM::enable } }
-
- Kevin_Stewart
Employee
Maybe a minor modification is in order:
when HTTP_REQUEST { Disable the stream filter for requests STREAM::disable Remove this header to prevent server from compression response HTTP::header remove Accept-Encoding } when HTTP_RESPONSE { Rewrite the Location header for redirects if { [HTTP::header exists Location] }{ HTTP::header replace Location [string map {"http://xyz.company.com:8010" "https://abc.company.com"} [HTTP::header Location]] } Rewrite the response content using a stream profile if it is text if { [HTTP::header Content-Type] contains "text" } { Set the stream expression with the find/replace strings STREAM::expression "@xyz.company.com:8010@abc.company.com@" Enable the stream filter STREAM::enable } }
- Kevin_Stewart
Employee
Add multiple conditions to your string map:
[string map {"old-1" "new" "old-2" "new" "old-3" "new"} [HTTP::header Location]]
Add multiple conditions to your STREAM evaluation:
STREAM::expression "@old-1@new@ @old-2@new@ @old-3@new@"
- trx_94323
Nimbostratus
Hello , Was there ever a solution for this? We are currently trying to mask an public domain (i.e. "support.com") between browser and the f5, but serve content from the back-end server with "myqadcloud.com" (from f5 to back-end server); and finally on each response from back-end server should ensure all domains used are "support.com" domain. Long story short, in theory, this method would prevent cross domain errors from IFrames within parent windows that contains a different domain name. So in a sense we are fooling the browser that the parent and iframe domain are the same, but the iframe will server content from a different back-end server (myqadcloud.com).
Thoughts on how that can be done?
Thanks in advance.
Traolly Xiong
Recent Discussions
Related Content
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com