Forum Discussion
I need an irule to decline/refuse/ an incomming tcp session from a source to a vip (ip address/port)
- Oct 10, 2023
I plan to use this
# Limit each client IP address to 20 concurrent connections
when CLIENT_ACCEPTED {# Check if the subtable has over 20 entries
if { [table keys -subtable connlimit:[IP::client_addr] -count] >= 20 } {
reject
} else {# Add the client IP:port to the client IP-specific subtable
# with a max lifetime of 180 seconds
table set -subtable connlimit:[IP::client_addr] [TCP::client_port] "" 180
}
}when CLIENT_CLOSED {
# When the client connection is closed, remove the table entry
table delete -subtable connlimit:[IP::client_addr] [TCP::client_port]
}
https://community.f5.com/t5/technical-articles/advanced-irules-tables/ta-p/290369
https://clouddocs.f5.com/api/irules/table.html#:~:text=If%20no%20timeout%20is%20specified,timeout%20will%20not%20be%20changed.
Hi S_Meulmeester ,
Sorry for that mis-understanding , you can't limit per source and VS at the same time , you can use only limiting per Virtual server or rate limiting for ( source address & virtual server )
Could you try this irule :
when RULE_INIT {
array set ::active_clients { }
}
when CLIENT_ACCEPTED {
set client_ip [IP::remote_addr]
if { [info exists ::active_clients($client_ip)] } {
if {$::active_clients($client_ip) > 5 } {
reject
return
} else {
incr ::active_clients($client_ip)
}
} else {
set ::active_clients($client_ip) 1
}
}
when CLIENT_CLOSED {
if { [info exists ::active_clients($client_ip)] } {
incr ::active_clients($client_ip) -1
if { $::active_clients($client_ip) <= 0 } {
unset ::active_clients($client_ip)
}
}
}
use this as a reference : https://github.com/f5devcentral/f5-irule-editor/blob/master/iRuler/Templates/Limit%20Connections%20From%20Client.txt
Hi, it does something but not as expected, I verified it with a TCP dump : 5 first connection get accepted, 6th° gets RST, 7th°gets accepted again, 8th get RST, 9th gets accepted : at that time I have 7 open connections from the same source .... and so on ...
I found this rule
when CLIENT_ACCEPTED {
set x [table incr "ip-block-[IP::client_addr]"]
if { $x == 1 } {
required because we cannot set timeout via 'table incr'
table set "ip-block-[IP::client_addr]" 1 3600 indef
} elseif { $x >= 50 } {
reject
}
}
when CLIENT_CLOSED {
if { [table incr "ip-block-[IP::client_addr]" -1] <= 0 } {
table delete "ip-block-[IP::client_addr]"
}
}
It gave an error adding it and I had to remove the bolt line so now I have
when CLIENT_ACCEPTED {
set x [table incr "ip-block-[IP::client_addr]"]
if { $x == 1 } {
table set "ip-block-[IP::client_addr]" 1 3600 indef
} elseif { $x >= 4 } {
reject
}
}
when CLIENT_CLOSED {
if { [table incr "ip-block-[IP::client_addr]" -1] <= 0 } {
table delete "ip-block-[IP::client_addr]"
}
}
This seems to work but to be honest I don't fully understand what it does and what the 3600 indef is about
Any suggestions ?
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