# is there any way to solve this - Limiting icmp ping response ....



## edhunter (Jan 12, 2009)

Hello guys

I have this problem. I am running apinger on my freebsd router for simple monitoring the connectivity to different kind of hosts (local and internet). But when someone in the network tries very intensive pings to my router, freebsd automaticaly limits the icmp rate and thus the packets from apinger gets lost. And then I got false alarms.


```
Jan 12 15:15:07 ROUTER kernel: Limiting icmp ping response from 2521 to 200 packets/sec
Jan 12 15:15:08 ROUTER kernel: Limiting icmp ping response from 2522 to 200 packets/sec
...
...
Jan 12 15:15:12 ROUTER apinger: ALARM: localhost IPv4(127.0.0.1)  *** down ***
Jan 12 15:15:12 ROUTER kernel: Limiting icmp ping response from 874 to 200 packets/sec
Jan 12 15:15:13 ROUTER apinger: alarm canceled: localhost IPv4(127.0.0.1)  *** down ***
```

Is there any way to avoid blocking of apingers packets (they are 1 packet per second)?
I know about net.inet.icmp.icmplim (default 200), but raising it is not a good option.
I am using ipfw for firewall. Is there any way to limit the icmp packets rate with ipfw somewhere under 200?
And if there is such way for limiting the rate .. will the os react first to higher rate of icmp packets or firewall will drop them first?

10x in advance
Georgi Iovchev


----------



## SirDice (Jan 12, 2009)

You could try and block just the ICMP Echo Requests send to your fbsd box. 
Then it won't respond to pings anymore but still allow an ICMP Echo Response in.


----------



## anomie (Jan 12, 2009)

edhunter said:
			
		

> I am using ipfw for firewall. Is there any way to limit the icmp packets rate with ipfw somewhere under 200?



No need to reinvent the wheel with ipfw. You could use the sysctl MIB for this purpose, e.g.: 

*# echo 'net.inet.icmp.icmplim=100' >> /etc/sysctl.conf*

---

Eh, I think I misunderstood your post. You're trying to avoid false alarms? 

See the manpages for icmp(4). The sysctl MIB icmplim_output might be what you want.


----------



## edhunter (Jan 13, 2009)

SirDice said:
			
		

> You could try and block just the ICMP Echo Requests send to your fbsd box.
> Then it won't respond to pings anymore but still allow an ICMP Echo Response in.



I still want this box "pingable" from outside ...  But "priority" to go for replies to pings from my box.



			
				anomie said:
			
		

> Eh, I think I misunderstood your post. You're trying to avoid false alarms?
> 
> See the manpages for icmp(4). The sysctl MIB icmplim_output might be what you want.



Yes I am trying to avoid this alarms 
"net.inet.icmp.icmplim_output: Enable rate limiting of ICMP responses"
this would enable or disable the icmp rate limit at all is that correct. But if I disable it, my box could get flooded... So this is not a good option too (

My idea was .. if I may limit the rate of icmp with rule in ipfw, and add another rule for "my" pings skipping the limit rule. But I dont know if this is possible with ipfw.


----------



## DutchDaemon (Jan 13, 2009)

You could look into ipfw pipes.


----------



## edhunter (Jan 13, 2009)

DutchDaemon said:
			
		

> You could look into ipfw pipes.



hmm thats good idea 
to add general icmp traffic to pipe1 with very low bw
and to add my icmp to another pipe or just to skip the rule for pipe1
that may work ... i'll try it 
10x


----------



## DutchDaemon (Jan 13, 2009)

Exactly.


----------



## edhunter (Jan 13, 2009)

it is working ... but not exactly how i need it
can you help a little more, i still feel like noob with ipfw 

First the working part 
here is the simple test i made:

```
#:> ipfw show
00010    0      0 allow icmp from me to any
00020    0      0 allow ip from any to any icmptypes 0
00100    0      0 pipe 1 icmp from any to any
65535 4158 748662 allow ip from any to any

#:> ipfw pipe list
00001:  40.000 Kbit/s    0 ms   50 sl. 0 queues (1 buckets) droptail
```

then I ping this computer from another bsd machine like this  ping -c 2 192.168.0.3. Here is result:

```
00010    2    168 allow icmp from me to any
00020    0      0 allow ip from any to any icmptypes 0
00100    2    168 pipe 1 icmp from any to any

#:> ipfw pipe list
00001:  40.000 Kbit/s    0 ms   50 sl. 1 queues (1 buckets) droptail
    mask: 0x00 0x00000000/0x0000 -> 0x00000000/0x0000
BKT Prot ___Source IP/port____ ____Dest. IP/port____ Tot_pkt/bytes Pkt/Byte Drp
  0 icmp     192.168.0.2/0         192.168.0.3/0        2      168  0    0   0
```
At least two incoming request has moved through the pipe . I wish theese were 4 (2 incoming and 2 outgoing), but for that I'll ask a bit lower in my post.

Then I zero counters and try to "flood" this machine from another with ping like this ping -c 1000 -i 0.005 192.168.0.3, and got about 60% loss  thats ok (without the pipe this type of ping is with 0% losses). Here it is:

```
#:> ipfw show
00010  406   34104 allow icmp from me to any
00020    0       0 allow ip from any to any icmptypes 0
00100 1000   84000 pipe 1 icmp from any to any
65535 5722 1056417 allow ip from any to any

#:> ipfw pipe list
00001:  40.000 Kbit/s    0 ms   50 sl. 1 queues (1 buckets) droptail
    mask: 0x00 0x00000000/0x0000 -> 0x00000000/0x0000
BKT Prot ___Source IP/port____ ____Dest. IP/port____ Tot_pkt/bytes Pkt/Byte Drp
  0 icmp     192.168.0.2/0         192.168.0.3/0     1000    84000  0    0 594
```


Now the problems:
1. What I mentioned above, only half traffic goes through the pipe (because of rule 10)

2. I cant make incoming replies associated with my requests to bypass the pipe.. I do it by allowing all replies, but I thing that this is not proper way

here is:

```
#:> ipfw show
00010    0      0 allow icmp from me to any
00020    0      0 allow ip from any to any icmptypes 0
00100    0      0 pipe 1 icmp from any to any
65535 3119 534452 allow ip from any to any
```
Then I ping some address (reachable) with two packets, and is the result:

```
00010    2    168 allow icmp from me to any
00020    2    168 allow ip from any to any icmptypes 0
00100    0      0 pipe 1 icmp from any to any
```
Nothing has moved through the pipe and it is ok, but I think that rule number 20 is too general. I may be too paranoic, but someone may flood me (or the real ips behind my router) with "artificial" icmp echo replies.

To be sure that I will not be missunderstood here is what I am trying to achieve: pings from me (request and their associated replies) never go through the pipe; Pings from another machines (requests to me and their replies from me) - always to go through the pipe.

Can you help more please :>>>


----------



## DutchDaemon (Jan 13, 2009)

Why don't you use 'from me to any' and 'from any to me' to differentiate between the two flows? You can also try adding 'keep-state' to bind return traffic to outbound traffic, forcing them into the same pipe (or forcing them around that pipe).


----------



## edhunter (Jan 14, 2009)

i did it 

```
#!/bin/sh

friends="192.168.0.0/24"
#there will be more

ipfw -f flush
ipfw -f pipe flush

ipfw pipe 1 config bw 5KB/s

ipfw add 10 allow icmp from me to $friends
ipfw add 20 allow icmp from $friends to me
ipfw add 30 allow icmp from $friends to $friends
ipfw add 40 allow icmp from me to me

ipfw add 100 skipto 1000 icmptypes 8 # check for request from me
ipfw add 200 skipto 2000 icmptypes 0 # check for replies to me

ipfw add 1000 allow icmp from me to any # allow request only from me
ipfw add 1001 skipto 9000 icmp from any to any # go in the pipe
ipfw add 2000 allow icmp from any to me # allow replies only to me
ipfw add 2001 skipto 9000 icmp from any to any # go in the pipe

ipfw add 9000 pipe 1 icmp from any to any
```

There is weakness that at rule 2000 I may pass replies that are not associated with my requests.
I couldnt make it with keep-state/check-state. I cant fully understand the mechanism of statefull rules.

However this should be enough for avoiding false alarms from apinger ...


----------

