Forum Discussion
Matthew_McCleme
Nimbostratus
Oct 11, 2007ClamAV iRule
ClamAV has an FTP'esque protocol in that initial connections are made via a control connection, which then requests a stream port to send the actual files to be scanned on. I've written and tested the following iRule, however there might be a few issues with it:
when SERVER_CONNECTED {
log "server connected"
TCP::collect
}
when SERVER_DATA {
log "server data"
set sdata [TCP::payload]
if { $sdata contains "PORT" } {
set ::clamport [regexp -inline {[0-9]+} [TCP::payload]]
log "I have $::clamport"
listen {
proto 6
timeout 30
bind [LINK::vlan_id] [peer {IP::local_addr}] $::clamport
server [LB::server addr] $::clamport
allow [IP::client_addr]
}
}
TCP::release
TCP::collect
}
This iRule is attached to an internal VS listening on 3310, SNAT automap, round robin load balancing an no persistance profile.
Now, the main issue I can see is that $::clamport is global(assuming my reading of the TCL manual is right), however listen{} doesn't appear to work with non-global variables. If I simply used $clamport TCL would complain that the variable doesn't exist.
Any suggestions on improving the iRule? I don't think speed is hugely important as the control connection is pretty lightweight however the use of globals makes me nervous and I'm hoping that I've missed something and listen can be made to work with local variables.
2 Replies
- Matthew_McCleme
Nimbostratus
Updated iRule to get around the fact that ::port is global and to avoid possible stomping of the variable. Although I'm guessing that no one is all that interested in load balancing ClamAV considering how quickly this topic started sinking to the bottom.when RULE_INIT { array set ::clamp { } } when SERVER_CONNECTED { log "server connected" TCP::collect 1 } when SERVER_DATA { log "server data" set sdata [TCP::payload] if { $sdata contains "PORT" } { set ::clamp([IP::client_addr][TCP::client_port]) [regexp -inline {[0-9]+} [TCP::payload]] log "I have $::clamp([IP::client_addr][TCP::client_port])" listen { proto 6 timeout 10 bind [LINK::vlan_id] [peer {IP::local_addr}] $::clamp([IP::client_addr][TCP::client_port]) server [LB::server addr] $::clamp([IP::client_addr][TCP::client_port]) allow [IP::client_addr] } array unset ::clamp([IP::client_addr][TCP::client_port]) } TCP::release TCP::collect 1 }
- MattB_MA_170307
Nimbostratus
FWIW: We're standing up a pool of ClamAV containers to check incoming SMTP services post-decryption, and this iRule worked flawlessly. Thanks very much for taking the time to write it out!
Recent Discussions
Related Content
DevCentral Quicklinks
* 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
Discover DevCentral Connects