aboutsummaryrefslogtreecommitdiff
path: root/en_US.ISO8859-1/articles/dialup-firewall/article.sgml
blob: cb25f96671a12ea409563161dfa17b9195449fbf (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
<!--
     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;
]>

<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>

    <abstract>
      <para>This article documents how to setup 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 cover setting up your PPP connection in the first place.</para>
    </abstract>
  </articleinfo>

  <sect1 id="preface">
    <title>Preface</title>
    
    <para>Dialup Firewalling with FreeBSD</para>

     <para>This document covers the process that is required to setup
       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 your
       comments/suggestions to the <email>marcs@draenor.org</email>.</para>    
   </sect1>

  <sect1 id="kernel">
    <title>Kernel Options</title>
    
    <para>The first thing you'll need to do is recompile your kernel
      If you need more information on how to recompile the kernel,
      then the best place to start is the <ulink
	URL="http://www.freebsd.org/handbook/kernelconfig.html">kernel
	configuration section in the Handbook</ulink>. You need to add the
      following options into your kernel configuration file:</para>

    <variablelist>
      <varlistentry>
	<term><literal>options IPFIREWALL</literal></term>

	<listitem>
	  <para>Enables the kernel's firewall code.</para>
	</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>100</replaceable></literal></term>

	<listitem>
	  <para>Limits the number of times a matching entry is logged.  This
            prevents your log file from filling up with lots of repetitive
	    entries.
	    <replaceable>100</replaceable> is a reasonable number to use, but
	    you can adjust it based on your requirements.</para>
	</listitem>
      </varlistentry>

      <varlistentry>
	<term><literal>options IPDIVERT</literal></term>

	<listitem>
	  <para>Enables <emphasis>divert</emphasis> sockets, which will be
	    shown later.</para>
	</listitem>
      </varlistentry>
    </variablelist>

    <para>There are some other OPTIONAL items that you can compile
     into the kernel for some added security.  These are not required in
     order to get firewalling to work, but some more paranoid users may
     want to use them.</para>

    <variablelist>
      <varlistentry>
	<term><literal>options TCP_DROP_SYNFIN</literal></term>

	<listitem>
	  <para>This option ignores TCP packets with SYN and FIN.  This
	   prevents tools such as nmap etc from identifying the TCP/IP
 	   stack of the machine, but breaks support for RFC1644
	   extensions.  This is NOT recommended if the machine will be
	   running a web server.</para>
	</listitem>
      </varlistentry>
     </variablelist>

    <para>Don't reboot once you have recompiled the kernel. Hopefully, 
      we will only need to reboot once to complete the installation of the
      firewall.</para>
  </sect1>

  <sect1 id="rcconf">
    <title>Changing <filename>/etc/rc.conf</filename> to load the
      firewall</title>
    
    <para>We now need to make some changes to
      <filename>/etc/rc.conf</filename> in order to tell it about the
      firewall.  Simply add the following lines:</para>
    
    <programlisting>firewall_enable="YES"
firewall_script="/etc/firewall/fwrules"
natd_enable="YES"
natd_interface="tun0"
natd_flags="-dynamic"</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>Disable PPP's network address translation</title>
    
    <para>You may already be using PPP's built in network address
      translation (NAT).  If that is the case then you will have to disable 
      it, as these examples use &man.natd.8; to do the same.</para>

    <para>If you already have a block of entries to
      automatically start PPP, it probably looks like this:</para>

    <programlisting>ppp_enable="YES"
ppp_mode="auto"
ppp_nat="YES"
ppp_profile="<replaceable>profile</replaceable>"</programlisting>

    <para>If so, remove the <literal>ppp_nat="YES"</literal> line.  You will 
      also need to remove any <literal>nat enable yes</literal> or
      <literal>alias enable yes</literal> in
      <filename>/etc/ppp/ppp.conf</filename>.</para>
  </sect1>

  <sect1 id="rules">
    <title>The ruleset for the firewall</title>
    
    <para>We're nearly done now.  All that remains now is to define the
      firewall rules and then we can reboot and the firewall should be up and
      running.  I realize that everyone will want something slightly different
      when it comes to their rulebase.  What I've tried to do is write a
      rulebase that suits most dialup users.  You can obviously modify it to
      your needs by using the following rules as the foundation for
      your own rulebase.  First, let's start with the basics of closed
      firewalling.  What you want to do is deny everything by default and then
      only open up for the things you really need.  Rules should be in the
      order of allow first and then deny.  The premise is that you add the
      rules for your allows, and then everything else is denied. :)</para>

    <para>Now, let's make the dir /etc/firewall. 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 just gives an example of a
      filename. </para>

    <para>Now, let's look at a sample firewall file, that is commented
      nicely.</para>

    <programlisting># Firewall rules
# Written by Marc Silver (marcs@draenor.org)
# http://draenor.org/ipfw
# Freely distributable 


# Define the firewall command (as in /etc/rc.firewall) for easy
# reference.  Helps to make it easier to read.
fwcmd="/sbin/ipfw"

# Force a flushing of the current rules before we reload.
$fwcmd -f flush

# Divert all packets through the tunnel interface.
$fwcmd add divert natd all from any to any via tun0

# Allow all data from my network card and localhost.  Make sure you
# change your network card (mine was fxp0) before you reboot.  :)
$fwcmd add allow ip from any to any via lo0
$fwcmd add allow ip from any to any via fxp0

# Allow all connections that I initiate.
$fwcmd add allow tcp from any to any out xmit tun0 setup

# Once connections are made, allow them to stay open.
$fwcmd add allow tcp from any to any via tun0 established

# Everyone on the internet is allowed to connect to the following
# services on the machine.  This example shows that people may connect
# to ssh and apache.
$fwcmd add allow tcp from any to any 80 setup
$fwcmd add allow tcp from any to any 22 setup

# This sends a RESET to all ident packets.
$fwcmd add reset log tcp from any to any 113 in recv tun0

# Allow outgoing DNS queries ONLY to the specified servers.
$fwcmd add allow udp from any to <replaceable>x.x.x.x</replaceable> 53 out xmit tun0

# Allow them back in with the answers...  :)
$fwcmd add allow udp from <replaceable>x.x.x.x</replaceable> 53 to any in recv tun0

# Allow ICMP (for ping and traceroute to work).  You may wish to
# disallow this, but I feel it suits my needs to keep them in.
$fwcmd add 65435 allow icmp from any to any

# Deny all the rest.
$fwcmd add 65435 deny log ip from any to any</programlisting>

    <para>You now have a fully functional firewall that will allow on
      connections to ports 80 and 22 and will log any other connection
      attempts. Now, you should be able to safely reboot and your firewall 
      should come up fine. 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>Why are you using natd and ipfw when you could be using
	    the built in ppp-filters?</para>
	</question>
	
	<answer>
	  <para>I'll have to be honest and say there's no definitive reason
	    why I use ipfw and natd instead of the built in ppp filters.  From
	    the discussions I've had with people the consensus seems to be
	    that while ipfw is certainly more powerful and more configurable
	    than the ppp filters, what it makes up for in functionality it
	    loses in being easy to customise.  One of the reasons I use it is
	    because I prefer firewalling to be done at a kernel level rather
	    than by a userland program.</para>
	</answer>
      </qandaentry>

      <qandaentry>
        <question>
	  <para>I get messages like <errorname>limit 100 reached on entry
	    2800</errorname> and after that I never see more denies in my
	    logs.  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.  This can be done by simply prefixing the
	    ipfw command with the <literal>resetlog</literal> option.</para>
        </answer>
      </qandaentry>

      <qandaentry>
	<question>
	  <para>If I'm using private addresses internally, such as in the
	    192.168.0.0 range, could I add a command like <literal>$fwcmd add
	      deny all from any to 192.168.0.0:255.255.0.0 via tun0</literal>
	    to the firewall rules to prevent outside attempts to connect to
	    internal machines?</para>
	</question>

	<answer>
	  <para>The simple answer is no. The reason for this is that natd is
	    doing address translation for <emphasis>anything</emphasis> being
	    diverted through the tun0 device. As far as it's concerned
	    incoming packets will speak only to the dynamically assigned IP
	    address and NOT to the internal network. Note though that you can
	    add a rule like <literal>$fwcmd add deny all from
	      192.168.0.4:255.255.0.0 to any via tun0</literal> which would
	    limit a host on your internal network from going out via the
	    firewall.</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 ruleset
	    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 ruleset 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&lt;UP,POINTOPOINT,RUNNING,MULTICAST&gt; mtu 1524</replaceable>
                    inet <replaceable>xxx.xxx.xxx.xxx</replaceable> --&gt; <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&lt;POINTOPOINT,MULTICAST&gt; mtu 1500</replaceable>
	    <emphasis>(skipped...)</emphasis>
	    tun0: flags=<replaceable>8051&lt;UP,POINTOPOINT,RUNNING,MULTICAST&gt; mtu 1524</replaceable>
	            <emphasis>(IPv6 stuff skipped...)</emphasis>
                    inet <replaceable>xxx.xxx.xxx.xxx</replaceable> --&gt; <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>