Jump to content
Welcome to our new Citrix community!

Citrix ADC Redirect based on host header


Recommended Posts

Hi,

I want to migrate from HA Proxy to Citrix ADC with a standard license.

We only use HAProxy today, since the company only has 1 public IP and cant get more at the momemt.
Our border firewall, then NATs HTTP and HTTPS to the HAProxy VIP (192.168.62.160). 
The HAProxy setup then routes to the right backend, based on what domain is in the host header.
This includes:
Exchange OWA - http mode
Apache Sites - http mode
RDS Web - http mode
RDS GW - TCP mode

 

The backend servers uses a mix of Letsencrypt certificates and normal certificates.
So we are not looking for SSL termination, but simply being able to use the same public IP for several services, based on the host header.

 

Also all the servers accept HTTP, and then redirects to HTTPS at a new backend in HAProxy.
Since some of the servers needs to renew Letsencrypt certificates, they need to accept plain HTTP, and then redirect to HTTPS at the application level itself.

 

Im very new to the ADC, and i cant really decide what the right solution is here.
Based on what ive read, then content switching is the right solution at this point?

 

Any help or guides, would be much appreciated! :)

Thanks in advance.

Link to comment
Share on other sites

First, just basic content switching:

So for contentswitching, based on hostnames, you can create the content switching actions to point to the appropriate lb vservers (they can be non-addressable), and then write the cs policies to identify the host headers. I've used contains, as I only had partial host names to work with, you can use equals or other options.  And I think based on your examples, there's going to need to be adjustments for what you really want to do...but not enough details to refine this to make it more than a rough example.

 

Also, for your RDS Gateway (TCP) traffic, in can use the SAME VIP, but as you change protocls/ports, it will be on its own lb vserver (or cs vserver) and not part of the HTTP destnation.  If all your sites are on the VIP but different ports, then you don't need CS at all. Just lb vservers on a per VIP:PORT combination.    So if we have more details, we can clarify the example.

 

This is without concern for the SSL redirect...more on that afterwards.

## HTTP STUFF

# cs vserver on VIP1 and HTTP:80 for this example; but can just as easily be SSL:443 with a cert

add cs vserver cs_vsrv_demo HTTP <VIP1> 80 -cltTimeout 180

 

# CS actions pointing to lb vservers (non-addressable) for each lb destiation, lb vserver config not shown (except for one as an example)

add lb vserver lb_vsrv_owa http 0.0.0.0 0   # omit vip/port if non-addressable

   bind lb vserver lb_vsrv_owa <svc...>

 

add cs action cs_act_toowa -targetLBVserver lb_vs_owa
add cs policy cs_pol_toowa -rule "http.REQ.HEADER(\"host\").SET_TEXT_MODE(ignorecase).CONTAINS(\"owa\")" -action cs_act_toowa

 

add cs action cs_act_toapache_site1 -targetLBVserver lb_vs_appache_site1
add cs policy cs_pol_toapache_site1 -rule "http.REQ.HEADER(\"host\").SET_TEXT_MODE(ignorecase).CONTAINS(\"site1.demo.com\")" -action cs_act_toapcache_site1

add cs action cs_act_toapache_site2 -targetLBVserver lb_vs_appache_site2
add cs policy cs_pol_toapache_site2 -rule "http.REQ.HEADER(\"host\").SET_TEXT_MODE(ignorecase).CONTAINS(\"site2.demo.com\")" -action cs_act_toapache_site2

 

add cs action cs_act_tordsweb -targetLBVserver lb_vs_rdsweb
add cs policy cs_pol_tordsweb -rule "http.REQ.HEADER(\"host\").SET_TEXT_MODE(ignorecase).CONTAINS(\"rdsweb.demo.com\")" -action cs_act_toapache_rdsweb

 

# bind policies to cs vserver

bind cs vserver cs_vsrv_demo -policyName cs_pol_toowa -priority 100

bind cs vserver cs_vsrv_demo -policyName cs_pol_toapache_site1 -priority 110

bind cs vserver cs_vsrv_demo -policyName cs_pol_toapache_site2 -priority 120

bind cs vserver cs_vsrv_demo -policyName cs_pol_tordsweb -priority 130

 

##  RDS Gateway / TCP

# NO CS needed if only TCP app

add service svc_rdsgateway1 <ip1> tcp 3389  #or is it ssl_tcp:port?

add service svc_rdsgateway2 <ip2> tcp 3389

add lb vserver lb_vsrv_rdsgateway1 TCP <VIP1> <port>   # if encrypted, then may be SSL_TCP....

 

Now, the SSL Redirect issue, which is hard to understand as described:

What you say you want to do and how you're going to do it doesn't agree.

The easy way is to have the traffic hit an HTTP:80 entity on the ADC and redirect to HTTPS:443.  Then the ADC does the SSL TERMINATION.

While, you say you want the app to do the termination, the problem is you can't do Content Switching on the ADC for SSL traffic unless we are the SSL Termiantion point (can't sort based on headers or urls if we can't looks inside).

 

And if you aren't doing SSL Termination on the ADC, then you can only do HTTP only or SSL Bridge and then all traffic on SSL_BRIDGE:VIP:443 just goes to the backend as is and we can't sort or redirect based on hostnames at all.

 

So, this may not fit your needs, because I think some of the requirements are less clear.  So what I suggest we go back to what you are actually need your traffic to do and we figure out how to do it. 

 

It may be that there is a different approach that can be used for your traffic.

So better understanding of the lb needs, the whether all traffic is on the same VIP:Port or on different ports (in which case, this just becomes load balancing), and why wouldn't you wan the load balancer to do the cert redirect since its already in the flow of traffic?

If the appache sites are multiple websites on the same lb vserver destinations, then these won't actually be load balanced differently if they are on same destination IP:port, instead they would be "load balanced" as all the apache stuff together.  If they have different hostnames, we can contentswitch but only needed if we have policies or redirects based on name.

 

 

 

 

Link to comment
Share on other sites

4 hours ago, Rhonda Rowland1709152125 said:

First, just basic content switching:

So for contentswitching, based on hostnames, you can create the content switching actions to point to the appropriate lb vservers (they can be non-addressable), and then write the cs policies to identify the host headers. I've used contains, as I only had partial host names to work with, you can use equals or other options.  And I think based on your examples, there's going to need to be adjustments for what you really want to do...but not enough details to refine this to make it more than a rough example.

 

Also, for your RDS Gateway (TCP) traffic, in can use the SAME VIP, but as you change protocls/ports, it will be on its own lb vserver (or cs vserver) and not part of the HTTP destnation.  If all your sites are on the VIP but different ports, then you don't need CS at all. Just lb vservers on a per VIP:PORT combination.    So if we have more details, we can clarify the example.

 

This is without concern for the SSL redirect...more on that afterwards.

## HTTP STUFF

# cs vserver on VIP1 and HTTP:80 for this example; but can just as easily be SSL:443 with a cert

add cs vserver cs_vsrv_demo HTTP <VIP1> 80 -cltTimeout 180

 

# CS actions pointing to lb vservers (non-addressable) for each lb destiation, lb vserver config not shown (except for one as an example)

add lb vserver lb_vsrv_owa http 0.0.0.0 0   # omit vip/port if non-addressable

   bind lb vserver lb_vsrv_owa <svc...>

 

add cs action cs_act_toowa -targetLBVserver lb_vs_owa
add cs policy cs_pol_toowa -rule "http.REQ.HEADER(\"host\").SET_TEXT_MODE(ignorecase).CONTAINS(\"owa\")" -action cs_act_toowa

 

add cs action cs_act_toapache_site1 -targetLBVserver lb_vs_appache_site1
add cs policy cs_pol_toapache_site1 -rule "http.REQ.HEADER(\"host\").SET_TEXT_MODE(ignorecase).CONTAINS(\"site1.demo.com\")" -action cs_act_toapcache_site1

add cs action cs_act_toapache_site2 -targetLBVserver lb_vs_appache_site2
add cs policy cs_pol_toapache_site2 -rule "http.REQ.HEADER(\"host\").SET_TEXT_MODE(ignorecase).CONTAINS(\"site2.demo.com\")" -action cs_act_toapache_site2

 

add cs action cs_act_tordsweb -targetLBVserver lb_vs_rdsweb
add cs policy cs_pol_tordsweb -rule "http.REQ.HEADER(\"host\").SET_TEXT_MODE(ignorecase).CONTAINS(\"rdsweb.demo.com\")" -action cs_act_toapache_rdsweb

 

# bind policies to cs vserver

bind cs vserver cs_vsrv_demo -policyName cs_pol_toowa -priority 100

bind cs vserver cs_vsrv_demo -policyName cs_pol_toapache_site1 -priority 110

bind cs vserver cs_vsrv_demo -policyName cs_pol_toapache_site2 -priority 120

bind cs vserver cs_vsrv_demo -policyName cs_pol_tordsweb -priority 130

 

##  RDS Gateway / TCP

# NO CS needed if only TCP app

add service svc_rdsgateway1 <ip1> tcp 3389  #or is it ssl_tcp:port?

add service svc_rdsgateway2 <ip2> tcp 3389

add lb vserver lb_vsrv_rdsgateway1 TCP <VIP1> <port>   # if encrypted, then may be SSL_TCP....

 

Now, the SSL Redirect issue, which is hard to understand as described:

What you say you want to do and how you're going to do it doesn't agree.

The easy way is to have the traffic hit an HTTP:80 entity on the ADC and redirect to HTTPS:443.  Then the ADC does the SSL TERMINATION.

While, you say you want the app to do the termination, the problem is you can't do Content Switching on the ADC for SSL traffic unless we are the SSL Termiantion point (can't sort based on headers or urls if we can't looks inside).

 

And if you aren't doing SSL Termination on the ADC, then you can only do HTTP only or SSL Bridge and then all traffic on SSL_BRIDGE:VIP:443 just goes to the backend as is and we can't sort or redirect based on hostnames at all.

 

So, this may not fit your needs, because I think some of the requirements are less clear.  So what I suggest we go back to what you are actually need your traffic to do and we figure out how to do it. 

 

It may be that there is a different approach that can be used for your traffic.

So better understanding of the lb needs, the whether all traffic is on the same VIP:Port or on different ports (in which case, this just becomes load balancing), and why wouldn't you wan the load balancer to do the cert redirect since its already in the flow of traffic?

If the appache sites are multiple websites on the same lb vserver destinations, then these won't actually be load balanced differently if they are on same destination IP:port, instead they would be "load balanced" as all the apache stuff together.  If they have different hostnames, we can contentswitch but only needed if we have policies or redirects based on name.

 

 

 

 

 

Wauv! Thanks so much for this set of answers and suggestions - much appreciated!

Ive tried to describe the flow a bit better, and also attached the current config - hopefully it will be more helpfull to you.

 

The current environment is build this way:

2x HAProxy servers, that is running keepalive.d, which presents an VIP.
This VIP (192.168.62.160) binds *:80 and *:443.
The HAProxy servers have several frontends and backends, where most of the backends only have 1 server representing that backend.


So the flow is like this:
#Request to Exchange
The end users connects to http://mail.domain.com. That resolves to the public IP 20.30.40.50
This external IP NATs to the HAProxy VIP (192.168.62.160), which based on the subdomain / domain, redirects the request to the backend matching this hostname
Exchange receives the request on HTTP, and then redirects it to HTTPS.

 

#Request to RDSWeb
The end users connects to http://remote.domain.com. That resolves to the public IP 20.30.40.50
This external IP NATs to the HAProxy VIP (192.168.62.160), which based on the subdomain / domain, redirects the request to the backend matching this hostname
RDSWeb receives the request on HTTP, and then redirects it to HTTPS.

 

This flow is the same, for all the servers in the HAProxy config.
But the servers running Letsencrypt and RDSGW have some special requirements.

 

For Letsencrypt renewals, the backend servers needs to have plain HTTP opened, without the ADC is doing any form of rewrites / manipulation with the package.
The applications itself, will then redirect HTTP requests to HTTPS automatically.

 

For the RDSGW part, it dosent support HTTP mode. So all the backend servers, are running in TCP mode.
This is since the backend cant work in both TCP and HTTP mode.

 

Most importantly - then the HAProxy supports routing requests to the right backend, based on the hdr host.
We use alot of different certificates, and some of them renews every 3. month. So i would prefer not to import the certificates in the ADC.
Currently we do not have any certificates imported in the HAProxy servers, and it works fine.

Ive attached the config - it should be fairly easy to understand the flow, and might give you an better overview.

 

 

haproxy.txt

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...