F5 Redirection over Public Networks




I am trying to setup an F5 in this way and I am wondering where this is going wrong:

I have the F5 facing Internal netowrk and external network connected to a Firewall DMZ Interface facing the internet.

I created a public IP on the Firewall which NATs the traffic to the F5 BIG IP VIP which is in the External DMZ Interface conected to the Firewall



External NAT:

I created a new Public IP X.X.X.X on our Firewall and did a static NAT to VIP


Firewall(config)# static (DMZ,outside) X.X.X.X netmask


Opened external access to the X.X.X.X IP for www and https

access-list acl_out extended permit tcp any host X.X.X.X eq www

access-list acl_out extended permit tcp any host X.X.X.X eq https


So when external users hits the X.X.X.X IP they are NAT by the Firewall to which is the F5 VIP


I created:

Internal Vlan – Self IP – Reachable from Internal network

External Vlan – Self IP – Reachable from Firewall DMZ/Internet Firewall


Routes: GW (Internal Vlan Gateway) GW (FW DMZ Interface connected to F5 VIP External


HTTP Profile:

http_X-Forwarded-For inherited by http class with X-Forwarded Enabled







switch "[string tolower [HTTP::uri]]" {

       "/test" - "/test/" {

          HTTP::redirect ""


       "/cims" - "/cims/" {

          HTTP::redirect ""




} is a server in the Internal network for example

Virtual Server:


VIP (VIP is reachable from FW) with x-Forwarded Profile and SNAT AutoMap enabled on internal and external interface


Then I test the results on an external PC:


I go to:




When trying this from external network that does not have direct access to the Internal network it fails.

When trying this from internal network that has access to it works.


Seems like the redirect and NAT works, but the the is only able to reply if the request is sourced by an internal customer host and not from an external customer host.

I thought about something like Aasymettric routing, with the internal server not going trough the F5 to reply back to the external host after the redirect, however I do have SNAT enabled as AuoMap already

13 Answer(s):

Ruggero, would need to be resolvable externally with a public IP address, rather than a private RFC 1918 one. You could then do a new NAT on your firewall to this address, and of course go via the F5 or direct.

Hope this helps,

Thanks Nathan,

I would rather present the user with an external URL which is X.X.X.X in my example and it is resolvable externally and then have the VIP redirect to the internal which is not resolvable externally.

For example:

1) External user hits (IP is the X.X.X.X) and is resolvable from outside

2) I NAT this x.x.x.x IP on my Firewall to the F5 VIP

3) it then hits the VIP and the F5 redirects it to which is only resolvable internally

4) Internal host replies back to the F5 on VIP

5) VIP sends the session back out to the external user


Basically using the F5 as a Reverse Proxy for Internal Hosts.

Ruggero, this is possible but overly complicated. I assume with 3) you mean routes or forwards rather than issuing a HTTP redirect (301/302)?

Are you expecting the F5 to do a DNS lookup? Are we over thinking this? Can your internal VIP and pool not just point to the real servers and you configure those to accept more than one hostname (i.e Apache Virtual Servers).

If you just want to replace the domain name for the inbound request, an iRule will suffice but you'll also need to ensure the server only serves relative links else a Stream Profile will also be required. Any Java goodness might also break without the Stream Profile.

What I can see is that when I hit from external:
I get correctly redirected to the internal

But the external user does not know how to reach the internal domain.
Rather than a redirect rule I need a rule that forwards requests from the public domain to the internal domain like the Microsoft ISA Reverse Proxy is capable of doing.
While doing the forward the external user should always place the requests via the public domain rather than being redirected to the internal domain.

We have this working on Microsoft ISA but I'd like to migrate the same feature over to F5.

That's exactly what the F5 can do, reverse proxy to internal resources. The issue is the redirect to a non-resolvable domain name/IP. Presumably is not in the VIP's default pool? If not instead of a http redirect to a domain ( you could just route the requests, via an iRule, to a different pool with as the pool member.


Thanks Steve,


I was expecting the F5 to fo a DNS lookup using the Internal DNS configured on the F5.

Anyway I changed my iRule to redirect to the IP instead of the name:


 HTTP::redirect ""
And what I see is that the external user is redirected to
But is a private network which is not accessible from outside.
Thus rather than a redirect rule, I need something that forwards from public to internal via the F5 and not redirect.
We do this with Microsoft ISA using it as a Revers proxy, anything that hits public IP is forwarded to the Internal IPs via the ISA, we want to remove ISA and replace it with an F5.

Yep I was thinking of replacing the redirect rule using pool members, but the reqiuirement is a bit more complex:

Because the same public IP needs to be forwarded to multiple internal hosts pools based on the URI.


For example:   is forwarded to   is forwarded to


Thus the same VIP needs to forward, rather than redirect, to different internal member pools depending on the URI

OK, understood and no a redirect won't work. As I and Nathan have suggested, why can't you just have the Virtual Server and the real servers as Pool Members? All the necessary internal NAT and port translation is automatic. The only possible issue is the difference in domain names but this might not be an issue at all, hard to tell at this point.
Not a problem, something like this will work;

 switch -glob [string tolower [HTTP::uri]] {
  #If HTTP URI contains odt or pingpong, use PoolA
  "*odt*" -
  "*pingpoing*" { pool PoolA }
  #If HTTP URI contains ghi, use PoolB
  "*ghi*" { pool PoolB }
  #If HTTP URI is none of the above, take the default action below
  default {
   pool PoolC }

That's great, it seems like what I was missing. I will try this ASAP and let you know.

I also have another challenge which I did not reach yet, but you seem having answers for everything so why not asking for it ? :)

Basically on the same rule above, I want to present the external user with a SecureID authentication page before it gets sent to one of the pool members.

On Microsfot ISA, for example they hit the external domain, then the ISA Servers is configured to presents a SecureID authentication page and it then forwards the request to the Internal server application if the authentication is accepted.

Good stuff. I'd suggest you look into the APM module for the SecureID functionality; it's supported and a common configuration but obviously it'll cost.

Thanks guys,

I have configured the iRule using Pools instead of Redirect rules:

switch -glob [string tolower [HTTP::uri]] {
"*odt*" - "*cims*" - "*t3*" { pool }
"*cmtext*" { pool Europe-CMTExt }
"*cognos*" { pool server-tst-21 }
"*extcognos*" { pool server-svr-92 }

http://x.x.x.x/Odt FAILS from external hosts and works from internal hosts
http://x.x.x.x/Cims WORKS only if I use HTTP profile and not X-Forwarded
http://x.x.x.x/cmtext WORKS with any HTTP Profile both from external host and internal host
http://x.x.x.x/Extcognos FAILS from internal and external host
http://x.x.x.x/t3 WORKS from internal and external host BUT when opened from External Host it does not display images inside the page it just display the login prompt with broken images links.

Must be something on the application side that I need to figure out, however the rule appears to be correct now.
OK, this might prove slightly better especially where the cognos URIs are concerned. A HTTP profile is required.

I'd also suspect these issues are server related. You could add some logging to confirm the rule is working. So, here's the updated rule;

 switch -glob [string tolower [HTTP::uri]] {
  "/odt*" -
  "/cims*" -
  "/t3*" { 
   log local0. "Matched: [HTTP::uri] with /odt, /cims or /t3, using Pool:" }
  "/cmtext*" { 
   pool Europe-CMTExt
   log local0. "Matched: [HTTP::uri] with /cmtext, using Pool: Europe-CMTExt" }
  "/cognos*" { 
   pool server-tst-21
   log local0. "Matched: [HTTP::uri] with /cognos, using Pool: server-tst-21" }
  "/extcognos*" { 
   pool server-svr-92
   log local0. "Matched: [HTTP::uri] with /extcognos, using Pool: server-svr-92" }
  default { drop }

Your answer: