Forum Discussion
Martin_Kaiser_1
Nimbostratus
May 18, 2011Redirect http client to https on same non-default port
Hi guys,
I have a customer request of which I'm unsure whether it can be done at all or not:
I have a virtual https server on a BigIP running 10.2.0HF2. The virtual server is not running on port 443, but on non-default port 12345, balancing on a pool of development servers (plain http, SSL handling done by BigIP). Now, the customer requests a redirect from http to https in case the developers mistype http://some.site.net:12345 instead of https://some.site.net:12345
The problem is: you'll have to use an iRule event which is triggered very early during the transaction (e.g. CLIENT_CONNECTED or RULE_INIT), but I'm not sure how to make the iRule realize that there is a plain HTTP request following WITHOUT prior SSL handshake and then issue a SSL::DISABLE followed by an HTTP::REDIRECT...
Any ideas on that? Many thanks in advance!
Martin
14 Replies
- hoolio
Cirrostratus
Hi Martin,
Here's a solution for you:
http://devcentral.f5.com/wiki/default.aspx/iRules/Redirect_non_ssl_requests_on_ssl_vs_rule.html
Note you need to enable non-SSL connections on the client SSL profile in order for this to work. Non-SSL requests will not be allowed to the pool so this shouldn't be a security concern.
Aaron - Martin_Kaiser_1
Nimbostratus
Thanks Aaron - that helps a lot. I didn't even consider the "accept non-SSL connections" option in the clientssl profile. - Martin_Kaiser_1
Nimbostratus
one more question in order to understand that better:
what will SSL::cipher version, SSL::cipher bits or SSL::cipher name return if there is no SSL handshake at all?? - hoolio
Cirrostratus
The iRule checks to see if [SSL::cipher version] returns "none" to determine if there was no encryption. Those commands probably return none or nothing if no handshake was completed. You could test this with a simple log statement in the Codeshare example.
Aaron - Martin_Kaiser_1
Nimbostratus
Hi again.
in order to make this shorter and to avoid logging entries, I tried the following version of your suggestion:
rule ssl_redirect_sameport {
when HTTP_REQUEST {
this is useless without "accept non-SSL connections" option in clientssl profile!
if { not ( [SSL::cipher version] contains "SSL" ) } {
HTTP::redirect https://[HTTP::host]:[TCP::local_port][HTTP::uri]
}
}
}
this rule is enabled on a VS as follows:
virtual abc.de-29082 {
pool abc-29082
destination a.b.c.d:29082
ip protocol tcp
rules selfaccess-SNAT ssl_redirect_sameport
persist cookie
profiles { abc.de-acceptnonSSL { clientside } http {} tcp-lan-optimized { serverside } tcp-wan-optimized { clientside } }
vlans { internal external } enable
}
(rule selfaccess-SNAT uses a SNAT pool address if the client is on the same subnet as the VS, thus enabling the pool members themselves to access this VS - no SNAT otherwise)
The SSL profile reads as follows:
profile clientssl abc.de-acceptnonSSL {
defaults from abc.de
nonssl enable
}
With this setup, when typing http://abc.de:29082 into the browser address line, I do not get any webpage displayed (connection error - tested with IE8 and Firefox 4.0.1). Wireshark shows that the BigIP issues a TCP reset as soon as it receives the client's unencrypted http GET request. When disabling the ssl_redirect_sameport iRule, the unencrypted access works. Only the redirect doesn't seem to work. Any hints on this? Thanks again for your help.
Martin - hoolio
Cirrostratus
Can you add the logging back in to see what is being triggered in the iRule? Is it possible that the cipher is TLS and therefore not matching your check of the cipher version containing SSL?when HTTP_REQUEST { enable "accept non-SSL connections" option in clientssl profile to use this iRule log local0. "[IP::client_addr]:[TCP::client_port]: cipher name: [SSL::cipher name], version: [SSL::cipher version], bits: [SSL::cipher bits]" if { not ( [SSL::cipher version] contains "SSL" ) } { HTTP::redirect https://[HTTP::host]:[TCP::local_port][HTTP::uri] } }
Aaron - Martin_Kaiser_1
Nimbostratus
Hi.
even trying to only create those log entries gives me some TCL errors when trying to access VS through plain http:rule ssl_redirect_sameport { when HTTP_REQUEST { this is useless without "accept non-SSL connections" option in clientssl profile! log local0. "[IP::client_addr]:[TCP::client_port]: cipher name: [SSL::cipher name], version: [SSL::cipher version], bits: [SSL::cipher bits]" if { not ( [SSL::cipher version] contains "SSL" ) } { HTTP::redirect https://[HTTP::host]:[TCP::local_port][HTTP::uri] } } May 24 12:29:55 tmm3 tmm3[29219]: 01220001:3: TCL error: ssl_redirect_sameport - Error: SSL hudfilter not reached or not in chain (line 1) invoked from within "SSL::cipher name"
https access works properly, doesn't throw any errors and by the way: yes, you're right the cipher version contains TLS instead of SSL:May 24 12:40:26 tmm6 tmm6[29222]: Rule ssl_redirect_sameport : a.b.c.d:4612: cipher name: RC4-SHA, version: TLSv1, bits: 128
When writing the iRule with the following if-clause, it works perfectly:if {not ([catch {SSL::cipher version} result]) && $result ne "none"}
After looking up the catch TCL command with respect to those experienced errors, now I truly understand its purpose üôÇ
many thanks for the lesson!
Martin - hoolio
Cirrostratus
Great. Glad you've got it now :)
Aaron - nitass
Employee
it seems it does not work in 10.2.3.[root@ve1023:Active] config b version|grep -iA 1 version BIG-IP Version 10.2.3 112.0 Final Edition [root@ve1023:Active] config b virtual bar list virtual bar { snat automap pool foo destination 172.28.65.152:https ip protocol tcp rules myrule profiles { http {} myclientssl { clientside } tcp {} } } [root@ve1023:Active] config b profile myclientssl list profile clientssl myclientssl { defaults from clientssl nonssl enable } [root@ve1023:Active] config b rule myrule list rule myrule { when HTTP_REQUEST { log local0. "\[SSL::cipher version\]: [SSL::cipher version]" log local0. "\[catch {SSL::cipher version} result\]: [catch {SSL::cipher version} result]" log local0. "\$result: $result" if {$result equals "None"}{ log local0. "\$result is None" HTTP::redirect "https://[HTTP::host][HTTP::uri]" } else { log local0. "\$result is not None" } } } [root@ve1023:Active] config curl -I http://172.28.65.152:443/ Nov 11 16:42:17 local/tmm info tmm[4766]: Rule myrule : [SSL::cipher version]: None Nov 11 16:42:17 local/tmm info tmm[4766]: Rule myrule : [catch {SSL::cipher version} result]: 0 Nov 11 16:42:17 local/tmm info tmm[4766]: Rule myrule : $result: None Nov 11 16:42:17 local/tmm info tmm[4766]: Rule myrule : $result is None [root@ve1023:Active] config curl -Ik https://172.28.65.152:443/ HTTP/1.1 200 OK Date: Sat, 12 Nov 2011 00:42:46 GMT Server: Apache/2.2.3 (CentOS) Last-Modified: Fri, 11 Nov 2011 14:48:14 GMT ETag: "4183e4-3e-9c564780" Accept-Ranges: bytes Content-Length: 62 Connection: close Content-Type: text/html; charset=UTF-8 [root@ve1023:Active] config Nov 11 16:42:32 local/tmm info tmm[4766]: Rule myrule : [SSL::cipher version]: TLSv1 Nov 11 16:42:32 local/tmm info tmm[4766]: Rule myrule : [catch {SSL::cipher version} result]: 0 Nov 11 16:42:32 local/tmm info tmm[4766]: Rule myrule : $result: TLSv1 Nov 11 16:42:32 local/tmm info tmm[4766]: Rule myrule : $result is not None
however, if i trigger HTTP::redirect in HTTP_RESPONSE event, it works.[root@ve1023:Active] config b rule myrule list rule myrule { when HTTP_REQUEST { set http_redirect 0 log local0. "\[SSL::cipher version\]: [SSL::cipher version]" log local0. "\[catch {SSL::cipher version} result\]: [catch {SSL::cipher version} result]" log local0. "\$result: $result" if {$result equals "None"}{ log local0. "\$result is None" set http_redirect 1 set http_host [HTTP::host] set http_uri [HTTP::uri] } else { log local0. "\$result is not None" } } when HTTP_RESPONSE { if {$http_redirect}{ HTTP::redirect "https://$http_host$http_uri" } } } [root@ve1023:Active] config curl -I http://172.28.65.152:443/ HTTP/1.0 302 Found Location: https://172.28.65.152:443/ Server: BigIP Connection: close Content-Length: 0 [root@ve1023:Active] config Nov 11 16:45:21 local/tmm info tmm[4766]: Rule myrule : [SSL::cipher version]: None Nov 11 16:45:21 local/tmm info tmm[4766]: Rule myrule : [catch {SSL::cipher version} result]: 0 Nov 11 16:45:21 local/tmm info tmm[4766]: Rule myrule : $result: None Nov 11 16:45:21 local/tmm info tmm[4766]: Rule myrule : $result is None [root@ve1023:Active] config curl -Ik https://172.28.65.152:443/ HTTP/1.1 200 OK Date: Sat, 12 Nov 2011 00:45:47 GMT Server: Apache/2.2.3 (CentOS) Last-Modified: Fri, 11 Nov 2011 14:48:14 GMT ETag: "4183e4-3e-9c564780" Accept-Ranges: bytes Content-Length: 62 Connection: close Content-Type: text/html; charset=UTF-8 [root@ve1023:Active] config Nov 11 16:45:33 local/tmm info tmm[4766]: Rule myrule : [SSL::cipher version]: TLSv1 Nov 11 16:45:33 local/tmm info tmm[4766]: Rule myrule : [catch {SSL::cipher version} result]: 0 Nov 11 16:45:33 local/tmm info tmm[4766]: Rule myrule : $result: TLSv1 Nov 11 16:45:33 local/tmm info tmm[4766]: Rule myrule : $result is not None - hoolio
Cirrostratus
Hey Nitass,
Can you clarify what doesn't work in v11?
Thanks, Aaron
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
DevCentral Quicklinks
* 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
Discover DevCentral Connects