1FERM(1) FIREWALL RULES MADE EASY FERM(1)
2
3
4
6 ferm - a firewall rule parser for linux
7
9 ferm options inputfile
10
12 ferm is a frontend for iptables. It reads the rules from a structured
13 configuration file and calls iptables(8) to insert them into the
14 running kernel.
15
16 ferm's goal is to make firewall rules easy to write and easy to read.
17 It tries to reduce the tedious task of writing down rules, thus
18 enabling the firewall administrator to spend more time on developing
19 good rules than the proper implementation of the rule.
20
21 To achieve this, ferm uses a simple but powerful configuration
22 language, which allows variables, functions, arrays, blocks. It also
23 allows you to include other files, allowing you to create libraries of
24 commonly used structures and functions.
25
26 ferm, pronounced "firm", stands for "For Easy Rule Making".
27
29 This manual page does not indend to teach you how firewalling works and
30 how to write good rules. There is already enough documentation on this
31 topic.
32
34 Let's start with a simple example:
35
36 chain INPUT {
37 proto tcp ACCEPT;
38 }
39
40 This will add a rule to the predefined input chain, matching and
41 accepting all tcp packets. Ok, let's make it more complicated:
42
43 chain (INPUT OUTPUT) {
44 proto (udp tcp) ACCEPT;
45 }
46
47 This will insert 4 rules, namely 2 in chain input, and 2 in chain
48 output, matching and accepting both udp and tcp packets. Normally you
49 would type this:
50
51 iptables -A INPUT -p tcp -j ACCEPT
52 iptables -A OUTPUT -p tcp -j ACCEPT
53 iptables -A INPUT -p udp -j ACCEPT
54 iptables -A OUTPUT -p udp -j ACCEPT
55
56 Note how much less typing we need to do? :-)
57
58 Basically, this is all there is to it, although you can make it quite
59 more complex. Something to look at:
60
61 chain INPUT {
62 policy ACCEPT;
63 daddr 10.0.0.0/8 proto tcp dport ! ftp jump mychain sport :1023 TOS 4 settos 8 mark 2;
64 daddr 10.0.0.0/8 proto tcp dport ftp REJECT;
65 }
66
67 My point here is, that *you* need to make nice rules, keep them
68 readable to you and others, and not make it into a mess.
69
70 It would aid the reader if the resulting firewall rules were placed
71 here for reference. Also, you could include the nested version with
72 better readability.
73
74 Try using comments to show what you are doing:
75
76 # this line enables transparent http-proxying for the internal network:
77 proto tcp if eth0 daddr ! 192.168.0.0/255.255.255.0
78 dport http REDIRECT to-ports 3128;
79
80 You will be thankful for it later!
81
82 chain INPUT {
83 policy ACCEPT;
84 interface (eth0 ppp0) {
85 # deny access to notorius hackers, return here if no match
86 # was found to resume normal firewalling
87 jump badguys;
88
89 protocol tcp jump fw_tcp;
90 protocol udp jump fw_udp;
91 }
92 }
93
94 The more you nest, the better it looks. Make sure the order you specify
95 is correct, you would not want to do this:
96
97 chain FORWARD {
98 proto ! udp DROP;
99 proto tcp dport ftp ACCEPT;
100 }
101
102 because the second rule will never match. Best way is to specify first
103 everyting that is allowed, and then deny everything else. Look at the
104 examples for more good snapshots. Most people do something like this:
105
106 proto tcp {
107 dport (
108 ssh http ftp
109 ) ACCEPT;
110 dport 1024:65535 ! syn ACCEPT;
111 DROP;
112 }
113
115 The structure of a proper firewall file looks like simplified C-code.
116 Only a few syntactic characters are used in ferm- configuration files.
117 Besides these special caracters, ferm uses 'keys' and 'values', think
118 of them as options and parameters, or as variables and values,
119 whatever.
120
121 With these words, you define the characteristics of your firewall.
122 Every firewall consists of two things: First, look if network traffic
123 matches certain conditions, and second, what to do with that traffic.
124
125 You may specify conditions that are valid for the kernel interface
126 program you are using, probably iptables(8). For instance, in iptables,
127 when you are trying to match tcp packets, you would say:
128
129 iptables --protocol tcp
130
131 In ferm, this will become:
132
133 protocol tcp;
134
135 Just typing this in ferm doesn't do anything, you need to tell ferm
136 (actually, you need to tell iptables(8) and the kernel) what to do with
137 any traffic that matches this condition:
138
139 iptables --protocol tcp -j ACCEPT
140
141 Or, translated to ferm:
142
143 protocol tcp ACCEPT;
144
145 The ; character is at the end of every ferm rule. Ferm ignores line
146 breaks, meaning the above example is identical to the following:
147
148 protocol tcp
149 ACCEPT;
150
151 Here's a list of the special characters:
152
153 ; This character finalizes a rule.
154
155 Separated by semicolons, you may write multiple rules in one
156 line, although this decreases readability:
157
158 protocol tcp ACCEPT; protocol udp DROP;
159
160 {} The nesting symbol defines a 'block' of rules.
161
162 The curly brackets contain any number of nested rules. All
163 matches before the block are carried forward to these.
164
165 The closing curly bracket finalizes the rule set. You should
166 not write a ';' after that, because that would be an empty
167 rule.
168
169 Example:
170
171 chain INPUT proto icmp {
172 icmp-type echo-request ACCEPT;
173 DROP;
174 }
175
176 This block shows two rules inside a block, which will both be
177 merged with anything in front of it, so you will get two rules:
178
179 iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
180 iptables -A INPUT -p icmp -j DROP
181
182 There can be multiple nesting levels:
183
184 chain INPUT {
185 proto icmp {
186 icmp-type echo-request ACCEPT;
187 DROP;
188 }
189 daddr 172.16.0.0/12 REJECT;
190 }
191
192 Note that the 'REJECT' rule is not affected by 'proto icmp',
193 although there is no ';' after the closing curly brace.
194 Translated to iptables:
195
196 iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
197 iptables -A INPUT -p icmp -j DROP
198 iptables -A INPUT -d 172.16.0.0/12 -j REJECT
199
200 $ Variable expansion. Replaces '$FOO' by the value of the
201 variable. See the section VARIABLES for details.
202
203 & Function call. See the section FUNCTIONS for details.
204
205 () The array symbol. Using the parentheses, you can define a
206 'list' of values that should be applied for the key to the left
207 of it.
208
209 Example:
210
211 protocol ( tcp udp icmp )
212
213 this will result in three rules:
214
215 ... -p tcp ...
216 ... -p udp ...
217 ... -p icmp ...
218
219 Only values can be 'listed', so you cannot do something like
220 this:
221
222 proto tcp ( ACCEPT LOG );
223
224 but you can do this:
225
226 chain (INPUT OUTPUT FORWARD) proto (icmp udp tcp) DROP;
227
228 (which will result in nine rules!)
229
230 Values are separated by spaces. The array symbol is both left-
231 and right-associative, in contrast with the nesting block,
232 which is left-associative only.
233
234 " # " The comment symbol. Anything that follows this symbol up to the
235 end of line is ignored.
236
237 "`command`"
238 Execute the command in a shell, and insert the process output.
239 See the section backticks for details.
240
241 'string'
242 Quote a string which may contain whitespaces, the dollar sign
243 etc.
244
245 LOG log-prefix ' hey, this is my log prefix!';
246
247 "string"
248 Quote a string (see above), but variable references with a
249 dollar sign are evaluated:
250
251 DNAT to "$myhost:$myport";
252
253 Keywords
254 In the previous section, we already introduced some basic keywords like
255 "chain", "protocol" and "ACCEPT". Let's explore their nature.
256
257 There are three kinds of keywords:
258
259 · location keywords define where a rule will be created. Example:
260 "table", "chain".
261
262 · match keywords perform a test on all passing packets. The
263 current rule is without effect if one (or more) of the matches
264 does not pass. Example: "proto", "daddr".
265
266 Most matches are followed by a parameter: "proto tcp", "daddr
267 172.16.0.0/12".
268
269 · target keywords state what to do with a packet. Example:
270 "ACCEPT", "REJECT", "jump".
271
272 Some targets define more keywords to specify details: "REJECT
273 reject-with icmp-net-unreachable".
274
275 Every rule consists of a location and a target, plus any number of
276 matches:
277
278 table filter # location
279 proto tcp dport (http https) # match
280 ACCEPT; # target
281
282 Strictly speaking, there is a fourth kind: ferm keywords (which control
283 ferm's internal behaviour), but they will be explained later.
284
285 Parameters
286 Many keywords take parameters. These can be specified as literals,
287 variable references or lists (arrays):
288
289 proto udp
290 saddr %TRUSTED_HOSTS;
291 proto tcp dport (http https ssh);
292 LOG log-prefix "funky wardriver alert: ";
293
294 Some of them can be negated (lists cannot be negated):
295
296 proto !esp;
297 proto udp dport !domain;
298
299 Keywords which take no parameters are negated by a prefixed '!':
300
301 proto tcp !syn;
302
303 Read iptables(8) to see where the ! can be used.
304
306 Location keywords
307 domain [ip|ip6]
308 Set the domain. "ip" is default and means "IPv4" (iptables).
309 "ip6" is for IPv6 support, using "ip6tables".
310
311 table [filter|nat|mangle]
312 Specifies which netfilter table this rule will be inserted to:
313 "filter" (default), "nat" or "mangle".
314
315 chain [chain-name]
316 Specifies the netfilter chain (within the current table) this
317 rule will be inserted to. Common predefined chain names are
318 "INPUT", "OUTPUT", "FORWARD", "PREROUTING", "POSTROUTING",
319 depending on the table. See the netfilter documentation for
320 details.
321
322 If you specify a non-existing chain here, ferm will add the
323 rule to a custom chain with that name.
324
325 policy [ACCEPT|DROP|..]
326 Specifies the default policy for the current chain (built-in
327 only). Can be one of the built-in targets (ACCEPT, DROP,
328 REJECT, ...). A packet that matches no rules in a chain will be
329 treated as specified by the policy.
330
331 To avoid ambiguity, always specify the policies of all
332 predefined chains explicitly.
333
334 @subchain ["CHAIN-NAME"] { ... }
335 Works like the normal block operators (i.e. without the
336 @subchain keyword), except that ferm moves rules within the
337 curly braces into a new custom chain. The name for this chain
338 is chosen automatically by ferm.
339
340 In many cases, this is faster than just a block, because the
341 kernel may skip a huge block of rules when a precondition is
342 false. Imagine the following example:
343
344 table filter chain INPUT {
345 saddr (1.2.3.4 2.3.4.5 3.4.5.6 4.5.6.7 5.6.7.8) {
346 proto tcp dport (http https ssh) ACCEPT;
347 proto udp dport domain ACCEPT;
348 }
349 }
350
351 This generates 20 rules. When a packet arrives which does not
352 pass the saddr match, it nonetheless checks all 20 rules. With
353 @subchain, this check is done once, resulting in faster network
354 filtering and less CPU load:
355
356 table filter chain INPUT {
357 saddr (1.2.3.4 2.3.4.5 3.4.5.6 4.5.6.7 5.6.7.8) @subchain {
358 proto tcp dport (http https ssh) ACCEPT;
359 proto udp dport domain ACCEPT;
360 }
361 }
362
363 Optionally, you may define the name of the sub chain:
364
365 saddr (1.2.3.4 2.3.4.5 3.4.5.6) @subchain "foobar" {
366 proto tcp dport (http https ssh) ACCEPT;
367 proto udp dport domain ACCEPT;
368 }
369
370 The name can either be a quoted string literal, or an expanded
371 ferm expression such as @substr($var,0,20).
372
373 You can achieve the same by explicitly declaring a custom
374 chain, but you may feel that using @subchain requires less
375 typing.
376
377 Basic iptables match keywords
378 interface [interface-name]
379 Define the interface name, your outside network card, like
380 eth0, or dialup like ppp1, or whatever device you want to match
381 for passing packets. It is equivalent to the "-i" switch in
382 iptables(8).
383
384 outerface [interface-name]
385 Same as interface, only for matching the outgoing interface for
386 a packet, as in iptables(8).
387
388 protocol [protocol-name|protocol-number]
389 Currently supported by the kernel are tcp, udp and icmp, or
390 their respective numbers.
391
392 saddr|daddr [address-spec]
393 Matches on packets originating from the specified address
394 (saddr) or targeted at the address (daddr).
395
396 Examples:
397
398 saddr 192.168/8 ACCEPT; # (identical to the next one:)
399 saddr 192.168.0.0/255.255.255.0 ACCEPT;
400 daddr my.domain.com ACCEPT;
401
402 fragment
403 Specify that only fragmented IP packets should be matched.
404 When packets are larger that the maximum packet size your
405 system can handle (called Maximum Transmission Unit or MTU)
406 they will be chopped into bits and sent one by one as single
407 packets. See ifconfig(8) if you want to find the MTU for your
408 system (the default is usually 1500 bytes).
409
410 Fragments are frequently used in DOS attacks, because there is
411 no way of finding out the origin of a fragment packet.
412
413 sport|dport [port-spec]
414 Matches on packets on the specified TCP or UDP port. "sport"
415 matches the source port, and dport matches the destination
416 port.
417
418 This match can be used only after you specified "protocol tcp"
419 or "protocol udp", because only these two protocols actually
420 have ports.
421
422 And some examples of valid ports/ranges:
423
424 dport 80 ACCEPT;
425 dport http ACCEPT;
426 dport ssh:http ACCEPT;
427 dport 0:1023 ACCEPT; # equivalent to :1023
428 dport 1023:65535 ACCEPT;
429
430 syn Specify that the SYN flag in a tcp package should be matched,
431 which are used to build new tcp connections. You can identify
432 incoming connections with this, and decide wether you want to
433 allow it or not. Packets that do not have this flag are
434 probably from an already established connection, so it's
435 considered reasonably safe to let these through.
436
437 module [module-name]
438 Load an iptables module. Most modules provide more match
439 keywords. We'll get to that later.
440
441 Basic target keywords
442 jump [custom-chain-name]
443 Jumps to a custom chain. If no rule in the custom chain
444 matched, netfilter returns to the next rule in the previous
445 chain.
446
447 realgoto [custom-chain-name]
448 Go to a custom chain. Unlike the jump option, RETURN will not
449 continue processing in this chain but instead in the chain that
450 called us via jump.
451
452 The keyword realgoto was chosen during the transition period,
453 because goto (already deprecated) used to be an alias for jump.
454
455 ACCEPT Accepts matching packets.
456
457 DROP Drop matching packets without further notice.
458
459 REJECT Rejects matching packets, i.e. send an ICMP packet to the
460 sender, which is port-unreachable by default. You may specify
461 another ICMP type.
462
463 REJECT; # default to icmp-port-unreachable
464 REJECT reject-with icmp-net-unreachable;
465
466 Type "iptables -j REJECT -h" for details.
467
468 RETURN Finish the current chain and return to the calling chain (if
469 "jump [custom-chain-name]" was used).
470
471 NOP No action at all.
472
474 Netfilter is modular. Modules may provide additional targets and match
475 keywords. The list of netfilter modules is constantly growing, and ferm
476 tries to keep up with supporting them all. This chapter describes
477 modules which are currently supported.
478
479 iptables match modules
480 account Account traffic for all hosts in defined network/netmask. This
481 is one of the match modules which behave like a target, i.e.
482 you will mostly have to use the NOP target.
483
484 mod account aname mynetwork aaddr 192.168.1.0/24 ashort NOP;
485
486 addrtype
487 Check the address type; either source address or destination
488 address.
489
490 mod addrtype src-type BROADCAST;
491 mod addrtype dst-type LOCAL;
492
493 Type "iptables -m addrtype -h" for details.
494
495 ah Checks the SPI header in an AH packet.
496
497 mod ah ahspi 0x101;
498 mod ah ahspi ! 0x200:0x2ff;
499
500 Additional arguments for IPv6:
501
502 mod ah ahlen 32 ACCEPT;
503 mod ah ahlen !32 ACCEPT;
504 mod ah ahres ACCEPT;
505
506 comment Adds a comment of up to 256 characters to a rule, without an
507 effect. Note that unlike ferm comments ('#'), this one will
508 show up in "iptables -L".
509
510 mod comment comment "This is my comment." ACCEPT;
511
512 condition
513 Matches if a value in /proc/net/ipt_condition/NAME is 1 (path
514 is /proc/net/ip6t_condition/NAME for the ip6 domain).
515
516 mod condition condition (abc def) ACCEPT;
517 mod condition condition !foo ACCEPT;
518
519 connbytes
520 Match by how many bytes or packets a connection (or one of the
521 two flows constituting the connection) have tranferred so far,
522 or by average bytes per packet.
523
524 mod connbytes connbytes 65536: connbytes-dir both connbytes-mode bytes ACCEPT;
525 mod connbytes connbytes !1024:2048 connbytes-dir reply connbytes-mode packets ACCEPT;
526
527 Valid values for connbytes-dir: original, reply, both; for
528 connbytes-mode: packets, bytes, avgpkt.
529
530 connlimit
531 Allows you to restrict the number of parallel TCP connections
532 to a server per client IP address (or address block).
533
534 mod connlimit connlimit-above 4 REJECT;
535 mod connlimit connlimit-above !4 ACCEPT;
536 mod connlimit connlimit-above 4 connlimit-mask 24 REJECT;
537
538 connmark
539 Check the mark field associated with the connection, set by the
540 CONNMARK target.
541
542 mod connmark mark 64;
543 mod connmark mark 6/7;
544
545 conntrack
546 Check connection tracking information.
547
548 mod conntrack ctstate (ESTABLISHED RELATED);
549 mod conntrack ctproto tcp;
550 mod conntrack ctorigsrc 192.168.0.2;
551 mod conntrack ctorigdst 1.2.3.0/24;
552 mod conntrack ctreplsrc 2.3.4.5;
553 mod conntrack ctrepldst ! 3.4.5.6;
554 mod conntrack ctstatus ASSURED;
555 mod conntrack ctexpire 60;
556 mod conntrack ctexpire 180:240;
557
558 Type "iptables -m conntrack -h" for details.
559
560 dccp Check DCCP (Datagram Congestion Control Protocol) specific
561 attributes. This module is automatically loaded when you use
562 "protocol dccp".
563
564 proto dccp sport 1234 dport 2345 ACCEPT;
565 proto dccp dccp-types (SYNCACK ACK) ACCEPT;
566 proto dccp dccp-types !REQUEST DROP;
567 proto dccp dccp-option 2 ACCEPT;
568
569 dscp Match the 6 bit DSCP field within the TOS field.
570
571 mod dscp dscp 11;
572 mod dscp dscp-class AF41;
573
574 ecn Match the ECN bits of an IPv4 TCP header.
575
576 mod ecn ecn-tcp-cwr;
577 mod ecn ecn-tcp-ece;
578 mod ecn ecn-ip-ect 2;
579
580 Type "iptables -m ecn -h" for details.
581
582 esp Checks the SPI header in an ESP packet.
583
584 mod esp espspi 0x101;
585 mod esp espspi ! 0x200:0x2ff;
586
587 eui64 "This module matches the EUI-64 part of a stateless
588 autoconfigured IPv6 address. It compares the EUI-64 derived
589 from the source MAC address in Ehternet frame with the lower 64
590 bits of the IPv6 source address. But "Universal/Local" bit is
591 not compared. This module doesn't match other link layer
592 frame, and is only valid in the PREROUTING, INPUT and FORWARD
593 chains."
594
595 mod eui64 ACCEPT;
596
597 fuzzy "This module matches a rate limit based on a fuzzy logic
598 controller [FLC]."
599
600 mod fuzzy lower-limit 10 upper-limit 20 ACCEPT;
601
602 hbh Matches the Hop-by-Hop Options header (ip6).
603
604 mod hbh hbh-len 8 ACCEPT;
605 mod hbh hbh-len !8 ACCEPT;
606 mod hbh hbh-opts (1:4 2:8) ACCEPT;
607
608 hl Matches the Hop Limit field (ip6).
609
610 mod hl hl-eq (8 10) ACCEPT;
611 mod hl hl-eq !5 ACCEPT;
612 mod hl hl-gt 15 ACCEPT;
613 mod hl hl-lt 2 ACCEPT;
614
615 helper Checks which conntrack helper module tracks this connection.
616 The port may be specified with "-portnr".
617
618 mod helper helper irc ACCEPT;
619 mod helper helper ftp-21 ACCEPT;
620
621 icmp Check ICMP specific attributes. This module is automatically
622 loaded when you use "protocol icmp".
623
624 proto icmp icmp-type echo-request ACCEPT;
625
626 This option can also be used in be ip6 domain, although this is
627 called icmpv6 in ip6tables.
628
629 Use "iptables -p icmp "-h"" to obtain a list of valid ICMP
630 types.
631
632 iprange Match a range of IPv4 addresses.
633
634 mod iprange src-range 192.168.2.0-192.168.3.255;
635 mod iprange dst-range ! 192.168.6.0-192.168.6.255;
636
637 ipv4options
638 Match on IPv4 header options like source routing, record route,
639 timestamp and router-alert.
640
641 mod ipv4options ssrr ACCEPT;
642 mod ipv4options lsrr ACCEPT;
643 mod ipv4options no-srr ACCEPT;
644 mod ipv4options !rr ACCEPT;
645 mod ipv4options !ts ACCEPT;
646 mod ipv4options !ra ACCEPT;
647 mod ipv4options !any-opt ACCEPT;
648
649 ipv6header
650 Matches the IPv6 extension header (ip6).
651
652 mod ipv6header header !(hop frag) ACCEPT;
653 mod ipv6header header (auth dst) ACCEPT;
654
655 hashlimit
656 Similar to 'mod limit', but adds the ability to add per-
657 destination or per-port limits managed in a hash table.
658
659 mod hashlimit hashlimit 10/minute hashlimit-burst 30/minute
660 hashlimit-mode dstip hashlimit-name foobar ACCEPT;
661
662 Possible values for hashlimit-mode: dstip dstport srcip
663 srcport.
664
665 There are more possible settings, type "iptables -m hashlimit
666 -h" for documentation.
667
668 length Check the package length.
669
670 mod length length 128; # exactly 128 bytes
671 mod length length 512:768; # range
672 mod length length ! 256; # negated
673
674 limit Limits the packet rate.
675
676 mod limit limit 1/second;
677 mod limit limit 15/minute limit-burst 10;
678
679 Type "iptables -m limit -h" for details.
680
681 mac Match the source MAC address.
682
683 mod mac mac-source 01:23:45:67:89;
684
685 mark Matches packets based on their netfilter mark field. This may
686 be a 32 bit integer between 0 and 4294967295.
687
688 mod mark mark 42;
689
690 mh Matches the mobility header (domain ip6).
691
692 proto mh mh-type binding-update ACCEPT;
693
694 multiport
695 Match a set of source or destination ports (UDP and TCP only).
696
697 mod multiport source-ports (https ftp);
698 mod multiport destination-ports (mysql domain);
699
700 This rule has a big advantage over "dport" and "sport": it
701 generates only one rule for up to 15 ports instead of one rule
702 for every port.
703
704 nth Match every 'n'th packet.
705
706 mod nth every 3;
707 mod nth counter 5 every 2;
708 mod nth start 2 every 3;
709 mod nth start 5 packet 2 every 6;
710
711 Type "iptables -m nth -h" for details.
712
713 owner Check information about the packet creator, namely user id,
714 group id, process id, session id and command name.
715
716 mod owner uid-owner 0;
717 mod owner gid-owner 1000;
718 mod owner pid-owner 5432;
719 mod owner sid-owner 6543;
720 mod owner cmd-owner "sendmail";
721
722 ("cmd-owner", "pid-owner" and "sid-owner" require special
723 kernel patches not included in the vanilla Linux kernel)
724
725 physdev Matches the physical device on which a packet entered or is
726 about to leave the machine. This is useful for bridged
727 interfaces.
728
729 mod physdev physdev-in ppp1;
730 mod physdev physdev-out eth2;
731 mod physdev physdev-is-in;
732 mod physdev physdev-is-out;
733 mod physdev physdev-is-bridged;
734
735 pkttype Check the link-layer packet type.
736
737 mod pkttype pkt-type unicast;
738 mod pkttype pkt-type broadcase;
739 mod pkttype pkt-type multicast;
740
741 policy Matches IPsec policy being applied to this packet.
742
743 mod policy dir out pol ipsec ACCEPT;
744 mod policy strict reqid 23 spi 0x10 proto ah ACCEPT;
745 mod policy mode tunnel tunnel-src 192.168.1.2 ACCEPT;
746 mod policy mode tunnel tunnel-dst 192.168.2.1 ACCEPT;
747 mod policy strict next reqid 24 spi 0x11 ACCEPT;
748
749 Note that the keyword proto is also used as a shorthand version
750 of protocol (built-in match module). You can fix this conflict
751 by always using the long keyword protocol.
752
753 psd Detect TCP/UDP port scans.
754
755 mod psd psd-weight-threshold 21 psd-delay-threshold 300
756 psd-lo-ports-weight 3 psd-hi-ports-weight 1 DROP;
757
758 quota Implements network quotas by decrementing a byte counter with
759 each packet.
760
761 mod quota quota 65536 ACCEPT;
762
763 random Match a random percentage of all packets.
764
765 mod random average 70;
766
767 realm Match the routing realm. Useful in environments using BGP.
768
769 mod realm realm 3;
770
771 recent Temporarily mark source IP addresses.
772
773 mod recent set;
774 mod recent rcheck seconds 60;
775 mod recent set rsource name "badguy";
776 mod recent set rdest;
777 mod recent rcheck rsource name "badguy" seconds 60;
778 mod recent update seconds 120 hitcount 3 rttl;
779
780 This netfilter module has a design flaw: although it is
781 implemented as a match module, it has target-like behaviour
782 when using the "set" keyword.
783
784 <http://snowman.net/projects/ipt_recent/>
785
786 rt Match the IPv6 routing header (ip6 only).
787
788 mod rt rt-type 2 rt-len 20 ACCEPT;
789 mod rt rt-type !2 rt-len !20 ACCEPT;
790 mod rt rt-segsleft 2:3 ACCEPT;
791 mod rt rt-segsleft !4:5 ACCEPT;
792 mod rt rt-0-res rt-0-addrs (::1 ::2) rt-0-not-strict ACCEPT;
793
794 sctp Check SCTP (Stream Control Transmission Protocol) specific
795 attributes. This module is automatically loaded when you use
796 "protocol sctp".
797
798 proto sctp sport 1234 dport 2345 ACCEPT;
799 proto sctp chunk-types only DATA:Be ACCEPT;
800 proto sctp chunk-types any (INIT INIT_ACK) ACCEPT;
801 proto sctp chunk-types !all (HEARTBEAT) ACCEPT;
802
803 Use "iptables -p sctp "-h"" to obtain a list of valid chunk
804 types.
805
806 set Checks the source or destination IP/Port/MAC against a set.
807
808 mod set set badguys src DROP;
809
810 See <http://ipset.netfilter.org/> for more information.
811
812 state Checks the connection tracking state.
813
814 mod state state INVALID DROP;
815 mod state state (ESTABLISHED RELATED) ACCEPT;
816
817 Type "iptables -m state -h" for details.
818
819 statistic
820 Successor of nth and random, currently undocumented in the
821 iptables(8) man page.
822
823 mod statistic mode random probability 0.8 ACCEPT;
824 mod statistic mode nth every 5 packet 0 DROP;
825
826 string Matches a string.
827
828 mod string string "foo bar" ACCEPT;
829 mod string algo kmp from 64 to 128 hex-string "deadbeef" ACCEPT;
830
831 tcp Checks TCP specific attributes. This module is automatically
832 loaded when you use "protocol tcp".
833
834 proto tcp sport 1234;
835 proto tcp dport 2345;
836 proto tcp tcp-flags (SYN ACK) SYN;
837 proto tcp tcp-flags ! (SYN ACK) SYN;
838 proto tcp tcp-flags ALL (RST ACK);
839 proto tcp syn;
840 proto tcp tcp-option 2;
841 proto tcp mss 512;
842
843 Type "iptables -p tcp -h" for details.
844
845 tcpmss Check the TCP MSS field of a SYN or SYN/ACK packet.
846
847 mod tcpmss mss 123 ACCEPT;
848 mod tcpmss mss 234:567 ACCEPT;
849
850 time Check if the time a packet arrives is in given range.
851
852 mod time timestart 12:00;
853 mod time timestop 13:30;
854 mod time days (Mon Wed Fri);
855 mod time datestart 2005:01:01;
856 mod time datestart 2005:01:01:23:59:59;
857 mod time datestop 2005:04:01;
858 mod time monthday (30 31);
859 mod time weekdays (Wed Thu);
860 mod time timestart 12:00 utc;
861 mod time timestart 12:00 localtz;
862
863 Type "iptables -m time -h" for details.
864
865 tos Matches a packet on the specified TOS-value.
866
867 mod tos tos Minimize-Cost ACCEPT;
868 mod tos tos !Normal-Service ACCEPT;
869
870 Type "iptables -m tos -h" for details.
871
872 ttl Matches the ttl (time to live) field in the IP header.
873
874 mod ttl ttl-eq 12; # ttl equals
875 mod ttl ttl-gt 10; # ttl greater than
876 mod ttl ttl-lt 16; # ttl less than
877
878 u32 Compares raw data from the packet. You can specify more than
879 one filter in a ferm list; these are not expanded into multiple
880 rules.
881
882 mod u32 u32 '6&0xFF=1' ACCEPT;
883 mod u32 u32 ('27&0x8f=7' '31=0x527c4833') DROP;
884
885 unclean Matches packets which seem malformed or unusual. This match has
886 no further parameters.
887
888 iptables target modules
889 The following additional targets are available in ferm, provided that
890 you enabled them in your kernel:
891
892 CLASSIFY
893 Set the CBQ class.
894
895 CLASSIFY set-class 3:50;
896
897 CLUSTERIP
898 Configure a simple cluster of nodes that share a certain IP and
899 MAC address. Connections are statically distributed between
900 the nodes.
901
902 CLUSTERIP new hashmode sourceip clustermac 00:12:34:45:67:89
903 total-nodes 4 local-node 2 hash-init 12345;
904
905 CONNMARK
906 Sets the netfilter mark value associated with a connection.
907
908 CONNMARK set-mark 42;
909 CONNMARK save-mark;
910 CONNMARK restore-mark;
911 CONNMARK save-mark mask 0x7fff;
912 CONNMARK restore-mark mask 0x8000;
913
914 CONNSECMARK
915 This module copies security markings from packets to
916 connections (if unlabeled), and from connections back to
917 packets (also only if unlabeled). Typically used in
918 conjunction with SECMARK, it is only valid in the mangle table.
919
920 CONNSECMARK save;
921 CONNSECMARK restore;
922
923 DNAT to [ip-address|ip-range|ip-port-range]
924 Change the destination address of the packet.
925
926 DNAT to 10.0.0.4;
927 DNAT to 10.0.0.4:80;
928 DNAT to 10.0.0.4:1024-2048;
929 DNAT to 10.0.1.1-10.0.1.20;
930
931 ECN This target allows to selectively work around known ECN
932 blackholes. It can only be used in the mangle table.
933
934 ECN ecn-tcp-remove;
935
936 HL Modify the IPv6 Hop Limit field (ip6/mangle only).
937
938 HL hl-set 5;
939 HL hl-dec 2;
940 HL hl-inc 1;
941
942 IPV4OPTSSTRIP
943 Strip all the IP options from a packet. This module does not
944 take any options.
945
946 IPV4OPTSSTRIP;
947
948 LOG Log all packets that match this rule in the kernel log. Be
949 carefull with log flooding. Note that this is a "non-
950 terminating target", i.e. rule traversal continues at the next
951 rule.
952
953 LOG log-level warning log-prefix "Look at this: ";
954 LOG log-tcp-sequence log-tcp-options;
955 LOG log-ip-options;
956
957 MARK Sets the netfilter mark field for the packet (a 32 bit integer
958 between 0 and 4294967295):
959
960 MARK set-mark 42;
961 MARK set-xmark 7/3;
962 MARK and-mark 31;
963 MARK or-mark 1;
964 MARK xor-mark 12;
965
966 MASQUERADE
967 Masquerades matching packets. Optionally followed by a port or
968 port-range for iptables. Specify as "123", "123-456" or
969 "123:456". The port range parameter specifies what local ports
970 masqueraded connections should originate from.
971
972 MASQUERADE;
973 MASQUERADE to-ports 1234:2345;
974 MASQUERADE to-ports 1234:2345 random;
975
976 MIRROR Experimental demonstration target which inverts the source and
977 destination fields in the IP header.
978
979 MIRROR;
980
981 NETMAP Map a whole network onto another network in the nat table.
982
983 NETMAP to 192.168.2.0/24;
984
985 NOTRACK Disable connection tracking for all packets matching that rule.
986
987 proto tcp dport (135:139 445) NOTRACK;
988
989 NFLOG Log packets over netlink; this is the successor of ULOG.
990
991 NFLOG nflog-group 5 nflog-prefix "Look at this: ";
992 NFLOG nflog-range 256;
993 NFLOG nflog-threshold 10;
994
995 NFQUEUE Userspace queueing, requires nfnetlink_queue kernel support.
996
997 proto tcp dport ftp NFQUEUE queue-num 20;
998
999 QUEUE Userspace queueing, the predecessor to NFQUEUE. All packets go
1000 to queue 0.
1001
1002 proto tcp dport ftp QUEUE;
1003
1004 REDIRECT to-ports [ports]
1005 Transparent proxying: alter the destination IP of the packet to
1006 the machine itself.
1007
1008 proto tcp dport http REDIRECT to-ports 3128;
1009 proto tcp dport http REDIRECT to-ports 3128 random;
1010
1011 SAME Similar to SNAT, but a client is mapped to the same source IP
1012 for all its connections.
1013
1014 SAME to 1.2.3.4-1.2.3.7;
1015 SAME to 1.2.3.8-1.2.3.15 nodst;
1016 SAME to 1.2.3.16-1.2.3.31 random;
1017
1018 SECMARK This is used to set the security mark value associated with the
1019 packet for use by security subsystems such as SELinux. It is
1020 only valid in the mangle table.
1021
1022 SECMARK selctx "system_u:object_r:httpd_packet_t:s0";
1023
1024 SET [add-set|del-set] [setname] [flag(s)]
1025 Add the IP to the specified set. See
1026 <http://ipset.netfilter.org/>
1027
1028 proto icmp icmp-type echo-request SET add-set badguys src;
1029
1030 SNAT to [ip-address|ip-range|ip-port-range]
1031 Change the source address of the packet.
1032
1033 SNAT to 1.2.3.4;
1034 SNAT to 1.2.3.4:20000-30000;
1035 SNAT to 1.2.3.4 random;
1036
1037 TCPMSS Alter the MSS value of TCP SYN packets.
1038
1039 TCPMSS set-mss 1400;
1040 TCPMSS clamp-mss-to-pmtu;
1041
1042 TOS set-tos [value]
1043 Set the tcp package Type Of Service bit to this value. This
1044 will be used by whatever traffic scheduler is willing to,
1045 mostly your own linux-machine, but maybe more. The original
1046 tos-bits are blanked and overwritten by this value.
1047
1048 TOS set-tos Maximize-Throughput;
1049 TOS and-tos 7;
1050 TOS or-tos 1;
1051 TOS xor-tos 4;
1052
1053 Type "iptables -j TOS -h" for details.
1054
1055 TTL Modify the TTL header field.
1056
1057 TTL ttl-set 16;
1058 TTL ttl-dec 1; # decrease by 1
1059 TTL ttl-inc 4; # increase by 4
1060
1061 ULOG Log packets to a userspace program.
1062
1063 ULOG ulog-nlgroup 5 ulog-prefix "Look at this: ";
1064 ULOG ulog-cprange 256;
1065 ULOG ulog-qthreshold 10;
1066
1068 Since version 2.0, ferm supports not only ip and ip6, but also arp (ARP
1069 tables) and eb (ethernet bridging tables). The concepts are similar to
1070 iptables.
1071
1072 arptables keywords
1073 source-ip, destination-ip
1074 Matches the source or destination IPv4 address. Same as saddr
1075 and daddr in the ip domain.
1076
1077 source-mac, destination-mac
1078 Matches the source or destination MAC address.
1079
1080 interface, outerface
1081 Input and output interface.
1082
1083 h-length
1084 Hardware length of the packet.
1085
1086 chain INPUT h-length 64 ACCEPT;
1087
1088 opcode Operation code, for details see the iptables(8).
1089
1090 opcode 9 ACCEPT;
1091
1092 h-type Hardware type.
1093
1094 h-type 1 ACCEPT;
1095
1096 proto-type
1097 Protocol type.
1098
1099 proto-type 0x800 ACCEPT;
1100
1101 Mangling
1102 The keywords mangle-ip-s, mangle-ip-d, mangle-mac-s, mangle-
1103 mac-d, mangle-target may be used for ARP mangling. See
1104 iptables(8) for details.
1105
1106 ebtables keywords
1107 proto Matches the protocol which created the frame, e.g. IPv4 or PPP.
1108 For a list, see /etc/ethertypes.
1109
1110 interface, outerface
1111 Physical input and output interface.
1112
1113 logical-in, logical-out
1114 The logical bridge interface.
1115
1116 saddr, daddr
1117 Matches source or destination MAC address.
1118
1119 Match modules
1120 The following match modules are supported: 802.3, arp, ip,
1121 mark_m, pkttype, stp, vlan, log.
1122
1123 Target extensions
1124 The following target extensions are supported: arpreply, dnat,
1125 mark, redirect, snat.
1126
1127 Please note that there is a conflict between --mark from the
1128 mark_m match module and -j mark. Since both would be
1129 implemented with the ferm keyword mark, we decided to solve
1130 this by writing the target's name in uppercase, like in the
1131 other domains. The following example rewrites mark 1 to 2:
1132
1133 mark 1 MARK 2;
1134
1136 Variables
1137 In complex firewall files, it is helpful to use variables, e.g. to give
1138 a network interface a meaningful name.
1139
1140 To set variables, write:
1141
1142 @def $DEV_INTERNET = eth0;
1143 @def $PORTS = (http ftp);
1144 @def $MORE_PORTS = ($PORTS 8080);
1145
1146 In the real ferm code, variables are used like any other keyword
1147 parameter:
1148
1149 chain INPUT interface $DEV_INTERNET proto tcp dport $MORE_PORTS ACCEPT;
1150
1151 Note that variables can only be used in keyword parameters
1152 ("192.168.1.1", "http"); they cannot contain ferm keywords like "proto"
1153 or "interface".
1154
1155 Variables are only valid in the current block:
1156
1157 @def $DEV_INTERNET = eth1;
1158 chain INPUT {
1159 proto tcp {
1160 @def $DEV_INTERNET = ppp0;
1161 interface $DEV_INTERNET dport http ACCEPT;
1162 }
1163 interface $DEV_INTERNET DROP;
1164 }
1165
1166 will be expanded to:
1167
1168 chain INPUT {
1169 proto tcp {
1170 interface ppp0 dport http ACCEPT;
1171 }
1172 interface eth1 DROP;
1173 }
1174
1175 The "def $DEV_INTERNET = ppp0" is only valid in the "proto tcp" block;
1176 the parent block still knows "set $DEV_INTERNET = eth1".
1177
1178 Include files are special - variables declared in an included file are
1179 still available in the calling block. This is useful when you include a
1180 file which only declares variables.
1181
1182 Automatic variables
1183 Some variables are set internally by ferm. Ferm scripts can use them
1184 just like any other variable.
1185
1186 $FILENAME
1187 The name of the configuration file.
1188
1189 $DIRNAME
1190 The directory of the configuration file.
1191
1192 $DOMAIN The current domain. One of ip, ip6, arp, eb.
1193
1194 $TABLE The current netfilter table.
1195
1196 $CHAIN The current netfilter chain.
1197
1198 Functions
1199 Functions are similar to variables, except that they may have
1200 parameters, and they provide ferm commands, not values.
1201
1202 @def &FOO() = proto (tcp udp) dport domain;
1203 &FOO() ACCEPT;
1204
1205 @def &TCP_TUNNEL($port, $dest) = {
1206 table filter chain FORWARD interface ppp0 proto tcp dport $port daddr $dest outerface eth0 ACCEPT;
1207 table nat chain PREROUTING interface ppp0 proto tcp dport $port daddr 1.2.3.4 DNAT to $dest;
1208 }
1209
1210 &TCP_TUNNEL(http, 192.168.1.33);
1211 &TCP_TUNNEL(ftp, 192.168.1.30);
1212 &TCP_TUNNEL((ssh smtp), 192.168.1.2);
1213
1214 A function call which contains a block (like '{...}') must be the last
1215 command in a ferm rule, i.e. it must be followed by ';'. The '&FOO()'
1216 example does not contain a block, thus you may write 'ACCEPT' after the
1217 call. To circumvent this, you can reorder the keywords:
1218
1219 @def &IPSEC() = { proto (esp ah); proto udp dport 500; }
1220 chain INPUT ACCEPT &IPSEC();
1221
1222 Backticks
1223 With backticks, you may use the output of an external command:
1224
1225 @def $DNSSERVERS = `grep nameserver /etc/resolv.conf | awk '{print $2}'`;
1226 chain INPUT proto tcp saddr $DNSSERVERS ACCEPT;
1227
1228 The command is executed with the shell (/bin/sh), just like backticks
1229 in perl. ferm does not do any variable expansion here.
1230
1231 The output is then tokenized, and saved as a ferm list (array). Lines
1232 beginning with '#' are ignored; the other lines may contain any number
1233 of values, separated by whitespace.
1234
1235 Includes
1236 The @include keyword allows you to include external files:
1237
1238 @include 'vars.ferm';
1239
1240 The file name is relative to the calling file, e.g. when including from
1241 /etc/ferm/ferm.conf, the above statement includes /etc/ferm/vars.ferm.
1242 Variables and functions declared in an included file are still
1243 available in the calling file.
1244
1245 include works within a block:
1246
1247 chain INPUT {
1248 @include 'input.ferm';
1249 }
1250
1251 If you specify a directory (with a trailing '/'), all files in this
1252 directory are included, sorted alphabetically:
1253
1254 @include 'ferm.d/';
1255
1256 With a trailing pipe symbol, ferm executes a program and parses its
1257 output:
1258
1259 @include '/root/generate_ferm_rules.sh $HOSTNAME|'
1260
1261 Conditionals
1262 The keyword @if introduces a conditional expression:
1263
1264 @if $condition DROP;
1265
1266 A value is evaluated true just like in Perl: zero, empty list, empty
1267 string are false, everything else is true. Examples for true values:
1268
1269 (a b); 1; 'foo'; (0 0)
1270
1271 Examples for false values:
1272
1273 (); 0; '0'; ''
1274
1275 There is also @else:
1276
1277 @if $condition DROP; @else REJECT;
1278
1279 Note the semicolon before the @else.
1280
1281 It is possible to use curly braces after either @if or @else:
1282
1283 @if $condition {
1284 MARK set-mark 2;
1285 RETURN;
1286 } @else {
1287 MARK set-mark 3;
1288 }
1289
1290 Since the closing curly brace also finishes the command, there is no
1291 need for semicolon.
1292
1293 There is no @elsif, use @else @if instead.
1294
1295 Example:
1296
1297 @def $have_ipv6 = `test -f /proc/net/ip6_tables_names && echo 1 || echo`;
1298 @if $have_ipv6 {
1299 domain ip6 {
1300 # ....
1301 }
1302 }
1303
1304 Hooks
1305 To run custom commands, you may install hooks:
1306
1307 @hook pre "echo 0 >/proc/sys/net/ipv4/conf/eth0/forwarding";
1308 @hook post "echo 1 >/proc/sys/net/ipv4/conf/eth0/forwarding";
1309 @hook flush "echo 0 >/proc/sys/net/ipv4/conf/eth0/forwarding";
1310
1311 The specified command is executed using the shell. "pre" means run the
1312 command before applying the firewall rules, and "post" means run the
1313 command afterwards. "flush" hooks are run after ferm has flushed the
1314 firewall rules (option --flush). You may install any number of hooks.
1315
1317 There are several built-in functions which you might find useful.
1318
1319 @eq(a,b)
1320 Tests two values for equality. Example:
1321
1322 @if @eq($DOMAIN, ip6) DROP;
1323
1324 @ne(a,b)
1325 Similar to @eq, this tests for non-equality.
1326
1327 @not(x)
1328 Negates a boolean value.
1329
1330 @resolve((hostname1 hostname2 ...), [type])
1331 Usually, host names are resolved by iptables. To let ferm resolve host
1332 names, use the function @resolve:
1333
1334 saddr @resolve(my.host.foo) proto tcp dport ssh ACCEPT;
1335 saddr @resolve((another.host.foo third.host.foo)) proto tcp dport openvpn ACCEPT;
1336 daddr @resolve(ipv6.google.com, AAAA) proto tcp dport http ACCEPT;
1337
1338 Note the double parentheses in the second line: the inner pair for
1339 creating a ferm list, and the outer pair as function parameter
1340 delimiters.
1341
1342 The second parameter is optional, and specifies the DNS record type.
1343 The default is "A".
1344
1345 Be careful with resolved host names in firewall configuration. DNS
1346 requests may block the firewall configuration for a long time, leaving
1347 the machine vulnerable, or they may fail.
1348
1349 @cat(a, b, ...)
1350 Concatenate all parameters into one string.
1351
1352 @substr(expression, offset, length)
1353 Extracts a substring out of expression and returns it. First character
1354 is at offset 0. If OFFSET is negative, starts that far from the end of
1355 the string.
1356
1357 @length(expression)
1358 Returns the length in characters of the value of EXPR.
1359
1361 The ./examples/ directory contains numerous ferm configuration which
1362 can be used to begin a new firewall. This sections contains more
1363 samples, recipes and tricks.
1364
1365 Easy port forwarding
1366 Ferm function make routine tasks quick and easy:
1367
1368 @def &FORWARD_TCP($proto, $port, $dest) = {
1369 table filter chain FORWARD interface $DEV_WORLD outerface $DEV_DMZ daddr $dest proto $proto dport $port ACCEPT;
1370 table nat chain PREROUTING interface $DEV_WORLD daddr $HOST_STATIC proto $proto dport $port DNAT to $dest;
1371 }
1372
1373 &FORWARD_TCP(tcp, http, 192.168.1.2);
1374 &FORWARD_TCP(tcp, smtp, 192.168.1.3);
1375 &FORWARD_TCP((tcp udp), domain, 192.168.1.4);
1376
1377 Remote ferm
1378 If the target machine is not able to run ferm for some reason (maybe an
1379 embedded device without Perl), you can edit the ferm configuration file
1380 on another computer and let ferm generate a shell script there.
1381
1382 Example for OpenWRT:
1383
1384 ferm --remote --shell mywrt/ferm.conf >mywrt/firewall.user
1385 chmod +x mywrt/firewall.user
1386 scp mywrt/firewall.user mywrt.local.net:/etc/
1387 ssh mywrt.local.net /etc/firewall.user
1388
1390 --noexec Do not execute the iptables(8) commands, but skip instead.
1391 This way you can parse your data, use --lines to view the
1392 output.
1393
1394 --flush Clears the firewall rules and sets the policy of all chains
1395 to ACCEPT. ferm needs a configuration file for that to
1396 determine which domains and tables are affected.
1397
1398 --lines Show the firewall lines that were generated from the rules.
1399 They will be shown just before they are executed, so if you
1400 get error messages from iptables(8) etc., you can see which
1401 rule caused the error.
1402
1403 --interactive
1404 Apply the firewall rules and ask the user for confirmation.
1405 Reverts to the previous ruleset if there is no valid user
1406 response within 30 seconds. This is useful for remote
1407 firewall administration: you can test the rules without
1408 fearing to lock yourself out.
1409
1410 --help Show a brief list of available commandline options.
1411
1412 --version Shows the version number of the program.
1413
1414 --fast Enable fast mode: ferm generates an iptables-save(8) file,
1415 and installs it with iptables-restore(8). This is much
1416 faster, because ferm calls iptables(8) once for every rule
1417 by default.
1418
1419 Fast mode is enabled by default since ferm 2.0, deprecating
1420 this option.
1421
1422 --slow Disable fast mode, i.e. run iptables(8) for every rule, and
1423 don't use iptables-restore(8).
1424
1425 --shell Generate a shell script which calls iptables-restore(8) and
1426 prints it. Implies --fast --lines.
1427
1428 --remote Generate rules for a remote machine. Implies --noexec and
1429 --lines. Can be combined with --shell.
1430
1431 --domain {ip|ip6}
1432 Handle only the specified domain. ferm output may be empty
1433 if the domain is not configured in the input file.
1434
1435 --def '$name=value'
1436 Override a variable defined in the configuration file.
1437
1439 iptables(8)
1440
1442 Operating system
1443 Linux 2.4 or newer, with netfilter support and all netfilter modules
1444 used by your firewall script
1445
1446 Software
1447 iptables and perl 5.6
1448
1450 Bugs? What bugs?
1451
1452 If you find a bug, please tell us: ferm@foo-projects.org
1453
1455 Copyright (C) 2001-2010 Max Kellermann <max@foo-projects.org>, Auke Kok
1456 <sofar@foo-projects.org>
1457
1458 This program is free software; you can redistribute it and/or modify it
1459 under the terms of the GNU General Public License as published by the
1460 Free Software Foundation; either version 2 of the License, or (at your
1461 option) any later version.
1462
1463 This program is distributed in the hope that it will be useful, but
1464 WITHOUT ANY WARRANTY; without even the implied warranty of
1465 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1466 General Public License for more details.
1467
1468 You should have received a copy of the GNU General Public License along
1469 with this program; if not, write to the Free Software Foundation, Inc.,
1470 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1471
1473 Max Kellermann <max@foo-projects.org>, Auke Kok
1474 <sofar@foo-projects.org>
1475
1476
1477
1478ferm 2.0.9 2011-02-14 FERM(1)