Forum Discussion

Thornid's avatar
Thornid
Icon for Nimbostratus rankNimbostratus
Jul 28, 2020

Help with iRule to enable SSL profile based on XFF Header

Hi all

We have some apps on our F5s that will need to go behind the Silverline WAF (can't use ASM so this is our only option). Currently on the F5s we have an iRule which selects a particular client SSL profile based simply on the public IP of the client request. For those clients that require client authentication we then go on to do a few more checks under the CLIENTSSL_CLIENTCERT event as follows, finally we insert data from the client cert into some headers:

when CLIENT_ACCEPTED {
	if {[class match [IP::client_addr] equals ip_list_dg]} {
		SSL::profile "[string range [virtual name] 0 end-2]noclientcert_clientssl"
	} else {
		SSL::profile "[string range [virtual name] 0 end-2]clientssl"
	}
}

when CLIENTSSL_CLIENTCERT priority 500 {
	# Set DG Names for this VS
	set clientCertRequiredClass "[string range [virtual name] 0 end-2]client_cert_required_class"
	# iRules evaluate header names as case insensitive
	set static::clientCertHeaderName "ssl_client_cert"
	set clientIP [IP::client_addr]
	if {[SSL::cert count] eq 0} {
		# Hash out next line to disable logging
		# log local0.debug "No Client Cert received from $clientIP - rejecting the connection"
		reject
		return
	} else {
		set subjectDN [string tolower [X509::subject [SSL::cert 0]]]
		if {[class match $subjectDN contains $clientCertRequiredClass] ne 0} {
			set clientCertHeaderValue [b64encode [SSL::cert 0]]
			set flgInsertClientCertHeader 1
		}
	}
}

when HTTP_REQUEST priority 50 {
	if {[HTTP::header exists $static::clientCertHeaderName]} {
		# log local0.alert "Warning: SSL Client Header present in request from $clientIP - Removing header"
		HTTP::header remove $static::clientCertHeaderName
	}
	if {[info exists flgInsertClientCertHeader]} {
		HTTP::header insert $static::clientCertHeaderName $clientCertHeaderValue
		# Hash out next line to disable logging
		# log local0.debug "Client Cert inserted for $clientIP - Subject: $subjectDN"	
	}
}

All works well. But now we're going behind the Silverline WAF, all flows will appear to come from the same IP range and therefore our logic in the CLIENT_ACCEPTED event breaks. The WAF inserts the XFF header. What would be the best way therefore to utilise the XFF header to perform the same logical checks as above? As the XFF header is within the payload we would need to have the logic within one of the HTTP_xxx events, but then that comes after the TLS authentication. And the confusion begins... any ideas?

Thanks

1 Reply

  • You need to use SSL::renegotiate

     

    As you say, you need to examine the X-Forwarded-For header, but that does not arrive until after TLS negotiation.

     

    So you establish un-authenticated TLS, and then examine the XFF header, select the new TLS settings, and SSL::renegotiate

     

    However, the actual endpoint from the client perspective will be Silverline, who will be terminating TLS. I don't really see how you can make this work in this context.