316 lines
		
	
	
	
		
			12 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			316 lines
		
	
	
	
		
			12 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| <!--
 | |
|      The FreeBSD Documentation Project
 | |
| -->
 | |
| 
 | |
| <!DOCTYPE article PUBLIC "-//FreeBSD//DTD DocBook V4.1-Based Extension//EN" [
 | |
| <!ENTITY % articles.ent PUBLIC "-//FreeBSD//ENTITIES DocBook FreeBSD Articles Entity Set//EN">
 | |
| %articles.ent;
 | |
| ]>
 | |
| 
 | |
| <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>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="&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 are 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>Following that, let's create the directory where we will store our
 | |
|       firewall rules.  In this example, we will 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 reboot and the firewall should
 | |
|       be automatically started and the ruleset loaded.  If you find this
 | |
|       incorrect in any way 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 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>
 |