Forum Discussion

Sake_Blok's avatar
Sake_Blok
Icon for Nimbostratus rankNimbostratus
May 10, 2007

Providing an http-response after killing a serverside SSL connection

Hi,

I'm building an iRule on a vip with serverside-ssl. The iRule must validate the common name in the server-certificate dynamically against the Host: header in the http-request. If the cn doe not match, the iRule should terminate the ssl-session on the server-side and give a http-error-response on the client-side.

Here is what I have so far:


when HTTP_REQUEST {
   set hostname [HTTP::host]
}
when SERVERSSL_HANDSHAKE {
   set sslcert [SSL::cert 0]
   set cn [findstr [X509::subject $sslcert] "CN=" 3]
   if { $cn ne $hostname } {
      reject
      log local0. "Connection closed $cn != $hostname"
   }
}

I want to make sure that the initial http-request does not get forwarded to the back-end-server before I terminate the connection, so using the HTTP_RESPONSE event to give the error-message is not an option. Unfortunately I can't use "HTTP:respond" in the SERVERSSL_HANDSHAKE event.

Is there a way to close the SSL-session on the serverside *before* the client-request is forwarded to it, while keeping the client-connection open to provide an http-error-response?

I also tried LB::detach, but then the connection stalls. Is ther a way to turn back to the client-connection after the LB::detach command?

Cheers,

Sake

4 Replies

  • The HTTP_REQUEST should fire after the SERVERSSL_HANDSHAKE. So you can set a variable ("go/nogo") in the SERVERSSL_HANDSHAKE, and read it in HTTP_REQUEST. If its a "nogo", then HTTP_REQUEST can issue an HTTP::respond statement.

     

     

    Kevin
  • Hi Kevin,

    That's what I thought too. But unfortunately this is not the case in the server-side ssl-connection. I added an iRule that logs an entry on every event and this is what the logging looks like:

    
    May 10 11:09:37 tmm tmm[12822]: Rule rule_event : in CLIENT_ACCEPTED
    May 10 11:09:37 tmm tmm[12822]: Rule rule_event : in HTTP_REQUEST
    May 10 11:09:37 tmm tmm[12822]: Rule rule_event : in LB_SELECTED
    May 10 11:09:37 tmm tmm[12822]: Rule rule_event : in SERVER_CONNECTED
    May 10 11:09:37 tmm tmm[12822]: Rule rule_event : in HTTP_REQUEST_SEND
    May 10 11:09:37 tmm tmm[12822]: Rule rule_event : in SERVERSSL_HANDSHAKE
    May 10 11:09:37 tmm tmm[12822]: Rule rule_event : in HTTP_RESPONSE
    May 10 11:09:37 tmm tmm[12822]: Rule rule_event : in SERVER_CLOSED
    May 10 11:09:37 tmm tmm[12822]: Rule rule_event : in CLIENT_CLOSED

    Cheers,

    Sake
  • Sorry, it took me some time to figure out what you were trying to do. So SERVERSSL events happen when you're re-encrypting traffic from the BigIP back to the web server. And in this case, if I understand you correctly, you're trying to determine if that web server is presenting the correct server certificate. I guess I don't understand why you'd want to do that unless you no control over the web servers that you're in front of. In any case, the answer is that you have to do the HTTP::respond in the HTTP_RESPONSE event. You're terminating the connection if the server cert is wrong, so it really should matter if any data gets to the web server.

     

     

    Kevin
  • Deb_Allen_18's avatar
    Deb_Allen_18
    Historic F5 Account
    Hi Sake --

    You might try using "LB::detach" to close the server side of the connection without affecting the client side:
    when HTTP_REQUEST {
       set hostname [HTTP::host]
    }
    when SERVERSSL_HANDSHAKE {
       set sslcert [SSL::cert 0]
       set cn [findstr [X509::subject $sslcert] "CN=" 3]
       if { $cn ne $hostname } {
          LB::detach
          log local0. "Server-side connection closed: $cn != $hostname"
          HTTP::respond 200 content "blah"
       }
    }
    HTH

    /deb