324 lines
12 KiB
Text
324 lines
12 KiB
Text
<!--
|
|
The FreeBSD Documentation Project
|
|
-->
|
|
|
|
<!DOCTYPE article PUBLIC "-//FreeBSD//DTD DocBook V4.1-Based Extension//EN" [
|
|
<!ENTITY % man PUBLIC "-//FreeBSD//ENTITIES DocBook Manual Page Entities//EN">
|
|
%man;
|
|
|
|
<!ENTITY % freebsd PUBLIC "-//FreeBSD//ENTITIES DocBook Miscellaneous FreeBSD Entities//EN">
|
|
%freebsd;
|
|
|
|
<!ENTITY % trademarks PUBLIC "-//FreeBSD//ENTITIES DocBook Trademark Entities//EN">
|
|
%trademarks;
|
|
]>
|
|
|
|
<article>
|
|
<articleinfo>
|
|
<title>Dialup firewalling with FreeBSD</title>
|
|
|
|
<authorgroup>
|
|
<author>
|
|
<firstname>Marc</firstname>
|
|
<surname>Silver</surname>
|
|
|
|
<affiliation>
|
|
<address><email>marcs@draenor.org</email></address>
|
|
</affiliation>
|
|
</author>
|
|
</authorgroup>
|
|
|
|
<pubdate>$FreeBSD$</pubdate>
|
|
|
|
<legalnotice id="trademarks" role="trademarks">
|
|
&tm-attrib.freebsd;
|
|
&tm-attrib.general;
|
|
</legalnotice>
|
|
|
|
<abstract>
|
|
<para>This article documents how to set up a firewall using a PPP
|
|
dialup with FreeBSD and IPFW, and specifically with firewalling over
|
|
a dialup with a dynamically assigned IP address. This document does
|
|
not include information on setting up an initial PPP connection.
|
|
For more information on setting up a PPP connection, consult
|
|
the &man.ppp.8; manual page.</para>
|
|
</abstract>
|
|
</articleinfo>
|
|
|
|
<sect1 id="preface">
|
|
<title>Preface</title>
|
|
|
|
<para>Dialup Firewalling with FreeBSD</para>
|
|
|
|
<para>This document outlines the steps required to set up
|
|
firewalling with FreeBSD when an IP address is assigned dynamically
|
|
by your ISP. While every effort has been made to make this document
|
|
as informative and correct as possible, you are welcome to mail
|
|
any corrections, comments or suggestions to the author at
|
|
<email>marcs@draenor.org</email>.</para>
|
|
</sect1>
|
|
|
|
<sect1 id="kernel">
|
|
<title>Kernel Options</title>
|
|
|
|
<para>In order to use IPFW, support for it must be compiled into the
|
|
kernel. For more information on how to recompile the kernel,
|
|
please see the <ulink
|
|
URL="../../books/handbook/kernelconfig.html">kernel configuration
|
|
section in the Handbook</ulink>. The following options must be
|
|
added into your kernel configuration file for IPFW support:</para>
|
|
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term><literal>options IPFIREWALL</literal></term>
|
|
|
|
<listitem>
|
|
<para>Enables the kernel firewall code.</para>
|
|
<note><para>This document assumes that you are running
|
|
&os; 5.X. Users running &os; 4.X will need to
|
|
recompile their kernels with <emphasis>IPFW2</emphasis>
|
|
support. &os; 4.X users should consult the &man.ipfw.8;
|
|
manual page for more information on using IPFW2 on their
|
|
systems, and should pay particular attention to the
|
|
<emphasis>USING IPFW2 IN FreeBSD-STABLE</emphasis>
|
|
section.</para></note>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><literal>options IPFIREWALL_VERBOSE</literal></term>
|
|
|
|
<listitem>
|
|
<para>Sends logged packets to the system logger.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><literal>options
|
|
IPFIREWALL_VERBOSE_LIMIT=<replaceable>500</replaceable></literal></term>
|
|
|
|
<listitem>
|
|
<para>Limits the number of times a matching entry may be logged.
|
|
This allows you to log firewall activity without the risk of
|
|
syslog flooding in the event of a denial of service attack.
|
|
<replaceable>500</replaceable> is a reasonable number to use, but
|
|
may be adjusted based on your requirements.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
|
|
<warning><para>Once the kernel recompile has been completed,
|
|
<emphasis>do not reboot</emphasis> your system. Doing so may result
|
|
in you being locked out of your own system. You must only reboot
|
|
once the ruleset is in place and all the relevant configuration
|
|
files have been updated.</para></warning>
|
|
|
|
</sect1>
|
|
|
|
<sect1 id="rcconf">
|
|
<title>Changing <filename>/etc/rc.conf</filename> to load the
|
|
firewall</title>
|
|
|
|
<para><filename>/etc/rc.conf</filename> needs to be slightly
|
|
modified in order to tell the system about the firewall and to
|
|
specify the location for our rules file. Add the following lines
|
|
to <filename>/etc/rc.conf</filename>:</para>
|
|
|
|
<programlisting>firewall_enable="YES"
|
|
firewall_script="/etc/firewall/fwrules"</programlisting>
|
|
|
|
<para>For more information on the functions of these statements take
|
|
a look at <filename>/etc/defaults/rc.conf</filename> and read
|
|
&man.rc.conf.5;</para>
|
|
</sect1>
|
|
|
|
<sect1>
|
|
<title>Enable PPP's network address translation</title>
|
|
|
|
<para>In order to allow clients on your network to connect via
|
|
your gateway, you will need to enable PPP's network address
|
|
translation (NAT). In order to use PPP's NAT functions, add the
|
|
following lines to <filename>/etc/rc.conf</filename>:</para>
|
|
|
|
<programlisting>ppp_enable="YES"
|
|
ppp_mode="auto"
|
|
ppp_nat="YES"
|
|
ppp_profile="<replaceable>your_profile</replaceable>"</programlisting>
|
|
|
|
<note><para>Take care to change <literal>your_profile</literal> to
|
|
the name of your own dialup profile.</para></note>
|
|
</sect1>
|
|
|
|
<sect1 id="rules">
|
|
<title>The rule set for the firewall</title>
|
|
|
|
<para>This is the point where we define the firewall rules for your
|
|
system. The ruleset that we're about to describe is a generic
|
|
template for most dialup users. While it will not suit the exact
|
|
needs of every user, it provides you with a basic idea of how IPFW
|
|
works and should be fairly easy to customize.</para>
|
|
|
|
<para>First, let's start with the basics of closed firewalling.
|
|
Closed firewalling is based on the idea that everything is denied
|
|
by default. The system administrator may then explicitly add
|
|
rules for traffic that he or she would like to allow. Rules
|
|
should be in the order of allow first, and then deny. The premise
|
|
is that you add the rules for everything you would like to allow,
|
|
and then everything else is automatically denied.</para>
|
|
|
|
<para>First off, let's create the directory where we will store our
|
|
firewall rules. In this example, we'll use <filename
|
|
class="directory">/etc/firewall</filename>. Change into the
|
|
directory and edit the file <filename>fwrules</filename> as we
|
|
specified in <filename>rc.conf</filename>. Please note that you
|
|
can change this filename to anything you wish. This guide merely
|
|
gives an example of a filename you may want to use.</para>
|
|
|
|
<para>Now, let's look at a nicely commented sample firewall
|
|
file.</para>
|
|
|
|
<programlisting># Define the firewall command (as in /etc/rc.firewall) for easy
|
|
# reference. Helps to make it easier to read.
|
|
fwcmd="/sbin/ipfw"
|
|
|
|
# Define our outside interface. With userland-ppp this
|
|
# defaults to tun0.
|
|
oif="tun0"
|
|
|
|
# Define our inside interface. This is usually your network
|
|
# card. Be sure to change this to match your own network
|
|
# interface.
|
|
iif="fxp0"
|
|
|
|
# Force a flushing of the current rules before we reload.
|
|
$fwcmd -f flush
|
|
|
|
# Check the state of all packets.
|
|
$fwcmd add check-state
|
|
|
|
# Stop spoofing on the outside interface.
|
|
$fwcmd add deny ip from any to any in via $oif not verrevpath
|
|
|
|
# Allow all connections that we initiate, and keep their state.
|
|
# but deny established connections that don't have a dynamic rule.
|
|
$fwcmd add allow ip from me to any out via $oif keep-state
|
|
$fwcmd add deny tcp from any to any established in via $oif
|
|
|
|
# Allow all connections within our network.
|
|
$fwcmd add allow ip from any to any via $iif
|
|
|
|
# Allow all local traffic.
|
|
$fwcmd add allow all from any to any via lo0
|
|
$fwcmd add deny all from any to 127.0.0.0/8
|
|
$fwcmd add deny ip from 127.0.0.0/8 to any
|
|
|
|
# Allow internet users to connect to the port 22 and 80.
|
|
# This example specifically allows connections to the sshd and a
|
|
# webserver.
|
|
$fwcmd add allow tcp from any to me dst-port 22,80 in via $oif setup keep-state
|
|
|
|
# Allow ICMP packets: remove type 8 if you don't want your host
|
|
# to be pingable.
|
|
$fwcmd add allow icmp from any to any via $oif icmptypes 0,3,8,11,12
|
|
|
|
# Deny and log all the rest.
|
|
$fwcmd add deny log ip from any to any</programlisting>
|
|
|
|
<para>You now have a fully functional firewall that only allows
|
|
connections to ports 22 and 80 and will log any other connection
|
|
attempts. You may now safely safely reboot and the firewall should
|
|
be automatically started and the ruleset loaded. If you find this
|
|
incorrect in anyway or experience any problems, or have any
|
|
suggestions to improve this page, please email me.</para>
|
|
</sect1>
|
|
|
|
<sect1>
|
|
<title>Questions</title>
|
|
|
|
<qandaset>
|
|
<qandaentry>
|
|
<question>
|
|
<para>I get messages like <errorname>limit 500 reached on entry
|
|
2800</errorname> and after that I my machine stops logging
|
|
denied packets that match that rule number. Is my firewall
|
|
still working?</para>
|
|
</question>
|
|
|
|
<answer>
|
|
<para>This merely means that the maximum logging count for
|
|
the rule has been reached. The rule itself is still
|
|
working, but it will no longer log until such time as you
|
|
reset the logging counters. An example of how to clear your
|
|
counters can be found below:</para>
|
|
<screen>&prompt.root; <userinput>ipfw resetlog</userinput></screen>
|
|
<para>Alternatively, you may increase the log limit in
|
|
your kernel configuration with the
|
|
<option>IPFIREWALL_VERBOSE_LIMIT</option> option as
|
|
described above. You may also change this limit (without
|
|
recompiling your kernel and having to reboot) by using the
|
|
net.inet.ip.fw.verbose_limit &man.sysctl.8; value.</para>
|
|
</answer>
|
|
</qandaentry>
|
|
|
|
<qandaentry>
|
|
<question>
|
|
<para>There must be something wrong. I followed your instructions
|
|
to the letter and now I am locked out.</para>
|
|
</question>
|
|
|
|
<answer>
|
|
<para>This tutorial assumes that you are running
|
|
<emphasis>userland-ppp</emphasis>, therefore the supplied rule set
|
|
operates on the <devicename>tun0</devicename> interface, which
|
|
corresponds to the first connection made with &man.ppp.8; (a.k.a.
|
|
<emphasis>user-ppp</emphasis>). Additional connections would use
|
|
<devicename>tun1</devicename>, <devicename>tun2</devicename> and so
|
|
on.</para>
|
|
|
|
<para>You should also note that &man.pppd.8; uses the
|
|
<devicename>ppp0</devicename> interface instead, so if you
|
|
start the connection with &man.pppd.8; you must substitute
|
|
<devicename>tun0</devicename> for
|
|
<devicename>ppp0</devicename>. A quick way to edit the
|
|
firewall rules to reflect this change is shown below. The
|
|
original rule set is backed up as
|
|
<filename>fwrules_tun0</filename>.</para>
|
|
|
|
<screen> &prompt.user; <userinput>cd /etc/firewall</userinput>
|
|
/etc/firewall&prompt.user; <userinput>su</userinput>
|
|
<prompt>Password:</prompt>
|
|
/etc/firewall&prompt.root; <userinput>mv fwrules fwrules_tun0</userinput>
|
|
/etc/firewall&prompt.root; <userinput>cat fwrules_tun0 | sed s/tun0/ppp0/g > fwrules</userinput>
|
|
</screen>
|
|
|
|
<para>To know whether you are currently using &man.ppp.8; or
|
|
&man.pppd.8; you can examine the output of
|
|
&man.ifconfig.8; once the connection is up. E.g., for a
|
|
connection made with &man.pppd.8; you would see something
|
|
like this (showing only the relevant lines):</para>
|
|
|
|
<screen> &prompt.user; <userinput>ifconfig</userinput>
|
|
<emphasis>(skipped...)</emphasis>
|
|
ppp0: flags=<replaceable>8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1524</replaceable>
|
|
inet <replaceable>xxx.xxx.xxx.xxx</replaceable> --> <replaceable>xxx.xxx.xxx.xxx</replaceable> netmask <replaceable>0xff000000</replaceable>
|
|
<emphasis>(skipped...)</emphasis>
|
|
</screen>
|
|
|
|
<para>On the other hand, for a connection made with
|
|
&man.ppp.8; (<emphasis>user-ppp</emphasis>) you should see
|
|
something similar to this:</para>
|
|
|
|
<screen> &prompt.user; <userinput>ifconfig</userinput>
|
|
<emphasis>(skipped...)</emphasis>
|
|
ppp0: flags=<replaceable>8010<POINTOPOINT,MULTICAST> mtu 1500</replaceable>
|
|
<emphasis>(skipped...)</emphasis>
|
|
tun0: flags=<replaceable>8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1524</replaceable>
|
|
<emphasis>(IPv6 stuff skipped...)</emphasis>
|
|
inet <replaceable>xxx.xxx.xxx.xxx</replaceable> --> <replaceable>xxx.xxx.xxx.xxx</replaceable> netmask <replaceable>0xffffff00</replaceable>
|
|
Opened by PID <replaceable>xxxxx</replaceable>
|
|
<emphasis>(skipped...)</emphasis></screen>
|
|
</answer>
|
|
</qandaentry>
|
|
</qandaset>
|
|
</sect1>
|
|
</article>
|