FERM(1) FIREWALL RULES MADE EASY FERM(1) (NAME) ferm - (SYNOPSIS) ferm _ (DESCRIPTION) ferm (frontend) iptables . iptables(8) . ferm . . ferm . (include) . ferm ( <<>> ) <> ( ) . (CAUTION) . . (INTRODUCTION) : chain INPUT { proto tcp ACCEPT; } input TCP (ACCEPT). : chain (INPUT OUTPUT) { proto (udp tcp) ACCEPT; } input output UDP TCP . : iptables -A INPUT -p tcp -j ACCEPT iptables -A OUTPUT -p tcp -j ACCEPT iptables -A INPUT -p udp -j ACCEPT iptables -A OUTPUT -p udp -j ACCEPT ! :-) . : chain INPUT { policy ACCEPT; daddr 10.0.0.0/8 proto tcp dport ! ftp jump mychain sport :1023 TOS 4 settos 8 mark 2; daddr 10.0.0.0/8 proto tcp dport ftp REJECT; } ** . . . : # this line enables transparent http-proxying for the internal network: proto tcp if eth0 daddr ! 192.168.0.0/255.255.255.0 dport http REDIRECT to-ports 3128; ! chain INPUT { policy ACCEPT; interface (eth0 ppp0) { # deny access to notorious hackers, return here if no match # was found to resume normal firewalling jump badguys; protocol tcp jump fw_tcp; protocol udp jump fw_udp; } } . : chain FORWARD { proto ! udp DROP; proto tcp dport ftp ACCEPT; } . (deny) . . : proto tcp { dport ( ssh http ftp ) ACCEPT; dport 1024:65535 ! syn ACCEPT; DROP; } C . ferm . ferm <<>> ('keys') <<>> ('values') . . : . iptables(8) . iptables TCP : iptables --protocol tcp ferm : protocol tcp; ferm ferm ( iptables(8) ) : iptables --protocol tcp -j ACCEPT ferm: protocol tcp ACCEPT; ; ferm . Ferm : protocol tcp ACCEPT; : ; . : protocol tcp ACCEPT; protocol udp DROP; {} <<>> ('block') . . . . ';' . : chain INPUT proto icmp { icmp-type echo-request ACCEPT; DROP; } : iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT iptables -A INPUT -p icmp -j DROP : chain INPUT { proto icmp { icmp-type echo-request ACCEPT; DROP; } daddr 172.16.0.0/12 REJECT; } 'REJECT' 'proto icmp' ';' . iptables: iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT iptables -A INPUT -p icmp -j DROP iptables -A INPUT -d 172.16.0.0/12 -j REJECT $ . '$FOO' . VARIABLES . & . FUNCTIONS . () . <<>> ('list') . : protocol ( tcp udp icmp ) : ... -p tcp ... ... -p udp ... ... -p icmp ... <<>> : proto tcp ( ACCEPT LOG ); : chain (INPUT OUTPUT FORWARD) proto (icmp udp tcp) DROP; ( !) . . " # " (). . `command` (shell) . backticks . 'string' . LOG log-prefix ' hey, this is my log prefix!'; "string" ( ) : DNAT to "$myhost:$myport"; <> <> <> . . : o location (rule) . : <> <>. o match . ( ) . : <> <>. : <> <>. o target . : <> <> <>. : <>. location target matches : table filter # location proto tcp dport (http https) # match ACCEPT; # target : ferm ( ferm ) . (Parameters) . () : proto udp saddr $TRUSTED_HOSTS; proto tcp dport (http https ssh); LOG log-prefix "funky wardriver alert: "; (negate) ( ): proto !esp; proto udp dport !domain; "!" : proto tcp !syn; ! iptables(8) . (BASIC KEYWORDS) (Location keywords) domain [ip|ip6] . <> <> ( iptables) <> IPv6 <> . --domain <> . table [filter|nat|mangle] netfilter : <> () <> <>. chain [chain-name] netfilter ( ) . <> <> <> <> <>. netfilter . ferm . policy [ACCEPT|DROP|..] (policy) ( ). (ACCEPT DROP REJECT ...) . . . @subchain ["CHAIN-NAME"] { ... } ( @subchain) ferm . ferm . (kernel) . : table filter chain INPUT { saddr (1.2.3.4 2.3.4.5 3.4.5.6 4.5.6.7 5.6.7.8) { proto tcp dport (http https ssh) ACCEPT; proto udp dport domain ACCEPT; } } . saddr . @subchain : table filter chain INPUT { saddr (1.2.3.4 2.3.4.5 3.4.5.6 4.5.6.7 5.6.7.8) @subchain { proto tcp dport (http https ssh) ACCEPT; proto udp dport domain ACCEPT; } } (sub chain) : saddr (1.2.3.4 2.3.4.5 3.4.5.6) @subchain "foobar" { proto tcp dport (http https ssh) ACCEPT; proto udp dport domain ACCEPT; } ferm @cat("interface_", $iface) @substr($var,0,20) . @subchain . @gotosubchain ["CHAIN-NAME"] { ... } @subchain jump goto . . @preserve : chain (foo bar) @preserve; ferm iptables-save <<>> . <<>> ferm : . ferm Perl . KUBE-SEP- : chain "/^KUBE-SEP-.*/" @preserve; interface [interface-name] eth0 dialup ppp1 . "-i" iptables(8) . outerface [interface-name] interface iptables(8) . protocol [protocol-name|protocol-number] TCP UDP ICMP . protocol proto . saddr|daddr [address-spec] (saddr) (daddr) . : saddr 192.168.0.0/24 ACCEPT; # (identical to the next one:) saddr 192.168.0.0/255.255.255.0 ACCEPT; daddr my.domain.com ACCEPT; fragment (fragmented) IP . ( Maximum Transmission Unit MTU) . MTU ifconfig(8) ( ). (Fragments) DOS . sport|dport [port-spec] TCP UDP . <> dport . <> <> . / : dport 80 ACCEPT; dport http ACCEPT; dport ssh:http ACCEPT; dport 0:1023 ACCEPT; # equivalent to :1023 dport 1023:65535 ACCEPT; syn SYN TCP TCP . . . module [module-name] iptables. . . module mod . (Basic target keywords) jump [custom-chain-name] . netfilter . goto [custom-chain-name] . jump RETURN jump . ACCEPT . DROP . REJECT ICMP port-unreachable . ICMP . REJECT; # default to icmp-port-unreachable REJECT reject-with icmp-net-unreachable; <> . RETURN ( <> ). NOP . (ADDITIONAL KEYWORDS) Netfilter . . netfilter ferm . . iptables (iptables match modules) account / . NOP . mod account aname mynetwork aaddr 192.168.1.0/24 ashort NOP; addrtype . mod addrtype src-type BROADCAST; mod addrtype dst-type LOCAL; <> . ah SPI AH . mod ah ahspi 0x101; mod ah ahspi ! 0x200:0x2ff; IPv6: mod ah ahlen 32 ACCEPT; mod ah ahlen !32 ACCEPT; mod ah ahres ACCEPT; bpf Linux Socket Filter. mod bpf bytecode "4,48 0 0 9,21 0 1 6,6 0 0 1,6 0 0 0"; cgroup cgroupsv2 cgroup net_cls. mod cgroup path ! example/path ACCEPT; cgroupsv2 . mod cgroup cgroup 10:10 DROP; mod cgroup cgroup 1048592 DROP; "net_cls.classid" cgroup net_cls . major:minor ( tc(8) ) . comment . ferm ('#') <> . mod comment comment "This is my comment." ACCEPT; <> ferm . condition /proc/net/ipt_condition/NAME 1 ( ip6 /proc/net/ip6t_condition/NAME ). mod condition condition (abc def) ACCEPT; mod condition condition !foo ACCEPT; connbytes ( ) . mod connbytes connbytes 65536: connbytes-dir both connbytes-mode bytes ACCEPT; mod connbytes connbytes !1024:2048 connbytes-dir reply connbytes-mode packets ACCEPT; connbytes-dir : original reply both connbytes-mode : packets bytes avgpkt..IP connlabel 8 connlabel . mod connlabel label "name"; mod connlabel label "name" set; connlimit TCP IP ( ) . mod connlimit connlimit-above 4 REJECT; mod connlimit connlimit-above !4 ACCEPT; mod connlimit connlimit-above 4 connlimit-mask 24 REJECT; mod connlimit connlimit-upto 4 connlimit-saddr REJECT; mod connlimit connlimit-above 4 connlimit-daddr REJECT; connmark (mark) CONNMARK . mod connmark mark 64; mod connmark mark 6/7; conntrack . mod conntrack ctstate (ESTABLISHED RELATED); mod conntrack ctproto tcp; mod conntrack ctorigsrc 192.168.0.2; mod conntrack ctorigdst 1.2.3.0/24; mod conntrack ctorigsrcport 67; mod conntrack ctorigdstport 22; mod conntrack ctreplsrc 2.3.4.5; mod conntrack ctrepldst ! 3.4.5.6; mod conntrack ctstatus ASSURED; mod conntrack ctexpire 60; mod conntrack ctexpire 180:240; "iptables -m conntrack -h" . cpu (CPU) . mod cpu cpu 0; dccp DCCP ( ) . "protocol dccp" . proto dccp sport 1234 dport 2345 ACCEPT; proto dccp dccp-types (SYNCACK ACK) ACCEPT; proto dccp dccp-types !REQUEST DROP; proto dccp dccp-option 2 ACCEPT; dscp DSCP TOS . mod dscp dscp 11; mod dscp dscp-class AF41; dst Destination Options ( IPv6) . mod dst dst-len 10; mod dst dst-opts (type1 type2 ...); ecn ECN TCP IPv4 . mod ecn ecn-tcp-cwr; mod ecn ecn-tcp-ece; mod ecn ecn-ip-ect 2; "iptables -m ecn -h" . esp SPI ESP . mod esp espspi 0x101; mod esp espspi ! 0x200:0x2ff; eui64 " EUI-64 IPv6 . EUI-64 MAC IPv6 . "Universal/Local" . PREROUTING INPUT FORWARD ." mod eui64 ACCEPT; fuzzy " [FLC] ." mod fuzzy lower-limit 10 upper-limit 20 ACCEPT; geoip . ( GeoDB .) mod geoip src-cc "CN,VN,KR,BH,BR,AR,TR,IN,HK" REJECT; mod geoip dst-cc "DE,FR,CH,AT" ACCEPT; hbh Hop-by-Hop Options (ip6). mod hbh hbh-len 8 ACCEPT; mod hbh hbh-len !8 ACCEPT; mod hbh hbh-opts (1:4 2:8) ACCEPT; hl Hop Limit (ip6). mod hl hl-eq (8 10) ACCEPT; mod hl hl-eq !5 ACCEPT; mod hl hl-gt 15 ACCEPT; mod hl hl-lt 2 ACCEPT; helper conntrack . "-portnr" . mod helper helper irc ACCEPT; mod helper helper ftp-21 ACCEPT; icmp ICMP . "protocol icmp" . proto icmp icmp-type echo-request ACCEPT; ip6 ip6tables icmpv6 . "iptables -p icmp "-h"" ICMP . iprange IPv4 . mod iprange src-range 192.168.2.0-192.168.3.255; mod iprange dst-range ! 192.168.6.0-192.168.6.255; ipv4options IPv4 (source routing) (record route) (timestamp) (router-alert) . mod ipv4options ssrr ACCEPT; mod ipv4options lsrr ACCEPT; mod ipv4options no-srr ACCEPT; mod ipv4options !rr ACCEPT; mod ipv4options !ts ACCEPT; mod ipv4options !ra ACCEPT; mod ipv4options !any-opt ACCEPT; ipv6header IPv6 (ip6). mod ipv6header header !(hop frag) ACCEPT; mod ipv6header header (auth dst) ACCEPT; 'mod limit' (hash table) . mod hashlimit hashlimit 10/minute hashlimit-burst 30/minute hashlimit-mode dstip hashlimit-name foobar ACCEPT; hashlimit-mode : dstip dstport srcip srcport ( ). <> . ipvs IPVS. mod ipvs ipvs ACCEPT; # packet belongs to an IPVS connection mod ipvs vproto tcp ACCEPT; # VIP protocol to match; by number or name, e.g. "tcp mod ipvs vaddr 1.2.3.4/24 ACCEPT; # VIP address to match mod ipvs vport http ACCEPT; # VIP port to match mod ipvs vdir ORIGINAL ACCEPT; # flow direction of packet mod ipvs vmethod GATE ACCEPT; # IPVS forwarding method used mod ipvs vportctl 80; # VIP port of the controlling connection to match length . mod length length 128; # exactly 128 bytes mod length length 512:768; # range mod length length ! 256; # negated limit . mod limit limit 1/second; mod limit limit 15/minute limit-burst 10; <> . mac MAC . mod mac mac-source 01:23:45:67:89; mark mark netfilter . 0 4294967295 . mod mark mark 42; mh (mobility header) ( ip6). proto mh mh-type binding-update ACCEPT; multiport ( UDP TCP). mod multiport source-ports (https ftp); mod multiport destination-ports (mysql domain); <> <> : . <> <> ( <>) : sports (https ftp); dports (mysql domain); nfacct ( + ). <> . mod nfacct nfacct-name my-nfacct-object; nth n- . mod nth every 3; mod nth counter 5 every 2; mod nth start 2 every 3; mod nth start 5 packet 2 every 6; <> . osf . mod osf genre Linux; mod osf ! genre FreeBSD ttl 1 log 1; <> . owner (user id) (group id) (process id) (session id) . mod owner uid-owner 0; mod owner gid-owner 1000; mod owner pid-owner 5432; mod owner sid-owner 6543; mod owner cmd-owner "sendmail"; ( <> <> <> (vanilla) ) physdev . (bridged) . mod physdev physdev-in ppp1; mod physdev physdev-out eth2; mod physdev physdev-is-in; mod physdev physdev-is-out; mod physdev physdev-is-bridged; pkttype (link-layer). mod pkttype pkt-type unicast; mod pkttype pkt-type broadcast; mod pkttype pkt-type multicast; policy IPsec . mod policy dir out pol ipsec ACCEPT; mod policy strict reqid 23 spi 0x10 proto ah ACCEPT; mod policy mode tunnel tunnel-src 192.168.1.2 ACCEPT; mod policy mode tunnel tunnel-dst 192.168.2.1 ACCEPT; mod policy strict next reqid 24 spi 0x11 ACCEPT; proto protocol ( ) . protocol . psd TCP/UDP. mod psd psd-weight-threshold 21 psd-delay-threshold 300 psd-lo-ports-weight 3 psd-hi-ports-weight 1 DROP; quota . mod quota quota 65536 ACCEPT; random . mod random average 70; realm (routing realm). BGP . mod realm realm 3; recent IP . mod recent set; mod recent rcheck seconds 60; mod recent set rsource name "badguy"; mod recent set rdest; mod recent rcheck rsource name "badguy" seconds 60; mod recent update seconds 120 hitcount 3 rttl; mod recent mask 255.255.255.0 reap; netfilter : (match) <> (target) . .IP rpfilter 8 . loopback . mod rpfilter proto tcp loose RETURN; mod rpfilter validmark accept-local RETURN; mod rpfilter invert DROP; netfilter (reverse path filtering) IPv6 sysctl net.ipv4.conf.*.rp_filter . rt IPv6 ( ip6). mod rt rt-type 2 rt-len 20 ACCEPT; mod rt rt-type !2 rt-len !20 ACCEPT; mod rt rt-segsleft 2:3 ACCEPT; mod rt rt-segsleft !4:5 ACCEPT; mod rt rt-0-res rt-0-addrs (::1 ::2) rt-0-not-strict ACCEPT; sctp SCTP (Stream Control Transmission Protocol) . "protocol sctp" . proto sctp sport 1234 dport 2345 ACCEPT; proto sctp chunk-types only DATA:Be ACCEPT; proto sctp chunk-types any (INIT INIT_ACK) ACCEPT; proto sctp chunk-types !all (HEARTBEAT) ACCEPT; chunk "iptables -p sctp "-h"" . set IP MAC (set) . mod set set badguys src DROP; . state (connection tracking) . mod state state INVALID DROP; mod state state (ESTABLISHED RELATED) ACCEPT; "iptables -m state -h" . statistic nth random iptables(8) . mod statistic mode random probability 0.8 ACCEPT; mod statistic mode nth every 5 packet 0 DROP; string . mod string string "foo bar" ACCEPT; mod string algo kmp from 64 to 128 hex-string "deadbeef" ACCEPT; tcp TCP . "protocol tcp" . proto tcp sport 1234; proto tcp dport 2345; proto tcp tcp-flags (SYN ACK) SYN; proto tcp tcp-flags ! (SYN ACK) SYN; proto tcp tcp-flags ALL (RST ACK); proto tcp syn; proto tcp tcp-option 2; proto tcp mss 512; "iptables -p tcp -h" . tcpmss TCP MSS SYN SYN/ACK . mod tcpmss mss 123 ACCEPT; mod tcpmss mss 234:567 ACCEPT; time . mod time timestart 12:00; mod time timestop 13:30; mod time timestart 22:00 timestop 07:00 contiguous; mod time days (Mon Wed Fri); mod time datestart 2005:01:01; mod time datestart 2005:01:01:23:59:59; mod time datestop 2005:04:01; mod time monthday (30 31); mod time weekdays (Wed Thu); mod time timestart 12:00; mod time timestart 12:00 kerneltz; "iptables -m time -h" . tos TOS . mod tos tos Minimize-Cost ACCEPT; mod tos tos !Normal-Service ACCEPT; "iptables -m tos -h" . ttl TTL ( / time to live) IP . mod ttl ttl-eq 12; # ttl equals mod ttl ttl-gt 10; # ttl greater than mod ttl ttl-lt 16; # ttl less than u32 . ferm . mod u32 u32 '6&0xFF=1' ACCEPT; mod u32 u32 ('27&0x8f=7' '31=0x527c4833') DROP; unclean . ..SS " iptables (iptables target modules)" ferm () : CHECKSUM (checksum) . CHECKSUM checksum-fill; CLASSIFY CBQ. CLASSIFY set-class 3:50; CLUSTERIP IP MAC . . CLUSTERIP new hashmode sourceip clustermac 00:12:34:45:67:89 total-nodes 4 local-node 2 hash-init 12345; CONNMARK (mark) netfilter . CONNMARK set-xmark 42/0xff; CONNMARK set-mark 42; CONNMARK save-mark; CONNMARK restore-mark; CONNMARK save-mark nfmask 0xff ctmask 0xff; CONNMARK save-mark mask 0x7fff; CONNMARK restore-mark mask 0x8000; CONNMARK and-mark 0x7; CONNMARK or-mark 0x4; CONNMARK xor-mark 0x7; CONNMARK and-mark 0x7; CONNSECMARK ( ) ( ) . SECMARK mangle . CONNSECMARK save; CONNSECMARK restore; CT (connection tracking). CT notrack; CT helper ftp; CT ctevents new,related; CT expevents new; CT zone 1; CT zone mark; CT zone-orig mark; CT zone-reply mark; CT timeout 180; DNAT to [ip-address|ip-range|ip-port-range] . DNAT to 10.0.0.4; DNAT to 10.0.0.4:80; DNAT to 10.0.0.4:1024-2048; DNAT to 10.0.1.1-10.0.1.20; DNPT IPv6 IPv6 (Network Prefix Translation) . DNPT src-pfx 2001:42::/16 dst-pfx 2002:42::/16; ECN ECN . mangle . ECN ecn-tcp-remove; HL Hop Limit IPv6 ( ip6/mangle). HL hl-set 5; HL hl-dec 2; HL hl-inc 1; HMARK MARK fwmark ( ) . HMARK hmark-tuple "src" hmark-mod "1" hmark-offset "1" hmark-src-prefix 192.168.1.0/24 hmark-dst-prefix 192.168.2.0/24 hmark-sport-mask 0x1234 hmark-dport-mask 0x2345 hmark-spi-mask 0xdeadbeef hmark-proto-mask 0x42 hmark-rnd 0xcoffee; IDLETIMER . IDLETIMER timeout 60 label "foo"; IPV4OPTSSTRIP IP . . IPV4OPTSSTRIP; JOOL (stateful) NAT64 JOOL . JOOL jool . JOOL instance "foo"; JOOL_SIIT IP/ICMP ( SIIT) JOOL . JOOL jool_siit . JOOL_SIIT instance "foo"; LED LED ( LED-trigger) . LED led-trigger-id "foo" led-delay 100 led-always-blink; LOG (kernel log). (log flooding) . << >> (non-terminating target) . LOG log-level warning log-prefix "Look at this: "; LOG log-tcp-sequence log-tcp-options; LOG log-ip-options; MARK (mark) netfilter ( 0 4294967295): MARK set-mark 42; MARK set-xmark 7/3; MARK and-mark 31; MARK or-mark 1; MARK xor-mark 12; MASQUERADE (Masquerade) . iptables . "123" "123-456" "123:456" . . MASQUERADE; MASQUERADE to-ports 1234:2345; MASQUERADE to-ports 1234:2345 random; MASQUERADE to-ports 1234:2345 random-fully; MIRROR IP . MIRROR; nat. NETMAP to 192.168.2.0/24; NOTRACK . proto tcp dport (135:139 445) NOTRACK; RATEEST RATEEST rateest-name "foo" rateest-interval 60s rateest-ewmalog 100; proto tcp dport (135:139 445) NOTRACK; NFLOG () netlink ULOG . NFLOG nflog-group 5 nflog-prefix "Look at this: "; NFLOG nflog-range 256; NFLOG nflog-threshold 10; NFQUEUE nfnetlink_queue . proto tcp dport ftp NFQUEUE queue-num 20; QUEUE NFQUEUE. 0 . proto tcp dport ftp QUEUE; REDIRECT to-ports [ports] : IP . proto tcp dport http REDIRECT to-ports 3128; proto tcp dport http REDIRECT to-ports 3128 random; SAME SNAT IP . SAME to 1.2.3.4-1.2.3.7; SAME to 1.2.3.8-1.2.3.15 nodst; SAME to 1.2.3.16-1.2.3.31 random; SECMARK (security mark) SELinux . mangle . SECMARK selctx "system_u:object_r:httpd_packet_t:s0"; SET [add-set|del-set] [setname] [flag(s)] IP (set) . . proto icmp icmp-type echo-request SET add-set badguys src; SET add-set "foo" timeout 60 exist; SNAT to [ip-address|ip-range|ip-port-range] . SNAT to 1.2.3.4; SNAT to 1.2.3.4:20000-30000; SNAT to 1.2.3.4 random; SNPT IPv6 IPv6 . SNPT src-pfx 2001:42::/16 dst-pfx 2002:42::/16; SYNPROXY TCP: TCP . SYNPROXY wscale 7 mss 1460 timestamp sack-perm TCPMSS MSS TCP SYN. TCPMSS set-mss 1400; TCPMSS clamp-mss-to-pmtu; TCPOPTSTRIP TCP TCP . TCPOPTSTRIP strip-options (option1 option2 ...); TOS set-tos [value] (Type Of Service) TCP . ( ) . TOS . TOS set-tos Maximize-Throughput; TOS and-tos 7; TOS or-tos 1; TOS xor-tos 4; "iptables -j TOS -h" . TTL TTL. TTL ttl-set 16; TTL ttl-dec 1; # decrease by 1 TTL ttl-inc 4; # increase by 4 ULOG . ULOG ulog-nlgroup 5 ulog-prefix "Look at this: "; ULOG ulog-cprange 256; ULOG ulog-qthreshold 10; 2.0 ferm ip ip6 arp ( ARP) eb ( ethernet bridging) . iptables . arptables source-ip, destination-ip IPv4 . saddr daddr ip . source-mac, destination-mac MAC . interface, outerface . h-length . chain INPUT h-length 64 ACCEPT; opcode (operation code) iptables(8) . opcode 9 ACCEPT; h-type . h-type 1 ACCEPT; proto-type . proto-type 0x800 ACCEPT; Mangling mangle-ip-s mangle-ip-d mangle-mac-s mangle-mac-d mangle-target ARP (ARP mangling) . iptables(8) . ebtables proto IPv4 PPP. /etc/ethertypes . interface, outerface . logical-in, logical-out (bridge) . saddr, daddr MAC . Match modules : 802.3 arp ip mark_m pkttype stp vlan log. Target extensions : arpreply dnat mark redirect snat. --mark mark_m -j mark . mark ferm . mark 1 2 : mark 1 MARK 2; (ADVANCED FEATURES) (Variables) . : @def $DEV_INTERNET = eth0; @def $PORTS = (http ftp); @def $MORE_PORTS = ($PORTS 8080); ferm : chain INPUT interface $DEV_INTERNET proto tcp dport $MORE_PORTS ACCEPT; ("192.168.1.1" "http") ferm "proto" "interface" . : @def $DEV_INTERNET = eth1; chain INPUT { proto tcp { @def $DEV_INTERNET = ppp0; interface $DEV_INTERNET dport http ACCEPT; } interface $DEV_INTERNET DROP; } : chain INPUT { proto tcp { interface ppp0 dport http ACCEPT; } interface eth1 DROP; } "def $DEV_INTERNET = ppp0" "proto tcp" "set $DEV_INTERNET = eth1" . (Include files) - . ..SS " (Automatic variables)" ferm . ferm . $FILENAME ferm . $FILEBNAME (base name) . $DIRNAME . $DOMAIN . ip ip6 arp eb. $TABLE netfilter . $CHAIN (chain) netfilter. $LINE . : @def &log($msg) = { LOG log-prefix "rule=$msg:$LINE "; } . . . &log("log message"); (Functions) ferm . @def &FOO() = proto (tcp udp) dport domain; &FOO() ACCEPT; @def &TCP_TUNNEL($port, $dest) = { table filter chain FORWARD interface ppp0 proto tcp dport $port daddr $dest outerface eth0 ACCEPT; table nat chain PREROUTING interface ppp0 proto tcp dport $port daddr 1.2.3.4 DNAT to $dest; } &TCP_TUNNEL(http, 192.168.1.33); &TCP_TUNNEL(ftp, 192.168.1.30); &TCP_TUNNEL((ssh smtp), 192.168.1.2); ( '{...}') ferm ';' . '&FOO()' 'ACCEPT' . : @def &IPSEC() = { proto (esp ah); proto udp dport 500; } chain INPUT ACCEPT &IPSEC(); (Backticks) (`...`) : @def $DNSSERVERS = `grep nameserver /etc/resolv.conf | awk '{print $2}'`; chain INPUT proto tcp saddr $DNSSERVERS ACCEPT; Perl (/bin/sh) . ferm . () ferm . '#' (whitespace) . (Includes) @include : @include 'vars.ferm'; /etc/ferm/ferm.conf /etc/ferm/vars.ferm . . include : chain INPUT { @include 'input.ferm'; } ( '/' ) : @include 'ferm.d/'; @glob (wildcards) : @include @glob('*.include'); (pipe) ferm : @include "/root/generate_ferm_rules.sh $HOSTNAME|" 0 ferm ..SS " (Conditionals)" @if : @if $condition DROP; Perl : (false) (true) . : (a b); 1; 'foo'; (0 0) : (); 0; '0'; '' @else : @if $condition DROP; @else REJECT; - @else . @if @else : @if $condition { MARK set-mark 2; RETURN; } @else { MARK set-mark 3; } - . @elsif @else @if . : @def $have_ipv6 = `test -f /proc/net/ip6_tables_names && echo 1 || echo`; @if $have_ipv6 { domain ip6 { # .... } } (Hooks) : @hook pre "echo 0 >/proc/sys/net/ipv4/conf/eth0/forwarding"; @hook post "echo 1 >/proc/sys/net/ipv4/conf/eth0/forwarding"; @hook flush "echo 0 >/proc/sys/net/ipv4/conf/eth0/forwarding"; . <
>    
           
         <>   
           .
        <>   
           ferm
       ( --flush)  .
           
          .

  (BUILT-IN FUNCTIONS)
           
           
       .

   @defined($name), @defined(&name)
           
            
       .

           @def $a = 'foo';
           @if @defined($a) good;
           @if @not(@defined($a)) bad;
           @if @defined(&funcname) good;

   @eq(a,b)
           
       . :

           @if @eq($DOMAIN, ip6) DROP;

   @ne(a,b)
        @eq   
         .

   @not(x)
          (boolean)  
       .

   @resolve((hostname1 hostname2 ...), [type])
         
         iptables 
       .  
           ferm
         @resolve  :

           saddr @resolve(my.host.foo) proto tcp dport ssh ACCEPT;
           saddr @resolve((another.host.foo third.host.foo)) proto tcp dport openvpn ACCEPT;
           daddr @resolve(ipv6.google.com, AAAA) proto tcp dport http ACCEPT;

           
         :  
           ferm 
          
         
       .

           
         DNS  
       .   
        ip  <>  
        ip6  <> .

          
         
          
       .  DNS 
           
           
           
          
           
       .

   @cat(a, b, ...)
           
         .

   @join(separator, a, b, ...)
           
            
         
         .

   @substr(expression, offset, length)
          
       (expression)     
       .  
          .  OFFSET 
           
           .

   @length(expression)
         EXPR   
        .

   @basename(path)
            
        
       (File::Spec::splitpath).

   @dirname(path)
          
         
           
            
       (File::Spec::splitpath).

   @glob(path)
         (wildcards) 
           
        (    
          
       ).   
         . 
           @include
        .

   @ipfilter(list)
        IP    
          
        .  
          
          IPv4  IPv6
        :

           @def $TRUSTED_HOSTS = (192.168.0.40 2001:abcd:ef::40);

           domain (ip ip6) chain INPUT {
               saddr @ipfilter($TRUSTED_HOSTS) proto tcp dport ssh ACCEPT;
           }
        ./examples/     ferm             .         .

      (Easy port forwarding)
        ferm   
          :

           @def &FORWARD_TCP($proto, $port, $dest) = {
               table filter chain FORWARD interface $DEV_WORLD outerface $DEV_DMZ daddr $dest proto $proto dport $port ACCEPT;
               table nat chain PREROUTING interface $DEV_WORLD daddr $HOST_STATIC proto $proto dport $port DNAT to $dest;
           }

           &FORWARD_TCP(tcp, http, 192.168.1.2);
           &FORWARD_TCP(tcp, smtp, 192.168.1.3);
           &FORWARD_TCP((tcp udp), domain, 192.168.1.4);

   ferm    (Remote ferm)
            
          ferm 
       (    
       Perl)  
        ferm  
         
           ferm  
           .

         OpenWRT:

           ferm --remote --shell mywrt/ferm.conf >mywrt/firewall.user
           chmod +x mywrt/firewall.user
           scp mywrt/firewall.user mywrt.local.net:/etc/
           ssh mywrt.local.net /etc/firewall.user

 (OPTIONS)
       --noexec     iptables(8)  
                       
                     .  
                    
                      
                     
                     --lines 
                   .

       --flush        
                       (policy)
                      
                   ACCEPT  .  ferm 
                     
                      
                      
                     .

       --lines       
                     
                     
                   .  
                      
                     
                     
                     iptables(8)  
                    
                     
                       .

       --interactive
                      
                       
                    .
                      
                      
                     
                   ( --timeout  )
                      
                   .  
                       
                      
                   :  
                        
                     
                   .

       --timeout S    
                   --interactive    
                     
                      
                      
                    
                   . 
                     .

       --help        
                     
                      .

       --version      
                    .

       --fast         : ferm
                     iptables-save(8) 
                        iptables-restore(8)
                    .  
                     
                    ferm  
                       
                   iptables(8)  
                   .

                       ferm 2.0
                      
                       
                      
                   .

       --slow         
                      
                     iptables(8) 
                       iptables-restore(8)
                    .

       --shell        
                     iptables-restore(8) 
                       
                    . 
                     --fast  --lines .

       --remote       
                      .
                      --noexec
                    --lines .  
                   --shell  .

       --domain {ip|ip6}
                     
                        
                     
                     
                      
                     
                   .   
                     
                      ferm
                      .

       --def '$name=value'
                       
                     
                    (override) .

  (SEE ALSO)
       iptables(8)

 (REQUIREMENTS)
    (Operating system)
        2.4   
         netfilter  
        netfilter 
          
        

    (Software)
        iptables  perl 5.6

  (BUGS)
         

          
           GitHub 
       : 

   (COPYRIGHT)
        2001-2021   Max
       Kellermann  Auke Kok
         
         .

          
           
          << 
        >> (GPL)  
         
            
          ( 
       )   
          
        .

           
            
          
          
        <<  >> 
       <<    
       >>.   
       <<   >>
         .

           
           
           
           
           :
       Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
       Boston, MA 02110-1301 USA..SH " (AUTHOR)" Max
       Kellermann , Auke Kok
       

ferm 2.7                          2025-07-17                           FERM(1)