Forum Discussion

Virtualrana_132's avatar
Virtualrana_132
Icon for Nimbostratus rankNimbostratus
Nov 07, 2014

HSTS - Header not inserted with iRule

Hi,

 

Following is my iRule which is attached to $mydomain$ (http) VirtualServer in F5 for HSTS, but it is not inserting the "Strict-Transport-Security" header in the http response. When I run "curl -s -D- $mydomain$.com.au | grep Strict", it doesn't return anything. Am I missing something here? Please advise...

 

===================================================================

 

when HTTP_REQUEST { HTTP::respond 301 Location "https://[HTTP::host][HTTP::uri]" }

 

when HTTP_RESPONSE { HTTP::header insert Strict-Transport-Security "max-age=31536000" }

 

=====================================================================

 

Thanks and regards.

 

Rana

 

9 Replies

  • R_Eastman_13667's avatar
    R_Eastman_13667
    Historic F5 Account

    Try this in your HTTP_RESPONSE event and then check the /var/log/ltm log.

    foreach headerName [HTTP::header names] {
        append headerNames " |$headerName: [HTTP::header value $headerName]"
    }
    log local0. "$headerNames"
    
  • Are you attaching the HSTS response iRule to your HTTPS VIP? The HSTS header should only be sent via HTTPS.

     

  • Hi Guys... Thank you for your responses.

     

    @ Eastman: I've added the bit you mentioned and following is how the iRule looks like. Still no luck and the log shows nothing.

     

    ====

     

    iRule for HSTS HTTP Virtuals

    when HTTP_REQUEST { HTTP::respond 301 Location "https://[HTTP::host][HTTP::uri]" }

     

    when HTTP_RESPONSE { HTTP::header insert Strict-Transport-Security "max-age=31536000"

     

    foreach headerName [HTTP::header names] { append headerNames " |$headerName: [HTTP::header value $headerName]" }

     

    log local0. "$headerNames"

     

    }

     

    ====

     

    @ bepsoccer: My understanding: I applied the iRule to http VS as the first line of the iRule is HTTP REDIRECT, so i didn't apply the iRule to HTTPS VS. Please correct me if I am wrong.

     

    Thanks guys, appreciate your help.

     

    Rana

     

  • Hello,

     

    As your http VS directly answer with a redirect, your HTTP_RESPONSE event is never triggered.

     

    You should build your own irule in an HTTP_REQUEST event and use the following command instead :

     

    HTTP::respond 302 noserver Location "https://www.domain.org" Strict-Transport-Security "max-age=31536000"

     

    BR

     

    Yann

     

  • Your Virtual server that is listening for HTTP should have one iRule :

    when HTTP_REQUEST {
    set my_loc "https://[HTTP::host][HTTP::uri]"
    TCP::respond "HTTP/1.1 301 Moved Permanently\r\nLocation: $my_loc\r\nConnection: close\r\nContent-Length: 0\r\n\r\n"
    TCP::close
    }
    

    Your virtual server that is handing HTTPS has to have a client SSL profile and use a different iRule:

      when HTTP_RESPONSE {
        HTTP::header insert "Strict-Transport-Security" "max-age=15552000; includeSubDomains"
    }
    

    If you are going to use HSTS your HTTP response should be 301 not 302. Also, the specification states that the HSTS header should only be sent by the HTTPS site.

  • Hi Guys,

     

    It was my lack of understanding about how the iRules were triggering.

     

    Both Yann and bepsoccer are correct, that HTTP_RESPONSE event was never triggered and needed to have the Separate iRule attached to https VS with the following .

     

    when HTTP_RESPONSE { HTTP::header insert Strict-Transport-Security "max-age=15552000; includeSubDomains" }

     

    Really appreciate your help guys.

     

    Thank you

     

    Rana

     

  • This can also be caused by Web Acceleration or manual use of iRule CACHE commands.

    e.g. HTTP_RESPONSE will not fire on anything pulled from cache.

    You can use CACHE_RESPONSE instead. I now use two rules and attach as appropriate.

    when HTTP_RESPONSE {
        HTTP::header replace Strict-Transport-Security "max-age=31536000; includeSubDomains"
    }
    

    And,

    when CACHE_RESPONSE {
        CACHE::header replace Strict-Transport-Security "max-age=31536000; includeSubDomains"
    }
    
  • hey guys, may i know what is the difference between the following 2 lines?

     

    HTTP::header replace Strict-Transport-Security "max-age=31536000; includeSubDomains"

     

    HTTP::header insert Strict-Transport-Security "max-age=31536000; includeSubDomains"