Powered by Squarespace
Popular Categories
Blog Posts
Discussion Activity
Cisco Live 365
« Cisco CSS 11500 L5 Rules via SSL Acceleration (proxy) | Main | NetFlow -- The who/what/when/where of packet flows »

Cisco ACE Module HTTP-to-HTTPS (SSL) Redirection

A simple approach to handle sites that require SSL (HTTPS) encryption is to not allow plain-text HTTP, but that’s not very user-friendly and no one likes having to type extra characters into the browser to indicate HTTPS as the URI scheme.  So the elegant solution for the client-side request is to allow HTTP, but then to redirect all such requests over to SSL.  If you’re doing SSL Acceleration on your Cisco ACE load-balancer anyway, your configuration will become simpler in the long-run since you won’t have to maintain as much duplicate configuration to handle different load-balance policies for plain-text HTTP and SSL.

The solution is to create a generic redirect rserver and serverfarm that can be used for any  SSL loadbalance policies.  For web applications that may build absolute paths, the web server may need to know that the client protocol has switched over to SSL so you don’t have needless redirects.  A HTTP Header can be sent in the request toward the web server to inform it of the protocol using the de facto standard header called X-Forwarded-Proto.  Using the standard Via header is another alternative and will be shown in an example.

The ACE Module also has the ability to rewrite any HTTP redirects from the web server that should go to HTTPS using an action-list.  Any plain-text redirects which show in the location header will be caught and rewritten to SSL.

Let’s get into the config.  Complete config snippet here.

rserver redirect ssl-generic-redirect
  webhost-redirection https://%h%p 302

Real server (rserver) of type redirect is created.  This one is given a generic name of ssl-generic-redirect since it’s not tied to any particular VIPs (Virtual IPs).  The webhost-redirection takes the hostname (%h) along with the full path (%p) and does a 302 (temporary) redirect.  You could just as easily done a 301 (permanent) redirect.  Using variables for the hostname and path is what allows the reuse of this generic rserver anywhere.

serverfarm redirect ssl-redirect
  rserver ssl-generic-redirect

Now we simply tie the rserver to a serverfarm since the building blocks on the ACE require rservers into serverfarms into loadbalance policy-maps.

Now the interesting part is the action-list to set various request and response headers.  This is also where the SSL location header rewrite occurs.  The config below is a little overkill, but you’ll hopefully find some value in one or more of these actions.

action-list type modify http ssl-rewrite
  header insert request X-Forwarded-Proto header-value “%pd”
  header insert request Via header-value “1.1 web:%pd (ace10-8/a2)”
  header insert response Via header-value “1.1 web:%ps (ace10-8/a2)”
  ssl url rewrite location “.*”
  ssl header-insert session Id

The header insert request X-Forwarded-Proto is where we set the client-side protocol (number) in the request toward the web server.  Since by this time the client has already been redirected to SSL, the client will be making a request on port 443 which comes from the %pd (port destination) variable.  The web app can look at this value in determining how to build absolute paths so that https:// is sent to the client instead of http://An alternative is to use protocol-independent URL’s such as // — notice the lack of the URI scheme HTTP or HTTPS — but some browsers may have trouble with this (we’re talking about you Mr. IE6).  This header is added to the existing request headers and goes in the direction from the ACE to the web server since the request keyword appeared after header insert.

The Via header in the example is written in both directions with separate actions because the values are different.  In fact, the ACE can do a header insert both to write the same header and value in both directions (i.e., added to both the request and response headers), but we don’t want to do that here.  Following the RFC 2616 (HTTP/1.1) standard on the Via header, we identify our reverse proxy for the serverfarm in header insert request Via.  We set the value to http protocol version to 1.1 followed by a pseudonym and comment.  The pseudonym web:%pd in the example indicates the ACE context (web) plus the destination port (%pd) in the request.   The comment added could indicate the ACE hardware and slot (ACE10-8) followed by the major version A2.  The web server will see a value of “1.1 web:443 (ace10-8/a2)”.

For the response, we use header insert response Via which uses the source port (%ps) from the web server to show on the client-side that the web server handled the request in plain-text port 80.  If you’re overly concerned with exposing the type of hardware and version you’re running, then modify the comment or eliminate it to your liking. The client will see a value of “1.1 web:80 (ace10-8/a2)”.

What wasn’t initially clear to me, and no amount of searching and documentation explained this, the header insert will append the value if the header already exists.  I discovered this by accident by having two identical header insert response Via header-values in the config, and seeing in FireBug (for FireFox) — or Chrome or IE Developer Tools — that the second value was appended with a comma-delimeter.

The ssl url rewrite location “.*” uses the regex pattern “.*” to match any URL on the default clearport 80 so it can be rewritten to the default sslport 443.  Additional parameters are required to change the clearport or sslport to non-standard ports.  This handles any clear-text redirects being sent from the web server by modifying them to use the SSL port 443 to avoid unnecessary HTTP-to-HTTPS redirects on the ACE.

The ssl header-insert session Id shows how the SSL Session ID tied to the client session can be sent to the web server as another way in identifying that a SSL encryption with the client is in play.  When SSL Acceleration is done on the ACE Module with a ssl-proxy, the web server receives all requests in plain-text http on port 80.

The last part of the config is the usual stuff where the class-maps identify the traffic for the policy-maps.  Only key differences related to the HTTP-to-HTTPS redirection will be noted.

 class-map match-all
  2 match virtual-address tcp eq www
class-map match-all
  2 match virtual-address tcp eq https

Here we have two class-maps to match on port 80 and 443 for the policy-maps below since the serverfarms are different.

policy-map type loadbalance first-match
  class class-default
    serverfarm ssl-redirect
policy-map type loadbalance first-match
  class class-default
    sticky-serverfarm xyzzyweb-sticky
    action ssl-rewrite

The first policy-map takes the plaint-text http traffic and does the redirect to https (ssl).  The second policy-map ties the action-list to it and spells out the serverfarm (a sticky-serverfarm in this case).  The service-policy is not shown, but note that you need a parameter-map of type http with persistence-rebalance set in your policy-map multi-match (service policy) if you want the headers to be written on every request.  The parameter-map is applied to the class in your service policy with your appl-parameter http advanced-options.

Complete config snippet here.

Now you can allow your secure sites to have a friendlier redirection of non-secure requests.

[This discussion highlights a recurring theme with learning how to configure the ACE Module.  At first, the learning curve is high, but after seeing some examples and doing one of these yourself it is not so bad and exemplifies some of the power of the ACE.]



Reader Comments (6)

Thanks so much for this information! Tested this type of configuration this morning and it is working for us. Thanks for sharing!

By the way I noticed in your code snippet that you have the rserver config twice and no serverfarm config. Probably just a cut and paste error the one in the blog post worked great!

Apr 3, 2013 at 7:08 | Unregistered CommenterRoger

Code snippet fixed. Thanks Roger for pointing this out.

Apr 10, 2013 at 1:19 | Registered Commentergeneralnetworkerror

I've followed your configuration settings above and it's working as expected, I'm just wondering what the additional parameters are required to use a non-standard port in particular port 81 instead of port 80. You do mention that "Additional parameters are required to change the clearport or sslport to non-standard ports." I've been unable to work out what those parameters are though.


Sep 18, 2013 at 1:45 | Unregistered CommenterAnthony

@Anthony, the synatx is:
"ssl url rewrite location expression [clearport number] [sslport number]".

So you would use:
ssl url rewrite location “.*” clearport 81
#clearport 81 to sslport 443
ssl url rewrite location “.*” clearport 81 sslport 4443
#clearport 81 to sslport 4443 if you ssl port was also on a different port like 4443.

Sep 23, 2013 at 0:48 | Registered Commentergeneralnetworkerror

Hi generalnetworkerror,

I am having issue i did copy configuration you mentioned in blog but in policy-map multi-match intXXX It wouldn't allow me to have two policies,,,

In my scenario I have https all the way,,,it works fine using https://url but I am trying to achieve redirect so that if client forget to put https: ACE will redirect from http to https.


Nov 25, 2014 at 11:24 | Unregistered CommenterAnis

@Anis, not sure where you're having trouble in the config.... only one policy-map multi-match can get applied to an interface.... the other policy-maps and class-maps should cause any duplicates since those names are unique -- one has "ssl" in the class or policy name, the other doesn't.

Nov 29, 2014 at 21:18 | Registered Commentergeneralnetworkerror

PostPost a New Comment

Enter your information below to add a new comment.

My response is on my own website »
Author Email (optional):
Author URL (optional):
All HTML will be escaped. Textile formatting is allowed.