ICMP is a very important protocol that we use in the network. It can be used to do troubleshooting or possibly to give us a message when something happens to the link as an example.
However, attackers may use this protocol to crash our network devices because ICMP does not require any type of authentication to run. For this reason, we have to know what type of ICMP messages we should keep enabled and what we should disable.
You may ask yourself now: does ICMP have many types? Well, the answer is yes ????
Ping request is an ICMP type, Ping reply is another ICMP type, traceroute is another ICMP type, and the list can continue.
I have taken this picture from IANA website to show you how many types do ICMP have:
Moreover, on each of those listed ICMP types, there are codes. For example, ICMP type 0 has only 1 code which is code 0:
With this I know that ICMP type 0 code 0 is for Echo Reply. Based on that, I will use this information to allow or disallow this type of ICMP.
While ICMP type 3 and many codes as you can see below.
Each combination of types and codes refer to a specific ICMP message.
Now we understand that ICMP has many types, and each type may have many codes, let’s apply on a LAB and only allow the ICMP types that we wish to run in our network.
I am on this scenario now; my PC is connected to R1 on Ether2 and has from it an IP address of 184.108.40.206/24.
To check, let’s issue a ping from the PC to R1:
It is working perfectly ????
The mission of this LAB is to allow the following 3 ICMP types to pass:
- ICMP request/reply
- ICMP for Traceroute
- ICMP for MTU
We always need to be able to use ping when we want to do troubleshooting, so I have to allow ICMP request/reply.
Same for traceroute, it is an important tool to use for troubleshooting, so I will also keep its ICMP working. Finally, I should leave the ICMP for MTU available also in case we are running in our network something like PPPoE server/client.
Apart of those, I want to disable any other ICMP messages to not allow the attacker to profit from that and issue his attacks via them.
Now the questions that would come: shall I enable those ICMP messages on the input chain or the forward chain? Meaning, for traffic coming to the router itself or passing via the router. Well, it is up to you, but as a best practice I would say to apply it on both chains, and that’s what I am going to do in this LAB.
In the 1st rule, I need to check if what we are receiving on the router is an ICMP traffic and I will send it to a custom chain to be treated there. We have to do that on the input and forward chain:
With this rule I am saying that any ICMP traffic coming to the router itself on any of its interfaces, let it go to a custom chain that I called it ICMP chain.
I will do one also for the forward traffic similar to this one:
Now any ICMP traffic coming to the router or passing via the router, will be sent to the custom chain called ICMP.
Now we should do the filter rules inside the ICMP chain to say what is allowed and what is disallowed as ICMP types/codes.
We said that we should allow ping as echo request. Echo request has type 8 code 0 based on the list that I have shared to you from IANA (please check it there if you want). So, let’s allow this:
This will do the work to allow ICMP request.
Now we have to allow ICMP reply which is for the ping reply. Based on IANA, echo reply works on type 0 code 0, so let’s allow this:
Very good. Now I have also echo reply permitted.
The next step is to permit ICMP types/codes responsible for Traceroute. As small research, I have found that the following ICMP types/codes should be permitted so traceroute works in our network:
- ICMP destination unreachable (type 3 code 0)
- ICMP destination unreachable (type 3 code 3)
- ICMP Time exceeded (type 11 code 0)
Let’s create the rules:
Excellent! Those 3 rules have been created for traceroute ICMP packets to be permitted.
I still want to allow the ICMP responsible for MTU which has type 3 code 4, let’s do it:
Excellent! I have permitted all ICMP messages that I want them to be permitted. Now I need to make a final rule to say that any other ICMP traffic (than the one that I have permitted) to be dropped. This dropping rule you can create inside the custom chain or you can quit the custom chain then create the dropping rule there. I will quit the custom chain first then create the dropping rule to drop any other ICMP types.
This rule will take me out of the custom chain.
Now, I will create 2 rules to drop any ICMP packet that did not match the rules in the custom chain as following:
- 1 dropping rule on the input chain.
- 1 dropping rule on the forward chain.
Let’s do that:
This has been done. Now I have all those rules enabled and ready to only allow the ICMP traffic that we decided to allow and deny any other ICMP traffic.
I will do some tests now. I will issue ping from my PC to R1 and then to 220.127.116.11 and see if it will work:
Ping to R1 is working. Let’s see which rules did match:
Great! It detected ICMP traffic coming to the router itself, then sent it to the custom chain. It found it as an echo request and has allowed it.
I will do 1 more test to do ping to 18.104.22.168, let’s check:
Ping to google DNS is working. Let’s see which rules have been matched:
I can see that it has matched the forward chain, then send it to the custom chain and allow the Echo request as well as Echo reply because the router received ICMP echo reply message back from google DNS.
It is perfectly working for me ????
Before I end the LAB, let me share with you the script so you can use it in your LAB or production network:
/ip firewall filter
add action=jump chain=input comment=”ICMP traffic on input Chain are jumped to the ICMP Chain” jump-target=ICMP protocol=icmp
add action=jump chain=forward comment=”ICMP traffic on Forward Chain are jumped to the ICMP Chain” jump-target=ICMP protocol=icmp
add action=accept chain=ICMP comment=”Accept Echo Request ICMP” icmp-options=8:0 protocol=icmp
add action=accept chain=ICMP comment=”Accept Echo Reply ICMP” icmp-options=0:0 protocol=icmp
add action=accept chain=ICMP comment=”Accept Traceroute destination Unreachable ICMP” icmp-options=3:0 protocol=icmp
add action=accept chain=ICMP comment=”Accept Traceroute destination Unreachable ICMP (3-3)” icmp-options=3:3 protocol=icmp
add action=accept chain=ICMP comment=”Accept Time Exceed ICMP (11-0)” icmp-options=11:0 protocol=icmp
add action=accept chain=ICMP comment=”Accept Path MTU Discover (3:4)” icmp-options=3:4 protocol=icmp
add action=return chain=ICMP comment=”Return to the Firewall (leaving ICMP Chain)” icmp-options=0:0-255 protocol=icmp
add action=drop chain=input comment=”Drop any ICMP packet on Input chain” protocol=icmp
add action=drop chain=forward comment=”Drop any ICMP packet on Forward chain” protocol=icmp