Forum Discussion
I have finally decided to change to another approach: to validate client's ID (hostname or IP addr) via DNS lookup and make a deny/allow decision based on the result of the lookup. The irule is here:
Editors note: Updated this link to point to the new Codeshare @JG created.
An irule to validate client ID via DNS lookup using the stream profile. DevCentral (f5.com)
- Nikoolayy1Jun 29, 2021MVP
The link for the irule needs fixing as I don't find it even in the search in Devcentral.
- JGJun 30, 2021Cumulonimbus
I am trying to get this back.
- JGJul 01, 2021Cumulonimbus
Found it in the archives:
http://web.archive.org/web/20171128045302/https:/devcentral.f5.com/questions/an-irule-to-validate-client-id-via-dns-lookup-using-the-stream-profile
- Nikoolayy1Jul 01, 2021MVP
Thanks! You can reshare the code in code share but I will attach it here just in case:
when RULE_INIT {
set static::smtp_debug 1
set static::route_domain_id 1
}
when CLIENT_ACCEPTED {
if {[class match [getfield [IP::client_addr] % 1] equals internal_IP]} {
} else {
drop
return
}
STREAM::expression {@[hH][eE][lL][oO] .*[[:cntrl:]][[:cntrl:]]@@ @[eE][hH][lL][oO] .*[[:cntrl:]][[:cntrl:]]@@ @[.][[:cntrl:]][[:cntrl:]]@@ @354 End data with @@ @250 2.0.0 Ok: queued as @@}
STREAM::enable
set disable_matching 0
}
when STREAM_MATCHED {
switch -glob [STREAM::match] {
"354 End data with " {
incr disable_matching
STREAM::replace
return
}
"250 2.0.0 Ok: queued as " {
STREAM::replace
return
}
default {
set mstring_hex ""
set mstring_hex_trimmed ""
set mstring_ascii ""
set c_initiation_string_hex_trimmed ""
set detected_c_initiation_string ""
binary scan [STREAM::match] H* mstring_hex
set mstring_hex_trimmed [string range $mstring_hex 0 end-4]
set mstring_ascii [binary format H* $mstring_hex_trimmed]
if { $mstring_ascii eq "\." } {
set disable_matching 0
STREAM::replace
return
}
if { $disable_matching > 0 } {
STREAM::replace
return
}
if { ( [string tolower $mstring_ascii] starts_with "helo " ) or ( [string tolower $mstring_ascii] starts_with "ehlo " ) } {
set c_declared_id [string range $mstring_ascii 5 end]
}
if { $c_declared_id contains "\[" } {
set c_declared_id [ string map [ list \[ "" \] "" ] $c_declared_id ]
}
set a null
set b null
set c null
set d null
scan $c_declared_id {%d.%d.%d.%d} a b d c
if { !($a == "null") && !($b == "null") && !($c == "null") && !($d == "null") } {
if { (0 <= $a) && ($a <= 255) &&
(0 <= $b) && ($b <= 255) &&
(0 <= $c) && ($c <= 255) &&
(0 <= $d) && ($d <= 255) } {
if { $static::route_domain_id != 0 } {
append c_declared_id "%" $static::route_domain_id
}
if { not ( $c_declared_id equals [IP::client_addr] ) } {
drop
return
}
}
} else {
if { ! ( $c_declared_id contains "\." ) } {
drop
return
}
if { $static::route_domain_id != 0 } {
set resolved_addrs [RESOLV::lookup @172.18.240.210%$static::route_domain_id -a $c_declared_id]
} else {
set resolved_addrs [RESOLV::lookup @172.18.240.210 -a $c_declared_id]
}
if { not ( $resolved_addrs equals "" ) } {
set addr_matched 0
foreach resolved_addr $resolved_addrs {
if { $static::route_domain_id != 0 } {
append resolved_addr "%" $static::route_domain_id
}
if { $resolved_addr equals [IP::client_addr] } {
incr addr_matched
break
}
}
if { $addr_matched < 1 } {
drop
return
}
} else {
drop
return
}
}
STREAM::replace
return
}
}
}
when SERVER_CONNECTED {
STREAM::expression {@354 End data with @@ @250 2.0.0 Ok: queued as @@}
STREAM::enable
}