Forum Discussion

DaveC_53879's avatar
DaveC_53879
Icon for Nimbostratus rankNimbostratus
Apr 17, 2012

irule to eliminate the need for multiple virtuals

I have the rule below which I use to enforce SSL traffic and only allow ports 80 and 443 thru. I use this so I can create one virtual server that listens for port 80 and port 443 requests, instead of creating 2 virtual servers, one for each port. The rule works but it generates a lot of errors similar to the one below the rule. I'm not REAL worried about the errors, but I'm getting ready to upgrade from 9.4.6 to 10.2.3 and would like this setup to be as clean as possible. Is there a way to eliminate the errors and still do what I need it to do? If not, is this going to break when I upgrade? Thanks is advance. Sorry, but I don't know how to paste the rule and retain the formatting.

 

 

Rule:

 

when RULE_INIT { Requests to ports not defined in either the https or http ports list will be reset Define virtual server ports that should have SSL enabled This should be replaced with a datagroup set ::vip_https_ports [list \ 443 \ ] Define virtual server ports that should be answered with HTTP This should be replaced with a datagroup set ::vip_http_ports [list \ 80 \ ] Set this option to 1 to redirect client requests from HTTP to HTTPS. Set to 0 to not redirect clients from HTTP to HTTPS. set ::redirect_http_to_https 1 Set this option to 1 to rewrite the requested URI to lower case. Set to 0 to not rewrite the URI. set ::rewrite_uri_to_lower_case 0 Set this option to 1 to log debug messages (to /var/log/ltm by default) set ::single_vs_debug 0 } when CLIENT_ACCEPTED { Save the VIP name, client IP:port as a log prefix to make the log lines shorter set log_prefix "[IP::client_addr]:[TCP::client_port]" if { [matchclass [TCP::local_port] equals $::vip_https_ports] }{ Request was to an HTTPS port, so do nothing for the clientside connection. The defined client and/or server SSL profiles will be applied as normal if {$::single_vs_debug}{log local0. "$log_prefix: HTTPS request to [IP::local_addr]:[TCP::local_port]"} log an error if the virtual server doesn't have a client SSL profile, but receives an SSL request if {[PROFILE::exists clientssl] == 0}{ if {$::single_vs_debug}{log local0. "$log_prefix:\ Client connection received on port [TCP::local_port], but no client SSL profile is enabled on [IP::local_addr]"} reject } } elseif {([matchclass [TCP::local_port] equals $::vip_http_ports]) }{ Request was to an HTTP port, not an HTTPS port, so disable client SSL profile if one is enabled on the VIP set vip_http_port 1 if {$::single_vs_debug}{log local0. "$log_prefix: HTTP request to [IP::local_addr]:[TCP::local_port]"} Check to see if there is a client SSL profile and if so, disable it if { [PROFILE::exists clientssl] == 1} { if {$::single_vs_debug}{log local0. "$log_prefix: Client SSL profile enabled on VIP. Disabling SSL."} set disable_cmd "SSL::disable" eval $disable_cmd } } else { Request wasn't to a defined port, so reset the TCP connection. if {$::single_vs_debug}{log local0. "$log_prefix:\ Dropping request to undefined port [IP::local_addr]:[TCP::local_port]"} reject } } when HTTP_REQUEST { If redirect_http_to_https is enabled and the request was made to an HTTP port, redirect the client to the same host/URI over HTTPS if { ($::redirect_http_to_https == 1 or ([info exists redirect_http_to_https] && $redirect_http_to_https)) && \ ([info exists vip_http_port] && $vip_http_port==1)}{ HTTP::redirect https://[getfield [HTTP::host] ":" 1][HTTP::uri] if {$::single_vs_debug}{log local0. "$log_prefix:\ Redirecting client [IP::client_addr] to https://[getfield [HTTP::host] \":\" 1][HTTP::uri]"} } else { Rewrite the HTTP::path to lower case if the option is enabled globally or in a separate rule if {$::rewrite_uri_to_lower_case or ([info exists rewrite_uri_to_lower_case] and $rewrite_uri_to_lower_case)}{ HTTP::path [string tolower [HTTP::path]] } } }

 

 

Error:

 

Apr 17 13:45:57 tmm tmm[1710]: 01220001:3: TCL error: new_http-2-https - Operation not supported. Multiple redirect/respond invocations not allowed (line 3) invoked from within "HTTP::redirect https://[getfield [HTTP::host] ":" 1][HTTP::uri]" invoked from within "if { ($::redirect_http_to_https == 1 or ([info exists redirect_http_to_https] && $redirect_http_to_https)) && \ ([info exists vip_http_port] && ..."

 

1 Reply

  • Hi Dave,

     

     

    I updated the Codeshare example for use on v10/v11:

     

     

    https://devcentral.f5.com/wiki/iRules.HttpHttpsSingleVirtualServer.ashx?NoRedirect=1&NS=iRules

     

     

    The error you're getting seems to indicate you're making an HTTP request to the virtual server and getting multiple redirects. Do you have another iRule enabled on the virtual server? Or a custom HTTP profile? If either, can you post the anonymized config using 'tmsh list ltm rule RULE_NAME' or 'tmsh list ltm profile http PROFILE_NAME'

     

     

    Aaron