# kldload ipfw ipfw2 (+ipv6) initialized, divert loadable, nat loadable, default to deny, logging disabled
Chapter 2. IPFW Operation
Table of Contents
If you have been successful so far, you now have the initial lab setup shown in Figure 1 except for IP addressing. All the examples in this book use "Special Use Addresses" for both IPv4 and IPv6. Address references used are described here for IPv4 Addresses (RFC 5737) and here for IPv6 Addresses (RFC 3849).
Configure both VMs to use the addresses shown. Once these addresses are in place on the VMs (and the alias address on the FreeBSD host), it is unlikely that the VMs will be able to access sites on the Internet. The 203.0.113.0/24 network is considered non-routable by IPS and major telecom carriers on the Internet. However, this does not really matter, since all the communications for this book are local to the VMs running on the FreeBSD host. Bottom line - if you want your VMs to access the Internet, leave them on DHCP, but for the examples in this book, you’ll want to use manual addressing as shown in the figure below.
Scripts used by the two VMs are discussed in the next section.
2.1. Firewall Server Scripts
To demonstrate the firewall capabilities of ipfw, the firewall VM runs certain scripts that open local UDP and TCP ports using ncat(1) for TCP operation, and nc(1) for UDP operation. While the commands perform similar functions, the nc version on the base system is the one that performs best for receiving UDP traffic as it supports the keep-open option (-k).
The firewall VM runs one of four basic scripts. Recall that these are localed in /root/bin:
tserv.sh (userv.sh): Script that opens one TCP (UDP) port and listens for incoming traffic.
tserv3.sh (userv3.sh): Script that opens 3 TCP (UDP) ports and listens for incoming traffic.
These scripts will listen for an incoming connection and print whatever is sent over during the connection. When the connection is closed, the script will continue to listen for the next connection.
These script provide the basic mechanism for receiving a TCP or UDP connection. Once we start the firewall and populate the ipfw ruleset, we will see the effect each rule has on the connection capabilities.
2.2. External VM Scripts
Likewise, there are other basic scripts the external1 (and later, external2 and external3) VMs use for initiating or establishing communications with the firewall VM. The TCP and UDP versions perform similarly:
tcon.sh (ucon.sh): Connect via TCP (or UDP). This script takes a single argument, a port number to use for the connection. The external VM host can change the port number at each prompt. If there is no script listening on the port on the firewall, the script will indicate a "connection refused" error.
tconr.sh (uconr.sh): Connection takes a random port number and a sleep value. The script randomly selects one of three ports for its connection in a loop, controlled by the sleep value. If there is a listener on the firewall active on the port, the connection succeeds - otherwise the connection is refused.
tcont.sh (ucont.sh): Connection takes a port number and sleep value. The communication uses the same port in a loop, controlled by the sleep value.
These are simple scripts, but they allow for independent activity by the external VMs, while the firewall VM admin creates and tests ipfw rulesets. Most of the examples in the first part of this book can be done with just these scripts, so it is a good idea to familiarize yourself with their operation. Later scripts will use hping3(8), and iperf3(1), versatile tools used in network analysis.
By default, the external VMs and firewall VM scripts work on ports 5656
, 5657
, and 5658
.
The randomized communication scripts also utilize port 5659
, but since no services are listening on that port on the firewall VM, the connection fails.
It is important to understanding the underlying network activity. If you are unfamiliar with the basics of Internet protocols, network traffic, traffic monitoring and so forth, there are a number of excellent books, white papers, and tutorials, many free over the Internet. Check Appendix C for a modest selection.
2.3. Loading IPFW
ipfw can be built into the FreeBSD kernel directly, or it can be loaded as a kernel module. We will use the ipfw.ko loadable kernel module for most of the examples in this book. You can load ipfw as root with the command:
Notice the kernel display output - “ipfw2 (+ipv6) initialized, divert loadable, nat loadable, default to deny, logging disabled”. This gives a quick summary of this host’s ipfw's capabilities. The most important note is "default to deny" which indicates that, by default, the firewall has an immutable rule located at the end of the ruleset that denies all Internet Protocol (IP) traffic. This rule depends on how the kernel was configured when it was built. By default it is "default to deny". However, if you are working on a FreeBSD system where you do not know its provenance, use the ipfw list command to make sure:
# ipfw list 65535 deny ip from any to any #
Note that this does not mean it denies all network traffic, only traffic that is based on the Internet Protocol (RFC 791), and all of its derivatives (TCP, UDP, ICMP, etc). If you had the capability to send and receive non-IP based traffic you could possibly still send and receive it. You would need special rules to deny all traffic. We will see an example of that later in this book.
To begin the next section, start with the ipfw firewall unloaded:
# kldunload ipfw
Unloading (# kldunload ipfw) and loading (# kldload ipfw) the ipfw kernel module is a handy way of completely reinitializing ipfw. This removes all rules, sets, queues, pipes, and other ipfw operations. See kldload(8), kldunload(8), and kldstat(8) for details. |
2.4. Initial Firewall Setup
In this section we will introduce the operation of the scripts described above and demonstrate simple traffic filtering.
In the first example, the firewall host runs tserv.sh
which opens TCP port 5656.
The external1 VM runs tcon.sh
, which repetitively opens a TCP connection and sends data to the firewall VM.
Since there is no firewall in place, all TCP connections succeed.
On the host machine, it is possible to run tcpdump(1) on the bridge0 device to see the traffic in real time. Shown below is one successful transfer, i.e there are no firewall rules preventing the connection.
It follows the basic TCP connection sequence – 3 way handshake setup, send data, and close the connection:
We now load the ipfw firewall and retry the communication.
# kldload ipfw ipfw2 (+ipv6) initialized, divert loadable, nat loadable, default to deny, logging disabled # # ipfw list 65535 deny ip from any to any #
No communications were successful - the connections time out because the ipfw firewall has denied traffic with the default deny
rule as described above.
The external1 VM host sends SYN packets to start the connection, but they never reach the firewall VM’s TCP service on port 5656.
The TCP 3-way handshake is never completed.
We will use these same techniques to show how communications and data transfer operate. We now turn our attention to firewall rule creation in the next section.