Internet Control Message Protocol (ICMP)
Introduction to ICMP
ICMP is a protocol within the TCP/IP stack that exist basically
to provide control, troubleshooting, and error messages. It runs over
IP, like TCP and UDP do, but is a network-layer protocol, like IP,
rather than a transport layer protocol like TCP and UDP are. (Yes, this
is kind of weird, that ICMP is encapsulated within IP while being on the
same layer as IP. But then again, you can encapsulate IP within IP as
well.) [See RFC 792
for the full ICMP specification. See
this Geocities page for a chart explaining the functions of each
OSI
model network layer. See this
page for a nice chart showing various protocol stacks in relationship to
the OSI model.]
Message types and codes
With IPv4 (the current version of IP that's most in use...
there are people using IPv6, but it's not in general deployment over the
Internet at large), there are different message types within ICMP. The
message type identifies what sort of ICMP message it is (echo request
for ping vs. router solicitation vs. redirect...). Each ICMP message
type also has a message code, that lets you know the exact meaning. So
an ICMP packet with a message type 3 (Destination Unreachable) and a
message code 3 (Port Unreachable) lets you know that the machine you
tried to reach is not listening on this port. When you nmap a machine
on a port it's not listening on, it sends back an ICMP packet like this
to let you know that it's not listening on that port (if the port is not
firewalled. If it is, then what happens depends on the config of your
firewall).
Error and query messages
There are lots of types of ICMP error and query messages. Note
that although an ICMP reply can be sent to an ICMP query, ICMP error
messages are never (or should never be) sent in reply to ICMP error
messages. This keeps infinite loops of ICMP error messages from filling
the Internet. [grin] Most of the various ICMP types aren't in common
usage anymore. But let's take a quick tour so you know what would be a
good idea to let through your firewall and what would be a good idea to
block.
Ping example
When you ping someone, you are sending an ICMP packet with
message code 8 (Echo Request) to them. They reply with an ICMP packet
with message code 0 (Echo Reply). So if you want to allow people behind
your firewall to ping external systems and get a reply, you have to
allow ICMP message code 0 packets incoming, like Coldfire said. If you
want to allow people to ping you, you have to allow ICMP message code 8
requests incoming.
Of course, you can filter the opposite way outgoing, too, if you
want. I just find it easier to block incoming packets that I don't want
than to block the replies from my system. It's more efficient to catch
things before they get to my machines, and when it's TCP or UDP rather
than ICMP, it's a lot safer too.
Traceroute example
When you traceroute to someone, you send (under most
implementations; we'll get to tcptraceroute and its friends later) three
UDP packets with a time-to-live of one towards your destination. The
first system it hits sees the packets, sees the expired TTL, and sends
back three ICMP message type 11 (Time Exceeded), message code 0
(Time-To-Live Exceeded in Transit) packets to the originating system.
The system notes that, and sends out three packets with a TTL of 2. It
gets the ICMP errors from the next system down the line, and sends out
three UDP packets with a TTL of three... and so on until it gets back
the ICMP errors from the destination system.
So if you want people behind your firewall to be able to
traceroute to external systems, you want to allow those ICMP message
code 11 packets through.
Path MTU discovery
You also want to know when you can't get to something. So you
probably want to allow ICMP message type 3 (Destination Unreachable)
error messages through your firewall. Of particular importance is ICMP
message type 3, message code 4 (Fragmentation Required but DF Bit Is
Set). This error message is necessary for Path MTU discovery.
There's a feature of TCP/IP where it tries to auto-negotiate the
size of packets that can be sent between a given set of machines. This
is called Path MTU discovery. (MTU = Maximum Transmit Unit) One
machine will send the biggest packet it can with the DF (Don't Fragment)
bit set. With the DF bit set, this packet will not be broken up into
smaller packets. It has to be transmitted at its current size or not at
all. If any system along the path has a smaller MTU, it will drop the
packet with the DF bit set, and send an ICMP error message back to the
origin system saying that it couldn't send packets that big, but DF was
set so it couldn't fragment it.
Path MTU discovery depends on getting these error messages. If
there is no error message, the end system doesn't realize that it's
sending packets too big for its path, and will merrily keep on doing so.
(If the end system does get the ICMP error, it reduces the size of the
packets it's sending until it doesn't get the error any more.) This
causes transmission problems for you.
IMO, most of the rest of the ICMP error messages can be safely
blocked. (Anyone with arguments to the contrary, please chime in.)
Copyright (c) 2002 by Raven Alder. This material
may be distributed only subject to the terms and
conditions set forth in the Open Publication License,
v1.0 or later (the latest version is presently
available at http://www.opencontent.org/openpub/).
|