Forum Discussion
Restrict Source IPs iRule
Hi all
Forgive what may be such an easy iRule question but unfortunately my experience with them is rather limited and time is of the essence. We have an iRule which looks to be doing something with the client certificate as you can see:
when CLIENTSSL_CLIENTCERT priority 500 {
set cnAllowClass "[string range [virtual name] 0 end-2]cn_allow_class"
set clientCertRequiredClass "[string range [virtual name] 0 end-2]client_cert_required_class"
set clientCertHeaderName "ssl_client_cert"
set clientIP [IP::client_addr]
if {[SSL::cert count] eq 0} {
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
}
}
set cnExists [class match $subjectDN contains $cnAllowClass]
if {$cnExists ne 0} {
} else {
reject
}
}
...what we need to do is add something in before this code that will say, in plain English:
"if the source IP address is a.b.c.d, then use SSL profile abcd. If not, then use SSL profile efgh."
Any ideas on how we can achieve this?
Thank you.
- iaine
Nacreous
Hi
You need some logic within the CLIENT_ACCEPTED Event for this. Something like this for a single IP.....this will look for a connection from 10.10.10.10 and apply a different SSL profile. All other connections will used the default config of the VIP
when CLIENT_ACCEPTED { if { [IP::addr [IP::client_addr] equals 10.10.10.10] } { SSL::profile new_clientssl } }
You can expand out for look for a subnet
when CLIENT_ACCEPTED { if { [IP::addr [IP::client_addr] equals 10.10.10.0/24] } { SSL::profile new_clientssl } }
or use a DataGroup if you want to....
when CLIENT_ACCEPTED { if { [class match [IP::client_addr] equals source_ip] } { SSL::profile new_clientssl } }
- Thornid
Nimbostratus
Thank you iaine
That was something that did come across my mind but then I realised that I framed the question incorrectly, apologies.
The logic should actually read:
"if the source IP address is a.b.c.d, then use SSL profile abcd, then stop processing, i.e. do not process other logic in the iRule"
Essentially, there are some clients that we need to come into this VS but not be subject to the iRule logic (client cert, checks etc.) So need a way to allow them to come in and use an SSL profile that does not have Client Authentication enabled, then stop. All other clients just continue as normal using the default SSL profile (with client auth applied).
Thanks
- iaine
Nacreous
Hi
To stop processing the iRule further, you can either use Event disable command or you can use a variable to stop specific events or part of code from running depending on requirements. Such as...
when CLIENT_ACCEPTED { if { [IP::addr [IP::client_addr] equals 10.10.10.0/24] } { SSL::profile new_clientssl set sourceip 1 } } when CLIENTSSL_CLIENTCERT { if {[info exists sourceip]}{ return} }
this uses return to stop this particular event
- Thornid
Nimbostratus
Brill, thanks iaine
Out of curiosity, setting the variable 'sourceip 1' - what does '1' in this instance mean or refer to?
- iaine
Nacreous
hi - it's just an arbitrary value so that the attribute contains something when info exists queries it.
- Thornid
Nimbostratus
Excellent, that makes sense. I shall be giving this a whirl a bit later today and will report back.
Thank you iaine.
- Thornid
Nimbostratus
Hi iaine
Hasn't quite worked as expected. I added the new code snippet as follows:
when CLIENT_ACCEPTED { if { [IP::addr [IP::client_addr] equals 1.2.3.4/32] } { SSL::profile new-ssl-profile set sourceip 1 } } when CLIENTSSL_CLIENTCERT priority 500 { if {[info exists sourceip] }{ return} set cnAllowClass "[string range [virtual name] 0 end-2]cn_allow_class" set clientCertRequiredClass "[string range [virtual name] 0 end-2]client_cert_required_class" set clientCertHeaderName "ssl_client_cert" set clientIP [IP::client_addr] if {[SSL::cert count] eq 0} { 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 } } set cnExists [class match $subjectDN contains $cnAllowClass] if {$cnExists ne 0} { } else { reject } }
...yet when we debug this we see that the iRule does not stop at the CLIENTSSL_CLIENTCERT event and we get this log:
TCL error: /Common/test-irule <HTTP_REQUEST> - can't read "clientCertHeaderName": no such variable while executing "HTTP::header exists $clientCertHeaderName"
Any ideas?
- iaine
Nacreous
Hi
Have you confirmed that the CLIENT_ACCEPTED code is firing. Put a log statement in after the SSL profile line just to confirm that this is working
when CLIENT_ACCEPTED { if { [IP::addr [IP::client_addr] equals 1.2.3.4/32] } { SSL::profile new-ssl-profile set sourceip 1 log local0. " Source IP Config is working for [IP::client_addr]"
- Thornid
Nimbostratus
Hi iaine
Sorry for the delay. We actually got it working in the end. There was actually more code past the CLIENTSSL_CLIENTCERT event - HTTP REQUEST, we just added the if info exists return statement in there and voila, it worked.
Thank you for your effort and patience with this one.
Recent Discussions
Related Content
* 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