aboutsummaryrefslogtreecommitdiff
path: root/zh_CN.UTF-8/books/handbook/firewalls/chapter.xml
blob: 6070e21b11ee13c70af374caba6e2276369df611 (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
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
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
<?xml version="1.0" encoding="utf-8"?>
<!--
     The FreeBSD Documentation Project
     The FreeBSD Simplified Chinese Project

     Original Revision: 35babe0ae5 (r38826)
     $FreeBSD$
-->
<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="firewalls">
  <info><title>防火墙</title>
    <authorgroup>
      <author><personname><firstname>Joseph J.</firstname><surname>Barbish</surname></personname><contrib>Contributed by </contrib></author>
    </authorgroup>
    <authorgroup>
      <author><personname><firstname>Brad</firstname><surname>Davis</surname></personname><contrib>Converted to SGML and updated by </contrib></author>
    </authorgroup>
  </info>

  

  <indexterm><primary>防火墙</primary></indexterm>

  <indexterm>
    <primary>安全</primary>

    <secondary>防火墙</secondary>
  </indexterm>

  <sect1 xml:id="firewalls-intro">
    <title>入门</title>

    <para>防火墙的存在, 使得过滤出入系统的数据流成为可能。
      防火墙可以使用一组或多组 <quote>规则 (rules)</quote>,
      来检查出入您的网络连接的数据包, 并决定允许或阻止它们通过。
      这些规则通常可以检查数据包的某个或某些特征,
      这些特征包括, 但不必限于协议类型、 来源或目的主机地址,
      以及来源或目的端口。</para>

    <para>防火墙可以大幅度地改善主机或网络的安全。
      它可以用来完成下面的任务:</para>

    <itemizedlist>
      <listitem>
	<para>保护和隔离应用程序、 服务程序, 以及您内部网络上的机器,
	  不受那些来自公共的 Internet 网络上您所不希望的数据流量的干扰。</para>
      </listitem>

      <listitem>
	<para>限制或禁止从内部网访问公共的 Internet 上的服务。</para>
      </listitem>

      <listitem>
	<para>支持网络地址转换
	  (<acronym>NAT</acronym>),
	  它使得您的内部网络能够使用私有的 <acronym>IP</acronym> 地址,
	  并分享一条通往公共的 Internet 的连接 (使用一个
	  <acronym>IP</acronym> 地址, 或者一组公网地址)。</para>
      </listitem>
    </itemizedlist>

    <para>读完这章, 您将了解:</para>

    <itemizedlist>
      <listitem>
	<para>如何正确地定义包过滤规则。</para>
      </listitem>

      <listitem>
	<para>&os; 中内建的几种防火墙之间的差异。</para>
      </listitem>

      <listitem>
	<para>如何使用和配置 OpenBSD 的
	  <application>PF</application> 防火墙。</para>
      </listitem>

      <listitem>
	<para>如何使用和配置
	  <application>IPFILTER</application></para>
      </listitem>

      <listitem>
	<para>如何使用和配置
	  <application>IPFW</application></para>
      </listitem>
    </itemizedlist>

    <para>阅读这章之前, 您需要:</para>

    <itemizedlist>
      <listitem>
	<para>理解基本的 &os; 和 Internet 概念。</para>
      </listitem>
    </itemizedlist>
  </sect1>

  <sect1 xml:id="firewalls-concepts">
    <title>防火墙的概念</title>

    <indexterm>
      <primary>防火墙</primary>

      <secondary>规则集</secondary>
    </indexterm>

    <para>建立防火墙规则集的基本方法有两种:
      <quote>明示允许 (inclusive)</quote>型 或
      <quote>明示禁止 (exclusive)</quote>型。 明示禁止的防火墙规则,
      默认允许所有数据通过防火墙, 而这种规则集中定义的,
      则是不允许通过防火墙的流量, 换言之,
      与这些规则不匹配的数据, 全部是允许通过防火墙的。
      明示允许的防火墙正好相反, 它只允许符合规则集中定义规则的流量通过,
      而其他所有的流量都被阻止。</para>

    <para>明示允许型防火墙能够提供对于传出流量更好的控制,
      这使其更适合那些直接对 Internet 公网提供服务的系统的需要。
      它也能够控制来自 Internet 公网到您的私有网络的访问类型。
      所有和规则不匹配的流量都会被阻止并记录在案。
      一般来说明示允许防火墙要比明示禁止防火墙更安全,
      因为它们显著地减少了允许不希望的流量通过可能造成的风险。</para>

    <note>
      <para>除非特别说明,
	这一章的配置和示范的规则集都是创建明示允许防火墙的。</para>
    </note>

    <para>使用了 <quote>带状态功能的防火墙 (stateful
	firewall)</quote>, 可以进一步地收紧安全机制。
      这种防火墙能够记录通过防火墙的连接,
      进而只允许与现有连接匹配的连接, 或创建新的连接。
      带状态功能的防火墙的缺点是, 在很短时间内有大量的连接请求时,
      它们可能会受到拒绝服务 (<acronym>DoS</acronym>) 攻击。
      绝大多数防火墙都提供了同时启用两种防火墙的能力,
      以便为站点提供更好的保护。</para>
  </sect1>

  <sect1 xml:id="firewalls-apps">
    <title>防火墙软件包</title>

    <para>&os; 的基本系统内建了三种不同的防火墙软件包。
      它们是 <emphasis>IPFILTER</emphasis>
      (也被称作 <acronym>IPF</acronym>)、
      <emphasis>IPFIREWALL</emphasis> (也被称作 <acronym>IPFW</acronym>),
      以及 <emphasis>OpenBSD 的 PacketFilter</emphasis> (也被称为
      <acronym>PF</acronym>)。 &os; 也提供了两个内建的、
      用于流量整形 (基本上是控制带宽占用) 的软件包:
      &man.altq.4; 和 &man.dummynet.4;。 Dummynet 在过去一直和
      <acronym>IPFW</acronym> 紧密集成, 而
      <acronym>ALTQ</acronym> 则需要配合
      <acronym>PF</acronym> 使用。 IPFILTER
      的流量整形功能可以使用 IPFILTER 的 NAT
      和过滤功能以及 <acronym>IPFW</acronym> 的 &man.dummynet.4; 配合,
      <emphasis>或者</emphasis> 使用 <acronym>PF</acronym><acronym>ALTQ</acronym> 的组合。
      IPFW, 以及 PF 都是用规则来控制是否允许数据包出入您的系统,
      虽然它们采取了不同的实现方法和规则语法。</para>

    <para>&os; 包含多个内建的防火墙软件包的原因在于,
      不同的人会有不同的需求和偏好。 任何一个防火墙软件包都很难说是最好的。</para>

    <para>作者倾向于使用 IPFILTER, 因为它提供的状态式规则,
      在 <acronym>NAT</acronym> 的环境中要简单许多,
      而且它内建了 ftp 代理, 这简化了使用外部 FTP 服务时所需的配置。</para>

    <para>由于所有的防火墙都基于检查所选定的包控制字段来实现功能,
      撰写防火墙规则集时, 就必须了解
      <acronym>TCP/IP</acronym> 是如何工作的,
      以及包的控制字段在正常会话交互中的作用。
      您可以在这个网站找到一份很好的解释文档:
      <uri xlink:href="http://www.ipprimer.com/overview.cfm">http://www.ipprimer.com/overview.cfm</uri>.</para>
  </sect1>

  <sect1 xml:id="firewalls-pf">
      <info><title>OpenBSD Packet Filter (PF) 和
      <acronym>ALTQ</acronym></title>
	<authorgroup>
	  <author><personname><firstname>John</firstname><surname>Ferrell</surname></personname><contrib>Revised and updated by </contrib></author>
	</authorgroup>
      </info>

    

    <indexterm>
      <primary>防火墙</primary>

      <secondary>PF</secondary>
    </indexterm>

    <para>20037 月, OpenBSD 的防火墙,
      也就是常说的 <acronym>PF</acronym> 被成功地移植到了 &os; 上,
      并可以通过 &os; Ports Collection 来安装了;
      第一个将 <acronym>PF</acronym> 集成到基本系统中的版本是
      200411 月发行的 &os;&nbsp;5.3<acronym>PF</acronym> 是一个完整的提供了大量功能的防火墙软件,
      并提供了可选的 <acronym>ALTQ</acronym> (交错队列, Alternate
      Queuing) 功能。 <acronym>ALTQ</acronym> 提供了服务品质
      (<acronym>QoS</acronym>) 带宽整形功能。</para>

    <para>OpenBSD 项目非常杰出的维护着一份
      <link xlink:href="http://www.openbsd.org/faq/pf/">PF FAQ</link>。
      就其本身而言,这一节注重于 &os;<acronym>PF</acronym>
      和提供一些关于使用方面的一般常识。更详细的使用信息请参阅
      <link xlink:href="http://www.openbsd.org/faq/pf/">PF FAQ</link></para>

    <para>更多的详细信息, 可以在 &os; 版本的
      <acronym>PF</acronym> 网站上找到: <uri xlink:href="http://pf4freebsd.love2party.net/">http://pf4freebsd.love2party.net/</uri></para>

    <sect2>
      <title>使用 PF 可加载的内核模块</title>

        <para>要加载 PF 内核模块, 可以在
	  <filename>/etc/rc.conf</filename> 中加入下面的设置:</para>

        <programlisting>pf_enable="YES"</programlisting>

        <para>然后使用启动脚本来加载模块:</para>

        <screen>&prompt.root; <userinput>/etc/rc.d/pf start</userinput></screen>

	<para>需要说明的是, 如果系统中没有规则集配置文件,
	  则上述操作不会加载 PF 模块。 配置文件的默认位置是
	  <filename>/etc/pf.conf</filename>。 如果 PF 规则集在其他位置,
	  可以用下面的
	  <filename>/etc/rc.conf</filename> 配置来告诉 PF:</para>

        <programlisting>pf_rules="<replaceable>/path/to/pf.conf</replaceable>"</programlisting>

      <para><filename>pf.conf</filename> 的例子可以在 <filename>/usr/share/examples/pf/</filename> 找到。</para>

      <para><acronym>PF</acronym> 模块也可以手工从命令行加载:</para>

      <screen>&prompt.root; <userinput>kldload pf.ko</userinput></screen>

      <para>PF 的日志记录功能是由
        <literal>pflog.ko</literal> 提供的, 通过在
	<filename>/etc/rc.conf</filename> 中加入下面的设置:</para>

      <programlisting>pflog_enable="YES"</programlisting>

      <para>然后使用启动脚本来加载模块:</para>

      <screen>&prompt.root; <userinput>/etc/rc.d/pflog start</userinput></screen>

      <para>如果您需要其他 <acronym>PF</acronym> 特性,
	则需要将 <acronym>PF</acronym> 支持联编进内核。</para>
    </sect2>

    <sect2>
      <title>PF 内核选项</title>

      <indexterm>
	<primary>内核选项</primary>

	<secondary>device pf</secondary>
      </indexterm>

      <indexterm>
	<primary>内核选项</primary>

	<secondary>device pflog</secondary>
      </indexterm>

      <indexterm>
	<primary>内核选项</primary>

	<secondary>device pfsync</secondary>
      </indexterm>

      <para>虽然你不必亲自把对 <acronym>PF</acronym> 的支持编译进 &os;
        内核,但是有时你仍然需要这么做来使用到 PF
        的某些没有被收录进可加载模块的高级特性,比如 &man.pfsync.4;
        伪设备用来发送某些改变到<acronym>PF</acronym> 状态表。
        它能配合 &man.carp.4; 使用 PF 建立支持故障转移的防火墙。
        更多有关 <acronym>CARP</acronym> 的详细信息可以参阅本手册的
	<xref linkend="carp"/></para>

      <para>The <acronym>PF</acronym> kernel options can be found in
	<filename>/usr/src/sys/conf/NOTES</filename> and are reproduced
	below:</para>
      <para>有关 <acronym>PF</acronym> 的内核选项可以在
        <filename>/usr/src/sys/conf/NOTES</filename> 中找到,
        以下也略有阐述:</para>

      <programlisting>device pf
device pflog
device pfsync</programlisting>

      <para><literal>device pf</literal> 选项用于启用
	<quote>Packet Filter</quote> 防火墙的支持
        (&man.pf.4;)。</para>

      <para><literal>device pflog</literal> 启用可选的
	&man.pflog.4; 伪网络设备, 用以通过 &man.bpf.4;
	描述符来记录流量。 &man.pflogd.8; 服务可以用来存储信息,
	并把它们以日志形式记录到磁盘上。</para>

      <para><literal>device pfsync</literal> 选项启用可选的
        &man.pfsync.4; 支持,这是用于监视 <quote>状态变更</quote>
        的伪网络设备。</para>
    </sect2>

    <sect2>
      <title>可用的 <filename>rc.conf</filename> 选项</title>

      <para>The following &man.rc.conf.5; statements configure
	<acronym>PF</acronym> and &man.pflog.4; at boot:</para>
      <para>以下 &man.rc.conf.5; 中的语句用于启动时配置
        <acronym>PF</acronym> 和 &man.pflog.4;</para>

      <programlisting>pf_enable="YES"                 # 启用 PF (如果需要的话, 自动加载内核模块)
pf_rules="/etc/pf.conf"         # pf 使用的规则定义文件
pf_flags=""                     # 启动时传递给 pfctl 的其他选项
pflog_enable="YES"              # 启动 pflogd(8)
pflog_logfile="/var/log/pflog"  # pflogd 用于记录日志的文件名
pflog_flags=""                  # 启动时传递给 pflogd 的其他选项</programlisting>

      <para>如果您的防火墙后面有一个 LAN,
	而且需要通过它来转发 LAN 上的包, 或进行 NAT,
	还需要同时启用下述选项:</para>

      <programlisting>gateway_enable="YES"            # 启用为 LAN 网关</programlisting>
    </sect2>

    <sect2>
      <title>建立过滤规则</title>

      <para><acronym>PF</acronym> 会从 &man.pf.conf.5;
        (默认为 <filename>/etc/pf.conf</filename>)
        文件中读取配置规则, 并根据那里的规则修改、丢弃或让数据包通过。
        默认安装的 &os; 已经提供了一些简单的例子放在
        <filename>/usr/share/examples/pf/</filename> 目录下。
        请参阅 <link xlink:href="http://www.openbsd.org/faq/pf/">PF FAQ</link>
	获取完整的 <acronym>PF</acronym> 规则信息。</para>

      <warning>
	<para>在浏览 <link xlink:href="http://www.openbsd.org/faq/pf/">PF FAQ</link> 时,
          请时刻注意不同版本的 &os; 可能会使用不同版本的 PF。 目前,
	  &os;&nbsp;8.<replaceable>X</replaceable> 和之前的系统使用的是与
	  OpenBSD&nbsp;4.1 相同版本的 <acronym>PF</acronym>&os;&nbsp;9.<replaceable>X</replaceable> 和之后的系统使用的是与
          OpenBSD&nbsp;4.5 相同版本的 <acronym>PF</acronym></para>
      </warning>

      <para>&a.pf; 是一个提有关配置使用 <acronym>PF</acronym>
        防火墙问题的好地方。请在提问之前查阅邮件列表的归档!</para>
    </sect2>

    <sect2>
      <title>使用 PF</title>

      <para>使用 &man.pfctl.8; 可以控制 <acronym>PF</acronym>。
        以下是一些实用的命令
        (请查阅 &man.pfctl.8; 获得全部可用的选项):</para>

      <informaltable frame="none" pgwide="1">
	<tgroup cols="2">
	  <thead>
	    <row>
	      <entry>命令</entry>
	      <entry>作用</entry>
	    </row>
	  </thead>

	  <tbody>
	    <row>
	      <entry><command>pfctl -e</command></entry>
	      <entry>启用 PF</entry>
	    </row>

	    <row>
	      <entry><command>pfctl -d</command></entry>
	      <entry>禁用 PF</entry>
	    </row>

	    <row>
	      <entry><command>pfctl -F all -f /etc/pf.conf</command></entry>
	      <entry>清除所有规则 (nat, filter, state, table, 等等。)
		并读取 <filename>/etc/pf.conf</filename></entry>
	    </row>

	    <row>
	      <entry><command>pfctl -s [ rules | nat | state ]</command></entry>
	      <entry>列出 filter 规则, nat 规则,
		或状态表</entry>
	    </row>

	    <row>
	      <entry><command>pfctl -vnf /etc/pf.conf</command></entry>
	      <entry>检查 <filename>/etc/pf.conf</filename>
                中的错误,但不加载相关的规则</entry>
	    </row>
	  </tbody>
	</tgroup>
      </informaltable>
    </sect2>

    <sect2>
      <title>启用 <acronym>ALTQ</acronym></title>

      <para><acronym>ALTQ</acronym> 只有在作为编译选项加入到 &os;
        内核时才能使用。<acronym>ALTQ</acronym>
        目前还不是所有的可用网卡驱动都能够支持的。
	请参见 &man.altq.4; 联机手册了解您正使用的 &os;
        版本中的驱动支持情况。</para>

      <para>下面这些选项将启用 <acronym>ALTQ</acronym>
        以及一些附加的功能:</para>

      <programlisting>options         ALTQ
options         ALTQ_CBQ        # 基于分类的排列 (CBQ)
options         ALTQ_RED        # 随机先期检测 (RED)
options         ALTQ_RIO        # 对进入和发出的包进行 RED
options         ALTQ_HFSC       # 带等级的包调度器 (HFSC)
options         ALTQ_PRIQ       # 按优先级的排列 (PRIQ)
options         ALTQ_NOPCC      # 在联编 SMP 内核时必须使用,禁止读时钟</programlisting>

      <para><literal>options ALTQ</literal> 将启用
	<acronym>ALTQ</acronym> 框架的支持。</para>

      <para><literal>options ALTQ_CBQ</literal>
	用于启用 <emphasis>基于分类的队列</emphasis> (<acronym>CBQ</acronym>) 支持。 <acronym>CBQ</acronym>
	允许您将连接分成不同的类别, 或者说, 队列,
	以便在规则中为它们指定不同的优先级。</para>

      <para><literal>options ALTQ_RED</literal>
	将启用 <emphasis>随机预检测</emphasis> (<acronym>RED</acronym>)。
	<acronym>RED</acronym> 是一种用于防止网络拥塞的技术。
	<acronym>RED</acronym> 度量队列的长度,
	并将其与队列的最大和最小长度阈值进行比较。
	如果队列过长, 则新的包将被丢弃。
	如名所示, <acronym>RED</acronym> 从不同的连接中随机地丢弃数据包。</para>

      <para><literal>options ALTQ_RIO</literal> 将启用 <emphasis>出入的随机预检测</emphasis></para>

      <para><literal>options ALTQ_HFSC</literal>
	启用 <emphasis>层次式公平服务平滑包调度器</emphasis>。
	要了解关于 <acronym>HFSC</acronym> 进一步的信息, 请参见 <uri xlink:href="http://www-2.cs.cmu.edu/~hzhang/HFSC/main.html">http://www-2.cs.cmu.edu/~hzhang/HFSC/main.html</uri></para>

      <para><literal>options ALTQ_PRIQ</literal> 启用 <emphasis>优先队列</emphasis>
	(<acronym>PRIQ</acronym>)。 <acronym>PRIQ</acronym>
	首先允许高优先级队列中的包通过。</para>

      <para><literal>options ALTQ_NOPCC</literal> 启用
	<acronym>ALTQ</acronym><acronym>SMP</acronym> 支持。
	如果是 <acronym>SMP</acronym> 系统,
	则必须使用它。</para>
    </sect2>
  </sect1>

  <sect1 xml:id="firewalls-ipf">
    <title>IPFILTER (IPF) 防火墙</title>

    <indexterm>
      <primary>防火墙</primary>

      <secondary>IPFILTER</secondary>
    </indexterm>

    <para>IPFILTER 的作者是 Darren Reed。 IPFILTER 是独立于操作系统的:
      它是一个开放源代码的应用, 并且已经被移植到了 &os;、 NetBSD、
      OpenBSD、 SunOS、 HP/UX, 以及 Solaris 操作系统上。
      IPFILTER 的支持和维护都相当活跃, 并且有规律地发布更新版本。</para>

    <para>IPFILTER 提供了内核模式的防火墙和
      <acronym>NAT</acronym> 机制,
      这些机制可以通过用户模式运行的接口程序进行监视和控制。
      防火墙规则可以使用 &man.ipf.8; 工具来动态地设置和删除。
      <acronym>NAT</acronym> 规则可以通过
      &man.ipnat.1; 工具来维护。 &man.ipfstat.8; 工具则可以用来显示
      IPFILTER 内核部分的统计数据。 最后, 使用
      &man.ipmon.8; 程序可以把 IPFILTER 的动作记录到系统日志文件中。</para>

    <para>IPF 最初是使用一组
      <quote>以最后匹配的规则为准</quote> 的策略来实现的,
      这种方式只能支持无状态的规则。 随着时代的进步,
      IPF 被逐渐增强, 并加入了 <quote>quick</quote> 选项,
      以及支持状态的 <quote>keep
      state</quote> 选项, 这使得规则处理逻辑变得更富有现代气息。
      IPF 的官方文档只介绍了传统的规则编写方法和文件处理逻辑。
      新增的功能只是作为一些附加的选项出现, 如果能完全理解这些功能,
      则对于建立更安全的防火墙就很有好处。</para>

    <para>这一节中主要是针对 <quote>quick</quote> 选项,
      以及支持状态的 <quote>keep state</quote> 选项的介绍。
      这是明示允许防火墙规则集最基本的编写要素。</para>

    <para>要获得关于传统规则处理方式的详细信息,
      请参考: <uri xlink:href="http://www.obfuscation.org/ipf/ipf-howto.html#TOC_1">http://www.obfuscation.org/ipf/ipf-howto.html#TOC_1</uri>
      以及 <uri xlink:href="http://coombs.anu.edu.au/~avalon/ip-filter.html">http://coombs.anu.edu.au/~avalon/ip-filter.html</uri></para>

    <para>IPF FAQ 可以在 <uri xlink:href="http://www.phildev.net/ipf/index.html">http://www.phildev.net/ipf/index.html</uri> 找到。</para>

    <para>除此之外, 您还可以在 <uri xlink:href="http://marc.theaimsgroup.com/?l=ipfilter">http://marc.theaimsgroup.com/?l=ipfilter</uri>
      找到开放源代码的 IPFilter 的邮件列表存档, 并进行搜索。</para>

    <sect2>
      <title>启用 IPF</title>

      <indexterm>
	<primary>IPFILTER</primary>

	<secondary>启用</secondary>
      </indexterm>

      <para>IPF 作为 &os; 基本安装的一部分,
	以一个独立的内核模块的形式提供。
	如果在 <filename>rc.conf</filename> 中配置了
	<literal>ipfilter_enable="YES"</literal>,
	系统就会自动地动态加载 IPF 内核模块。
	这个内核模块在创建时启用了日志支持, 并加入了 <literal>default
	pass all</literal> 选项。 如果只是需要把默认的规则设置为
	<literal>block all</literal> 的话, 就不需要把 IPF 编译到内核中。
	简单地通过把 <literal>block all</literal>
	这条规则加入自己的规则集来达到同样的目的。</para>
    </sect2>

    <sect2>
      <title>内核选项</title>

      <indexterm>
	<primary>内核选项</primary>

	<secondary>IPFILTER</secondary>
      </indexterm>

      <indexterm>
	<primary>内核选项</primary>

	<secondary>IPFILTER_LOG</secondary>
      </indexterm>

      <indexterm>
	<primary>内核选项</primary>

	<secondary>IPFILTER_DEFAULT_BLOCK</secondary>
      </indexterm>

      <indexterm>
	<primary>IPFILTER</primary>

	<secondary>内核选项</secondary>
      </indexterm>

      <para>下面这些 &os; 内核编译选项并不是启用 IPF 所必需的。
	这里只是作为背景知识来加以阐述。 如果将 IPF
	编入了内核, 则对应的内核模块将不被使用。</para>

      <para>关于 IPF 选项语句的内核编译配置的例子, 可以在内核源代码中的
	<filename>/usr/src/sys/conf/NOTES</filename> 找到。
	此处列举如下:</para>

      <programlisting>options IPFILTER
options IPFILTER_LOG
options IPFILTER_DEFAULT_BLOCK</programlisting>

      <para><literal>options IPFILTER</literal> 用于启用
	<quote>IPFILTER</quote> 防火墙的支持。</para>

      <para><literal>options IPFILTER_LOG</literal> 用于启用 IPF 的日志支持,
	所有匹配了包含 <literal>log</literal> 的规则的包,
	都会被记录到 <filename>ipl</filename> 这个包记录伪&mdash;设备中。</para>

      <para><literal>options IPFILTER_DEFAULT_BLOCK</literal>
	将改变防火墙的默认动作, 进而, 所有不匹配防火墙的 <literal>pass</literal>
	规则的包都会被阻止。</para>

      <para>这些选项只有在您重新编译并安装了上述配置的内核之后才会生效。</para>
    </sect2>

    <sect2>
      <title>可用的 <filename>rc.conf</filename> 选项</title>

      <para>要在启动时激活 IPF, 需要在 <filename>/etc/rc.conf</filename>
	中增加下面的设置:</para>

      <programlisting>ipfilter_enable="YES"             # 启动 ipf 防火墙
ipfilter_rules="/etc/ipf.rules"   # 将被加载的规则定义, 这是一个文本文件
ipmon_enable="YES"                # 启动 IP 监视日志
ipmon_flags="-Ds"                 # D = 作为服务程序启动
                                  # s = 使用 syslog 记录
                                  # v = 记录 tcp 窗口大小、 ack 和顺序号(seq)
                                  # n = 将 IP 和端口映射为名字</programlisting>

      <para>如果在防火墙后面有使用了保留的私有 IP 地址范围的 LAN,
	还需要增加下面的一些选项来启用 <acronym>NAT</acronym> 功能:</para>

      <programlisting>gateway_enable="YES"              # 启用作为 LAN 网关的功能
ipnat_enable="YES"                # 启动 ipnat 功能
ipnat_rules="/etc/ipnat.rules"    # 用于 ipnat 的规则定义文件</programlisting>
    </sect2>

    <sect2>
      <title>IPF</title>

      <indexterm><primary><command>ipf</command></primary></indexterm>

      <para>&man.ipf.8; 命令可以用来加载您自己的规则文件。 一般情况下,
	您可以建立一个包括您自定义的规则的文件,
	并使用这个命令来替换掉正在运行的防火墙中的内部规则:</para>

      <screen>&prompt.root; <userinput>ipf -Fa -f /etc/ipf.rules</userinput></screen>

      <para><option>-Fa</option> 表示清除所有的内部规则表。</para>

      <para><option>-f</option> 用于指定将要被读取的规则定义文件。</para>

      <para>这个功能使得您能够修改自定义的规则文件, 通过运行上面的 IPF 命令,
	可以将正在运行的防火墙刷新为使用全新的规则集, 而不需要重新启动系统。
	这对于测试新的规则来说就很方便, 因为您可以任意执行上面的命令。</para>

      <para>请参考 &man.ipf.8; 联机手册以了解这个命令提供的其它选项。</para>

      <para>&man.ipf.8; 命令假定规则文件是一个标准的文本文件。
	它不能处理使用符号代换的脚本。</para>

      <para>也确实有办法利用脚本的非常强大的符号替换能力来构建 IPF 规则。
	要了解进一步的细节, 请参考
	<xref linkend="firewalls-ipf-rules-script"/></para>
     </sect2>

    <sect2>
      <title>IPFSTAT</title>

      <indexterm><primary><command>ipfstat</command></primary></indexterm>

      <indexterm>
	<primary>IPFILTER</primary>

	<secondary>统计</secondary>
      </indexterm>

      <para>默认情况下, &man.ipfstat.8; 会获取并显示所有的累积统计,
	这些统计是防火墙启动以来用户定义的规则匹配的出入流量,
	您可以通过使用
	<command>ipf -Z</command> 命令来将这些计数器清零。</para>

      <para>请参见 &man.ipfstat.8; 联机手册以了解进一步的细节。</para>

      <para>默认的 &man.ipfstat.8; 命令输出类似于下面的样子:</para>

      <screen>input packets: blocked 99286 passed 1255609 nomatch 14686 counted 0
 output packets: blocked 4200 passed 1284345 nomatch 14687 counted 0
 input packets logged: blocked 99286 passed 0
 output packets logged: blocked 0 passed 0
 packets logged: input 0 output 0
 log failures: input 3898 output 0
 fragment state(in): kept 0 lost 0
 fragment state(out): kept 0 lost 0
 packet state(in): kept 169364 lost 0
 packet state(out): kept 431395 lost 0
 ICMP replies: 0 <acronym>TCP</acronym> RSTs sent: 0
 Result cache hits(in): 1215208 (out): 1098963
 IN Pullups succeeded: 2 failed: 0
 OUT Pullups succeeded: 0 failed: 0
 Fastroute successes: 0 failures: 0
 <acronym>TCP</acronym> cksum fails(in): 0 (out): 0
 Packet log flags set: (0)</screen>

      <para>如果使用了 <option>-i</option> (进入流量)
	或者 <option>-o</option> (输出流量),
	这个命令就只获取并显示内核中所安装的对应过滤器规则的统计数据。</para>

      <para><command>ipfstat -in</command> 以规则号的形式显示进入的内部规则表。</para>

      <para><command>ipfstat -on</command> 以规则号的形式显示流出的内部规则表。</para>

      <para>输出和下面的类似:</para>

      <screen>@1 pass out on xl0 from any to any
@2 block out on dc0 from any to any
@3 pass out quick on dc0 proto tcp/udp from any to any keep state</screen>

      <para><command>ipfstat -ih</command> 显示内部规则表中的进入流量,
	每一个匹配规则前面会同时显示匹配的次数。</para>

      <para><command>ipfstat -oh</command> 显示内部规则表中的流出流量,
	每一个匹配规则前面会同时显示匹配的次数。</para>

      <para>输出和下面的类似:</para>

      <screen>2451423 pass out on xl0 from any to any
354727 block out on dc0 from any to any
430918 pass out quick on dc0 proto tcp/udp from any to any keep state</screen>

      <para><command>ipfstat</command> 命令的一个重要的功能可以通过指定
	<option>-t</option> 参数来使用, 它会以类似 &man.top.1;
	的显示 &os; 正运行的进程表的方式来显示统计数据。
	当您的防火墙正在受到攻击的时候, 这个功能让您得以识别、
	试验, 并查看攻击的数据包。 这个选项提还提供了实时选择希望监视的目的或源 IP、
	端口或协议的能力。 请参见 &man.ipfstat.8; 联机手册以了解详细信息。</para>
    </sect2>

    <sect2>
      <title>IPMON</title>

      <indexterm><primary><command>ipmon</command></primary></indexterm>

      <indexterm>
	<primary>IPFILTER</primary>

	<secondary>记录日志</secondary>
      </indexterm>

      <para>为了使 <command>ipmon</command> 能够正确工作,
	必须打开 <literal>IPFILTER_LOG</literal> 这个内核选项。
	这个命令提供了两种不同的使用模式。
	内建模式是默认的模式, 如果您不指定
	<option>-D</option> 参数, 就会采用这种模式。</para>

      <para>服务模式是持续地通过系统日志来记录的工作模式, 这样,
	您就可以通过查看日志来了解过去曾经发生过的事情。
	这种模式是 &os; 和 IPFILTER 配合工作的模式。
	由于在 &os; 中提供了一个内建的系统日志自动轮转功能,
	因此, 使用 &man.syslogd.8; 比默认的将日志信息记录到一个普通文件要好。
	在默认的 <filename>rc.conf</filename> 文件中,
	<literal>ipmon_flags</literal> 语句会指定 <option>-Ds</option> 标志:</para>

      <programlisting>ipmon_flags="-Ds"                 # D = 作为服务程序启动
                  # s = 使用 syslog 记录
                  # v = 记录 tcp 窗口大小、 ack 和顺序号(seq)
                  # n = 将 IP 和端口映射为名字</programlisting>

      <para>记录日志的好处是很明显的。 它提供了在事后重新审查相关信息,
	例如哪些包被丢弃, 以及这些包的来源地址等等。
	这将为查找攻击者提供非常有用的第一手资料。</para>

      <para>即使启用了日志机制, IPF 仍然不会对其规则进行任何日志记录工作。
	防火墙管理员可以决定规则集中的哪些应记录日志,
	并在这些规则上加入 log 关键字。 一般来说, 只应记录拒绝性的规则。</para>

      <para>作为惯例, 通常会有一条默认的、拒绝所有网络流量的规则,
	并指定 log 关键字, 作为您的规则集的最后一条。
	这样就能够看到所有没有匹配任何规则的数据包了。</para>
    </sect2>

    <sect2>
      <title>IPMON 的日志</title>

      <para><application>Syslogd</application> 使用特殊的方法对日志数据进行分类。
	它使用称为 <quote>facility</quote><quote>level</quote> 的组。
	以 <option>-Ds</option> 模式运行的 IPMON 采用 <literal>local0</literal>
	作为默认的 <quote>facility</quote>
	名。 如果需要, 可以用下列 levels
	来进一步区分数据:</para>

      <screen>LOG_INFO - 使用 "log" 关键字指定的通过或阻止动作
LOG_NOTICE - 同时记录通过的那些数据包
LOG_WARNING - 同时记录阻止的数据包
LOG_ERR - 进一步记录含不完整的包头的数据包</screen>

      <!-- XXX: "can be considered short" == "with incomplete header" -->

      <para>要设置 IPFILTER 来将所有的数据记录到
	<filename>/var/log/ipfilter.log</filename>, 需要首先建立这个文件。
	下面的命令可以完成这个工作:</para>

       <screen>&prompt.root; <userinput>touch /var/log/ipfilter.log</userinput></screen>

      <para>&man.syslogd.8; 功能可以通过在 <filename>/etc/syslog.conf</filename> 文件中的语句来定义。
	<filename>syslog.conf</filename> 提供了相当多的用以控制 syslog
	如何处理类似 IPF 这样的用用程序所产生的系统消息的方法。</para>

      <para>您需要将下列语句加到
	<filename>/etc/syslog.conf</filename></para>

      <programlisting>local0.* /var/log/ipfilter.log</programlisting>

      <para>这里的 <literal>local0.*</literal>
	表示把所有的相关日志信息写到指定的文件中。</para>

      <para>要让 <filename>/etc/syslog.conf
	</filename> 中的修改立即生效, 可以重新启动计算机, 或者通过执行
	<command>/etc/rc.d/syslogd reload</command>
	来让它重新读取 <filename>/etc/syslog.conf</filename></para>

      <para>不要忘了修改 <filename>/etc/newsyslog.conf
	</filename> 来让刚创建的日志进行轮转。</para>
    </sect2>

     <sect2>
       <title>记录消息的格式</title>

       <para><command>ipmon</command> 生成的消息由空格分隔的数据字段组成。
         所有的消息都包含的字段是:</para>

      <orderedlist>
	<listitem>
	  <para>接到数据包的日期。</para>
	</listitem>

	<listitem>
	  <para>接到数据包的时间。 其格式为
	    HH:MM:SS.F, 分别是小时、 分钟、 秒,
	    以及分秒 (这个数字可能有许多位)。</para>
	</listitem>

	<listitem>
	  <para>处理数据包的网络接口名字,
	    例如 <filename>dc0</filename></para>
	</listitem>

	<listitem>
	  <para>组和规则的编号, 例如 <literal>@0:17</literal></para>
	</listitem>
      </orderedlist>

      <para>可以通过 <command>ipfstat -in</command> 来查看这些信息。</para>

      <orderedlist>
	<listitem>
	  <para>动作: p 表示通过, b 表示阻止, S 表示包头不全,
	    n 表示没有匹配任何规则, L 表示 log 规则。
	    显示这些标志的顺序是: S, p, b, n, L。
	    大写的 P 或 B 表示记录包的原因是某个全局的日志配置,
	    而不是某个特定的规则。</para>
	</listitem>

	<listitem>
	  <para>地址。 这实际上包括三部分:
	    源地址和端口 (以逗号分开), 一个 -&gt;
	    符号, 以及目的地址和端口, 例如:
	    <literal>209.53.17.22,80 -&gt; 198.73.220.17,1722</literal></para>
	</listitem>

	<listitem>
	  <para><literal>PR</literal>, 后跟协议名称或编号,
	    例如: <literal>PR tcp</literal></para>
	</listitem>

	<listitem>
	  <para><literal>len</literal>, 后跟包头的长度, 以及包的总长度,
	    例如: <literal>len 20 40</literal></para>
	</listitem>
      </orderedlist>

      <para>对于 <acronym>TCP</acronym> 包, 则还会包括一个附加的字段,
	由一个连字号开始, 之后是表示所设置的标志的一个字母。
	请参见 &man.ipf.5; 联机手册, 以了解这些字母所对应的标志。</para>

      <para>对于 ICMP 包, 则在最后会有两个字段。
	前一个总是 <quote>ICMP</quote>, 而后一个则是 ICMP
	消息和子消息的类型, 中间以斜线分靠, 例如 ICMP 3/3
	表示端口不可达消息。</para>
    </sect2>

    <sect2 xml:id="firewalls-ipf-rules-script">
      <title>构建采用符号替换的规则脚本</title>

      <para>一些有经验的 IPF 会创建包含规则的文件,
	并把它编写成能够与符号替换脚本兼容的方式。
	这样做最大的好处是能够在修改时只修改符号名字所代表的值,
	而在脚本执行时直接替换掉所有的名符。
	作为脚本, 可以使用符号替换来把那些经常使用的值直接用于多个规则。
	下面将给出一个例子。</para>

      <para>这个脚本所使用的语法与 &man.sh.1;、 &man.csh.1;,
	以及 &man.tcsh.1; 脚本。</para>

      <para>符号替换的前缀字段是美元符号: <literal>&dollar;</literal></para>

      <para>符号字段不使用 &dollar; 前缀。</para>

      <para>希望替换符号字段的值,
	必须使用双引号 (<literal>"</literal>) 括起来。</para>

       <para>您的规则文件的开头类似这样:</para>

      <programlisting>############# IPF 规则脚本的开头 ########################
oif="dc0"            # 外网接口的名字
odns="192.0.2.11"    # ISP 的 DNS 服务器 IP 地址
myip="192.0.2.7"     # 来自 ISP 的静态 IP 地址
ks="keep state"
fks="flags S keep state"

# 可以使用这个脚本来建立 /etc/ipf.rules 文件,
# 也可以 "直接地" 运行它。
#
# 请删除两个注释号之一。
#
# 1) 保留下面一行, 则创建 /etc/ipf.rules:
#cat &gt; /etc/ipf.rules &lt;&lt; EOF
#
# 2) 保留下面一行, 则 "直接地" 运行脚本:
/sbin/ipf -Fa -f - &lt;&lt; EOF

# 允许发出到我的 ISP 的域名服务器的访问
pass out quick on &dollar;oif proto tcp from any to &dollar;odns port = 53 &dollar;fks
pass out quick on &dollar;oif proto udp from any to &dollar;odns port = 53 &dollar;ks

# 允许发出未加密的 www 访问请求
pass out quick on &dollar;oif proto tcp from &dollar;myip to any port = 80 &dollar;fks

# 允许发出使用 TLS SSL 加密的 https www 访问请求
pass out quick on &dollar;oif proto tcp from &dollar;myip to any port = 443 &dollar;fks
EOF
################## IPF 规则脚本的结束 ########################</programlisting>

      <para>这就是所需的全部内容。 这个规则本身并不重要,
	它们主要是用于体现如何使用符号代换字段,
	以及如何完成值的替换。
	如果上面的例子的名字是 <filename>/etc/ipf.rules.script</filename>,
	就可以通过输入下面的命令来重新加载规则:</para>

      <screen>&prompt.root; <userinput>sh /etc/ipf.rules.script</userinput></screen>

      <para>在规则文件中嵌入符号有一个问题: IPF 无法识别符号替换,
	因此它不能直接地读取这样的脚本。</para>

      <para>这个脚本可以使用下面两种方法之一来使用:</para>

      <itemizedlist>
	<listitem>
	  <para>去掉 <literal>cat</literal> 之前的注释,
	    并注释掉
	    <literal>/sbin/ipf</literal> 开头的那一行。 像其他配置一样, 将
	    <literal>ipfilter_enable="YES"</literal> 放到
	    <filename>/etc/rc.conf</filename> 文件中,
	    并在此后立刻执行脚本, 以创建或更新
	    <filename>/etc/ipf.rules</filename>。</para>
	</listitem>

	<listitem>
	  <para>通过把 <literal>ipfilter_enable="NO"</literal>
	    (这是默认值) 加到
	    <filename>/etc/rc.conf</filename> 中,
	    来禁止系统启动脚本开启 IPFILTER。</para>

	  <para>在
	    <filename>/usr/local/etc/rc.d/</filename>
	    启动目录中增加一个类似下面的脚本。
	    应该给它起一个显而易见的名字, 例如
	    <filename>ipf.loadrules.sh</filename>。
	    请注意, <filename>.sh</filename>
	    扩展名是必需的。</para>

	  <programlisting>#!/bin/sh
sh /etc/ipf.rules.script</programlisting>

	  <para>脚本文件必须设置为属于 <systemitem class="username">root</systemitem>,
	    并且属主可读、 可写、 可执行。</para>

	  <screen>&prompt.root; <userinput>chmod 700 /usr/local/etc/rc.d/ipf.loadrules.sh</userinput></screen>
	</listitem>
      </itemizedlist>

      <para>这样, 在系统启动时, 就会自动加载您的 IPF
	规则了。</para>
    </sect2>

    <sect2>
      <title>IPF 规则集</title>

      <para>规则集是指一组编写好的依据包的值决策允许通过或阻止 IPF 规则。
	包的双向交换组成了一个会话交互。 防火墙规则集会作用于来自于
	Internet 公网的包以及由系统发出来回应这些包的数据包。
	每一个 <acronym>TCP/IP</acronym> 服务 (例如 telnet, www,
	邮件等等) 都由协议预先定义了其特权 (监听) 端口。
	发到特定服务的包会从源地址使用非特权 (高编号) 端口发出,
	并发到特定服务在目的地址的对应端口。
	所有这些参数 (例如: 端口和地址)
	都是可以为防火墙规则所利用的, 判别是否允许服务通过的标准。</para>

      <indexterm>
	<primary>IPFILTER</primary>

	<secondary>规则处理顺序</secondary>
       </indexterm>

      <para>IPF 最初被写成使用一组称作
	<quote>以最后匹配的规则为准</quote> 的处理逻辑, 且只能处理无状态的规则。
	随着时代的发展, IPF 进行了改进, 并提供了 <quote>quick</quote>
	选项, 以及一个有状态的 <quote>keep state</quote> 选项。
	后者使处理逻辑迅速地跟上了时代的步伐。</para>

      <para>这一节中提供的一些指导,
	是基于使用包含 <quote>quick</quote> 选项和有状态的
	<quote>keep state</quote> 选项来进行阐述的。
	这些是编写明示允许防火墙规则集的基本要素。</para>

      <warning>
	<para>当对防火墙规则进行操作时, 应
	    <emphasis>谨慎行事</emphasis>。 某些配置可能会
	    <emphasis>将您反锁在</emphasis> 服务器外面。
	  保险起见, 您可以考虑在第一次进行防火墙配置时在本地控制台上,
	  而不是远程, 如通过
	  <application>ssh</application> 来进行。</para>
      </warning>
    </sect2>

    <sect2>
      <title>规则语法</title>

      <indexterm>
	<primary>IPFILTER</primary>

	<secondary>规则语法</secondary>
      </indexterm>

      <para>这里给出的规则语法已经简化到只处理那些新式的带状态规则,
	并且都是 <quote>第一个匹配的规则获胜</quote> 逻辑的。
	要了解完整的传统规则语法描述, 请参见 &man.ipf.8; 联机手册。</para>

      <para>以 <literal>#</literal> 字符开头的内容会被认为是注释。
	这些注释可以出现在一行规则的末尾, 或者独占一行。 空行会被忽略。</para>

      <para>规则由关键字组成。 这些关键字必须以一定的顺序,
	从左到右出现在一行上。 接下来的文字中关键字将使用粗体表示。
	某些关键字可能提供了子选项, 这些子选项本身可能也是关键字,
	而且可能会提供更多的子选项。 下面的文字中,
	每种语法都使用粗体的小节标题呈现, 并介绍了其上下文。</para>

      <!-- This section is probably wrong. See the OpenBSD flag -->
      <!-- What is the "OpenBSD flag"?  Reference please -->

      <para><replaceable>ACTION IN-OUT OPTIONS SELECTION STATEFUL PROTO
	SRC_ADDR,DST_ADDR OBJECT PORT_NUM TCP_FLAG
	STATEFUL</replaceable></para>

      <para><replaceable>ACTION</replaceable> = block | pass</para>

      <para><replaceable>IN-OUT</replaceable> = in | out</para>

      <para><replaceable>OPTIONS</replaceable> = log | quick | on
	网络接口的名字</para>

      <para><replaceable>SELECTION</replaceable> = proto 协议名称 |
	源/目的 IP | port = 端口号 | flags 标志值</para>

      <para><replaceable>PROTO</replaceable> = tcp/udp | udp | tcp |
	icmp</para>

      <para><replaceable>SRC_ADD,DST_ADDR</replaceable> = all | from
	对象 to 对象</para>

      <para><replaceable>OBJECT</replaceable> = IP地址 | any</para>

      <para><replaceable>PORT_NUM</replaceable> = port 端口号</para>

      <para><replaceable>TCP_FLAG</replaceable> = S</para>

      <para><replaceable>STATEFUL</replaceable> = keep state</para>

      <sect3>
	<title>ACTION (动作)</title>

	<para>动作对表示匹配规则的包应采取什么动作。
	  每一个规则 <emphasis>必须</emphasis> 包含一个动作。
	  可以使用下面两种动作之一:</para>

	<para><literal>block</literal> 表示如果规则与包匹配,
	  则丢弃包。</para>

	<para><literal>pass</literal> 表示如果规则与包匹配,
	  则允许包通过防火墙。</para>
      </sect3>

      <sect3>
	<title>IN-OUT</title>
	<para>每个过滤器规则都必须明确地指定是流入还是流出的规则。
	  下一个关键字必须要么是 <literal>in</literal>,
	  要么是 <literal>out</literal>,
	  否则将无法通过语法检查。</para>

	<para><literal>in</literal> 表示规则应被应用于刚刚从 Internet
	  公网上收到的数据包。</para>

	<para><literal>out</literal> 表示规则应被应用于即将发出到
	  Internet 的数据包。</para>
      </sect3>

      <sect3>
	<title>OPTIONS</title>
	<note>
	  <para>这些选项必须按下面指定的顺序出现。</para>
	</note>

	<para><literal>log</literal> 表示包头应被写入到

	<!-- XXX - xref here -->

	  <filename>ipl</filename> 日志 (如前面 LOGGING 小节所介绍的那样),
	  如果它与规则匹配的话。</para>

	<para><literal>quick</literal> 表示如果给出的参数与包匹配,
	  则以这个规则为准, 这使得能够 "短路" 掉后面的规则。
	  这个选项对于使用新式的处理逻辑是必需的。</para>

	<para><literal>on</literal> 表示将网络接口的名称作为筛选参数的一部分。
	  接口的名字会在 &man.ifconfig.8; 的输出中显示。 使用这个选项,
	  则规则只会应用到某一个网络接口上的出入数据包上。
	  要配置新式的处理逻辑, 必须使用这个选项。</para>

	<para>当记录包时, 包的头会被写入到 <acronym>IPL</acronym> 包日志伪设备中。
	  紧跟 <literal>log</literal> 关键字, 可以使用下面几个修饰符
	  (按照下列顺序):</para>

	<para><literal>body</literal> 表示应同时记录包的前 128 字节的内容。</para>

	<para><literal>first</literal> 如果 <literal>log</literal> 关键字和
	  <literal>keep state</literal> 选项同时使用,
	  则这个选项只在第一个包上触发, 这样就不用记录每一个
	  <quote>keep state</quote> 包信息了。</para>
      </sect3>

      <sect3>
	<title>SELECTION</title>

	<para>这一节所介绍的关键字可以用于所检察的包的属性。
	  有一个关键字主题, 以及一组子选项关键字,
	  您必须从他们中选择一个。 以下是一些通用的属性,
	  它们必须按下面的顺序使用:</para>
      </sect3>

      <sect3>
	<title>PROTO</title>
	<para><literal>proto</literal> 是一个主题关键字,
	  它必须与某个相关的子选项关键字配合使用。
	  这个值的作用是匹配某个特定的协议。
	  要使用新式的规则处理逻辑, 就必须使用这个选项。</para>

	<para><literal>tcp/udp | udp | tcp | icmp</literal> 或其他在
	  <filename>/etc/protocols</filename> 中定义的协议。
	  特殊的协议关键字 <literal>tcp/udp</literal> 可以用于匹配
	  <acronym>TCP</acronym> 或 <acronym>UDP</acronym> 包,
	  引入这个关键字的作用是是避免大量的重复规则的麻烦。</para>
      </sect3>

      <sect3>
	<title>SRC_ADDR/DST_ADDR</title>
	<para>使用 <literal>all</literal> 关键词, 基本上相当于 <quote>from
	  any to any</quote> 在没有配合其他关键字的情形。</para>

	<para><literal>from src to dst</literal>: <literal>from</literal> 和 <literal>to</literal>
	  关键字主要是用来匹配 IP 地址。 所有的规则都必须
	  <emphasis>同时</emphasis> 给出源和目的两个参数。
	  <literal>any</literal> 是一个可以用于匹配任意 IP 地址的特殊关键字。
	  例如, 您可以使用 <literal>from any to any</literal> 或 <literal>from
	  0.0.0.0/0 to any</literal> 或 <literal>from any to 0.0.0.0/0</literal> 或 <literal>from
	  0.0.0.0 to any</literal> 以及 <literal>from any to 0.0.0.0</literal>。</para>

	<para>如果无法使用子网掩码来表示 IP 的话, 表达地址就会很麻烦。
	  使用 <package>net-mgmt/ipcalc</package> port 可以帮助进行计算。
	  请参见下面的网页了解如何撰写长度掩码:
	  <uri xlink:href="http://jodies.de/ipcalc">http://jodies.de/ipcalc</uri>。</para>
      </sect3>

      <sect3>
	<title>PORT</title>

	<para>如果为源或目的指定了匹配端口, 规则就只能应用于
	  <acronym>TCP</acronym> 和 <acronym>UDP</acronym> 包了。
	  当编写端口比较规则时, 可以指定
	  <filename>/etc/services</filename> 中所定义的名字,
	  也可以直接用端口号来指定。 如果端口号出现在源对象一侧,
	  则被认为是源端口号; 反之, 则被认为是目的端口号。
	  要使用新式的规则处理逻辑,
	  就必须与 <literal>to</literal> 对象配合使用这个选项。 使用的例子:
	  <literal>from any to any port = 80</literal></para>

	<!-- XXX: Rewritten, but probably needs more changes -->

	<para>对单个端口的比较可以多种方式进行, 并可使用不同的比较算符。
	  此外, 还可以指定端口的范围。</para>

	<para>port "=" | "!=" | "&lt;" | "&gt;" | "&lt;=" | "&gt;=" |
	  "eq" | "ne" | "lt" | "gt" | "le" | "ge".</para>

	<para>要指定端口范围, 可以使用 "&lt;&gt;" | "&gt;&lt;"。</para>

	<warning>
	  <para>在源和目的匹配参数之后, 需要使用下面两个参数,
	    才能够使用新式的规则处理逻辑。</para>
	</warning>
      </sect3>

      <sect3>
	<title><acronym>TCP</acronym>_FLAG</title>

	<para>标志只对 <acronym>TCP</acronym> 过滤有用。
	  这些字母用来表达 <acronym>TCP</acronym> 包头的标志。</para>

	<para>新式的规则处理逻辑使用
	  <literal>flags S</literal> 参数来识别 tcp
	  会话开始的请求。</para>
      </sect3>

      <sect3>
	<title>STATEFUL</title>
	<para><literal>keep state</literal> 表示如果有一个包与规则匹配,
	  则其筛选参数应激活有状态的过滤机制。</para>

	<note>
	  <para>如果使用新式的处理逻辑, 则这个选项是必需的。</para>
	</note>
      </sect3>
    </sect2>


    <sect2>
      <title>有状态过滤</title>

      <indexterm>
	<primary>IPFILTER</primary>

	<secondary>有状态过滤</secondary>
      </indexterm>

      <!-- XXX: duplicated -->

      <para>有状态过滤将网络流量当作一种双向的包交换来处理。
	如果激活它, keep-state 会动态地为每一个相关的包在双向会话交互过程中产生内部规则。
	它能够确认发起者和包的目的地之间的会话是有效的双向包交换过程的一部分。
	如果包与这些规则不符, 则将自动地拒绝。</para>

      <para>状态保持也使得 ICMP 包能够与 <acronym>TCP</acronym>
	或 UDP 会话相关。 因此, 如果您在浏览网站时收到允许的状态保持规则匹配的
	ICMP 类型 3 代码 4 响应, 则这些响应会被自动地允许进入。
	所有 IPF 能够处理的包, 都可以作为某种活跃会话的一部分,
	即使它是另一种协议的, 也会被允许进入。</para>

      <para>所发生的事情是:</para>

      <para>将要通过连入 Internet 公网的网络接口发出的包,
	首先会经过动态状态表的检查。 如果包与会话中预期的下一个包匹配,
	防火墙就会允许包通过, 并更新状态表中的会话的交互流信息。
	不属于活跃会话的包, 则简单地交给输出规则集去检查。</para>

      <para>发到连入 Internet 公网接口的包, 也会先经过动态状态表的检查。
	如果包与会话中预期的下一个包匹配,
	防火墙就会允许包通过, 并更新状态表中的会话的交互流信息。
	不属于活跃会话的包, 则简单地交给输入规则集去检查。</para>

      <para>当会话结束时, 对应的项会在动态状态表中删除。</para>

      <para>有状态过滤使得您能够集中于阻止/允许新的会话。
	一旦新会话被允许通过, 则所有后续的包就都被自动地允许通过,
	而伪造的包则被自动地拒绝。 如果新的会话被阻止,
	则后续的包也都不会被允许通过。 有状态过滤从技术角度而言,
	在阻止目前攻击者常用的洪水式攻击来说, 具有更好的抗御能力。</para>
    </sect2>

    <sect2>
      <!-- XXX: This section needs a rewrite -->

      <title>明示允许规则集的例子</title>

      <para>下面的规则集是如何编写非常安全的明示允许防火墙规则集的一个范例。
	明示允许防火墙只让允许的服务 <literal>pass</literal> (通过),
	而所有其他的访问都会被默认地拒绝。 期望用来保护其他机器的防火墙,
	通常也叫做 <quote>网络防火墙</quote>, 应使用至少两个网络接口,
	并且通常只有一个接入到受信的一端 (<acronym>LAN</acronym>),
	而另一块则接入不受信的一端 (Internet 公网)。 另外,
	防火墙也可以配置为只保护它所运行的那个系统 &mdash; 这种类型称作
	<quote>主机防火墙</quote>, 通常在接入不受信网络的服务器上使用。</para>

      <para>包括 &os; 在内的所有类 &unix; 系统通常都会使用
	<filename>lo0</filename> 和 IP 地址
	<systemitem class="ipaddress">127.0.0.1</systemitem> 用于操作系统中内部的通讯。
	防火墙规则必须允许这些包无阻碍地通过。</para>

      <para>接入 Internet 公网的网络接口, 是放置规则并允许将访问请求发到
	Internet 以及接收响应的地方。 这有可能是用户模式的 PPP
	<filename>tun0</filename> 接口,
	如果您的网卡同 DSL 或电缆调制解调器相联的话。</para>

      <para>如果有网卡是直接接入私有网段的,
	这些网络接口就可能需要配置允许来自这些 LAN 的包在彼此之间,
	以及到外界 (Internet) 上的对应的通过规则。</para>

      <para>一般说来, 规则应被组织为三个主要的小节:
	所有允许自由通过的接口规则, 发到公网接口的规则,
	以及进入公网接口的规则。</para>

      <para>每一个公网接口规则中, 经常会匹配到的规则应该放置在尽可能靠前的位置。
	而最后一个规则应该是阻止包通过, 并记录它们。</para>

      <para>下面防火墙规则集中, Outbound 部分是一些使用
	<literal>pass</literal> 的规则, 这些规则指定了允许访问的公网
	Internet 服务, 并且指定了 <literal>quick</literal>、 <literal>on</literal>、
	<literal>proto</literal>、 <literal>port</literal>, 以及 <literal>keep state</literal> 这些选项。 <literal>proto
	tcp</literal> 规则还指定了 <literal>flag</literal> 这个选项, 这样会话的第一个包将出发状态机制。</para>

      <para>接收部分则首先阻止所有不希望的包, 这样做有两个不同的原因。
	其一是恶意的包可能和某些允许的流量规则存在部分匹配, 而我们希望阻止,
	而不是让这些包仅仅与 <literal>allow</literal> 规则部分匹配就允许它们进入。
	其二是, 已经确信要阻止的包被拒绝这件事, 往往并不是我们需要关注的,
	因此只要简单地予以阻止即可。
	防火墙规则集中的每个部分的最后一条规则都是阻止并记录包,
	这有助于为逮捕攻击者留下法律所要求的证据。</para>

      <para>另外一个需要注意的事情是确保系统对不希望的数据包不做回应。
	无效的包应被丢弃和消失。 这样, 攻击者便无法知道包是否到达了您的系统。
	攻击者对系统了解的越少, 攻陷系统所需的时间也就越多。
	包含 <literal>log first</literal> 选项的规则只会记录它们第一次被触发时的包,
	在例子中这个选项被用于记录 <literal>nmap OS 指纹探测</literal> 规则。
	<package>security/nmap</package>
	是攻击者常用的一种用于探测目标系统所用操作系统的工具。</para>

      <para>如果您看到了 <literal>log first</literal> 规则的日志,
	就应该用 <command>ipfstat -hio</command> 命令来看看那个规则被匹配的次数。
	如果数目较大, 则表示系统正在受到洪水式攻击。</para>

      <para>如果记录的包的端口号并不是您所知道的,
	可以在 <filename>/etc/services</filename> 或 <uri xlink:href="http://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers">http://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers</uri>
	了解端口号通常的用途。</para>

      <para>参考下面的网页, 了解木马使用的端口: <uri xlink:href="http://www.sans.org/security-resources/idfaq/oddports.php">http://www.sans.org/security-resources/idfaq/oddports.php</uri>。</para>

      <para>下面是我在自己的系统中使用的完整的, 非常安全的
	<literal>明示允许</literal> 防火墙规则集。 直接使用这个规则集不会给您造成问题,
	您所要做的只是注释掉那些您不需要 <literal>pass</literal>(允许通过) 的服务。</para>

      <para>如果在日志中发现了希望 <literal>阻止</literal> 的记录, 只需在
	inbound 小节中增加一条阻止规则集可。</para>

      <para>您必须将每一个规则中的 <filename>dc0</filename>
	替换为您系统上接入 Internet 的网络接口名称, 例如,
	用户环境下的 PPP 应该是 <filename>tun0</filename>。</para>

      <para>在
	<filename>/etc/ipf.rules</filename> 中加入下面的内容:</para>

      <programlisting>#################################################################
# No restrictions on Inside LAN Interface for private network
# Not needed unless you have LAN
#################################################################

#pass out quick on xl0 all
#pass in quick on xl0 all

#################################################################
# No restrictions on Loopback Interface
#################################################################
pass in quick on lo0 all
pass out quick on lo0 all

#################################################################
# Interface facing Public Internet (Outbound Section)
# Match session start requests originating from behind the
# firewall on the private network
# or from this gateway server destined for the public Internet.
#################################################################

# Allow out access to my ISP's Domain name server.
# xxx must be the IP address of your ISP's DNS.
# Dup these lines if your ISP has more than one DNS server
# Get the IP addresses from /etc/resolv.conf file
pass out quick on dc0 proto tcp from any to xxx port = 53 flags S keep state
pass out quick on dc0 proto udp from any to xxx port = 53 keep state

# Allow out access to my ISP's DHCP server for cable or DSL networks.
# This rule is not needed for 'user ppp' type connection to the
# public Internet, so you can delete this whole group.
# Use the following rule and check log for IP address.
# Then put IP address in commented out rule &amp; delete first rule
pass out log quick on dc0 proto udp from any to any port = 67 keep state
#pass out quick on dc0 proto udp from any to z.z.z.z port = 67 keep state


# Allow out non-secure standard www function
pass out quick on dc0 proto tcp from any to any port = 80 flags S keep state

# Allow out secure www function https over TLS SSL
pass out quick on dc0 proto tcp from any to any port = 443 flags S keep state

# Allow out send &amp; get email function
pass out quick on dc0 proto tcp from any to any port = 110 flags S keep state
pass out quick on dc0 proto tcp from any to any port = 25 flags S keep state

# Allow out Time
pass out quick on dc0 proto tcp from any to any port = 37 flags S keep state

# Allow out nntp news
pass out quick on dc0 proto tcp from any to any port = 119 flags S keep state

# Allow out gateway &amp; LAN users' non-secure FTP ( both passive &amp; active modes)
# This function uses the IP<acronym>NAT</acronym> built in FTP proxy function coded in
# the nat rules file to make this single rule function correctly.
# If you want to use the pkg_add command to install application packages
# on your gateway system you need this rule.
pass out quick on dc0 proto tcp from any to any port = 21 flags S keep state

# Allow out ssh/sftp/scp (telnet/rlogin/FTP replacements)
# This function is using SSH (secure shell)
pass out quick on dc0 proto tcp from any to any port = 22 flags S keep state

# Allow out insecure Telnet
pass out quick on dc0 proto tcp from any to any port = 23 flags S keep state

# Allow out FreeBSD CVSup
pass out quick on dc0 proto tcp from any to any port = 5999 flags S keep state

# Allow out ping to public Internet
pass out quick on dc0 proto icmp from any to any icmp-type 8 keep state

# Allow out whois from LAN to public Internet
pass out quick on dc0 proto tcp from any to any port = 43 flags S keep state

# Block and log only the first occurrence of everything
# else that's trying to get out.
# This rule implements the default block
block out log first quick on dc0 all

#################################################################
# Interface facing Public Internet (Inbound Section)
# Match packets originating from the public Internet
# destined for this gateway server or the private network.
#################################################################

# Block all inbound traffic from non-routable or reserved address spaces
block in quick on dc0 from 192.168.0.0/16 to any    #RFC 1918 private IP
block in quick on dc0 from 172.16.0.0/12 to any     #RFC 1918 private IP
block in quick on dc0 from 10.0.0.0/8 to any        #RFC 1918 private IP
block in quick on dc0 from 127.0.0.0/8 to any       #loopback
block in quick on dc0 from 0.0.0.0/8 to any         #loopback
block in quick on dc0 from 169.254.0.0/16 to any    #DHCP auto-config
block in quick on dc0 from 192.0.2.0/24 to any      #reserved for docs
block in quick on dc0 from 204.152.64.0/23 to any   #Sun cluster interconnect
block in quick on dc0 from 224.0.0.0/3 to any       #Class D &amp; E multicast

##### Block a bunch of different nasty things. ############
# That I do not want to see in the log

# Block frags
block in quick on dc0 all with frags

# Block short tcp packets
block in quick on dc0 proto tcp all with short

# block source routed packets
block in quick on dc0 all with opt lsrr
block in quick on dc0 all with opt ssrr

# Block nmap OS fingerprint attempts
# Log first occurrence of these so I can get their IP address
block in log first quick on dc0 proto tcp from any to any flags FUP

# Block anything with special options
block in quick on dc0 all with ipopts

# Block public pings
block in quick on dc0 proto icmp all icmp-type 8

# Block ident
block in quick on dc0 proto tcp from any to any port = 113

# Block all Netbios service. 137=name, 138=datagram, 139=session
# Netbios is MS/Windows sharing services.
# Block MS/Windows hosts2 name server requests 81
block in log first quick on dc0 proto tcp/udp from any to any port = 137
block in log first quick on dc0 proto tcp/udp from any to any port = 138
block in log first quick on dc0 proto tcp/udp from any to any port = 139
block in log first quick on dc0 proto tcp/udp from any to any port = 81

# Allow traffic in from ISP's DHCP server. This rule must contain
# the IP address of your ISP's DHCP server as it's the only
# authorized source to send this packet type. Only necessary for
# cable or DSL configurations. This rule is not needed for
# 'user ppp' type connection to the public Internet.
# This is the same IP address you captured and
# used in the outbound section.
pass in quick on dc0 proto udp from z.z.z.z to any port = 68 keep state

# Allow in standard www function because I have apache server
pass in quick on dc0 proto tcp from any to any port = 80 flags S keep state

# Allow in non-secure Telnet session from public Internet
# labeled non-secure because ID/PW passed over public Internet as clear text.
# Delete this sample group if you do not have telnet server enabled.
#pass in quick on dc0 proto tcp from any to any port = 23 flags S keep state

# Allow in secure FTP, Telnet, and SCP from public Internet
# This function is using SSH (secure shell)
pass in quick on dc0 proto tcp from any to any port = 22 flags S keep state

# Block and log only first occurrence of all remaining traffic
# coming into the firewall. The logging of only the first
# occurrence avoids filling up disk with Denial of Service logs.
# This rule implements the default block.
block in log first quick on dc0 all
################### End of rules file #####################################</programlisting>
    </sect2>

    <sect2>
      <title><acronym>NAT</acronym></title>

      <indexterm><primary>NAT</primary></indexterm>

      <indexterm>
	<primary>IP 伪装</primary>

	<see>NAT</see>
      </indexterm>

      <indexterm>
	<primary>网络地址转换</primary>

	<see>NAT</see>
      </indexterm>

      <para><acronym>NAT</acronym> 是 网络地址转换(Network Address
	Translation) 的缩写。 对于那些熟悉 &linux; 的人来说,
	这个概念叫做 IP 伪装 (Masquerading); <acronym>NAT</acronym> 和 IP
	伪装是完全一样的概念。 由
	IPF 的 <acronym>NAT</acronym> 提供的一项功能是,
	将防火墙后的本地局域网 (LAN) 共享一个 ISP 提供的 IP
	地址来接入 Internet 公网。</para>

      <para>有些人可能会问, 为什么需要这么做。 一般而言, ISP
	会为非商业用户提供动态的 IP 地址。 动态地址意味着每次登录到
	ISP 都有可能得到不同的 IP 地址, 无论是采用电话拨号登录,
	或使用 cable 以及 DSL 调制解调器的方式。 这个 IP 是您与
	Internet 公网交互时使用的身份。</para>

      <para>现在考虑家中有五台 PC 需要访问
	Internet 的情形。 您可能需要向 ISP 为每一台 PC
	所使用的独立的 Internet 账号付费, 并且拥有五根电话线。</para>

      <para>有了 <acronym>NAT</acronym>, 您就只需要一个 ISP 账号,
	然后将另外四台 PC 的网卡通过交换机连接起来,
	并通过运行 &os; 系统的那台机器作为网关连接出去。
	<acronym>NAT</acronym> 会自动地将每一台 PC 在内网的 LAN IP 地址,
	在离开防火墙时转换为公网的 IP 地址。 此外, 当数据包返回时,
	也将进行逆向的转换。</para>

      <para>在 IP 地址空间中, 有一些特殊的范围是保留供经过
	<acronym>NAT</acronym> 的内网 LAN IP 地址使用的。 根据
	RFC 1918, 可以使用下面这些 IP 范围用于内网,
	它们不会在 Internet 公网上路由:</para>

      <informaltable frame="none" pgwide="1">
	<tgroup cols="3">
	  <colspec colwidth="1*"/>

	  <colspec colwidth="1*"/>

	  <colspec colwidth="1*"/>

	  <tbody>
	    <row>
	      <entry>起始 IP <systemitem class="ipaddress">10.0.0.0</systemitem></entry>

	      <entry>-</entry>

	      <entry>结束 IP <systemitem class="ipaddress">10.255.255.255</systemitem></entry>
	    </row>

	    <row>
	      <entry>起始 IP <systemitem class="ipaddress">172.16.0.0</systemitem></entry>

	      <entry>-</entry>

	      <entry>结束 IP <systemitem class="ipaddress">172.31.255.255</systemitem></entry>
	    </row>

	    <row>
	      <entry>起始 IP <systemitem class="ipaddress">192.168.0.0</systemitem></entry>

	      <entry>-</entry>

	      <entry>结束 IP <systemitem class="ipaddress">192.168.255.255</systemitem></entry>
	    </row>
	  </tbody>
	</tgroup>
      </informaltable>
    </sect2>

    <sect2>
      <title>IP<acronym>NAT</acronym></title>

      <indexterm>
	<primary>NAT</primary>

	<secondary>以及 IPFILTER</secondary>
      </indexterm>

      <indexterm><primary><command>ipnat</command></primary></indexterm>

      <para><acronym>NAT</acronym> 规则是通过
	<command>ipnat</command> 命令加载的。 默认情况下,
	<acronym>NAT</acronym> 规则会保存在
	<filename>/etc/ipnat.rules</filename> 文件中。 请参见 &man.ipnat.1;
	了解更多的详情。</para>

      <para>如果在 <acronym>NAT</acronym> 已经启动之后想要修改
	<acronym>NAT</acronym> 规则, 可以修改保存 NAT 规则的那个文件,
	然后在执行 <command>ipnat</command> 命令时加上 <option>-CF</option> 参数,
	以删除在用的 <acronym>NAT</acronym> 内部规则表,
	以及所有地址翻译表中已有的项。</para>

      <para>要重新加载 <acronym>NAT</acronym> 规则, 可以使用类似下面的命令:</para>

      <screen>&prompt.root; <userinput>ipnat -CF -f /etc/ipnat.rules</userinput></screen>

      <para>如果想要看看您系统上
	<acronym>NAT</acronym> 的统计信息, 可以用下面的命令:</para>

      <screen>&prompt.root; <userinput>ipnat -s</userinput></screen>

      <para>要列出当前的 <acronym>NAT</acronym> 表的映射关系,
	使用下面的命令:</para>

      <screen>&prompt.root; <userinput>ipnat -l</userinput></screen>

      <para>要显示详细的信息并显示与规则处理和当前的规则/表项:</para>

      <screen>&prompt.root; <userinput>ipnat -v</userinput></screen>
    </sect2>

    <sect2>
      <title>IP<acronym>NAT</acronym> 规则</title>

      <para><acronym>NAT</acronym> 规则非常的灵活,
	能够适应商业用户和家庭用户的各种不同的需求。</para>

      <para>这里所介绍的规则语法已经被简化,
	以适应非商用环境中的一般情况。 完整的规则语法描述,
	请参考 &man.ipnat.5; 联机手册中的介绍。</para>

      <para><acronym>NAT</acronym> 规则的写法与下面的例子类似:</para>

      <programlisting>map <replaceable>IF</replaceable> <replaceable>LAN_IP_RANGE</replaceable> -&gt; <replaceable>PUBLIC_ADDRESS</replaceable></programlisting>

      <para>关键词 <literal>map</literal> 出现在规则的最前面。</para>

      <para>将 <replaceable>IF</replaceable> 替换为对外的网络接口名。</para>

      <para><replaceable>LAN_IP_RANGE</replaceable> 是内网中的客户机使用的地址范围。
	通常情况下, 这应该是类似 <systemitem class="ipaddress">192.168.1.0/24</systemitem> 的地址。</para>

      <para><replaceable>PUBLIC_ADDRESS</replaceable>
	既可以是外网的 IP 地址, 也可以是
	<literal>0/32</literal> 这个特殊的关键字,
	它表示分配到 <replaceable>IF</replaceable> 上的所有地址。</para>
    </sect2>

    <sect2>
      <title><acronym>NAT</acronym> 的工作原理</title>

      <para>当包从 LAN 到达防火墙, 而目的地址是公网地址时,
	它首先会通过 outbound 过滤规则。 接下来,
	<acronym>NAT</acronym> 会得到包, 并按自顶向下的顺序处理规则,
	而第一个匹配的规则将生效。
	<acronym>NAT</acronym> 接下来会根据包对应的接口名字和源
	IP 地址检查所有的规则。 如果包和某个 <acronym>NAT</acronym>
	规则匹配, 则会检查包的
	(源 IP 地址, 例如, 内网的 IP 地址) 是否在
	<acronym>NAT</acronym> 规则中箭头左侧指定的 IP 地址范围匹配。
	如果匹配, 则包的原地址将被根据用 <literal>0/32</literal>
	关键字指定的 IP 地址重写。
	<acronym>NAT</acronym> 将向它的内部
	<acronym>NAT</acronym> 表发送此地址, 这样, 当包从 Internet
	公网中返回时, 就能够把地址映射回原先的内网 IP 地址,
	并在随后使用过滤器规则来处理。</para>
    </sect2>

    <sect2>
      <title>启用 IP<acronym>NAT</acronym></title>

      <para>要启用 IP<acronym>NAT</acronym>, 只需在
	<filename>/etc/rc.conf</filename> 中加入下面一些语句。</para>

      <para>使机器能够在不同的网络接口之间进行包的转发,
	需要:</para>

      <programlisting>gateway_enable="YES"</programlisting>

      <para>每次开机时自动启动 IP<acronym>NAT</acronym>:</para>

      <programlisting>ipnat_enable="YES"</programlisting>

      <para>指定 IP<acronym>NAT</acronym> 规则集文件:</para>

      <programlisting>ipnat_rules="/etc/ipnat.rules"</programlisting>
    </sect2>

    <sect2>
      <title>大型 LAN 中的 <acronym>NAT</acronym></title>

      <para>对于在一个 LAN 中有大量 PC, 以及包含多个 LAN 的情形,
	把所有的内网 IP 地址都映射到同一个公网 IP 上会导致资源不够的问题,
	因为同一个端口可能在许多做了
	<acronym>NAT</acronym> 的 LAN PC 上被多次使用, 并导致碰撞。
	有两种方法来缓解这个难题。</para>

      <sect3>
	<title>指定使用哪些端口</title>

	<!-- What does it mean ? Is there something missing ?-->
	<!-- XXXBLAH <- Apparently you can't start a sect
	     with a <programlisting> tag ?-->

	<para>普通的 NAT 规则类似于:</para>

	<programlisting>map dc0 192.168.1.0/24 -&gt; 0/32</programlisting>

	<para>上面的规则中, 包的源端口在包通过 IP<acronym>NAT</acronym>
	  时时不会发生变化的。 通过使用 <literal>portmap</literal> 关键字, 您可以要求
	  IP<acronym>NAT</acronym> 只使用指定范围内的端口地址。
	  比如说, 下面的规则将让
	  IP<acronym>NAT</acronym> 把源端口改为指定范围内的端口:</para>

	<programlisting>map dc0 192.168.1.0/24 -&gt; 0/32 portmap tcp/udp 20000:60000</programlisting>

	<para>使用
	  <literal>auto</literal> 关键字可以让配置变得更简单一些, 它会要求
	  IP<acronym>NAT</acronym> 自动地检测可用的端口并使用:</para>

	<programlisting>map dc0 192.168.1.0/24 -&gt; 0/32 portmap tcp/udp auto</programlisting>
      </sect3>

      <sect3>
	<title>使用公网地址池</title>

	<para>对很大的 LAN 而言, 总有一天会达到这样一个临界值,
	  此时的 LAN 地址已经多到了无法只用一个公网地址表现的程度。
	  如果有可用的一块公网 IP 地址, 则可以将这些地址作为一个
	  <quote>地址池</quote> 来使用, 让 IP<acronym>NAT</acronym>
	  来从这些公网 IP 地址中挑选用于发包的地址,
	  并将其为这些包创建映射关系。</para>

	<para>例如, 如果将下面这个把所有包都映射到同一公网 IP 地址的规则:</para>

	<programlisting>map dc0 192.168.1.0/24 -&gt; 204.134.75.1</programlisting>

	<para>稍作修改, 就可以用子网掩码来表达 IP 地址范围:</para>

	<programlisting>map dc0 192.168.1.0/24 -&gt; 204.134.75.0/255.255.255.0</programlisting>

	<para>或者用 CIDR 记法来指定的一组地址了:</para>

	<programlisting>map dc0 192.168.1.0/24 -&gt; 204.134.75.0/24</programlisting>
      </sect3>
    </sect2>

    <sect2>
      <title>端口重定向</title>

      <para>非常流行的一种做法是, 将 web 服务器、
	邮件服务器、 数据库服务器以及 DNS 分别放到 LAN 上的不同的 PC 上。
	这种情况下, 来自这些服务器的网络流量仍然应该被 <acronym>NAT</acronym>,
	但必须有办法把进入的流量发到对应的局域网的
	PC 上。 IP<acronym>NAT</acronym> 提供了 <acronym>NAT</acronym>
	重定向机制来解决这个问题。 考虑下面的情况,
	您的 web 服务器的 LAN 地址是 <systemitem class="ipaddress">10.0.10.25</systemitem>, 而您的唯一的公网 IP
	地址是 <systemitem class="ipaddress">20.20.20.5</systemitem>, 则可以编写这样的规则:</para>

	<programlisting>rdr dc0 20.20.20.5/32 port 80 -&gt; 10.0.10.25 port 80</programlisting>

	<para>或者:</para>

	<programlisting>rdr dc0 0.0.0.0/0 port 80 -&gt; 10.0.10.25 port 80</programlisting>

	<para>另外, 也可以让 LAN 地址 <systemitem class="ipaddress">10.0.10.33</systemitem> 上运行的 LAN DNS 服务器来处理公网上的
	  DNS 请求:</para>

	<programlisting>rdr dc0 20.20.20.5/32 port 53 -&gt; 10.0.10.33 port 53 udp</programlisting>
    </sect2>

    <sect2>
      <title>FTP 和 <acronym>NAT</acronym></title>

      <para>FTP 是一个在 Internet 如今天这样为人所熟知之前就已经出现的恐龙,
	那时, 研究机构和大学是通过租用的线路连到一起的, 而 FTP
	则被用于在科研人员之间共享大文件。 那时,
	数据的安全性并不是需要考虑的事情。 若干年之后, FTP
	协议则被埋进了正在形成中的 Internet 骨干,
	而它使用明文来交换用户名和口令的缺点,
	并没有随着新出现的一些安全需求而得到改变。 FTP 提供了两种不同的风格,
	即主动模式和被动模式。 两者的区别在于数据通道的建立方式。
	被动模式相对而言要更加安全, 因为数据通道是由发起 ftp
	会话的一方建立的。 关于 FTP 以及它所提供的不同模式,
	在 <uri xlink:href="http://www.slacksite.com/other/ftp.html">http://www.slacksite.com/other/ftp.html</uri>
	进行了很好的阐述。</para>

      <sect3>
	<title>IP<acronym>NAT</acronym> 规则</title>

	<para>IP<acronym>NAT</acronym> 提供了一个内建的 FTP 代理选项,
	  它可以在 <acronym>NAT</acronym> map 规则中指定。
	  它能够监视所有外发的 FTP 主动或被动模式的会话开始请求,
	  并动态地创建临时性的过滤器规则, 只打开用于数据通道的端口号。
	  这样, 就消除了 FTP 一般会给防火墙带来的,
	  需要大范围地打开高端口所可能带来的安全隐患。</para>

	<para>下面的规则可以处理来自内网的 FTP 访问:</para>

	<programlisting>map dc0 10.0.10.0/29 -&gt; 0/32 proxy port 21 ftp/tcp</programlisting>

	<para>这个规则能够处理来自网关的 FTP 访问:</para>

	<programlisting>map dc0 0.0.0.0/0 -&gt; 0/32 proxy port 21 ftp/tcp</programlisting>

	<para>这个则处理所有来自内网的非 FTP 网络流量:</para>

	<programlisting>map dc0 10.0.10.0/29 -&gt; 0/32</programlisting>

	<para>FTP map 规则应该在普通的 map 规则之前出现。
	  所有的包会从最上面的第一个规则开始进行检查。
	  匹配的顺序是网卡名称, 内网源 IP 地址, 以及它是否是 FTP 包。
	  如果所有这些规则都匹配成功, 则 FTP
	  代理将建立一个临时的过滤规则, 以便让 FTP 会话的数据包能够正常出入,
	  同时对这些包进行 <acronym>NAT</acronym>。
	  所有的 LAN 数据包, 如果没有匹配第一条规则,
	  则会继续尝试匹配下面的规则, 并最终被
	  <acronym>NAT</acronym>。</para>
      </sect3>

      <sect3>
	<title>IP<acronym>NAT</acronym> FTP 过滤规则</title>

	<para>如果使用了
	  <acronym>NAT</acronym> FTP 代理, 则只需要为 FTP 创建一个规则。</para>

	<para>如果不使用 FTP 代理, 就需要下面这三个规则:</para>

	<programlisting># Allow out LAN PC client FTP to public Internet
# Active and passive modes
pass out quick on rl0 proto tcp from any to any port = 21 flags S keep state

# Allow out passive mode data channel high order port numbers
pass out quick on rl0 proto tcp from any to any port &gt; 1024 flags S keep state

# Active mode let data channel in from FTP server
pass in quick on rl0 proto tcp from any to any port = 20 flags S keep state</programlisting>
      </sect3>
    </sect2>
  </sect1>

  <sect1 xml:id="firewalls-ipfw">
    <title>IPFW</title>

    <indexterm>
      <primary>防火墙</primary>

      <secondary>IPFW</secondary>
    </indexterm>

    <para>IPFIREWALL (<acronym>IPFW</acronym>) 是一个由 &os; 发起的防火墙应用软件,
      它由 &os; 的志愿者成员编写和维护。
      它使用了传统的无状态规则和规则编写方式,
      以期达到简单状态逻辑所期望的目标。</para>

    <para>标准的 &os; 安装中, IPFW 所给出的规则集样例 (可以在
      <filename>/etc/rc.firewall</filename> 和
      <filename>/etc/rc.firewall6</filename> 中找到) 非常简单,
      建议不要不加修改地直接使用。 该样例中没有使用状态过滤,
      而该功能在大部分的配置中都是非常有用的,
      因此这一节并不以系统自带的样例作为基础。</para>

    <para>IPFW 的无状态规则语法, 是由一种提供复杂的选择能力的技术支持的,
      这种技术远远超出了一般的防火墙安装人员的知识水平。
      IPFW 是为满足专业用户,
      以及掌握先进技术的电脑爱好者们对于高级的包选择需求而设计的。
      要完全释放 IPFW 的规则所拥有的强大能力,
      需要对不同的协议的细节有深入的了解,
      并根据它们独特的包头信息来编写规则。
      这一级别的详细阐述超出了这本手册的范围。</para>

    <para>IPFW 由七个部分组成, 其主要组件是内核的防火墙过滤规则处理器,
      及其集成的数据包记帐工具、 日志工具、  用以触发
      <acronym>NAT</acronym> 工具的 <literal>divert</literal> (转发) 规则、
      高级特殊用途工具、 dummynet 流量整形机制,
      <literal>fwd rule</literal> 转发工具, 桥接工具, 以及 ipstealth 工具。
      IPFW 支持 IPv4 和 IPv6。</para>

    <sect2 xml:id="firewalls-ipfw-enable">
      <title>启用 IPFW</title>

      <indexterm>
	<primary>IPFW</primary>

	<secondary>启用</secondary>
      </indexterm>

      <para>IPFW 是基本的 &os; 安装的一部分, 以单独的可加载内核模块的形式提供。
	如果在 <filename>rc.conf</filename> 中加入
	<literal>firewall_enable="YES"</literal> 语句, 就会自动地加载对应的内核模块。
	除非您打算使用由它提供的
	<acronym>NAT</acronym> 功能, 一般情况下并不需要把 IPFW 编进
	&os; 的内核。</para>

      <para>如果将
	<literal>firewall_enable="YES"</literal> 加入到
	<filename>rc.conf</filename> 中并重新启动系统,
	则下列信息将在启动过程中, 以高亮的白色显示出来:</para>

      <screen>ipfw2 initialized, divert disabled, rule-based forwarding disabled, default to deny, logging disabled</screen>

      <para>可加载内核模块在编译时加入了记录日志的能力。 要启用日志功能,
	并配置详细日志记录的限制, 需要在
	<filename>/etc/sysctl.conf</filename> 中加入一些配置。
	这些设置将在重新启动之后生效:</para>

      <programlisting>net.inet.ip.fw.verbose=1
net.inet.ip.fw.verbose_limit=5</programlisting>
    </sect2>

    <sect2 xml:id="firewalls-ipfw-kernel">
      <title>内核选项</title>

      <indexterm>
	<primary>内核选项</primary>

	<secondary>IPFIREWALL</secondary>
      </indexterm>

      <indexterm>
	<primary>内核选项</primary>

	<secondary>IPFIREWALL_VERBOSE</secondary>
      </indexterm>

      <indexterm>
	<primary>内核选项</primary>

	<secondary>IPFIREWALL_VERBOSE_LIMIT</secondary>
      </indexterm>

      <indexterm>
	<primary>IPFW</primary>

	<secondary>内核选项</secondary>
      </indexterm>

      <para>把下列选项在编译 &os; 内核时就加入, 并不是启用 IPFW 所必需的,
	除非您需要使用 <acronym>NAT</acronym> 功能。
	这里只是将这些选项作为背景知识来介绍。</para>

      <programlisting>options    IPFIREWALL</programlisting>

      <para>这个选项将 IPFW 作为内核的一部分来启用。</para>

      <programlisting>options    IPFIREWALL_VERBOSE</programlisting>

      <para>这个选项将启用记录通过 IPFW 的匹配了包含
	<literal>log</literal> 关键字规则的每一个包的功能。</para>

      <programlisting>options    IPFIREWALL_VERBOSE_LIMIT=5</programlisting>

      <para>以每项的方式, 限制通过 &man.syslogd.8; 记录的包的个数。
	如果在比较恶劣的环境下记录防火墙的活动可能会需要这个选项。
	它能够避免潜在的针对 syslog 的洪水式拒绝服务攻击。</para>

      <indexterm>
	<primary>内核选项</primary>

	<secondary>IPFIREWALL_DEFAULT_TO_ACCEPT</secondary>
      </indexterm>

      <programlisting>options    IPFIREWALL_DEFAULT_TO_ACCEPT</programlisting>

      <para>这个选项默认地允许所有的包通过防火墙,
	如果您是第一次配置防火墙, 使用这个选项将是一个不错的主意。</para>

      <indexterm>
	<primary>内核选项</primary>

	<secondary>IPDIVERT</secondary>
      </indexterm>

      <programlisting>options    IPDIVERT</programlisting>

      <para>这一选项启用 <acronym>NAT</acronym>
	功能。</para>

      <note>
	<para>如果内核选项中没有加入
	  <literal>IPFIREWALL_DEFAULT_TO_ACCEPT</literal>,
	  而配置使用的规则集中也没有明确地指定允许连接进入的规则,
	  默认情况下, 发到本机和从本机发出的所有包都会被阻止。</para>
      </note>
    </sect2>

    <sect2 xml:id="firewalls-ipfw-rc">
      <title><filename>/etc/rc.conf</filename> Options</title>

      <para>启用防火墙:</para>

      <programlisting>firewall_enable="YES"</programlisting>

      <para>要选择由 &os; 提供的几种防火墙类型中的一种来作为默认配置,
	您需要阅读
	<filename>/etc/rc.firewall</filename> 文件并选出合适的类型,
	然后在 <filename>/etc/rc.conf</filename> 中加入类似下面的配置:</para>

      <programlisting>firewall_type="open"</programlisting>

      <para>您还可以指定下列配置规则之一:</para>

      <itemizedlist>
	<listitem>
	  <para><literal>open</literal> &mdash; 允许所有流量通过。</para>
	</listitem>
	<listitem>
	  <para><literal>client</literal> &mdash; 只保护本机。</para>
	</listitem>
	<listitem>
	  <para><literal>simple</literal> &mdash; 保护整个网络。</para>
	</listitem>
	<listitem>
	  <para><literal>closed</literal> &mdash; 完全禁止除回环设备之外的全部 IP
	    流量。</para>
	</listitem>
	<listitem>
	  <para><literal>UNKNOWN</literal> &mdash; 禁止加载防火墙规则。</para>
	</listitem>
	<listitem>
	  <para><filename>filename</filename> &mdash; 到防火墙规则文件的绝对路径。</para>
	</listitem>
      </itemizedlist>

      <para>有两种加载自定义 <application>ipfw</application> 防火墙规则的方法。
	其一是将变量 <literal>firewall_type</literal> 设为包含不带 &man.ipfw.8;
	命令行选项的 <emphasis>防火墙规则</emphasis>
	文件的完整路径。 下面是一个简单的规则集例子:</para>

     <programlisting>add deny in
add deny out</programlisting>

     <para>除此之外, 也可以将
	<literal>firewall_script</literal> 变量设为包含
	<command>ipfw</command> 命令的可执行脚本,
	这样这个脚本会在启动时自动执行。 与前面规则集文件等价的规则脚本如下:</para>

      <para><command>ipfw</command> 命令是在防火墙运行时,
	用于在其内部规则表中手工逐条添加或删除防火墙规则的标准工具。
	这一方法的问题在于, 一旦您的关闭计算机或停机,
	则所有增加或删除或修改的规则也就丢掉了。
	把所有的规则都写到一个文件中, 并在启动时使用这个文件来加载规则,
	或一次大批量地替换防火墙规则, 那么推荐使用这里介绍的方法。</para>

      <para><command>ipfw</command> 的另一个非常实用的功能是将所有正在运行的防火墙规则显示出来。
	IPFW 的记账机制会为每一个规则动态地创建计数器,
	用以记录与它们匹配的包的数量。 在测试规则的过程中,
	列出规则及其计数器是了解它们是否工作正常的重要手段。</para>

      <para>按顺序列出所有的规则:</para>

      <screen>&prompt.root; <userinput>ipfw list</userinput></screen>

      <para>列出所有的规则, 同时给出最后一次匹配的时间戳:</para>

      <screen>&prompt.root; <userinput>ipfw -t list</userinput></screen>

      <para>列出所有的记账信息、 匹配规则的包的数量, 以及规则本身。
	第一列是规则的编号, 随后是发出包匹配的数量, 进入包的匹配数量,
	最后是规则本身。</para>

      <screen>&prompt.root; <userinput>ipfw -a list</userinput></screen>

      <para>列出所有的动态规则和静态规则:</para>

      <screen>&prompt.root; <userinput>ipfw -d list</userinput></screen>

      <para>同时显示已过期的动态规则:</para>

      <screen>&prompt.root; <userinput>ipfw -d -e list</userinput></screen>

      <para>将计数器清零:</para>

      <screen>&prompt.root; <userinput>ipfw zero</userinput></screen>

      <para>只把规则号为
	<replaceable>NUM</replaceable> 的计数器清零:</para>

      <screen>&prompt.root; <userinput>ipfw zero NUM</userinput></screen>
    </sect2>

    <sect2 xml:id="firewalls-ipfw-rules">
      <title>IPFW 规则集</title>

      <!-- This has already appeared once -->

      <para>规则集是指一组编写好的依据包的值决策允许通过或阻止 IPFW 规则。
	包的双向交换组成了一个会话交互。 防火墙规则集会作用于来自于
	Internet 公网的包以及由系统发出来回应这些包的数据包。
	每一个 <acronym>TCP/IP</acronym> 服务 (例如 telnet, www,
	邮件等等) 都由协议预先定义了其特权 (监听) 端口。
	发到特定服务的包会从源地址使用非特权 (高编号) 端口发出,
	并发到特定服务在目的地址的对应端口。
	所有这些参数 (例如: 端口和地址)
	都是可以为防火墙规则所利用的, 判别是否允许服务通过的标准。</para>

      <indexterm>
	<primary>IPFW</primary>

	<secondary>规则处理顺序</secondary>
      </indexterm>

      <!-- Needs rewording to include note below -->

      <para>当有数据包进入防火墙时, 会从规则集里的第一个规则开始进行比较,
	并自顶向下地进行匹配。 当包与某个选择规则参数相匹配时,
	将会执行规则所定义的动作, 并停止规则集搜索。 这种策略,
	通常也被称作 <quote>最先匹配者获胜</quote> 的搜索方法。
	如果没有任何与包相匹配的规则, 那么它就会根据强制的 IPFW
	默认规则, 也就是 65535 号规则截获。 一般情况下这个规则是阻止包,
	而且不给出任何回应。</para>

      <note>
	<para>如果规则定义的动作是 <literal>count</literal>、
	  <literal>skipto</literal> 或 <literal>tee</literal>
	  规则的话, 搜索会继续。</para>
      </note>

      <para>这里所介绍的规则, 都是使用了那些包含状态功能的,
	也就是 <literal>keep state</literal>、 <literal>limit</literal>、 <literal>in</literal>、 <literal>out</literal>
	以及 <literal>via</literal> 选项的规则。
	这是编写明示允许防火墙规则集所需的基本框架。</para>

      <warning>
	<para>在操作防火墙规则时应谨慎行事, 如果操作不当,
	  很容易将自己反锁在外面。</para>
      </warning>

      <sect3 xml:id="firewalls-ipfw-rules-syntax">
	<title>规则语法</title>

	<indexterm>
	  <primary>IPFW</primary>

	  <secondary>规则语法</secondary>
	</indexterm>

	<para>这里所介绍的规则语法已经经过了简化,
	  只包括了建立标准的明示允许防火墙规则集所必需的那些。
	  要了解完整的规则语法说明,
	  请参见 &man.ipfw.8; 联机手册。</para>

	<para>规则是由关键字组成的: 这些关键字必须以特定的顺序从左到右书写。
	  下面的介绍中, 关键字使用粗体表示。 某些关键字还包括了子选项,
	  这些子选项本身可能也是关键字, 有些还可以包含更多的子选项。</para>

	<para><literal>#</literal> 用于表示开始一段注释。
	  它可以出现在一个规则的后面, 也可以独占一行。
	  空行会被忽略。</para>

	<para><replaceable>CMD RULE_NUMBER ACTION LOGGING SELECTION
	    STATEFUL</replaceable></para>

	<sect4>
	  <title>CMD</title>

	  <para>每一个新的规则都应以
	    <parameter>add</parameter> 作为前缀, 它表示将规则加入内部表。</para>
	</sect4>

	<sect4>
	  <title>RULE_NUMBER</title>

	  <para>每一条规则都与一个范围在 1 到 65535 之间的规则编号相关联。</para>
	</sect4>

	<sect4>
	  <title>ACTION</title>

	  <para>每一个规则可以与下列的动作之一相关联,
	    所指定的动作将在进入的数据包与规则所指定的选择标准相匹配时执行。</para>

	  <para><parameter>allow | accept | pass |
	      permit</parameter></para>

	  <para>这些关键字都表示允许匹配规则的包通过防火墙,
	    并停止继续搜索规则。</para>

	  <para><parameter>check-state</parameter></para>

	  <para>根据动态规则表检查数据包。 如果匹配,
	    则执行规则所指定的动作, 亦即生成动态规则;
	    否则, 转移到下一个规则。 check-state 规则没有选择标准。
	    如果规则集中没有 check-state 规则,
	    则会在第一个 keep-state 或 limit 规则处,
	    对动态规则表实施检查。</para>

	  <para><parameter>deny | drop</parameter></para>

	  <para>这两个关键字都表示丢弃匹配规则的包。
	    同时, 停止继续搜索规则。</para>
	</sect4>

	<sect4>
	  <title>LOGGING</title>

	  <para><parameter>log</parameter> or
	    <parameter>logamount</parameter></para>

	  <para>当数据包与带 <literal>log</literal> 关键字的规则匹配时,
	    将通过名为 SECURITY 的 facility 来把消息记录到 &man.syslogd.8;。
	    只有在记录的次数没有超过 logamount 参数所指定的次数时,
	    才会记录日志。 如果没有指定 <literal>logamount</literal>,
	    则会以 sysctl 变量
	    <literal>net.inet.ip.fw.verbose_limit</literal> 所指定的限制为准。
	    如果将这两种限制值之一指定为零, 则表示不作限制。
	    如果达到了限制数,
	    可以通过将规则的日志计数或包计数清零来重新启用日志,
	    请参见 <command>ipfw reset log</command> 命令来了解细节。</para>

	  <note>
	    <para>日志是在所有其他匹配条件都验证成功之后,
	      在针对包实施最终动作 (accept, deny) 之前进行的。
	      您可以自行决定哪些规则应启用日志。</para>
	    </note>
	</sect4>

	<sect4>
	  <title>SELECTION</title>

	  <para>这一节所介绍的关键字主要用来描述检查包的哪些属性,
	    用以判断包是否与规则相匹配。
	    下面是一些通用的用于匹配包特征的属性,
	    它们必须按顺序使用:</para>

	  <para><parameter>udp | tcp | icmp</parameter></para>

	  <para>也可以指定在
	    <filename>/etc/protocols</filename> 中所定义的协议。
	    这个值定义的是匹配的协议, 在规则中必须指定它。</para>

	  <para><parameter>from src to dst</parameter></para>

	  <para><literal>from</literal> 和 <literal>to</literal> 关键字用于匹配 IP
	    地址。 规则中必须 <emphasis>同时</emphasis> 指定源和目的两个参数。
	    如果需要匹配任意 IP 地址,
	    可以使用特殊关键字 <literal>any</literal>。
	    还有一个特殊关键字, 即 <literal>me</literal>,
	    用于匹配您的 &os; 系统上所有网络接口上所配置的 IP 地址,
	    它可以用于表达网络上的其他计算机到防火墙 (也就是本机),
	    例如 <literal>from me to any</literal> 或 <literal>from any to me</literal> 或 <literal>from 0.0.0.0/0 to any</literal> 或
	    <literal>from any to 0.0.0.0/0</literal> 或 <literal>from 0.0.0.0 to any</literal> 或 <literal>from
	    any to 0.0.0.0</literal> 以及 <literal>from me to 0.0.0.0</literal>。 IP
	    地址可以通过 带点的 IP 地址/掩码长度 (CIDR 记法),
	    或者一个带点的 IP 地址的形式来指定。
	    这是编写规则时所必需的。 使用 <package>net-mgmt/ipcalc</package> port 可以用来简化计算。
	    关于这个工具的更多信息, 也可参考它的主页: <uri xlink:href="http://jodies.de/ipcalc">http://jodies.de/ipcalc</uri>。</para>

	  <para><parameter>port number</parameter></para>

	  <para>这个参数主要用于那些支持端口号的协议 (例如
	    <acronym>TCP</acronym> 和 <acronym>UDP</acronym>)。 如果要通过端口号匹配某个协议,
	    就必须指定这个参数。 此外, 也可以通过服务的名字 (根据
	    <filename>/etc/services</filename>) 来指定服务,
	    这样会比使用数字指定端口号直观一些。</para>

	  <para><parameter>in | out</parameter></para>

	  <para>相应地, 匹配进入和发出的包。
	    这里的 <literal>in</literal> 和 <literal>out</literal> 都是关键字, 在编写匹配规则时,
	    必需作为其他条件的一部分来使用。</para>

	  <para><parameter>via IF</parameter></para>

	  <para>根据指定的网络接口的名称精确地匹配进出的包。
	    这里的 <literal>via</literal>
	    关键字将使得接口名称成为匹配过程的一部分。</para>

	  <para><parameter>setup</parameter></para>

	  <para>要匹配 <acronym>TCP</acronym> 会话的发起请求,
	    就必须使用它。</para>

	  <para><parameter>keep-state</parameter></para>

	  <para>这是一个必须使用的关键字。 在发生匹配时,
	    防火墙将创建一个动态规则, 其默认行为是,
	    匹配使用同一协议的、从源到目的 IP/端口 的双向网络流量。</para>

	  <para><parameter>limit {src-addr | src-port | dst-addr |
	      dst-port}</parameter></para>

	  <para>防火墙只允许匹配规则时, 与指定的参数相同的
	    <replaceable>N</replaceable> 个连接。
	    可以指定至少一个源或目的地址及端口。
	    <literal>limit</literal> 和 <literal>keep-state</literal> 不能在同一规则中同时使用。
	    <literal>limit</literal> 提供了与 <literal>keep-state</literal> 相同的功能,
	    并增加了一些独有的能力。</para>
	</sect4>
      </sect3>

      <sect3>
	<title>状态规则选项</title>

	<indexterm>
	  <primary>IPFW</primary>

	  <secondary>带状态过滤</secondary>
	</indexterm>

	<!-- XXX: duplicated -->

	<para>有状态过滤将网络流量当作一种双向的包交换来处理。
	  它提供了一种额外的检查能力,
	  用以检测会话中的包是否来自最初的发送者,
	  并在遵循双向包交换的规则进行会话。
	  如果包与这些规则不符, 则将自动地拒绝它们。</para>

	<para><literal>check-state</literal> 用来识别在 IPFW
	  规则集中的包是否符合动态规则机制的规则。
	  如果匹配, 则允许包通过,
	  此时防火墙将创建一个新的动态规则来匹配双向交换中的下一个包。
	  如果不匹配, 则将继续尝试规则集中的下一个规则。</para>

	<para>动态规则机制在 SYN-flood 攻击下是脆弱的,
	  因为这种情况会产生大量的动态规则, 从而耗尽资源。
	  为了抵抗这种攻击, 从 &os; 中加入了一个叫做 <literal>limit</literal>
	  的新选项。
	  这个选项可以用来限制符合规则的会话允许的并发连接数。
	  如果动态规则表中的规则数超过 <literal>limit</literal> 的限制数量,
	  则包将被丢弃。</para>
      </sect3>

      <sect3>
	<title>记录防火墙消息</title>

	<indexterm>
	  <primary>IPFW</primary>

	  <secondary>记录日志</secondary>
	</indexterm>

	<para>记录日志的好处是显而易见的: 它提供了在事后检查所发生的状况的方法,
	  例如哪些包被丢弃了, 这些包的来源和目的地,
	  从而为您提供找到攻击者所需的证据。</para>

	<para>即使启用了日志机制, IPFW 也不会自行生成任何规则的日志。
	  防火墙管理员需要指定规则集中的哪些规则应该记录日志,
	  并在这些规则上增加 <literal>log</literal> 动作。 一般来说, 只有
	  deny 规则应记录日志, 例如对于进入的
	  <acronym>ICMP</acronym> ping 的 deny 规则。 另外,
	  复制 <quote>默认的 ipfw 终极 deny 规则</quote>, 并加入 <literal>log</literal>
	  动作来作为您的规则集的最后一条规则也是很常见的用法。
	  这样, 您就能看到没有匹配任何一条规则的那些数据包。</para>

	<para>日志是一把双刃剑, 如果不谨慎地加以利用,
	  则可能会陷入过多的日志数据中, 并导致磁盘被日志塞满。
	  将磁盘填满是 DoS 攻击最为老套的手法之一。
	  由于 <application>syslogd</application> 除了会将日志写入磁盘之外,
	  还会输出到 root 的控制台屏幕上,
	  因此有过多的日志信息是很让人恼火的事情。</para>

	<para><literal>IPFIREWALL_VERBOSE_LIMIT=5</literal>
	  内核选项将限制同一个规则发到系统日志程序 &man.syslogd.8; 的连续消息的数量。
	  当内核启用了这个选项时,
	  某一特定规则所产生的连续消息的数量将封顶为这个数字。
	  一般来说, 没有办法从连续 200 条一模一样的日志信息中获取更多有用的信息。
	  举例来说, 如果同一个规则产生了 5 次消息并被记录到
	  <application>syslogd</application>, 余下的相同的消息将被计数,
	  并像下面这样发给 <application>syslogd</application>:</para>

	<programlisting>last message repeated 45 times</programlisting>

	<para>所有记录的数据包包消息, 默认情况下会最终写到
	  <filename>/var/log/security</filename> 文件中,
	  后者在 <filename>/etc/syslog.conf</filename> 文件里进行了定义。</para>
      </sect3>

      <sect3 xml:id="firewalls-ipfw-rules-script">
	<title>编写规则脚本</title>

	<para>绝大多数有经验的 IPFW 用户会创建一个包含规则的文件,
	  并且, 按能够以脚本形式运行的方式来书写。 这样做最大的一个好处是,
	  可以大批量地刷新防火墙规则, 而无须重新启动系统就能够激活它们。
	  这种方法在测试新规则时会非常方便,
	  因为同一过程在需要时可以多次执行。
	  作为脚本, 您可以使用符号替换来撰写那些经常需要使用的值,
	  并用同一个符号在多个规则中反复地表达它。
	  下面将给出一个例子。</para>

	<para>这个脚本使用的语法同 &man.sh.1;、
	  &man.csh.1; 以及 &man.tcsh.1; 脚本兼容。 符号替换字段使用美元符号 &dollar;
	  作为前缀。 符号字段本身并不使用 &dollar; 前缀。
	  符号替换字段的值必须使用 "双引号" 括起来。</para>

	<para>可以使用类似下面的规则文件:</para>

	<programlisting>############### start of example ipfw rules script #############
#
ipfw -q -f flush       # Delete all rules
# Set defaults
oif="tun0"             # out interface
odns="192.0.2.11"      # ISP's DNS server IP address
cmd="ipfw -q add "     # build rule prefix
ks="keep-state"        # just too lazy to key this each time
&dollar;cmd 00500 check-state
&dollar;cmd 00502 deny all from any to any frag
&dollar;cmd 00501 deny tcp from any to any established
&dollar;cmd 00600 allow tcp from any to any 80 out via &dollar;oif setup &dollar;ks
&dollar;cmd 00610 allow tcp from any to &dollar;odns 53 out via &dollar;oif setup &dollar;ks
&dollar;cmd 00611 allow udp from any to &dollar;odns 53 out via &dollar;oif &dollar;ks
################### End of example ipfw rules script ############</programlisting>

	<para>这就是所要做的全部事情了。 例子中的规则并不重要,
	  它们主要是用来表示如何使用符号替换。</para>

	<para>如果把上面的例子保存到
	  <filename>/etc/ipfw.rules</filename> 文件中。
	  下面的命令来会重新加载规则。</para>

	<screen>&prompt.root; <userinput>sh /etc/ipfw.rules</userinput></screen>

	<para><filename>/etc/ipfw.rules</filename> 这个文件可以放到任何位置,
	  也可以命名为随便什么别的名字。</para>

	<para>也可以手工执行下面的命令来达到类似的目的:</para>

	<screen>&prompt.root; <userinput>ipfw -q -f flush</userinput>
&prompt.root; <userinput>ipfw -q add check-state</userinput>
&prompt.root; <userinput>ipfw -q add deny all from any to any frag</userinput>
&prompt.root; <userinput>ipfw -q add deny tcp from any to any established</userinput>
&prompt.root; <userinput>ipfw -q add allow tcp from any to any 80 out via tun0 setup keep-state</userinput>
&prompt.root; <userinput>ipfw -q add allow tcp from any to 192.0.2.11 53 out via tun0 setup keep-state</userinput>
&prompt.root; <userinput>ipfw -q add 00611 allow udp from any to 192.0.2.11 53 out via tun0 keep-state</userinput></screen>
      </sect3>

      <sect3>
	<title>带状态规则集</title>

	<para>以下的这组非-<acronym>NAT</acronym> 规则集,
	  是如何编写非常安全的 '明示允许' 防火墙的一个例子。
	  明示允许防火墙只允许匹配了 pass 规则的包通过,
	  而默认阻止所有的其他数据包。
	  用来保护整个网段的防火墙, 至少需要有两个网络接口,
	  并且其上必须配置规则, 以便让防火墙正常工作。</para>

	<para>所有类 &unix; 操作系统, 也包括 &os;,
	  都设计为允许使用网络接口 <filename>lo0</filename> 和 IP
	  地址 <systemitem class="ipaddress">127.0.0.1</systemitem> 来完成操作系统内部的通讯。
	  防火墙必须包含一组规则, 使这些数据包能够无障碍地收发。</para>

	<para>接入 Internet 公网的那个网络接口上,
	  应该配置授权和访问控制, 来限制对外的访问, 以及来自 Internet
	  公网的访问。 这个接口很可能是您的用户态
	  <acronym>PPP</acronym> 接口, 例如
	  <filename>tun0</filename>, 或者您接在 DSL 或电缆 modem
	  上的网卡。</para>

	<para>如果有至少一个网卡接入了防火墙后的内网 LAN,
	  则必须为这些接口配置规则,
	  以便让这些接口之间的包能够顺畅地通过。</para>

	<para>所有的规则应被组织为三个部分, 所有应无阻碍地通过的规则,
	  公网的发出规则, 以及公网的接收规则。</para>

	<para>公网接口相关的规则的顺序,
	  应该是最经常用到的放在尽可能靠前的位置,
	  而最后一个规则, 则应该是阻止那个接口在那一方向上的包。</para>

	<para>发出部分的规则只包含一些 <literal>allow</literal> 规则,
	  允许选定的那些唯一区分协议的端口号所指定的协议通过,
	  以允许访问 Internet 公网上的这些服务。
	  所有的规则中都指定了 <literal>proto</literal>、 <literal>port</literal>、
	  <literal>in/out</literal>、 <literal>via</literal> 以及 <literal>keep state</literal> 这些选项。 <literal>proto tcp</literal>
	  规则同时指定 <literal>setup</literal> 选项, 来区分开始协议会话的包,
	  以触发将包放入
	  keep state 规则表中的动作。</para>

	<para>接收部分则首先阻止所有不希望的包, 这样做有两个不同的原因。
	  其一是恶意的包可能和某些允许的流量规则存在部分匹配, 而我们希望阻止,
	  而不是让这些包仅仅与 <literal>allow</literal> 规则部分匹配就允许它们进入。
	  其二是, 已经确信要阻止的包被拒绝这件事, 往往并不是我们需要关注的,
	  因此只要简单地予以阻止即可。
	  防火墙规则集中的每个部分的最后一条规则都是阻止并记录包,
	  这有助于为逮捕攻击者留下法律所要求的证据。</para>

	<para>另外一个需要注意的事情是确保系统对不希望的数据包不做回应。
	  无效的包应被丢弃和消失。 这样, 攻击者便无法知道包是否到达了您的系统。
	  攻击者对系统了解的越少, 其攻击的难度也就越大。 如果不知道端口号,
	  可以查阅 <filename>/etc/services/</filename> 或到 <uri xlink:href="http://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers">http://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers</uri>
	  并查找一下端口号, 以了解其用途。 另外,
	  您也可以在这个网页上了解常见木马所使用的端口: <uri xlink:href="http://www.sans.org/security-resources/idfaq/oddports.php">http://www.sans.org/security-resources/idfaq/oddports.php</uri>。</para>
      </sect3>

      <sect3>
	<title>明示允许规则集的例子</title>

	<para>下面是一个非-<acronym>NAT</acronym> 的规则集,
	  它是一个完整的明示允许规则集。 使用它作为您的规则集不会有什么问题。
	  只需把那些不需要的服务对应的 pass 规则注释掉就可以了。
	  如果您在日志中看到消息, 而且不想再看到它们,
	  只需在接收部分增加一个一个 <literal>deny</literal> 规则。
	  您可能需要把 <filename>dc0</filename> 改为接入公网的接口的名字。
	  对于使用用户态 <acronym>PPP</acronym> 的用户而言, 应该是
	  <filename>tun0</filename>。</para>

	<para>这些规则遵循一定的模式。</para>

	<itemizedlist>
	  <listitem>
	    <para>所有请求 Internet 公网上服务的会话开始包,
	      都使用了 <literal>keep-state</literal>。</para>
	  </listitem>

	  <listitem>
	    <para>所有来自 Internet 的授权服务请求,
	      都采用了 <literal>limit</literal> 选项来防止洪水式攻击。</para>
	  </listitem>

	  <listitem>
	    <para>所有的规则都使用了 <literal>in</literal> 或者 <literal>out</literal> 来说明方向。</para>
	  </listitem>

	  <listitem>
	    <para>所有的规则都使用了 <literal>via</literal> <replaceable>接口名</replaceable>
	      来指定应该匹配通过哪一个接口的包。</para>
	  </listitem>
	</itemizedlist>

	<para>这些规则都应放到
	  <filename>/etc/ipfw.rules</filename>。</para>

	<programlisting>################ Start of IPFW rules file ###############################
# Flush out the list before we begin.
ipfw -q -f flush

# Set rules command prefix
cmd="ipfw -q add"
pif="dc0"     # public interface name of NIC
              # facing the public Internet

#################################################################
# No restrictions on Inside LAN Interface for private network
# Not needed unless you have LAN.
# Change xl0 to your LAN NIC interface name
#################################################################
#&dollar;cmd 00005 allow all from any to any via xl0

#################################################################
# No restrictions on Loopback Interface
#################################################################
&dollar;cmd 00010 allow all from any to any via lo0

#################################################################
# Allow the packet through if it has previous been added to the
# the "dynamic" rules table by a allow keep-state statement.
#################################################################
&dollar;cmd 00015 check-state

#################################################################
# Interface facing Public Internet (Outbound Section)
# Interrogate session start requests originating from behind the
# firewall on the private network or from this gateway server
# destined for the public Internet.
#################################################################

# Allow out access to my ISP's Domain name server.
# x.x.x.x must be the IP address of your ISP.s DNS
# Dup these lines if your ISP has more than one DNS server
# Get the IP addresses from /etc/resolv.conf file
&dollar;cmd 00110 allow tcp from any to x.x.x.x 53 out via &dollar;pif setup keep-state
&dollar;cmd 00111 allow udp from any to x.x.x.x 53 out via &dollar;pif keep-state

# Allow out access to my ISP's DHCP server for cable/DSL configurations.
# This rule is not needed for .user ppp. connection to the public Internet.
# so you can delete this whole group.
# Use the following rule and check log for IP address.
# Then put IP address in commented out rule &amp; delete first rule
&dollar;cmd 00120 allow log udp from any to any 67 out via &dollar;pif keep-state
#&dollar;cmd 00120 allow udp from any to x.x.x.x 67 out via &dollar;pif keep-state

# Allow out non-secure standard www function
&dollar;cmd 00200 allow tcp from any to any 80 out via &dollar;pif setup keep-state

# Allow out secure www function https over TLS SSL
&dollar;cmd 00220 allow tcp from any to any 443 out via &dollar;pif setup keep-state

# Allow out send &amp; get email function
&dollar;cmd 00230 allow tcp from any to any 25 out via &dollar;pif setup keep-state
&dollar;cmd 00231 allow tcp from any to any 110 out via &dollar;pif setup keep-state

# Allow out FBSD (make install &amp; CVSUP) functions
# Basically give user root "GOD" privileges.
&dollar;cmd 00240 allow tcp from me to any out via &dollar;pif setup keep-state uid root

# Allow out ping
&dollar;cmd 00250 allow icmp from any to any out via &dollar;pif keep-state

# Allow out Time
&dollar;cmd 00260 allow tcp from any to any 37 out via &dollar;pif setup keep-state

# Allow out nntp news (i.e., news groups)
&dollar;cmd 00270 allow tcp from any to any 119 out via &dollar;pif setup keep-state

# Allow out secure FTP, Telnet, and SCP
# This function is using SSH (secure shell)
&dollar;cmd 00280 allow tcp from any to any 22 out via &dollar;pif setup keep-state

# Allow out whois
&dollar;cmd 00290 allow tcp from any to any 43 out via &dollar;pif setup keep-state

# deny and log everything else that.s trying to get out.
# This rule enforces the block all by default logic.
&dollar;cmd 00299 deny log all from any to any out via &dollar;pif

#################################################################
# Interface facing Public Internet (Inbound Section)
# Check packets originating from the public Internet
# destined for this gateway server or the private network.
#################################################################

# Deny all inbound traffic from non-routable reserved address spaces
&dollar;cmd 00300 deny all from 192.168.0.0/16 to any in via &dollar;pif  #RFC 1918 private IP
&dollar;cmd 00301 deny all from 172.16.0.0/12 to any in via &dollar;pif     #RFC 1918 private IP
&dollar;cmd 00302 deny all from 10.0.0.0/8 to any in via &dollar;pif          #RFC 1918 private IP
&dollar;cmd 00303 deny all from 127.0.0.0/8 to any in via &dollar;pif        #loopback
&dollar;cmd 00304 deny all from 0.0.0.0/8 to any in via &dollar;pif            #loopback
&dollar;cmd 00305 deny all from 169.254.0.0/16 to any in via &dollar;pif   #DHCP auto-config
&dollar;cmd 00306 deny all from 192.0.2.0/24 to any in via &dollar;pif       #reserved for docs
&dollar;cmd 00307 deny all from 204.152.64.0/23 to any in via &dollar;pif  #Sun cluster interconnect
&dollar;cmd 00308 deny all from 224.0.0.0/3 to any in via &dollar;pif         #Class D &amp; E multicast

# Deny public pings
&dollar;cmd 00310 deny icmp from any to any in via &dollar;pif

# Deny ident
&dollar;cmd 00315 deny tcp from any to any 113 in via &dollar;pif

# Deny all Netbios service. 137=name, 138=datagram, 139=session
# Netbios is MS/Windows sharing services.
# Block MS/Windows hosts2 name server requests 81
&dollar;cmd 00320 deny tcp from any to any 137 in via &dollar;pif
&dollar;cmd 00321 deny tcp from any to any 138 in via &dollar;pif
&dollar;cmd 00322 deny tcp from any to any 139 in via &dollar;pif
&dollar;cmd 00323 deny tcp from any to any 81 in via &dollar;pif

# Deny any late arriving packets
&dollar;cmd 00330 deny all from any to any frag in via &dollar;pif

# Deny ACK packets that did not match the dynamic rule table
&dollar;cmd 00332 deny tcp from any to any established in via &dollar;pif

# Allow traffic in from ISP's DHCP server. This rule must contain
# the IP address of your ISP.s DHCP server as it.s the only
# authorized source to send this packet type.
# Only necessary for cable or DSL configurations.
# This rule is not needed for .user ppp. type connection to
# the public Internet. This is the same IP address you captured
# and used in the outbound section.
#&dollar;cmd 00360 allow udp from any to x.x.x.x 67 in via &dollar;pif keep-state

# Allow in standard www function because I have apache server
&dollar;cmd 00400 allow tcp from any to me 80 in via &dollar;pif setup limit src-addr 2

# Allow in secure FTP, Telnet, and SCP from public Internet
&dollar;cmd 00410 allow tcp from any to me 22 in via &dollar;pif setup limit src-addr 2

# Allow in non-secure Telnet session from public Internet
# labeled non-secure because ID &amp; PW are passed over public
# Internet as clear text.
# Delete this sample group if you do not have telnet server enabled.
&dollar;cmd 00420 allow tcp from any to me 23 in via &dollar;pif setup limit src-addr 2

# Reject &amp; Log all incoming connections from the outside
&dollar;cmd 00499 deny log all from any to any in via &dollar;pif

# Everything else is denied by default
# deny and log all packets that fell through to see what they are
&dollar;cmd 00999 deny log all from any to any
################ End of IPFW rules file ###############################</programlisting>
      </sect3>

      <sect3>
	<title>一个 <acronym>NAT</acronym> 和带状态规则集的例子</title>

	<indexterm>
	  <primary>NAT</primary>

	  <secondary>以及 IPFW</secondary>
	</indexterm>

	<para>要使用 IPFW 的 <acronym>NAT</acronym> 功能, 还需要进行一些额外的配置。
	  除了其他 IPFIREWALL 语句之外,
	  还需要在内核编译配置中加上 <literal>option IPDIVERT</literal> 语句。</para>

	<para>在
	  <filename>/etc/rc.conf</filename> 中, 除了普通的 IPFW 配置之外,
	  还需要加入:</para>

	<programlisting>natd_enable="YES"                   # Enable <acronym>NAT</acronym>D function
natd_interface="rl0"                # interface name of public Internet NIC
natd_flags="-dynamic -m"            # -m = preserve port numbers if possible</programlisting>

	<para>将带状态规则与 <literal>divert natd</literal> 规则 (网络地址转换)
	  会使规则集的编写变得非常复杂。 <literal>check-state</literal> 的位置,
	  以及 <literal>divert natd</literal> 规则将变得非常关键。 这样一来,
	  就不再有简单的顺序处理逻辑流程了。 提供了一种新的动作类型, 称为
	  <literal>skipto</literal>。 要使用 <literal>skipto</literal> 命令,
	  就必须给每一个规则进行编号, 以确定
	  <literal>skipto</literal> 规则号是您希望跳转到的位置。</para>

	<para>下面给出了一些未加注释的例子来说明如何编写这样的规则,
	  用以帮助您理解包处理规则集的处理顺序。</para>

	<para>处理流程从规则文件最上边的第一个规则开始处理,
	  并自顶向下地尝试每一个规则, 直到找到匹配的规则,
	  且数据包从防火墙中放出为止。 请注意规则号 100 101,
	  450, 500, 以及 510 的位置非常重要。
	  这些规则控制发出和接收的包的地址转换过程,
	  这样它们在 keep-state 动态表中的对应项中就能够与内网的
	  LAN IP 地址关联。 另一个需要注意的是, 所有的 allow
	  和 deny 规则都指定了包的方向 (也就是 outbound 或 inbound)
	  以及网络接口。 最后, 请注意所有发出的会话请求都会请求
	  <literal>skipto rule 500</literal> 以完成网络地址转换。</para>

	<para>下面以 LAN 用户使用 web 浏览器访问一个 web 页面为例。
	  Web 页面使用 80 来完成通讯。 当包进入防火墙时,
	  规则 100 并不匹配, 因为它是发出而不是收到的包。
	  它能够通过规则 101, 因为这是第一个包,
	  因而它还没有进入动态状态保持表。
	  包最终到达规则 125, 并匹配该规则。
	  最终, 它会通过接入 Internet 公网的网卡发出。
	  这之前, 包的源地址仍然是内网 IP 地址。
	  一旦匹配这个规则, 就会触发两个动作。
	  <literal>keep-state</literal> 选项会把这个规则发到 keep-state 动态规则表中,
	  并执行所指定的动作。 动作是发到规则表中的信息的一部分。
	  在这个例子中, 这个动作是 <literal>skipto rule
	  500</literal>。 规则 500 <acronym>NAT</acronym> 包的 IP 地址,
	  并将其发出。 请务必牢记, 这一步非常重要。
	  接下来, 数据包将到达目的地, 之后返回并从规则集的第一条规则开始处理。
	  这一次, 它将与规则 100 匹配, 其目的 IP 地址将被映射回对应的内网
	  LAN IP 地址。 其后, 它会被
	  <literal>check-state</literal> 规则处理, 进而在暨存会话表中找到对应项,
	  并发到 LAN。 数据包接下来发到了内网 LAN PC 上,
	  而后者则会发送从远程服务器请求下一段数据的新数据包。
	  这个包会再次由 <literal>check-state</literal> 规则检查, 并找到发出的表项,
	  并执行其关联的动作, 即 <literal>skipto 500</literal>。 包跳转到规则 500 并被
	  <acronym>NAT</acronym> 后发出。</para>

	<para>在接收一侧, 已经存在的会话的数据包会被 <literal>check-state</literal>
	  规则自动地处理, 并转到 <literal>divert nat</literal> 规则。 我们需要解决的问题是,
	  阻止所有的坏数据包, 而只允许授权的服务。
	  例如在防火墙上运行了 Apache 服务, 而我们希望人们在访问 Internet
	  公网的同时, 也能够访问本地的 web 站点。
	  新的接入开始请求包将匹配规则 100, 而 IP
	  地址则为防火墙所在的服务器而映射到了 LAN
	  IP。 此后, 包会匹配所有我们希望检查的那些令人生厌的东西,
	  并最终匹配规则 425。 一旦发生匹配, 会发生两件事。
	  数据包会被发到 keep-state 动态表, 但此时,
	  所有来自那个源 IP 的会话请求的数量会被限制为 2。
	  这一做法能够挫败针对指定端口上服务的 DoS 攻击。
	  动作同时指定了 <literal>allow</literal> 包应被发到 LAN 上。 包返回时,
	  <literal>check-state</literal> 规则会识别出包属于某一已经存在的会话交互,
	  并直接把它发到规则 500 做
	  <acronym>NAT</acronym>, 并发到发出接口。</para>

	<para>示范规则集 #1:</para>

	<programlisting>#!/bin/sh
cmd="ipfw -q add"
skip="skipto 500"
pif=rl0
ks="keep-state"
good_tcpo="22,25,37,43,53,80,443,110,119"

ipfw -q -f flush

&dollar;cmd 002 allow all from any to any via xl0  # exclude LAN traffic
&dollar;cmd 003 allow all from any to any via lo0  # exclude loopback traffic

&dollar;cmd 100 divert natd ip from any to any in via &dollar;pif
&dollar;cmd 101 check-state

# Authorized outbound packets
&dollar;cmd 120 &dollar;skip udp from any to xx.168.240.2 53 out via &dollar;pif &dollar;ks
&dollar;cmd 121 &dollar;skip udp from any to xx.168.240.5 53 out via &dollar;pif &dollar;ks
&dollar;cmd 125 &dollar;skip tcp from any to any &dollar;good_tcpo out via &dollar;pif setup &dollar;ks
&dollar;cmd 130 &dollar;skip icmp from any to any out via &dollar;pif &dollar;ks
&dollar;cmd 135 &dollar;skip udp from any to any 123 out via &dollar;pif &dollar;ks


# Deny all inbound traffic from non-routable reserved address spaces
&dollar;cmd 300 deny all from 192.168.0.0/16  to any in via &dollar;pif  #RFC 1918 private IP
&dollar;cmd 301 deny all from 172.16.0.0/12   to any in via &dollar;pif  #RFC 1918 private IP
&dollar;cmd 302 deny all from 10.0.0.0/8      to any in via &dollar;pif  #RFC 1918 private IP
&dollar;cmd 303 deny all from 127.0.0.0/8     to any in via &dollar;pif  #loopback
&dollar;cmd 304 deny all from 0.0.0.0/8       to any in via &dollar;pif  #loopback
&dollar;cmd 305 deny all from 169.254.0.0/16  to any in via &dollar;pif  #DHCP auto-config
&dollar;cmd 306 deny all from 192.0.2.0/24    to any in via &dollar;pif  #reserved for docs
&dollar;cmd 307 deny all from 204.152.64.0/23 to any in via &dollar;pif  #Sun cluster
&dollar;cmd 308 deny all from 224.0.0.0/3     to any in via &dollar;pif  #Class D &amp; E multicast

# Authorized inbound packets
&dollar;cmd 400 allow udp from xx.70.207.54 to any 68 in &dollar;ks
&dollar;cmd 420 allow tcp from any to me 80 in via &dollar;pif setup limit src-addr 1


&dollar;cmd 450 deny log ip from any to any

# This is skipto location for outbound stateful rules
&dollar;cmd 500 divert natd ip from any to any out via &dollar;pif
&dollar;cmd 510 allow ip from any to any

######################## end of rules  ##################</programlisting>

	<para>下面的这个规则集基本上和上面一样,
	  但使用了易于读懂的编写方式, 并给出了相当多的注解,
	  以帮助经验较少的 IPFW 规则编写者更好地理解这些规则到底在做什么。</para>

	<para>示范规则集 #2:</para>

	<programlisting>#!/bin/sh
################ Start of IPFW rules file ###############################
# Flush out the list before we begin.
ipfw -q -f flush

# Set rules command prefix
cmd="ipfw -q add"
skip="skipto 800"
pif="rl0"     # public interface name of NIC
              # facing the public Internet

#################################################################
# No restrictions on Inside LAN Interface for private network
# Change xl0 to your LAN NIC interface name
#################################################################
&dollar;cmd 005 allow all from any to any via xl0

#################################################################
# No restrictions on Loopback Interface
#################################################################
&dollar;cmd 010 allow all from any to any via lo0

#################################################################
# check if packet is inbound and nat address if it is
#################################################################
&dollar;cmd 014 divert natd ip from any to any in via &dollar;pif

#################################################################
# Allow the packet through if it has previous been added to the
# the "dynamic" rules table by a allow keep-state statement.
#################################################################
&dollar;cmd 015 check-state

#################################################################
# Interface facing Public Internet (Outbound Section)
# Check session start requests originating from behind the
# firewall on the private network or from this gateway server
# destined for the public Internet.
#################################################################

# Allow out access to my ISP's Domain name server.
# x.x.x.x must be the IP address of your ISP's DNS
# Dup these lines if your ISP has more than one DNS server
# Get the IP addresses from /etc/resolv.conf file
&dollar;cmd 020 &dollar;skip tcp from any to x.x.x.x 53 out via &dollar;pif setup keep-state


# Allow out access to my ISP's DHCP server for cable/DSL configurations.
&dollar;cmd 030 &dollar;skip udp from any to x.x.x.x 67 out via &dollar;pif keep-state

# Allow out non-secure standard www function
&dollar;cmd 040 &dollar;skip tcp from any to any 80 out via &dollar;pif setup keep-state

# Allow out secure www function https over TLS SSL
&dollar;cmd 050 &dollar;skip tcp from any to any 443 out via &dollar;pif setup keep-state

# Allow out send &amp; get email function
&dollar;cmd 060 &dollar;skip tcp from any to any 25 out via &dollar;pif setup keep-state
&dollar;cmd 061 &dollar;skip tcp from any to any 110 out via &dollar;pif setup keep-state

# Allow out FreeBSD (make install &amp; CVSUP) functions
# Basically give user root "GOD" privileges.
&dollar;cmd 070 &dollar;skip tcp from me to any out via &dollar;pif setup keep-state uid root

# Allow out ping
&dollar;cmd 080 &dollar;skip icmp from any to any out via &dollar;pif keep-state

# Allow out Time
&dollar;cmd 090 &dollar;skip tcp from any to any 37 out via &dollar;pif setup keep-state

# Allow out nntp news (i.e., news groups)
&dollar;cmd 100 &dollar;skip tcp from any to any 119 out via &dollar;pif setup keep-state

# Allow out secure FTP, Telnet, and SCP
# This function is using SSH (secure shell)
&dollar;cmd 110 &dollar;skip tcp from any to any 22 out via &dollar;pif setup keep-state

# Allow out whois
&dollar;cmd 120 &dollar;skip tcp from any to any 43 out via &dollar;pif setup keep-state

# Allow ntp time server
&dollar;cmd 130 &dollar;skip udp from any to any 123 out via &dollar;pif keep-state

#################################################################
# Interface facing Public Internet (Inbound Section)
# Check packets originating from the public Internet
# destined for this gateway server or the private network.
#################################################################

# Deny all inbound traffic from non-routable reserved address spaces
&dollar;cmd 300 deny all from 192.168.0.0/16  to any in via &dollar;pif  #RFC 1918 private IP
&dollar;cmd 301 deny all from 172.16.0.0/12   to any in via &dollar;pif  #RFC 1918 private IP
&dollar;cmd 302 deny all from 10.0.0.0/8      to any in via &dollar;pif  #RFC 1918 private IP
&dollar;cmd 303 deny all from 127.0.0.0/8     to any in via &dollar;pif  #loopback
&dollar;cmd 304 deny all from 0.0.0.0/8       to any in via &dollar;pif  #loopback
&dollar;cmd 305 deny all from 169.254.0.0/16  to any in via &dollar;pif  #DHCP auto-config
&dollar;cmd 306 deny all from 192.0.2.0/24    to any in via &dollar;pif  #reserved for docs
&dollar;cmd 307 deny all from 204.152.64.0/23 to any in via &dollar;pif  #Sun cluster
&dollar;cmd 308 deny all from 224.0.0.0/3     to any in via &dollar;pif  #Class D &amp; E multicast

# Deny ident
&dollar;cmd 315 deny tcp from any to any 113 in via &dollar;pif

# Deny all Netbios service. 137=name, 138=datagram, 139=session
# Netbios is MS/Windows sharing services.
# Block MS/Windows hosts2 name server requests 81
&dollar;cmd 320 deny tcp from any to any 137 in via &dollar;pif
&dollar;cmd 321 deny tcp from any to any 138 in via &dollar;pif
&dollar;cmd 322 deny tcp from any to any 139 in via &dollar;pif
&dollar;cmd 323 deny tcp from any to any 81  in via &dollar;pif

# Deny any late arriving packets
&dollar;cmd 330 deny all from any to any frag in via &dollar;pif

# Deny ACK packets that did not match the dynamic rule table
&dollar;cmd 332 deny tcp from any to any established in via &dollar;pif

# Allow traffic in from ISP's DHCP server. This rule must contain
# the IP address of your ISP's DHCP server as it's the only
# authorized source to send this packet type.
# Only necessary for cable or DSL configurations.
# This rule is not needed for 'user ppp' type connection to
# the public Internet. This is the same IP address you captured
# and used in the outbound section.
&dollar;cmd 360 allow udp from x.x.x.x to any 68 in via &dollar;pif keep-state

# Allow in standard www function because I have Apache server
&dollar;cmd 370 allow tcp from any to me 80 in via &dollar;pif setup limit src-addr 2

# Allow in secure FTP, Telnet, and SCP from public Internet
&dollar;cmd 380 allow tcp from any to me 22 in via &dollar;pif setup limit src-addr 2

# Allow in non-secure Telnet session from public Internet
# labeled non-secure because ID &amp; PW are passed over public
# Internet as clear text.
# Delete this sample group if you do not have telnet server enabled.
&dollar;cmd 390 allow tcp from any to me 23 in via &dollar;pif setup limit src-addr 2

# Reject &amp; Log all unauthorized incoming connections from the public Internet
&dollar;cmd 400 deny log all from any to any in via &dollar;pif

# Reject &amp; Log all unauthorized out going connections to the public Internet
&dollar;cmd 450 deny log all from any to any out via &dollar;pif

# This is skipto location for outbound stateful rules
&dollar;cmd 800 divert natd ip from any to any out via &dollar;pif
&dollar;cmd 801 allow ip from any to any

# Everything else is denied by default
# deny and log all packets that fell through to see what they are
&dollar;cmd 999 deny log all from any to any
################ End of IPFW rules file ###############################</programlisting>
      </sect3>
    </sect2>
  </sect1>
</chapter>