09-Oct-2023 06:03
I need an irule to decline/refuse/ an incomming tcp session from a source to a vip (ip address/port) if that source has aleady "n" number of connections open. I am using Fast layer 4 LTM configuration
So for every incomming TCP SYN from a /32 source to a vip (destination ip and port)
-> the irule should verify the amount of open connections from that source to the vip it requests a connection for (destination ip and port)
-> if the amount of "open" connections is lower than a configured value > the connections is allowed
-> if the amount of "open" connections is higher than a configured value > the connection is refused
As I am not used ti create Irules I am a bit lost, ps I don't have ASM on the F5
Can someone help please ?
Solved! Go to Solution.
10-Oct-2023 07:02
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%20....
09-Oct-2023 06:38
Hi @S_Meulmeester ,
you can use Connection limit per virtual server and source ip subnet , look at this Article :
https://my.f5.com/manage/s/article/K45530602
don't bother yourself with complex irule in this case , it consumes your resources and sometimes you may not be able to measure the impact if you wrote it wrong or if it consumed alot of resources
09-Oct-2023 06:51
Hi,
That is not the same as what I need! what you propose is : Connection Rate Limit Mode = rate limiting per second so if i put it to 10 it will allow 10 connections per second = 600 connections per minute
I want to be able to limit a source ip to connect for example 200 sessions max and not per time interval.
09-Oct-2023 06:56
Hi @S_Meulmeester ,
Not rate limit , there is another option of connection limit.
if you put for ex 10 connection limit , if this source did 11 connection the 11th will be dropped till one of 10 concurrent connections goes out.
Don't go for rate limit
09-Oct-2023 07:12
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%20F...
10-Oct-2023 01:15
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 ?
10-Oct-2023 07:02
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%20....