Tighten up this subsection.
Sponsored by: iXsystems
This commit is contained in:
parent
c4a79914aa
commit
68e4a86d99
Notes:
svn2git
2020-12-08 03:00:23 +00:00
svn path=/head/; revision=43928
1 changed files with 69 additions and 86 deletions
|
|
@ -540,104 +540,87 @@ options ALTQ_PRIQ # Priority Queuing (PRIQ)</programlisting>
|
||||||
</info>
|
</info>
|
||||||
|
|
||||||
<para>This section demonstrates how to create a customized
|
<para>This section demonstrates how to create a customized
|
||||||
ruleset, using several examples.</para>
|
ruleset. It starts with the simplest of rulesets and builds
|
||||||
|
upon its concepts using several examples to demonstrate
|
||||||
|
real-world usage of <application>PF</application>'s many
|
||||||
|
features.</para>
|
||||||
|
|
||||||
<para>The simplest possible setup is for a single machine
|
<para>The simplest possible ruleset is for a single machine
|
||||||
which will not run any services, and which will talk to one
|
that does not run any services and which needs access to one
|
||||||
network which may be the Internet. A minimal
|
network, which may be the Internet. To create this minimal
|
||||||
<filename>/etc/pf.conf</filename> looks like this:</para>
|
ruleset, edit
|
||||||
|
<filename>/etc/pf.conf</filename> so it looks like this:</para>
|
||||||
|
|
||||||
<programlisting>block in all
|
<programlisting>block in all
|
||||||
pass out all keep state</programlisting>
|
pass out all keep state</programlisting>
|
||||||
|
|
||||||
<para>Here we deny any incoming traffic, allow traffic we make
|
<para>The first rule denies all incoming traffic by default.
|
||||||
ourselves to pass, and retain state information on our
|
The second rule allows
|
||||||
connections. Keeping state information allows return
|
connections created by this system
|
||||||
traffic for all connections we have initiated to pass back
|
to pass out, while retaining state information on those
|
||||||
to us. This rule set is used on machines that can be
|
connections. This state information allows return
|
||||||
trusted. The rule set can be loaded with</para>
|
traffic for those connections to pass back and
|
||||||
|
should only be used on machines that can be
|
||||||
|
trusted. The ruleset can be loaded with:</para>
|
||||||
|
|
||||||
<screen>&prompt.root; <userinput>pfctl -e ; pfctl -f /etc/pf.conf</userinput></screen>
|
<screen>&prompt.root; <userinput>pfctl -e ; pfctl -f /etc/pf.conf</userinput></screen>
|
||||||
|
|
||||||
<para>For a slightly more structured and complete setup, we
|
<para>In addition to keeping state,
|
||||||
start by denying everything and then allowing only those
|
<application>PF</application> provides
|
||||||
things we know that we need
|
|
||||||
<footnote><para>Why write the rule set to default deny? The
|
|
||||||
short answer is, it gives better control at the expense
|
|
||||||
of some thinking. The point of packet filtering is to
|
|
||||||
take control, not to run catch-up with what the bad guys
|
|
||||||
do. Marcus Ranum has written a very entertaining and
|
|
||||||
informative article about this, <link
|
|
||||||
xlink:href="http://www.ranum.com/security/computer_security/editorials/dumb/index.html">The
|
|
||||||
Six Dumbest Ideas in Computer Security</link>, and
|
|
||||||
it is well written too.</para></footnote>. This gives
|
|
||||||
us the opportunity to introduce two of the features which
|
|
||||||
make <application>PF</application> such a wonderful tool:
|
|
||||||
<firstterm>lists</firstterm> and
|
<firstterm>lists</firstterm> and
|
||||||
<firstterm>macros</firstterm>.</para>
|
<firstterm>macros</firstterm> which can be defined for use
|
||||||
|
when creating rules. Macros can include lists and need to be defined
|
||||||
<para>We will make some changes to
|
before use. As an example, insert these lines at the
|
||||||
<filename>/etc/pf.conf</filename>, starting with</para>
|
very top of the ruleset:</para>
|
||||||
|
|
||||||
<programlisting>block all</programlisting>
|
|
||||||
|
|
||||||
<para>Then we back up a little. Macros need to be defined
|
|
||||||
before use, so at the very top of the file, we add:</para>
|
|
||||||
|
|
||||||
<programlisting>tcp_services = "{ ssh, smtp, domain, www, pop3, auth, pop3s }"
|
<programlisting>tcp_services = "{ ssh, smtp, domain, www, pop3, auth, pop3s }"
|
||||||
udp_services = "{ domain }"</programlisting>
|
udp_services = "{ domain }"</programlisting>
|
||||||
|
|
||||||
<para>Now we have demonstrated several things at once - what
|
<para><application>PF</application> understands port
|
||||||
macros look like, that macros may be lists, and that
|
names as well as port numbers, as long as the names are listed
|
||||||
<application>PF</application> understands rules using port
|
in <filename>/etc/services</filename>. This example
|
||||||
names equally well as it does port numbers. The names are
|
creates two macros. The first is a list of seven
|
||||||
the ones listed in <filename>/etc/services</filename>. This
|
<acronym>TCP</acronym> port names and the second is one
|
||||||
gives us something to put in our rules, which we edit
|
<acronym>UDP</acronym> port name. Once defined, macros can
|
||||||
slightly to look like this:</para>
|
be used in rules. In this example, all traffic is blocked
|
||||||
|
except for the connections initiated by this system for the
|
||||||
|
seven specified <acronym>TCP</acronym> services and the one
|
||||||
|
specified <acronym>UDP</acronym> service:</para>
|
||||||
|
|
||||||
<programlisting>block all
|
<programlisting>tcp_services = "{ ssh, smtp, domain, www, pop3, auth, pop3s }"
|
||||||
|
udp_services = "{ domain }"
|
||||||
|
block all
|
||||||
pass out proto tcp to any port $tcp_services keep state
|
pass out proto tcp to any port $tcp_services keep state
|
||||||
pass proto udp to any port $udp_services keep state</programlisting>
|
pass proto udp to any port $udp_services keep state</programlisting>
|
||||||
|
|
||||||
<para>At this point some of us will point out that UDP is
|
<para>Even though <acronym>UDP</acronym> is considered to be
|
||||||
stateless, but <application>PF</application> actually
|
a stateless protocol, <application>PF</application>
|
||||||
manages to maintain state information despite this. Keeping
|
is able to track some state information. For example, when a
|
||||||
state for a UDP connection means that for example when you
|
<acronym>UDP</acronym> request is passed which
|
||||||
ask a name server about a domain name, you will be able to
|
asks a name server about a domain name, <application>PF</application>
|
||||||
receive its answer.</para>
|
will watch for the response in order to pass it back.</para>
|
||||||
|
|
||||||
<para>Since we have made changes to our
|
<para>Whenever an edit is made to a ruleset, the new rules
|
||||||
<filename>pf.conf</filename>, we load the new
|
must be loaded so they can be used:</para>
|
||||||
rules:</para>
|
|
||||||
|
|
||||||
<screen>&prompt.root; <userinput>pfctl -f /etc/pf.conf</userinput></screen>
|
<screen>&prompt.root; <userinput>pfctl -f /etc/pf.conf</userinput></screen>
|
||||||
|
|
||||||
<para>and the new rules are applied. If there are no syntax
|
<para>If there are no syntax
|
||||||
errors, <command>pfctl</command> will not output any
|
errors, <command>pfctl</command> will not output any
|
||||||
messages during the rule load. The <option>-v</option> flag
|
messages during the rule load. Rules can also be tested before attempting to load them:</para>
|
||||||
will produce more verbose <command>pfctl</command>
|
|
||||||
output.</para>
|
|
||||||
|
|
||||||
<para>If there have been extensive changes to the rule set,
|
|
||||||
the rules can be tested before attempting to load them. The
|
|
||||||
command to do this is</para>
|
|
||||||
|
|
||||||
<screen>&prompt.root; <userinput>pfctl -nf /etc/pf.conf</userinput></screen>
|
<screen>&prompt.root; <userinput>pfctl -nf /etc/pf.conf</userinput></screen>
|
||||||
|
|
||||||
<para><option>-n</option> causes the rules to be interpreted
|
<para>Including <option>-n</option> causes the rules to be interpreted
|
||||||
only, but does not load them. This provides an opportunity
|
only, but not loaded. This provides an opportunity
|
||||||
to correct any errors. Under any circumstances, the last
|
to correct any errors. At all times, the last
|
||||||
valid rule set loaded will be in force until
|
valid ruleset loaded will be enforced until either
|
||||||
<application>PF</application> is disabled or a new rule set
|
<application>PF</application> is disabled or a new ruleset
|
||||||
is loaded.</para>
|
is loaded.</para>
|
||||||
|
|
||||||
<tip>
|
<tip>
|
||||||
<title>Use <command>pfctl -v</command> to Show the Parsed
|
<para>Adding <option>-v</option> to a
|
||||||
Rule Set</title>
|
<command>pfctl</command> ruleset verify or load will display the fully parsed rules
|
||||||
|
|
||||||
<para>Adding the <option>-v</option> to a
|
|
||||||
<command>pfctl</command> ruleset load (even a dry run with
|
|
||||||
<option>-n</option>) will display the fully parsed rules
|
|
||||||
exactly the way they will be loaded. This is extremely
|
exactly the way they will be loaded. This is extremely
|
||||||
useful when debugging rules.</para>
|
useful when debugging rules.</para>
|
||||||
</tip>
|
</tip>
|
||||||
|
|
@ -699,10 +682,10 @@ pass proto udp to any port $udp_services keep state</programlisting>
|
||||||
good these days, and we will get back to them later. For
|
good these days, and we will get back to them later. For
|
||||||
now we just accept the fact that for simple setups,
|
now we just accept the fact that for simple setups,
|
||||||
interface-bound rules with in/out rules tend to add more
|
interface-bound rules with in/out rules tend to add more
|
||||||
clutter than they are worth to rule sets.</para>
|
clutter than they are worth to rulesets.</para>
|
||||||
|
|
||||||
<para>For a busy network admin, a readable rule set is a
|
<para>For a busy network admin, a readable ruleset is a
|
||||||
safer rule set.</para>
|
safer ruleset.</para>
|
||||||
|
|
||||||
<para>For the remainder of this section, with some
|
<para>For the remainder of this section, with some
|
||||||
exceptions, we will keep the rules as simple as possible
|
exceptions, we will keep the rules as simple as possible
|
||||||
|
|
@ -713,7 +696,7 @@ pass proto udp to any port $udp_services keep state</programlisting>
|
||||||
|
|
||||||
<para>Above, we introduced the
|
<para>Above, we introduced the
|
||||||
<literal>interface:network</literal> notation. That is a
|
<literal>interface:network</literal> notation. That is a
|
||||||
nice piece of shorthand, but the rule set can be made even
|
nice piece of shorthand, but the ruleset can be made even
|
||||||
more readable and maintainable by taking the macro use a
|
more readable and maintainable by taking the macro use a
|
||||||
tiny bit further.</para>
|
tiny bit further.</para>
|
||||||
|
|
||||||
|
|
@ -809,7 +792,7 @@ pass from { lo0, $localnet } to any keep state</programlisting>
|
||||||
the last time during this tutorial we will find this of
|
the last time during this tutorial we will find this of
|
||||||
any interest whatsoever. In truly simple setups like this
|
any interest whatsoever. In truly simple setups like this
|
||||||
one, we may not gain very much by using macros like these,
|
one, we may not gain very much by using macros like these,
|
||||||
but once the rule sets grow somewhat larger, you will
|
but once the rulesets grow somewhat larger, you will
|
||||||
learn to appreciate the readability this provides.</para>
|
learn to appreciate the readability this provides.</para>
|
||||||
|
|
||||||
<para>Also note the <literal>nat</literal> rule. This is
|
<para>Also note the <literal>nat</literal> rule. This is
|
||||||
|
|
@ -825,7 +808,7 @@ pass from { lo0, $localnet } to any keep state</programlisting>
|
||||||
interruptions even if the external IP address
|
interruptions even if the external IP address
|
||||||
changes.</para>
|
changes.</para>
|
||||||
|
|
||||||
<para>On the other hand, this rule set probably allows more
|
<para>On the other hand, this ruleset probably allows more
|
||||||
traffic to pass out of the network than actually desired.
|
traffic to pass out of the network than actually desired.
|
||||||
One reasonable setup could contain the macro</para>
|
One reasonable setup could contain the macro</para>
|
||||||
|
|
||||||
|
|
@ -866,9 +849,9 @@ pass from { lo0, $localnet } to any keep state</programlisting>
|
||||||
<programlisting>pass quick inet proto { tcp, udp } to any port $udp_services keep state</programlisting>
|
<programlisting>pass quick inet proto { tcp, udp } to any port $udp_services keep state</programlisting>
|
||||||
|
|
||||||
<para>Note the <literal>quick</literal> keyword in this
|
<para>Note the <literal>quick</literal> keyword in this
|
||||||
rule. We have started writing rule sets which consist of
|
rule. We have started writing rulesets which consist of
|
||||||
several rules, and it is time to take a look at the
|
several rules, and it is time to take a look at the
|
||||||
relationships between the rules in a rule set. The rules
|
relationships between the rules in a ruleset. The rules
|
||||||
are evaluated from top to bottom, in the sequence they are
|
are evaluated from top to bottom, in the sequence they are
|
||||||
written in the configuration file. For each packet or
|
written in the configuration file. For each packet or
|
||||||
connection evaluated by <application>PF</application>,
|
connection evaluated by <application>PF</application>,
|
||||||
|
|
@ -1083,7 +1066,7 @@ rdr-anchor "ftp-proxy/*"</programlisting>
|
||||||
<para>One of the early workarounds was to simply block either
|
<para>One of the early workarounds was to simply block either
|
||||||
all <acronym>ICMP</acronym> traffic or at least
|
all <acronym>ICMP</acronym> traffic or at least
|
||||||
<acronym>ICMP</acronym> ECHO, which is what ping uses. Now
|
<acronym>ICMP</acronym> ECHO, which is what ping uses. Now
|
||||||
these rule sets have been around for roughly fifteen years,
|
these rulesets have been around for roughly fifteen years,
|
||||||
and the people who put them there are still scared.</para>
|
and the people who put them there are still scared.</para>
|
||||||
|
|
||||||
<sect4 xml:id="pftut-dowepass">
|
<sect4 xml:id="pftut-dowepass">
|
||||||
|
|
@ -1128,7 +1111,7 @@ pass inet proto icmp from any to $ext_if keep state</programlisting>
|
||||||
<sect4 xml:id="pftut-letpingthru">
|
<sect4 xml:id="pftut-letpingthru">
|
||||||
<title>Letting <command>ping</command> Through</title>
|
<title>Letting <command>ping</command> Through</title>
|
||||||
|
|
||||||
<para>The rule set we have developed so far has one clear
|
<para>The ruleset we have developed so far has one clear
|
||||||
disadvantage: common troubleshooting commands such as
|
disadvantage: common troubleshooting commands such as
|
||||||
&man.ping.8; and &man.traceroute.8; will not work. That
|
&man.ping.8; and &man.traceroute.8; will not work. That
|
||||||
may not matter too much to end users, and since it was
|
may not matter too much to end users, and since it was
|
||||||
|
|
@ -1138,9 +1121,9 @@ pass inet proto icmp from any to $ext_if keep state</programlisting>
|
||||||
we are better off without it. If you are in my perceived
|
we are better off without it. If you are in my perceived
|
||||||
target audience, you will be rather fond of having those
|
target audience, you will be rather fond of having those
|
||||||
troubleshooting tools avalable. With a couple of small
|
troubleshooting tools avalable. With a couple of small
|
||||||
additions to the rule set, they will be. &man.ping.8;
|
additions to the ruleset, they will be. &man.ping.8;
|
||||||
uses <acronym>ICMP</acronym>, and in order to keep our
|
uses <acronym>ICMP</acronym>, and in order to keep our
|
||||||
rule set tidy, we start by defining another macro:</para>
|
ruleset tidy, we start by defining another macro:</para>
|
||||||
|
|
||||||
<programlisting>icmp_types = "echoreq"</programlisting>
|
<programlisting>icmp_types = "echoreq"</programlisting>
|
||||||
|
|
||||||
|
|
@ -1261,7 +1244,7 @@ pass out on $ext_if inet proto udp from any to any port 33433 >< 33626 kee
|
||||||
Quite right, and <application>PF</application> offers
|
Quite right, and <application>PF</application> offers
|
||||||
mechanisms for handling these situations as well. Tables
|
mechanisms for handling these situations as well. Tables
|
||||||
are one such feature, mainly useful as lists which can be
|
are one such feature, mainly useful as lists which can be
|
||||||
manipulated without needing to reload the entire rule set,
|
manipulated without needing to reload the entire ruleset,
|
||||||
and where fast lookups are desirable. Table names are
|
and where fast lookups are desirable. Table names are
|
||||||
always enclosed in <literal>< ></literal>, like
|
always enclosed in <literal>< ></literal>, like
|
||||||
this:</para>
|
this:</para>
|
||||||
|
|
@ -1361,7 +1344,7 @@ Sep 26 03:12:44 skapet sshd[24703]: Failed password for invalid user admin from
|
||||||
|
|
||||||
<programlisting>table <bruteforce> persist</programlisting>
|
<programlisting>table <bruteforce> persist</programlisting>
|
||||||
|
|
||||||
<para>Then somewhere fairly early in the rule set, add a rule
|
<para>Then somewhere fairly early in the ruleset, add a rule
|
||||||
to block the bruteforcers:</para>
|
to block the bruteforcers:</para>
|
||||||
|
|
||||||
<programlisting>block quick from <bruteforce></programlisting>
|
<programlisting>block quick from <bruteforce></programlisting>
|
||||||
|
|
@ -1598,7 +1581,7 @@ Sep 26 03:12:44 skapet sshd[24703]: Failed password for invalid user admin from
|
||||||
</step>
|
</step>
|
||||||
|
|
||||||
<step>
|
<step>
|
||||||
<para>Next, edit the rule set to include</para>
|
<para>Next, edit the ruleset to include</para>
|
||||||
|
|
||||||
<programlisting>table <spamd> persist
|
<programlisting>table <spamd> persist
|
||||||
table <spamd-white> persist
|
table <spamd-white> persist
|
||||||
|
|
@ -1698,7 +1681,7 @@ rdr pass on $ext_if inet proto tcp from !<spamd-white> to \
|
||||||
<programlisting>spamd_flags="-v" # for normal use: "" and see spamd-setup(8)</programlisting>
|
<programlisting>spamd_flags="-v" # for normal use: "" and see spamd-setup(8)</programlisting>
|
||||||
|
|
||||||
<para>When done with editing the setup,
|
<para>When done with editing the setup,
|
||||||
reload the rule set, start
|
reload the ruleset, start
|
||||||
<application>spamd</application> with the options
|
<application>spamd</application> with the options
|
||||||
desired using the
|
desired using the
|
||||||
<filename>/usr/local/etc/rc.d/obspamd</filename>
|
<filename>/usr/local/etc/rc.d/obspamd</filename>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue