Editorial pass through ICMP section.

Sponsored by: iXsystems
This commit is contained in:
Dru Lavigne 2014-02-18 19:25:16 +00:00
parent d927ced901
commit e45dac121c
Notes: svn2git 2020-12-08 03:00:23 +00:00
svn path=/head/; revision=43983

View file

@ -882,152 +882,79 @@ rdr-anchor "ftp-proxy/*"</programlisting>
<sect3 xml:id="pftut-icmp">
<title>Managing <acronym>ICMP</acronym></title>
<para>Making network troubleshooting friendly is a potentially
large subject. At most times, the debugging or
troubleshooting friendliness of a <acronym>TCP/IP</acronym>
network depends on treatment of the Internet protocol which
was designed specifically with debugging in mind, the
<emphasis>Internet Control Message Protocol</emphasis>, or
<acronym>ICMP</acronym> as it is usually abbreviated.</para>
<para>Many of the tools used for debugging or
troubleshooting a <acronym>TCP/IP</acronym> network rely on the
Internet Control Message Protocol (<acronym>ICMP</acronym>), which
was designed specifically with debugging in mind.</para>
<para><acronym>ICMP</acronym> is the protocol for sending and
receiving <emphasis>control messages</emphasis> between
<para>The <acronym>ICMP</acronym> protocol sends and
receives <emphasis>control messages</emphasis> between
hosts and gateways, mainly to provide feedback to a sender
about any unusual or difficult conditions enroute to the
target host.</para>
<para>There is a lot of <acronym>ICMP</acronym> traffic which
usually just happens in the background while users are
surfing the web, reading mail or transferring files.
target host.
Routers use <acronym>ICMP</acronym> to negotiate packet
sizes and other transmission parameters in a process often
referred to as <emphasis>path <acronym>MTU</acronym>
discovery</emphasis>.</para>
<para>Some admins refer to <acronym>ICMP</acronym> as either
<quote>just evil</quote>, or, if their understanding runs a
little deeper, <quote>a necessary evil</quote>. The reason
for this attitude is purely historical. The reason can be
found a few years back when it was discovered that several
operating systems contained code in their networking stack
which could make a machine running one of the affected
systems crash and fall over, or in some cases just do really
strange things, with a sufficiently large
<acronym>ICMP</acronym> request.</para>
<para>One of the companies which was hit hard was Microsoft,
and you can find rather a lot of material on the
<quote>ping of death</quote> bug by using your favorite
search engine. This all happened in the second half of the
1990s, and all modern operating systems, at least the ones
we can read, have thoroughly sanitized their network code
since then. At least that is what we are led to
believe.</para>
<para>One of the early workarounds was to simply block either
all <acronym>ICMP</acronym> traffic or at least
<acronym>ICMP</acronym> ECHO, which is what ping uses. Now
these rulesets have been around for roughly fifteen years,
and the people who put them there are still scared.</para>
<para>The obvious question then becomes, if
<acronym>ICMP</acronym> is such a good and useful thing,
should we not let it all through, all the time? The
answer is <quote>It depends</quote>.</para>
<para>Letting diagnostic traffic pass unconditionally of
course makes debugging easier, but also makes it
relatively easy for others to extract information about
your network. That means that a rule like</para>
<para>From a firewall perspective, some <acronym>ICMP</acronym>
control messages are vulnerable to known attack vectors.
Also, letting all diagnostic traffic pass unconditionally
makes debugging easier, but it also makes it
easier for others to extract information about
the network. For these reasons, the following rule may not be
optimal:</para>
<programlisting>pass inet proto icmp from any to any</programlisting>
<para>might not be optimal if the internal workings of the
local network should be cloaked in a bit of mystery. In
all fairness it should also be said that some
<acronym>ICMP</acronym> traffic might be found quite
harmlessly riding piggyback on
<literal>keep state</literal> rules.</para>
<para>The easiest solution could very well be to let all
<acronym>ICMP</acronym> traffic from the local net through
and stop probes from elsewhere at the gateway:</para>
<para>One solution is to let all
<acronym>ICMP</acronym> traffic from the local network through
while stopping all probes from outside the network:</para>
<programlisting>pass inet proto icmp from $localnet to any keep state
pass inet proto icmp from any to $ext_if keep state</programlisting>
<para>Stopping probes at the gateway might be an attractive
option anyway, but let us have a look at a few other
options which will show some of
<application>PF</application>'s flexibility.</para>
<sect4 xml:id="pftut-letpingthru">
<title>Letting <command>ping</command> Through</title>
<para>The ruleset we have developed so far has one clear
disadvantage: common troubleshooting commands such as
&man.ping.8; and &man.traceroute.8; will not work. That
may not matter too much to end users, and since it was
<command>ping</command> which scared people into
filtering or blocking <acronym>ICMP</acronym> traffic in
the first place, there are apparently some people who feel
we are better off without it. If you are in my perceived
target audience, you will be rather fond of having those
troubleshooting tools avalable. With a couple of small
additions to the ruleset, they will be. &man.ping.8;
uses <acronym>ICMP</acronym>, and in order to keep our
ruleset tidy, we start by defining another macro:</para>
<para>Additional
options are available which demonstrate some of
<application>PF</application>'s flexibility. For example,
rather than allowing all <acronym>ICMP</acronym> messages,
one can specify the messages used by &man.ping.8; and
&man.traceroute.8;. Start by defining a macro for
that type of message:</para>
<programlisting>icmp_types = "echoreq"</programlisting>
<para>and a rule which uses the definition,</para>
<para>and a rule which uses the macro:</para>
<programlisting>pass inet proto icmp all icmp-type $icmp_types keep state</programlisting>
<para>More or other types of <acronym>ICMP</acronym> packets
may need to go through, and <literal>icmp_types</literal>
can be expanded to a list of those packet types that are
allowed.</para>
</sect4>
<para>If other types of <acronym>ICMP</acronym> packets
are needed, expand <literal>icmp_types</literal>
to a list of those packet types. Type
<command>more /usr/src/contrib/pf/pfctl/pfctl_parser.c</command>
to see the list of <acronym>ICMP</acronym> message
types supported by <application>PF</application>. Refer to
<link
xlink:href="http://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml">http://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml</link>
for an explanation of each message type.</para>
<sect4 xml:id="pftut-helptraceroute">
<title>Helping &man.traceroute.8;</title>
<para>&man.traceroute.8; is another command which is quite
useful when users claim that the Internet is not working.
By default, Unix <command>traceroute</command> uses UDP
connections according to a set formula based on
destination. The rule below works with
<command>traceroute</command> on all Unixes I have had
access to, including GNU/Linux:</para>
<para>Since Unix <command>traceroute</command> uses <acronym>UDP</acronym>
by default, another rule is needed to allow Unix
<command>traceroute</command>:</para>
<programlisting># allow out the default range for traceroute(8):
# "base+nhops*nqueries-1" (33434+64*3-1)
pass out on $ext_if inet proto udp from any to any port 33433 &gt;&lt; 33626 keep state</programlisting>
<para>Experience so far indicates that
<command>traceroute</command> implementations on other
operating systems work roughly the same. Except, of
course, on Microsoft Windows. On that platform,
<command>TRACERT.EXE</command> uses ICMP ECHO for this
purpose. So to let Windows traceroutes through, only the
first rule is needed. Unix <command>traceroute</command>
<para>Since <command>TRACERT.EXE</command> on Microsoft Windows systems
uses <acronym>ICMP</acronym> echo request messages,
only the
first rule is needed to allow network traces from those systems. Unix <command>traceroute</command>
can be instructed to use other protocols as well, and will
behave remarkably like its Microsoft counterpart if
use <acronym>ICMP</acronym> echo request messages if
<option>-I</option> is used. Check the &man.traceroute.8;
man page (or its source code, for that matter) for all the
man page for
details.</para>
<para>Under any circumstances, this solution was lifted
from an openbsd-misc post. I have found that list, and
the searchable list archives (accessible among other
places from <link
xlink:href="http://marc.theaimsgroup.com/">http://marc.theaimsgroup.com/</link>),
to be a very valuable resource whenever you need OpenBSD
or <application>PF</application> related
information.</para>
</sect4>
<sect4 xml:id="pftut-pathmtudisc">
<title>Path <acronym>MTU</acronym> Discovery</title>
@ -1035,60 +962,47 @@ pass out on $ext_if inet proto udp from any to any port 33433 &gt;&lt; 33626 kee
independent, and one consequence of device independence is
that the optimal packet size for a given connection cannot
always be predicted reliably. The main constraint on
packet size is called the
<firstterm>Maximum Transmission Unit</firstterm>, or
<acronym>MTU</acronym>, which sets the upper limit on the
packet size for an interface. &man.ifconfig.8; shows the
<acronym>MTU</acronym> for the network interfaces.</para>
packet size is the
<firstterm>Maximum Transmission Unit</firstterm>
(<acronym>MTU</acronym>) which sets the upper limit on the
packet size for an interface. Type <command>ifconfig</command> to view the
<acronym>MTU</acronym>s for a system's network interfaces.</para>
<para>Modern TCP/IP implementations expect to be able to
determine the right packet size for a connection through a
process which, simply put, involves sending packets of
<para><acronym>TCP/IP</acronym> uses a process known as path
<acronym>MTU</acronym> discovery to
determine the right packet size for a connection. This
process sends packets of
varying sizes with the <quote>Do not fragment</quote> flag
set, expecting an <acronym>ICMP</acronym> return packet
indicating <quote>type 3, code 4</quote> when the upper
limit has been reached. Now do not dive for the RFCs
right away. Type 3 means <quote>destination
unreachable</quote>, while code 4 is short for
of <quote>type 3, code 4</quote> when the upper
limit has been reached. Type 3 means <quote>destination
unreachable</quote>, and code 4 is short for
<quote>fragmentation needed, but the do-not-fragment flag
is set</quote>. So if connections to networks which may
have other <acronym>MTU</acronym>s than the local network
seem sub-optimal, and there is no need to be that
specific, the list of <acronym>ICMP</acronym> types can be
changed slightly to let the
<quote>destination unreachable</quote> packets through,
too:</para>
is set</quote>. To allow path MTU discovery in order
to support connections to other <acronym>MTU</acronym>s, add
the
<literal>destination unreachable</literal> type to the
<literal>icmp_types</literal> macro:</para>
<programlisting>icmp_types = "{ echoreq, unreach }"</programlisting>
<para>As we can see, this means we do not need to change
the pass rule itself:</para>
<para>Since
the pass rule already uses that macro, it does not need to
be modified in order to support the new
<acronym>ICMP</acronym> type:</para>
<programlisting>pass inet proto icmp all icmp-type $icmp_types keep state</programlisting>
<para><application>PF</application> allows filtering on all
variations of <acronym>ICMP</acronym> types and codes.
For those who want to delve into what to pass (or not) of
<acronym>ICMP</acronym> traffic, the list of possible
types and codes are documented in the &man.icmp.4; and
&man.icmp6.4; man pages. The background information is
available in the <acronym>RFC</acronym>s
<footnote><para>The main internet <acronym>RFC</acronym>s
describing <acronym>ICMP</acronym> and
some related techhiques are RFC792, RFC950, RFC1191,
RFC1256, RFC2521, rfc2765, while necessary updates for
ICMP for IPv6 are found in RFC1885, RFC2463, RFC2466.
These documents are available in a number of places on
the net, such as the
<link xlink:href="http://www.ietf.org">ietf.org</link>
and
<link xlink:href="http://www.faqs.org">faqs.org</link>
web sites.</para></footnote>.</para>
The list of possible
types and codes are documented in &man.icmp.4; and
&man.icmp6.4;.</para>
</sect4>
</sect3>
<sect3 xml:id="pftut-tables">
<title>Tables Make Life Easier</title>
<title>Using Tables</title>
<para>By this time it may appear that this gets awfully static
and rigid. There will after all be some kinds of data which