aboutsummaryrefslogtreecommitdiffstats
path: root/doc/src/firewall.html
blob: 5051b458d8f19f5460dacf15f67cd6d86f92253b (plain)
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
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html">
  <title>FreeS/WAN and firewalls</title>
  <meta name="keywords"
  content="Linux, IPsec, VPN, security, FreeSWAN, firewall, ipchains, iptables">
  <!--

  Written by Sandy Harris for the Linux FreeS/WAN project
  Freely distributable under the GNU General Public License

  More information at www.freeswan.org
  Feedback to users@lists.freeswan.org

  CVS information:
  RCS ID:          $Id: firewall.html,v 1.1 2004/03/15 20:35:24 as Exp $
  Last changed:    $Date: 2004/03/15 20:35:24 $
  Revision number: $Revision: 1.1 $

  CVS revision numbers do not correspond to FreeS/WAN release numbers.
  -->
</head>

<body>
<h1><a name="firewall">FreeS/WAN and firewalls</a></h1>

<p>FreeS/WAN, or other IPsec implementations, frequently run on gateway
machines, the same machines running firewall or packet filtering code. This
document discusses the relation between the two.</p>

<p>The firewall code in 2.4 and later kernels is called Netfilter. The
user-space utility to manage a firewall is iptables(8). See the <a
href="http://netfilter.samba.org">netfilter/iptables web site</a> for
details.</p>

<h2><a name="filters">Filtering rules for IPsec packets</a></h2>

<p>The basic constraint is that <strong>an IPsec gateway must have packet
filters that allow IPsec packets</strong>, at least when talking to other
IPsec gateways:</p>
<ul>
  <li>UDP port 500 for <a href="glossary.html#IKE">IKE</a> negotiations</li>
  <li>protocol 50 if you use <a href="glossary.html#ESP">ESP</a> encryption
    and/or authentication (the typical case)</li>
  <li>protocol 51 if you use <a href="glossary.html#AH">AH</a> packet-level
    authentication</li>
</ul>

<p>Your gateway and the other IPsec gateways it communicates with must be
able to exchange these packets for IPsec to work. Firewall rules must allow
UDP 500 and at least one of <a href="glossary.html#AH">AH</a> or 
<a href="glossary.html#ESP">ESP</a> on
the interface that communicates with the other gateway.</p>

<p>For nearly all FreeS/WAN applications, you must allow UDP port 500 and the
ESP protocol.</p>

<p>There are two ways to set this up:</p>
<dl>
  <dt>easier but less flexible</dt>
    <dd>Just set up your firewall scripts at boot time to allow IPsec packets
      to and from your gateway. Let FreeS/WAN reject any bogus packets.</dd>
  <dt>more work, giving you more precise control</dt>
    <dd>Have the <a href="manpage.d/ipsec_pluto.8.html">ipsec_pluto(8)</a>
      daemon call scripts to adjust firewall rules dynamically as required.
      This is done by naming the scripts in the <a
      href="manpage.d/ipsec.conf.5.html">ipsec.conf(5)</a> variables
      <var>prepluto=</var>, <var>postpluto=</var>, <var>leftupdown=</var> and
      <var>rightupdown=</var>.</dd>
</dl>

<p>Both methods are described in more detail below.</p>

<h2><a name="examplefw">Firewall configuration at boot</a></h2>

<p>It is possible to set up both firewalling and IPsec with appropriate
scripts at boot and then not use <var>leftupdown=</var> and
<var>rightupdown=</var>, or use them only for simple up and down
operations.</p>

<p>Basically, the technique is</p>
<ul>
  <li>allow IPsec packets (typically, IKE on UDP port 500 plus ESP, protocol
    50)
    <ul>
      <li>incoming, if the destination address is your gateway (and
        optionally, only from known senders)</li>
      <li>outgoing, with the from address of your gateway (and optionally,
        only to known receivers)</li>
    </ul>
  </li>
  <li>let <a href="glossary.html#Pluto">Pluto</a> deal with IKE</li>
  <li>let <a href="glossary.html#KLIPS">KLIPS</a> deal with ESP</li>
</ul>

<p>Since Pluto authenticates its partners during the negotiation, and KLIPS
drops packets for which no tunnel has been negotiated, this may be all you
need.</p>

<h3><a name="simple.rules">A simple set of rules</a></h3>

<p>In simple cases, you need only a few rules, as in this example:</p>
<pre># allow IPsec
#
# IKE negotiations
iptables -I INPUT  -p udp --sport 500 --dport 500 -j ACCEPT
iptables -I OUTPUT -p udp --sport 500 --dport 500 -j ACCEPT
# ESP encryption and authentication
iptables -I INPUT  -p 50 -j ACCEPT
iptables -I OUTPUT -p 50 -j ACCEPT
</pre>

<P>This should be all you need to allow IPsec through <var>lokkit</var>,
which ships with Red Hat 9, on its medium security setting.
Once you've tweaked to your satisfaction, save your active rule set with:</P>
<PRE>service iptables save</PRE>

<h3><a name="complex.rules">Other rules</a></h3>
You can add additional rules, or modify existing ones, to work with IPsec and
with your network and policies. We give a some examples in this section.

<p>However, while it is certainly possible to create an elaborate set of
rules yourself (please let us know via the <a href="mail.html">mailing
list</a> if you do), it may be both easier and more secure to use a set which
has already been published and tested.</p>

<p>The published rule sets we know of are described in the <a
href="#rules.pub">next section</a>.</p>

<h4>Adding additional rules</h4>
If necessary, you can add additional rules to:
<dl>
  <dt>reject IPsec packets that are not to or from known gateways</dt>
    <dd>This possibility is discussed in more detail <a
      href="#unknowngate">later</a></dd>
  <dt>allow systems behind your gateway to build IPsec tunnels that pass
  through the gateway</dt>
    <dd>This possibility is discussed in more detail <a
      href="#through">later</a></dd>
  <dt>filter incoming packets emerging from KLIPS.</dt>
    <dd>Firewall rules can recognise packets emerging from IPsec. They are
      marked as arriving on an interface such as <var>ipsec0</var>, rather
      than <var>eth0</var>, <var>ppp0</var> or whatever.</dd>
</dl>

<p>It is therefore reasonably straightforward to filter these packets in
whatever way suits your situation.</p>

<h4>Modifying existing rules</h4>

<p>In some cases rules that work fine before you add IPsec may require
modification to work with IPsec.</p>

<p>This is especially likely for rules that deal with interfaces on the
Internet side of your system. IPsec adds a new interface; often the rules
must change to take account of that.</p>

<p>For example, consider the rules given in <a
href="http://www.netfilter.org/documentation/HOWTO//packet-filtering-HOWTO-5.html">this
section</a> of the Netfilter documentation:</p>
<pre>Most people just have a single PPP connection to the Internet, and don't
want anyone coming back into their network, or the firewall:

    ## Insert connection-tracking modules (not needed if built into kernel).
    # insmod ip_conntrack
    # insmod ip_conntrack_ftp

    ## Create chain which blocks new connections, except if coming from inside.
    # iptables -N block
    # iptables -A block -m state --state ESTABLISHED,RELATED -j ACCEPT
    # iptables -A block -m state --state NEW -i ! ppp0 -j ACCEPT
    # iptables -A block -j DROP

    ## Jump to that chain from INPUT and FORWARD chains.
    # iptables -A INPUT -j block
    # iptables -A FORWARD -j block</pre>

<p>On an IPsec gateway, those rules may need to be modified. The above allows
new connections from <em>anywhere except ppp0</em>. That means new
connections from ipsec0 are allowed.</p>

<p>Do you want to allow anyone who can establish an IPsec connection to your
gateway to initiate TCP connections to any service on your network? Almost
certainly not if you are using opportunistic encryption. Quite possibly not
even if you have only explicitly configured connections.</p>

<p>To disallow incoming connections from ipsec0, change the middle section
above to:</p>
<pre>    ## Create chain which blocks new connections, except if coming from inside.
    # iptables -N block
    # iptables -A block -m state --state ESTABLISHED,RELATED -j ACCEPT
    # iptables -A block -m state --state NEW -i ppp+ -j DROP
    # iptables -A block -m state --state NEW -i ipsec+ -j DROP
    # iptables -A block -m state --state NEW -i -j ACCEPT
    # iptables -A block -j DROP</pre>

<p>The original rules accepted NEW connections from anywhere except ppp0.
This version drops NEW connections from any PPP interface (ppp+) and from any
ipsec interface (ipsec+), then accepts the survivors.</p>

<p>Of course, these are only examples. You will need to adapt them to your
own situation.</p>

<h3><a name="rules.pub">Published rule sets</a></h3>

<p>Several sets of firewall rules that work with FreeS/WAN are available.</p>

<h4><a name="Ranch.trinity">Scripts based on Ranch's work</a></h4>

<p>One user, Rob Hutton, posted his boot time scripts to the mailing list,
and we included them in previous versions of this documentation. They are
still available from our <a
href="http://www.freeswan.org/freeswan_trees/freeswan-1.5/doc/firewall.html#examplefw">web
site</a>. However, they were for an earlier FreeS/WAN version so we no longer
recommend them. Also, they had some bugs. See this <a
href="http://www.sandelman.ottawa.on.ca/linux-ipsec/html/2000/04/msg00316.html">message</a>.</p>

<p>Those scripts were based on David Ranch's scripts for his "Trinity OS" for
setting up a secure Linux. Check his <a
href="http://www.ecst.csuchico.edu/~dranch/LINUX/index-linux.html">home
page</a> for the latest version and for information on his <a
href="biblio.html#ranch">book</a> on securing Linux. If you are going to base
your firewalling on Ranch's scripts, we recommend using his latest version,
and sending him any IPsec modifications you make for incorporation into later
versions.</p>

<h4><a name="seawall">The Seattle firewall</a></h4>

<p>We have had several mailing lists reports of good results using FreeS/WAN
with Seawall (the Seattle Firewall). See that project's <a
href="http://seawall.sourceforge.net/">home page</a> on Sourceforge.</p>

<h4><a name="rcf">The RCF scripts</a></h4>

<p>Another set of firewall scripts with IPsec support are the RCF or
rc.firewall scripts. See their <a
href="http://jsmoriss.mvlan.net/linux/rcf.html">home page</a>.</p>

<h4><a name="asgard">Asgard scripts</a></h4>

<p><a href="http://heimdall.asgardsrealm.net/linux/firewall/">Asgard's
Realm</a> has set of firewall scripts with FreeS/WAN support, for 2.4 kernels
and iptables.</p>

<h4><a name="user.scripts">User scripts from the mailing list</a></h4>

<p>One user gave considerable detail on his scripts, including supporting <a
href="glossary.html#IPX">IPX</a> through the tunnel. His message was too long
to conveniently be quoted here, so I've put it in a <a
href="user_examples.html">separate file</a>.</p>

<h2><a name="updown">Calling firewall scripts, named in ipsec.conf(5)</a></h2>

<p>The <a href="manpage.d/ipsec.conf.5.html">ipsec.conf(5)</a> configuration
file has three pairs of parameters used to specify an interface between
FreeS/WAN and firewalling code.</p>

<p>Note that using these is not required if you have a static firewall setup.
In that case, you just set your firewall up at boot time (in a way that
permits the IPsec connections you want) and do not change it thereafter. Omit
all the FreeS/WAN firewall parameters and FreeS/WAN will not attempt to
adjust firewall rules at all. See <a href="#examplefw">above</a> for some
information on appropriate scripts.</p>

<p>However, if you want your firewall rules to change when IPsec connections
change, then you need to use these parameters.</p>

<h3><a name="pre_post">Scripts called at IPsec start and stop</a></h3>

<p>One pair of parmeters are set in the <var>config setup</var> section of
the <a href="manpage.d/ipsec.conf.5.html">ipsec.conf(5)</a> file and affect
all connections:</p>
<dl>
  <dt>prepluto=</dt>
    <dd>script to be called before <a
      href="manpage.d/ipsec_pluto.8.html">pluto(8)</a> IKE daemon is
    started.</dd>
  <dt>postpluto=</dt>
    <dd>script to be called after <a
      href="manpage.d/ipsec_pluto.8.html">pluto(8)</a> IKE daemon is
    stopped.</dd>
</dl>
These parameters allow you to change firewall parameters whenever IPsec is
started or stopped.

<p>They can also be used in other ways. For example, you might have
<var>prepluto</var> add a module to your kernel for the secure network
interface or make a dialup connection, and then have <var>postpluto</var>
remove the module or take the connection down.</p>

<h3><a name="up_down">Scripts called at connection up and down</a></h3>

<p>The other parameters are set in connection descriptions. They can be set
in individual connection descriptions, and could even call different scripts
for each connection for maximum flexibility. In most applications, however,
it makes sense to use only one script and to call it from <var>conn
%default</var> section so that it applies to all connections.</p>

<p>You can:</p>
<dl>
  <dt><strong>either</strong></dt>
    <dd>set <var>leftfirewall=yes</var> or <var>rightfirewall=yes</var> to
      use our supplied default script</dd>
  <dt><strong>or</strong></dt>
    <dd>assign a name in a <var>leftupdown=</var> or <var>rightupdown=</var>
      line to use your own script</dd>
</dl>

<p>Note that <strong>only one of these should be used</strong>. You cannot
sensibly use both. Since <strong>our default script is obsolete</strong>
(designed for firewalls using <var>ipfwadm(8)</var> on 2.0 kernels), most
users who need this service will <strong>need to write a custom
script</strong>.</p>

<h4><a name="fw.default">The default script</a></h4>

<p>We supply a default script named <var>_updown</var>.</p>
<dl>
  <dt>leftfirewall=</dt>
    <dd></dd>
  <dt>rightfirewall=</dt>
    <dd>indicates that the gateway is doing firewalling and that <a
      href="manpage.d/ipsec_pluto.8.html">pluto(8)</a> should poke holes in
      the firewall as required.</dd>
</dl>

<p>Set these to <var>yes</var> and Pluto will call our default script
<var>_updown</var> with appropriate arguments whenever it:</p>
<ul>
  <li>starts or stops IPsec services</li>
  <li>brings a connection up or down</li>
</ul>

<p>The supplied default <var>_updown</var> script is appropriate for simple
cases using the <var>ipfwadm(8)</var> firewalling package.</p>

<h4><a name="userscript">User-written scripts</a></h4>

<p>You can also write your own script and have Pluto call it. Just put the
script's name in one of these <a
href="manpage.d/ipsec.conf.5.html">ipsec.conf(5)</a> lines:</p>
<dl>
  <dt>leftupdown=</dt>
    <dd></dd>
  <dt>rightupdown=</dt>
    <dd>specifies a script to call instead of our default script
      <var>_updown</var>.</dd>
</dl>

<p>Your script should take the same arguments and use the same environment
variables as <var>_updown</var>. See the "updown command" section of the <a
href="manpage.d/ipsec_pluto.8.html">ipsec_pluto(8)</a> man page for
details.</p>

<p>Note that <strong>you should not modify our _updown script in
place</strong>. If you did that, then upgraded FreeS/WAN, the upgrade would
install a new default script, overwriting your changes.</p>

<h3><a name="ipchains.script">Scripts for ipchains or iptables</a></h3>

<p>Our <var>_updown</var> is for firewalls using <var>ipfwadm(8)</var>, the
firewall code for the 2.0 series of Linux kernels. If you are using the more
recent packages <var>ipchains(8)</var> (for 2.2 kernels) or
<var>iptables(8)</var> (2.4 kernels), then you must do one of:</p>
<ul>
  <li>use static firewall rules which are set up at boot time as described <a
    href="#examplefw">above</a> and do not need to be changed by Pluto</li>
  <li>limit yourself to ipchains(8)'s ipfwadm(8) emulation mode in order to
    use our script</li>
  <li>write your own script and call it with <var>leftupdown</var> and
    <var>rightupdown</var>.</li>
</ul>

<p>You can write a script to do whatever you need with firewalling. Specify
its name in a <var>[left|right]updown=</var> parameter in <a
href="manpage.d/ipsec.conf.5.html">ipsec.conf(5)</a> and Pluto will
automatically call it for you.</p>

<p>The arguments Pluto passes such a script are the same ones it passes to
our default _updown script, so the best way to build yours is to copy ours
and modify the copy.</p>

<p>Note, however, that <strong>you should not modify our _updown script in
place</strong>. If you did that, then upgraded FreeS/WAN, the upgrade would
install a new default script, overwriting your changes.</p>

<h2><a name="NAT">A complication: IPsec vs. NAT</a></h2>

<p><a href="glossary.html#NAT.gloss">Network Address Translation</a>, also
known as IP masquerading, is a method of allocating IP addresses dynamically,
typically in circumstances where the total number of machines which need to
access the Internet exceeds the supply of IP addresses.</p>

<p>Any attempt to perform NAT operations on IPsec packets <em>between the
IPsec gateways</em> creates a basic conflict:</p>
<ul>
  <li>IPsec wants to authenticate packets and ensure they are unaltered on a
    gateway-to-gateway basis</li>
  <li>NAT rewrites packet headers as they go by</li>
  <li>IPsec authentication fails if packets are rewritten anywhere between
    the IPsec gateways</li>
</ul>

<p>For <a href="glossary.html#AH">AH</a>, which authenticates parts of the
packet header including source and destination IP addresses, this is fatal.
If NAT changes those fields, AH authentication fails.</p>

<p>For <a href="glossary.html#IKE">IKE</a> and <a
href="glossary.html#ESP">ESP</a> it is not necessarily fatal, but is
certainly an unwelcome complication.</p>

<h3><a name="nat_ok">NAT on or behind the IPsec gateway works</a></h3>

<p>This problem can be avoided by having the masquerading take place <em>on
or behind</em> the IPsec gateway.</p>

<p>This can be done physically with two machines, one physically behind the
other. A picture, using SG to indicate IPsec <strong>S</strong>ecurity
<strong>G</strong>ateways, is:</p>
<pre>      clients --- NAT ----- SG ---------- SG
                  two machines</pre>

<p>In this configuration, the actual client addresses need not be given in
the <var>leftsubnet=</var> parameter of the FreeS/WAN connection description.
The security gateway just delivers packets to the NAT box; it needs only that
machine's address. What that machine does with them does not affect
FreeS/WAN.</p>

<p>A more common setup has one machine performing both functions:</p>
<pre>      clients ----- NAT/SG ---------------SG
                  one machine</pre>

<p>Here you have a choice of techniques depending on whether you want to make
your client subnet visible to clients on the other end:</p>
<ul>
  <li>If you want the single gateway to behave like the two shown above, with
    your clients hidden behind the NAT, then omit the <var>leftsubnet=</var>
    parameter. It then defaults to the gateway address. Clients on the other
    end then talk via the tunnel only to your gateway. The gateway takes
    packets emerging from the tunnel, applies normal masquerading, and
    forwards them to clients.</li>
  <li>If you want to make your client machines visible, then give the client
    subnet addresses as the <var>leftsubnet=</var> parameter in the
    connection description and
    <dl>
      <dt>either</dt>
        <dd>set <var>leftfirewall=yes</var> to use the default
          <var>updown</var> script</dd>
      <dt>or</dt>
        <dd>use your own script by giving its name in a
          <var>leftupdown=</var> parameter</dd>
    </dl>
    These scripts are described in their own <a href="#updown">section</a>.
    <p>In this case, no masquerading is done. Packets to or from the client
    subnet are encrypted or decrypted without any change to their client
    subnet addresses, although of course the encapsulating packets use
    gateway addresses in their headers. Clients behind the right security
    gateway see a route via that gateway to the left subnet.</p>
  </li>
</ul>

<h3><a name="nat_bad">NAT between gateways is problematic</a></h3>

<p>We recommend not trying to build IPsec connections which pass through a
NAT machine. This setup poses problems:</p>
<pre>      clients --- SG --- NAT ---------- SG</pre>

<p>If you must try it, some references are:</p>
<ul>
  <li>Jean_Francois Nadeau's document on doing <a
    href="http://jixen.tripod.com/#NATed gateways">IPsec behind NAT</a></li>
  <li><a href="web.html#VPN.masq">VPN masquerade patches</a> to make a Linux
    NAT box handle IPsec packets correctly</li>
</ul>

<h3><a name="NAT.ref">Other references on NAT and IPsec</a></h3>

<p>Other documents which may be relevant include:</p>
<ul>
  <li>an Internet Draft on <a
    href="http://search.ietf.org/internet-drafts/draft-aboba-nat-ipsec-04.txt">IPsec
    and NAT</a> which may eventually evolve into a standard solution for this
    problem.</li>
  <li>an informational <a
    href="http://www.cis.ohio-state.edu/rfc/rfc2709.txt">RFC</a>,
    <cite>Security Model with Tunnel-mode IPsec for NAT Domains</cite>.</li>
  <li>an <a
    href="http://www.cisco.com/warp/public/759/ipj_3-4/ipj_3-4_nat.html">article</a>
    in Cisco's <cite>Internet Protocol Journal</cite></li>
</ul>

<h2><a name="complications">Other complications</a></h2>

<p>Of course simply allowing UDP 500 and ESP packets is not the whole story.
Various other issues arise in making IPsec and packet filters co-exist and
even co-operate. Some of them are summarised below.</p>

<h3><a name="through">IPsec <em>through</em></a> the gateway</h3>

<p>Basic IPsec packet filtering rules deal only with packets addressed to or
sent from your IPsec gateway.</p>

<p>It is a separate policy decision whether to permit such packets to pass
through the gateway so that client machines can build end-to-end IPsec
tunnels of their own. This may not be practical if you are using <a
href="#NAT">NAT (IP masquerade)</a> on your gateway, and may conflict with
some corporate security policies.</p>

<p>Where possible, allowing this is almost certainly a good idea. Using IPsec
on an end-to-end basis is more secure than gateway-to-gateway.</p>

<p>Doing it is quite simple. You just need firewall rules that allow UDP port
500 and protocols 50 and 51 to pass through your gateway. If you wish, you
can of course restrict this to certain hosts.</p>

<h3><a name="ipsec_only">Preventing non-IPsec traffic</a></h3>
You can also filter <em>everything but</em> UDP port 500 and ESP or AH to
restrict traffic to IPsec only, either for anyone communicating with your
host or just for specific partners.

<p>One application of this is for the telecommuter who might have:</p>
<pre>     Sunset==========West------------------East ================= firewall --- the Internet
         home network      untrusted net        corporate network</pre>

<p>The subnet on the right is 0.0.0.0/0, the whole Internet. The West gateway
is set up so that it allows only IPsec packets to East in or out.</p>

<p>This configuration is used in AT&amp;T Research's network. For details,
see the <a href="intro.html#applied">papers</a> links in our introduction.</p>

<p>Another application would be to set up firewall rules so that an internal
machine, such as an employees-only web server, could not talk to the outside
world except via specific IPsec tunnels.</p>

<h3><a name="unknowngate">Filtering packets from unknown gateways</a></h3>

<p>It is possible to use firewall rules to restrict UDP 500, ESP and AH
packets so that these packets are accepted only from known gateways. This is
not strictly necessary since FreeS/WAN will discard packets from unknown
gateways. You might, however, want to do it for any of a number of reasons.
For example:</p>
<ul>
  <li>Arguably, "belt and suspenders" is the sensible approach to security.
    If you can block a potential attack in two ways, use both. The only
    question is whether to look for a third way after implementing the first
    two.</li>
  <li>Some admins may prefer to use the firewall code this way because they
    prefer firewall logging to FreeS/WAN's logging.</li>
  <li>You may need it to implement your security policy. Consider an employee
    working at home, and a policy that says traffic from the home system to
    the Internet at large must go first via IPsec to the corporate LAN and
    then out to the Internet via the corporate firewall. One way to do that
    is to make <var>ipsec0</var> the default route on the home gateway and
    provide exceptions only for UDP 500 and ESP to the corporate gateway.
    Everything else is then routed via the tunnel to the corporate
  gateway.</li>
</ul>

<p>It is not possible to use only static firewall rules for this filtering if
you do not know the other gateways' IP addresses in advance, for example if
you have "road warriors" who may connect from a different address each time
or if want to do <a href="glossary.html#carpediem">opportunistic
encryption</a> to arbitrary gateways. In these cases, you can accept UDP 500
IKE packets from anywhere, then use the <a href="#updown">updown</a> script
feature of <a href="manpage.d/ipsec_pluto.8.html">pluto(8)</a> to dynamically
adjust firewalling for each negotiated tunnel.</p>

<p>Firewall packet filtering does not much reduce the risk of a <a
href="glossary.html#DOS">denial of service attack</a> on FreeS/WAN. The
firewall can drop packets from unknown gateways, but KLIPS does that quite
efficiently anyway, so you gain little. The firewall cannot drop otherwise
legitmate packets that fail KLIPS authentication, so it cannot protect
against an attack designed to exhaust resources by making FreeS/WAN perform
many expensive authentication operations.</p>

<p>In summary, firewall filtering of IPsec packets from unknown gateways is
possible but not strictly necessary.</p>

<h2><a name="otherfilter">Other packet filters</a></h2>

<p>When the IPsec gateway is also acting as your firewall, other packet
filtering rules will be in play. In general, those are outside the scope of
this document. See our <a href="web.html#firewall.linux">Linux firewall
links</a> for information. There are a few types of packet, however, which
can affect the operation of FreeS/WAN or of diagnostic tools commonly used
with it. These are discussed below.</p>

<h3><a name="ICMP">ICMP filtering</a></h3>

<p><a href="glossary.html#ICMP.gloss">ICMP</a> is the
<strong>I</strong>nternet <strong>C</strong>ontrol <strong>M</strong>essage
<strong>P</strong>rotocol. It is used for messages between IP implementations
themselves, whereas IP used is used between the clients of those
implementations. ICMP is, unsurprisingly, used for control messages. For
example, it is used to notify a sender that a desination is not reachable, or
to tell a router to reroute certain packets elsewhere.</p>

<p>ICMP handling is tricky for firewalls.</p>
<ul>
  <li>You definitely want some ICMP messages to get through; things won't
    work without them. For example, your clients need to know if some
    destination they ask for is unreachable.</li>
  <li>On the other hand, you do equally definitely do not want untrusted folk
    sending arbitrary control messages to your machines. Imagine what someone
    moderately clever and moderately malicious could do to you, given control
    of your network's routing.</li>
</ul>

<p>ICMP does not use ports. Messages are distinguished by a "message type"
field and, for some types, by an additional "code" field. The definitive list
of types and codes is on the <a href="http://www.iana.org">IANA</a> site.</p>

<p>One expert uses this definition for ICMP message types to be dropped at
the firewall.</p>
<pre># ICMP types which lack socially redeeming value.
#  5     Redirect
#  9     Router Advertisement
# 10     Router Selection
# 15     Information Request
# 16     Information Reply
# 17     Address Mask Request
# 18     Address Mask Reply

badicmp='5 9 10 15 16 17 18'</pre>

<p>A more conservative approach would be to make a list of allowed types and
drop everything else.</p>

<p>Whichever way you do it, your ICMP filtering rules on a FreeS/WAN gateway
should allow at least the following ICMP packet types:</p>
<dl>
  <dt>echo (type 8)</dt>
    <dd></dd>
  <dt>echo reply (type 0)</dt>
    <dd>These are used by ping(1). We recommend allowing both types through
      the tunnel and to or from your gateway's external interface, since
      ping(1) is an essential testing tool.
      <p>It is fairly common for firewalls to drop ICMP echo packets
      addressed to machines behind the firewall. If that is your policy,
      please create an exception for such packets arriving via an IPsec
      tunnel, at least during intial testing of those tunnels.</p>
    </dd>
  <dt>destination unreachable (type 3)</dt>
    <dd>This is used, with code 4 (Fragmentation Needed and Don't Fragment
      was Set) in the code field, to control <a
      href="glossary.html#pathMTU">path MTU discovery</a>. Since IPsec
      processing adds headers, enlarges packets and may cause fragmentation,
      an IPsec gateway should be able to send and receive these ICMP messages
      <strong>on both inside and outside interfaces</strong>.</dd>
</dl>

<h3><a name="traceroute">UDP packets for traceroute</a></h3>

<p>The traceroute(1) utility uses UDP port numbers from 33434 to
approximately 33633. Generally, these should be allowed through for
troubleshooting.</p>

<p>Some firewalls drop these packets to prevent outsiders exploring the
protected network with traceroute(1). If that is your policy, consider
creating an exception for such packets arriving via an IPsec tunnel, at least
during intial testing of those tunnels.</p>

<h3><a name="l2tp">UDP for L2TP</a></h3>
<p>
Windows 2000 does, and products designed for compatibility with it may, build
<a href="glossary.html#L2TP">L2TP</a> tunnels over IPsec connections.

<p>For this to work, you must allow UDP protocol 1701 packets coming out of
your tunnels to continue to their destination. You can, and probably should,
block such packets to or from your external interfaces, but allow them from
<var>ipsec0</var>.</p>

<p>See also our Windows 2000 <a href="interop.html#win2k">interoperation
discussion</a>.</p>

<h2><a name="packets">How it all works: IPsec packet details</a></h2>

<p>IPsec uses three main types of packet:</p>
<dl>
  <dt><a href="glossary.html#IKE">IKE</a> uses <strong>the UDP protocol and
  port 500</strong>.</dt>
    <dd>Unless you are using only (less secure, not recommended) manual
      keying, you need IKE to negotiate connection parameters, acceptable
      algorithms, key sizes and key setup. IKE handles everything required to
      set up, rekey, repair or tear down IPsec connections.</dd>
  <dt><a href="glossary.html#ESP">ESP</a> is <strong>protocol number
  50</strong></dt>
    <dd>This is required for encrypted connections.</dd>
  <dt><a href="glossary.html#AH">AH</a> is <strong>protocol number
  51</strong></dt>
    <dd>This can be used where only authentication, not encryption, is
      required.</dd>
</dl>

<p>All of those packets should have appropriate IPsec gateway addresses in
both the to and from IP header fields. Firewall rules can check this if you
wish, though it is not strictly necessary. This is discussed in more detail
<a href="#unknowngate">later</a>.</p>

<p>IPsec processing of incoming packets authenticates them then removes the
ESP or AH header and decrypts if necessary. Successful processing exposes an
inner packet which is then delivered back to the firewall machinery, marked
as having arrived on an <var>ipsec[0-3]</var> interface. Firewall rules can
use that interface label to distinguish these packets from unencrypted
packets which are labelled with the physical interface they arrived on (or
perhaps with a non-IPsec virtual interface such as <var>ppp0</var>).</p>

<p>One of our users sent a mailing list message with a <a
href="http://www.sandelman.ottawa.on.ca/linux-ipsec/html/2000/12/msg00006.html">diagram</a>
of the packet flow.</p>

<h3><a name="noport">ESP and AH do not have ports</a></h3>

<p>Some protocols, such as TCP and UDP, have the notion of ports. Others
protocols, including ESP and AH, do not. Quite a few IPsec newcomers have
become confused on this point. There are no ports <em>in</em> the ESP or AH
protocols, and no ports used <em>for</em> them. For these protocols, <em>the
idea of ports is completely irrelevant</em>.</p>

<h3><a name="header">Header layout</a></h3>

<p>The protocol numbers for ESP or AH are used in the 'next header' field of
the IP header. On most non-IPsec packets, that field would have one of:</p>
<ul>
  <li>1 for ICMP</li>
  <li>4 for IP-in-IP encapsulation</li>
  <li>6 for TCP</li>
  <li>17 for UDP</li>
  <li>... or one of about 100 other possibilities listed by <a
    href="http://www.iana.org">IANA</a></li>
</ul>

<p>Each header in the sequence tells what the next header will be. IPsec adds
headers for ESP or AH near the beginning of the sequence. The original
headers are kept and the 'next header' fields adjusted so that all headers
can be correctly interpreted.</p>

<p>For example, using <strong>[</strong> <strong>]</strong> to indicate data
protected by ESP and unintelligible to an eavesdropper between the
gateways:</p>
<ul>
  <li>a simple packet might have only IP and TCP headers with:
    <ul>
      <li>IP header says next header --&gt; TCP</li>
      <li>TCP header port number --&gt; which process to send data to</li>
      <li>data</li>
    </ul>
  </li>
  <li>with ESP <a href="glossary.html#transport">transport mode</a>
    encapsulation, that packet would have:
    <ul>
      <li>IP header says next header --&gt; ESP</li>
      <li>ESP header <strong>[</strong> says next --&gt; TCP</li>
      <li>TCP header port number --&gt; which process to send data to</li>
      <li>data <strong>]</strong></li>
    </ul>
    Note that the IP header is outside ESP protection, visible to an
    attacker, and that the final destination must be the gateway.</li>
  <li>with ESP in <a href="glossary.html#tunnel">tunnel mode</a>, we might
    have:
    <ul>
      <li>IP header says next header --&gt; ESP</li>
      <li>ESP header <strong>[</strong> says next --&gt; IP</li>
      <li>IP header says next header --&gt; TCP</li>
      <li>TCP header port number --&gt; which process to send data to</li>
      <li>data <strong>]</strong></li>
    </ul>
    Here the inner IP header is protected by ESP, unreadable by an attacker.
    Also, the inner header can have a different IP address than the outer IP
    header, so the decrypted packet can be routed from the IPsec gateway to a
    final destination which may be another machine.</li>
</ul>

<p>Part of the ESP header itself is encrypted, which is why the
<strong>[</strong> indicating protected data appears in the middle of some
lines above. The next header field of the ESP header is protected. This makes
<a href="glossary.html#traffic">traffic analysis</a> more difficult. The next
header field would tell an eavesdropper whether your packet was UDP to the
gateway, TCP to the gateway, or encapsulated IP. It is better not to give
this information away. A clever attacker may deduce some of it from the
pattern of packet sizes and timings, but we need not make it easy.</p>

<p>IPsec allows various combinations of these to match local policies,
including combinations that use both AH and ESP headers or that nest multiple
copies of these headers.</p>

<p>For example, suppose my employer has an IPsec VPN running between two
offices so all packets travelling between the gateways for those offices are
encrypted. If gateway policies allow it (The admins could block UDP 500 and
protocols 50 and 51 to disallow it), I can build an IPsec tunnel from my
desktop to a machine in some remote office. Those packets will have one ESP
header throughout their life, for my end-to-end tunnel. For part of the
route, however, they will also have another ESP layer for the corporate VPN's
encapsulation. The whole header scheme for a packet on the Internet might
be:</p>
<ul>
  <li>IP header (with gateway address) says next header --&gt; ESP</li>
  <li>ESP header <strong>[</strong> says next --&gt; IP</li>
  <li>IP header (with receiving machine address) says next header --&gt;
  ESP</li>
  <li>ESP header <strong>[</strong> says next --&gt; TCP</li>
  <li>TCP header port number --&gt; which process to send data to</li>
  <li>data <strong>]]</strong></li>
</ul>

<p>The first ESP (outermost) header is for the corporate VPN. The inner ESP
header is for the secure machine-to-machine link.</p>

<h3><a name="dhr">DHR on the updown script</a></h3>

<p>Here are some mailing list comments from <a
href="manpage.d/ipsec_pluto.8.html">pluto(8)</a> developer Hugh Redelmeier on
an earlier draft of this document:</p>
<pre>There are many important things left out

- firewalling is important but must reflect (implement) policy.  Since
  policy isn't the same for all our customers, and we're not experts,
  we should concentrate on FW and MASQ interactions with FreeS/WAN.

- we need a diagram to show packet flow WITHIN ONE MACHINE, assuming
  IKE, IPsec, FW, and MASQ are all done on that machine.  The flow is
  obvious if the components are run on different machines (trace the
  cables).

  IKE input:
        + packet appears on public IF, as UDP port 500
        + input firewalling rules are applied (may discard)
        + Pluto sees the packet.

  IKE output:
        + Pluto generates the packet &amp; writes to public IF, UDP port 500
        + output firewalling rules are applied (may discard)
        + packet sent out public IF

  IPsec input, with encapsulated packet, outer destination of this host:
        + packet appears on public IF, protocol 50 or 51.  If this
          packet is the result of decapsulation, it will appear
          instead on the paired ipsec IF.
        + input firewalling rules are applied (but packet is opaque)
        + KLIPS decapsulates it, writes result to paired ipsec IF
        + input firewalling rules are applied to resulting packet
          as input on ipsec IF
        + if the destination of the packet is this machine, the
          packet is passed on to the appropriate protocol handler.
          If the original packet was encapsulated more than once
          and the new outer destination is this machine, that
          handler will be KLIPS.
        + otherwise:
          * routing is done for the resulting packet.  This may well
            direct it into KLIPS for encoding or encrypting.  What
            happens then is described elsewhere.
          * forwarding firewalling rules are applied
          * output firewalling rules are applied
          * the packet is sent where routing specified

 IPsec input, with encapsulated packet, outer destination of another host:
        + packet appears on some IF, protocol 50 or 51
        + input firewalling rules are applied (but packet is opaque)
        + routing selects where to send the packet
        + forwarding firewalling rules are applied (but packet is opaque)
        + packet forwarded, still encapsulated

  IPsec output, from this host or from a client:
        + if from a client, input firewalling rules are applied as the
          packet arrives on the private IF
        + routing directs the packet to an ipsec IF (this is how the
          system decides KLIPS processing is required)
        + if from a client, forwarding firewalling rules are applied
        + KLIPS eroute mechanism matches the source and destination
          to registered eroutes, yielding a SPI group.  This dictates
          processing, and where the resulting packet is to be sent
          (the destinations SG and the nexthop).
        + output firewalling is not applied to the resulting
          encapsulated packet

- Until quite recently, KLIPS would double encapsulate packets that
  didn't strictly need to be.  Firewalling should be prepared for
  those packets showing up as ESP and AH protocol input packets on
  an ipsec IF.

- MASQ processing seems to be done as if it were part of the
  forwarding firewall processing (this should be verified).

- If a firewall is being used, it is likely the case that it needs to
  be adjusted whenever IPsec SAs are added or removed.  Pluto invokes
  a script to do this (and to adjust routing) at suitable times.  The
  default script is only suitable for ipfwadm-managed firewalls.  Under
  LINUX 2.2.x kernels, ipchains can be managed by ipfwadm (emulation),
  but ipchains more powerful if manipulated using the ipchains command.
  In this case, a custom updown script must be used.

  We think that the flexibility of ipchains precludes us supplying an
  updown script that would be widely appropriate.</pre>
</body>
</html>