(no commit message)
[ikiwiki.git] / docs / ipfw3 / index.mdwn
1 [[!meta title="IPFW3 Documentation"]]
2 [[!meta robots="index, follow"]]
3
4
5 Bill Yuan
6
7 12 May, 2018
8
9 ---
10
11 [[!toc  levels=3]]
12
13 # Introduction
14
15 [IPFW](https://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/firewalls-ipfw.html) is a stateful firewall originally written for FreeBSD. It is comprised of several components, e.g. the kernel firewall filter rule processor and its integrated packet accounting facility, the logging facility, NAT, the [``dummynet(4)``](http://mdoc.su/d/4/dummynet) traffic shaper, a forward facility, a bridge facility, and an ipstealth facility. It is one of the most advanced opensource firewalls.
16
17 DragonFly BSD is a logical continuation of the FreeBSD 4.x series, but has diverged significantly from FreeBSD since the fork in 2004, e.g., DragonFly BSD has implemented a new Light Weight Kernel Threads implementation (LWKT) and a lightweight ports/messaging system.
18
19 In DragonFly, each CPU has its own thread scheduler. Upon creation, threads are assigned to processors and are never preemptively switched from one processor to another; they are only migrated by the passing of an inter-processor interrupt (IPI) message between the CPUs involved. Inter-processor thread scheduling is also accomplished by sending asynchronous IPI messages. One advantage to this clean compartmentalization of the threading subsystem is that the processors' on-board caches in Symmetric Multiprocessor Systems do not contain duplicated data, allowing for higher performance by giving each processor in the system the ability to use its own cache to store different things to work on.
20
21 The LWKT subsystem is being employed to partition work among multiple kernel threads (for example in the networking code there is one thread per protocol per processor), reducing competition by removing the need to share certain resources among various kernel tasks.
22
23 This IPFW3 is a rewritten from scratch of the FreeBSD's IPFW for DragonFly BSD. It is in modular design, and inherited the SMP-friendly feature from DragonFly BSD's LWKT, therefore IPFW3 is a lockless and stateful firewall.
24
25
26 ## Brief notes on design
27
28 IPFW3 is in modular design, with different functionalities implemented in different loadable modules, which can be loaded on requirements. The IPFW3 **core** module only comes with the ``allow`` and ``deny`` actions, which may be loaded manually by:
29
30     kldload ipfw3
31
32 More basic firewall filtering features, e.g., *filtering based on source IP*, are implemented in the **basic** module, which may be loaded by:
33
34     kldload ipfw3_basic
35
36 Besides the **core** and **basic** modules, there are also the **layer2**, **layer4**, in-kernel **NAT**, and **dummynet** modules.
37
38 Note that the corresponding kernel module must be loaded, otherwise, [``ipfw3(8)``](http://mdoc.su/d/8/ipfw3) would complain errors of **unknown/bad command**.
39
40 Each module contains 2 parts. library in user-space which will be loaded and parse the command line into rules. and kernel space portion will be invoked when the traffic hit the firewall and it will trigger the correct action according to the firewall rules.
41
42 ## Compare to FreeBSD's IPFW
43
44 IPFW3 not only inherited **most** features from FreeBSD's IPFW, but also introduced lots of new features from OpenBSD's PF and other rivals.
45
46 **Much more extensible**
47
48 Every filter/action needs to be identified using ID, but there are only 8 bits space to store the ID, so theoretically it can support 256 filters/actions in maximum in FreeBSD' IPFW. While in IPFW3, the space for ID are still the same, but one space introduced to keep the module's ID, so theoretically ipfw3 can have 256 modules and 256 filter/action in each module.
49
50 And in IPFW3, both user-space library and kernel space module are implemented with a simple interface, it is quite easy to build your own filter/module by following the interface.
51
52 **Much more concise**
53
54 The rules of IPFW3 are much more concise. For example, a simple rule of IPFW looks like:
55
56     ipfw add allow ip from any to any
57    
58 where the ``from any to any`` is actually just for more readable.  While IPFW3 supports the same syntax as FreeBSD's IPFW, we recommend to just use the simplified version, e.g.:
59
60     #1. ipfw3 add allow all 
61     #2. ipfw3 add allow icmp from 1.1.1.1
62     #3. ipfw3 add allow tcp via em0
63
64 **Higher Performance**
65
66 All modern CPUs are having mutil-cores, and each core are running independently. So the LWKT of DragonFly BSD is the best way to fully utilize the CPU power. by duplicating the environment for each CPU, all the CPU can run as fast as it can without any interference. So it is a lockless and stateful firewall.
67
68
69 # Basic Configuration
70
71 ## Core Framework
72
73 Below actions are directly supported from the core framework.
74
75 **accept**  -- accept the traffic
76
77 **deny**  -- deny the traffic
78
79 the default action of the firewall was compiled in the core framework. but it still can be interfered by below system tunable when the module was loaded into the kernel, e.g.,
80
81     sysctl net.filters_default_to_accept=1
82
83
84 ## Basic Module
85
86 Below filter/actions are supported in basic module.
87
88 **proto** -- matches traffic protocol, it is implicit after the action.
89
90 **from** -- matches the source.
91
92 Filter ``from`` supports multiple type of parameters:
93
94     from 8.8.8.8 -- match traffic from IP 8.8.8.8
95     from table 1    -- match traffic where source IP found in table 1
96     from any  -- not filtering
97     from me  -- match traffic from the host
98     from 192.168.1.0/24 -- match traffic from the IP range
99  
100 **to** -- matches the destination, which supports the same parameters as filter ``from``
101
102 **count** -- action count the traffic
103
104 **skipto** -- skipto another line in the rules
105
106 **forward** -- forward the current traffic to a destination
107
108 **in** -- matches the in direction traffic
109
110 **out** -- matches the out direction traffic
111
112 **via** -- matches the traffic go through an interface
113
114 **xmit** -- matches the out direction traffic through an interface
115
116 **recv** -- matches the in direction traffic through an interface
117
118 **src-port** --matches the src port of TCP/UDP traffic
119
120 **dst-port** --matches the dst port of TCP/UDP traffic
121
122 **prob** -- randomly match the traffic
123
124 **keep-state** -- setup a state in current CPU only
125
126 **check-state** -- check the traffic state against the state tables of current CPU
127
128 **tag** -- add a tag the traffic
129
130 **untag** -- remove the tag from the traffic
131
132 **tagged** -- matched the traffic with the tag
133
134 **//** -- append some comment at the end of the rule
135
136 ## Layer2 Module
137
138 **layer2** -- matches layer2 traffic
139
140 **mac** -- matches layer2 traffic with src and dst MAC addresses
141
142 **mac-from** -- matches layer2 traffic with src MAC address (supports lookup table)
143
144 **mac-to** -- matches layer2 traffic with dst MAC address (supports lookup table)
145  
146 ## Layer4 Module
147
148 **tcpflag**  -- matches the TCP flag
149
150 **uid** -- matches the sockets owner ID
151
152 **gid** -- matches the sockets owner's group ID
153
154 **established** --matched the established TCP connection
155
156 **bpf**  -- filter traffic with bpf syntax
157  
158 ## NAT Module
159
160 **nat** -- NAT traffic with pre-defined NAT configuration
161  
162 ## Dummynet3 Module
163
164 **pipe** -- pipe traffic with pre-defined pipe configuration
165
166 **queue** -- queue traffic with pre-defined queue configuration
167
168
169 # Advanced Configuration
170
171 ## Rule Set
172
173 Each rule belongs to one of 32 different sets , numbered 0 to 31. Set 31 is reserved for the default rule.
174
175 By default, rules are put in set 0, unless you use the set N attribute when entering a new rule. Sets can be individually and atomically enabled or disabled, so this mechanism permits an easy way to store multiple configurations of the firewall and quickly (and atomically) switch between them.  The command to enable/disable sets is
176
177     ipfw3 set [disable number ...] [enable number ...]
178
179 where multiple enable or disable sections can be specified.  Command execution is atomic on all the sets specified in the command.  By default, all sets are enabled.
180
181 ## Lookup Table
182
183 In the following example, We need to create several rules in order to block ICMP traffic from whole range of the network 192.168.0.0/24.
184
185     ipfw3 add deny icmp from 192.168.0.1
186     ipfw3 add deny icmp from 192.168.0.2
187     ipfw3 add deny icmp from 192.168.0.3
188     ...
189     ipfw3 add deny icmp from 192.168.0.254
190
191 The firewall need to process the 254 lines of rule line by line. in this situation, the lookup table was introduced in order to increase the performance and enhance the usability.
192
193     ipfw3 table 1 type ip  # create a table of id=1 and type=ip
194     ipfw3 table 1 append range 192.168.0.0/24
195     ipfw3 add deny icmp from table 1
196  
197 and lookup table are supported by multiple filters.
198
199
200 ## Forwarding
201
202 The forward action will change the next-hop on matching packets to ipaddr, which can be an IP address in dotted quad format or a host name.The search terminates if this rule matches.
203
204 If ipaddr it can be is a local addresses, then matching packets will be forwarded to port (or the port number in the packet if one is not specified in the rule) on the local machine. If ipaddr is not a local address, then the port number (if specified) is ignored, and the packet will be forwarded to the remote address, using the route as found in the local routing table for that IP.  Use commas to separate multiple ip addresses.
205
206 forward action supports multiple options, it can be `round-robin' or `sticky'.  `sticky' is calculated based on the src ip addresses, and if no forward-option, by default it will be 'random'.
207
208     ipfw3 add forward 192.168.1.1:80,192.168.1.2:80 round-robin tcp from ....
209  
210 Above example can forward the traffic to 2 destination in round-robin.
211
212 A forward rule will not match layer-2 packets (those received on ether_input() or ether_output()). The forward action does not change the contents of the packet at all.  In particular, the destination address remains unmodified, so packets forwarded to another system will usually be rejected by that system unless there is a matching rule on that system to capture them.  For packets forwarded locally, the local address of the socket will be set to the original destination address of the packet.  This makes the netstat(1) entry look rather weird but is intended for use with transparent proxy servers.
213
214
215 ## BPF Filtering
216
217 Berkeley Packet Filter (BPF)'s filtering capabilities are implemented as an interpreter for a machine language for the BPF virtual machine; programs in that language can fetch data from the packet, perform arithmetic operations on data from the packet, and compare the results against constants or against data in the packet or test bits in the results, accepting or rejecting the packet based on the results of those tests. The original paper was written by Steven McCanne and Van Jacobson in 1992 while at Lawrence Berkeley Laboratory.
218
219 The ipfw3 firewall integrates with a BPF filter, a just-in-time compilation is used to convert virtual machine instructions into native code, and it will be invoked when the traffic hits a rule with BPF filter.
220     
221     ipfw3 add allow all bpf "icmp and src 8.8.8.8"
222  
223 the bpf filter can be used to filter all parts of the packet, includes the payload.
224
225
226 ## Stateful
227
228 Stateful operation is a way for the firewall to dynamically create states for specific flows when packets that match a given pattern are detected. Support for stateful operation comes through the check-state, keep-state of rules.
229
230 States are created when a packet matches a keep-state rule, causing the creation of a dynamic rule which will match all and only packets with a given protocol between a src-ip/src-port dst-ip/dst-port pair of addresses (src and dst are used here only to denote the initial match addresses, but they are completely equivalent afterwards).  Dynamic rules will be checked at the first check-state, keep-state or limit occurrence, and the action performed upon a match will be the same as in the parent rule.
231
232 Note that no additional attributes other than protocol and IP addresses and ports are checked on dynamic rules.
233
234 The typical use of dynamic rules is to keep a closed firewall configuration, but let the first TCP SYN packet from the inside network install a state for the flow so that packets belonging to that session will be allowed through the firewall:
235
236     ipfw3 add check-state
237     ipfw3 add allow tcp from my-subnet to any keep-state
238     ipfw3 add deny tcp from any to any
239
240 A similar approach can be used for UDP, where an UDP packet coming from the inside will install a dynamic rule to let the response through the firewall:
241
242     ipfw3 add check-state
243     ipfw3 add allow udp from my-subnet to any keep-state
244     ipfw3 add deny udp from any to any
245
246 States expire after some time, which depends on the status of the flow and the setting of some sysctl variables.  See Section SYSCTL VARIABLES for more details.  For TCP sessions, dynamic rules can be instructed to periodically send keepalive packets to refresh the state of the rule when it is about to expire.
247
248 States can be added/deleted using the ipfw3 utility. and the inserted states will be hosted on the current CPU only. once the live time expired, the state will be purged by the housekeeping process and will not be able to influence the traffic.
249  
250     ipfw3 state add rule 1000 udp 192.168.1.100:0 8.8.8.8:53 expiry 600
251
252 Above example can immediately  insert a state which will link to rule 1000 for the UDP traffic which is from 192.168.1.100 to 8.8.8.8:53, and the state will be expired in 600 seconds if no traffic update the states.
253   
254 ## In-Kernel NAT
255
256 Ipfw3 supports in-kernel NAT using the kernel version of libalias which is a moderately portable set of functions designed to assist in the process of IP masquerading and network address translation. Out-going packets from a local network with unregistered IP addresses can be aliased to appear as if they came from an accessible IP address. Incoming packets are then de-aliased so that they are sent to the correct machine on the local network. 
257
258 A certain amount of flexibility is built into the packet aliasing engine. In the simplest mode of operation, a many-to-one address mapping takes place between the local network and the packet aliasing host.  This is known as IP masquerading. In addition, one-to-one mappings between local and public addresses can also be implemented, which is known as static NAT.  In between these extremes, different groups of private addresses can be linked to different public addresses, comprising several distinct many-to-one mappings.  Also, a given public address and port can be statically redirected to a private address/port.
259
260 In ipfw3, each CPU has its own context, and by storing the alias link records into different context according to the CPU, the lock can be removed in order to achieve the best performance. and due to the nature of NAT, the outgoing and returning packets are possible to be handled by different CPUs, to ensure the return traffic and be translated back to the correct address, the newly created alias_link are required to be duplicated and inserted into contexts of both CPUs. 
261
262 So this in-kernel NAT in DragonFly BSD is the only true lockless in-kernel NAT amount all common opensource operating systems.
263
264
265 ## IPFW3sync
266
267 IPFW3sync is the facility in IPFW3 which can synchronize firewall states between machines running ipfw3 firewall for high availability. It can be used together with CARP to make ensure a backup firewall has the same states as the main firewall. When the master machine in the firewall cluster dies, the slave machine will be able to takeover the services and accept current connections without loss.
268
269 In order to use this synchronization feature, the firewalls need to be configured into IPFW3sync **centre** and/or **edge** nodes, therefore, the **centre** firewall will continuously sync its states to the **edge**s using UDP protocol.
270
271 Use below commands to configure an IPFW3sync *edge* node, which will listen on the UDP port 5000:
272
273     ipfw3 sync edge 5000
274     ipfw3 sync start edge
275
276 Then configure an IPFW3sync *centre* node. Here the *centre* firewall will automatically sync its states to *edge* nodes 192.168.1.1:5000 and 192.168.1.2:5001 :
277
278     ipfw3 sync centre 192.168.1.1:5000,192.168.1.2:5001
279     ipfw3 sync start centre
280
281 This command to verify whether the IPFW3sync *centre* is able to send the test message to all the configured *edge* nodes:
282
283     ipfw3 sync test centre 1
284
285
286 # Additional Topics
287
288 ## Logging
289
290 IPFW3 supports up to 10 ``ipfw`` pseudo interfaces for logging, which can be created with:
291
292     ifconfig ipfw1 create
293
294 Traffic matching a rule with the ``log`` action will be captured by the BPF and duplicated into the corresponding ``ipfw`` pseudo interface. e.g.
295
296     ipfw3 add 100 allow log 1 icmp from 8.8.8.8
297
298 This rule attaches the ICMP packets from 8.8.8.8 to the ``ipfw1`` pseudo interface for logging. 
299
300
301 # Example Rules
302
303 Collection of the IPFW3 samples/articles.
304
305 * [IPFW3 and NAT](http://lists.dragonflybsd.org/pipermail/users/2015-June/207790.html)