Setting up a transparent firewall on NetBSD

Posted by marian on April 16, 2010

A transparent firewall is a firewall running at Layer 2 in the OSI layer, that is Data link layer. Its main feature is that an attacker, usually remote, can’t actually see it. At Layer 2 we have MAC addresses offering local addressing, and we don’t have IP addresses. If you think that this has no point whatsoever, think again [1].

So, after reading this I’ve searched for a software solution. I was mainly motivated by [2] and [3]. A similar solution is presented at [4] for OpenBSD. I will describe a working solution for NetBSD in more detail, in a bottom up fashion, to reduce the need of googleing.

A transparent firewall is mainly a Layer 2 device with added filtering capabilities. Since firewalls usually need at least two physical interfaces, the logical choice is a bridge. It turns out that OpenBSD and NetBSD support building such a transparent firewall. Very good documentation is provided at [5].

First of all, a small introduction to Netbsd and OpenBSD.
Although many of you appreciate the openness and novelty of systems based on GNU/Linux, I recommend taking a look at NetBSD and OpenBSD.

OpenBSD started as a fork of NetBSD, and it is advertised in the community as being the most secure Operating System. Although I disagree with this kind of assertions, I can tell you that it is rather difficult to do stupid things on it.

NetBSD is advertised as the most portable OS. And it actually is.

For those of you who want to experiment on a Dell Inspiron 1525 laptop, surprises await you. NetBSD does not offer out-of-box support for the Marvell Ethernet controller, while OpenBSD does. Neither of the two offer any support for Broadcom BCM4312 802.11b/g wireless network controller, if you were wondering.

Therefore, the best solution for a transparent firewall that I could think of was an ancient AMD Duron based computer. The computer has two PCI based Gigabit Ethernet NICs: RealTek 8169/8110 Gigabit Ethernet (rev. 0×10) and D-Link DGE-528T Gigabit Ethernet (rev. 0×10), and an on-board VIA VT6102 (Rhine II) 10/100 Ethernet.

For those of you who think that a dual-core or quad-core computer would be blazing fast running this OSes, I tell you … support for SMP was just recently added and has much to catch up to match the Linux Kernel. At the same time, a 200 MB and 27 user processes OS is quite tempting for those experimenting with XEN virtualization.

What I really enjoy in the case of OpenBSD and NetBSD is the kernel source code documentation and the style of writing the code. Please, don’t thrust me. Just download and look at it. You would gain a better understanding of the Linux kernel by doing so.

To decline my preferences, I commonly use and enjoy Ubuntu and Fedora. But I also started to enjoy and appreciate BSD based system.

I also tried OpenSolaris. I have never encountered such an awful OS in my entire life. Its just a very big piece of crap. I don’t care what others say about its commercial brother, the so-called “most advanced OS”. The correct way of presenting it is: “the crappiest OS that mankind has ever witnessed”.

Ok, returning to our discussion one thing that would annoy any living being regarding NetBSD and OpenBSD is the lack of applications. There are less applications than on GNU/Linux and usually they are outdated. Yes, of course there is a reason for this. A funny thing is that tcpdump is not present in the ports tree. The main argument being the high number of bugs that could threaten the security of the system.

So lets start building a transparent firewall using NetBSD.

Install NetBSD, currently at version 5.0.2

Download it from: http://www.netbsd.org/releases/.
Accept default settings.

Building a custom made NetBSD kernel [6]
1) Copy the GENERIC kernel config to your local directory:

  1. cp /usr/src/sys/arch/`machine`/conf/GENERIC ~/TranspareFIREWALL

And make a symbolic link to it:

  1. ln -s ~/TranspareFIREWALL /usr/src/sys/arch/`machine`/conf/TransparentFirewall

Now in our custom kernel config add / modify the networking options to look as following :

  1. # Networking options
  2. options         GATEWAY         # packet forwarding
  3. options         INET            # IP + ICMP + TCP + UDP
  4. options         INET6           # IPV6
  5. options         IPSEC           # IP security
  6. options         IPSEC_ESP       # IP security (encryption part; define w/IPSEC)
  7. options         IPSEC_NAT_T     # IPsec NAT traversal (NAT-T)
  8. options         IPSEC_DEBUG     # debug for IP security
  9. options         MROUTING        # IP multicast routing
  10. #options        PIM             # Protocol Independent Multicast
  11. #options        ISO,TPIP        # OSI
  12. #options        EON             # OSI tunneling over IP
  13. options         NETATALK        # AppleTalk networking protocols
  14. options         PPP_BSDCOMP     # BSD-Compress compression support for PPP
  15. options         PPP_DEFLATE     # Deflate compression support for PPP
  16. options         PPP_FILTER      # Active filter support for PPP (requires bpf)
  17. options         PFIL_HOOKS      # pfil(9) packet filter hooks
  18. options         IPFILTER_LOG    # ipmon(8) log support
  19. options         IPFILTER_LOOKUP # ippool(8) support
  20. options         IPFILTER_DEFAULT_BLOCK  # block all packets by default
  21. #options        TCP_DEBUG       # Record last TCP_NDEBUG packets with SO_DEBUG
  22. options         ICMP_BANDLIM
  23. options         ALTQ            # Manipulate network interfaces' output queues
  24. options         ALTQ_BLUE       # Stochastic Fair Blue
  25. options         ALTQ_CBQ        # Class-Based Queueing
  26. options         ALTQ_CDNR       # Diffserv Traffic Conditioner
  27. options         ALTQ_FIFOQ      # First-In First-Out Queue
  28. options         ALTQ_FLOWVALVE  # RED/flow-valve (red-penalty-box)
  29. options         ALTQ_HFSC       # Hierarchical Fair Service Curve
  30. options         ALTQ_LOCALQ     # Local queueing discipline
  31. options         ALTQ_PRIQ       # Priority Queueing
  32. options         ALTQ_RED        # Random Early Detection
  33. options         ALTQ_RIO        # RED with IN/OUT
  34. options         ALTQ_WFQ        # Weighted Fair Queueing

Enable this if they aren’t by default:

  1. pseudo-device bpfilter                # Berkeley packet filter
  2. pseudo-device pf                      # PF packet filter
  3. pseudo-device pflog                   # PF log if

Increase the memory available in kernel to a value specific to your available memory. The memory available to the firewall, among others, depends on it.

  1. options       NMBCLUSTERS=16384

Then build the kernel:

  1. cd /usr/src/sys/arch/`machine`/conf/
  2. config ./TransparentFirewall
  3. cd ../compile/TransparentFirewall/
  4. make depend  && make

Save the old kernel and copy the new one:

  1. cp /netbsd /netbsd.original
  2. cp /usr/src/sys/arch/`machine`/compile/MYKERNEL/netbsd /netbsd

and do a simple reboot.
If you encounter problems, read the available documentation.
Mainly, you can return to the original kernel using, at boot, the following commands:

  1. boot netbsd.original -s
  2. fsck /
  3. mount /
  4. mv netbsd.old netbsd
  5. reboot

Now that you have a working kernel supporting the pf firewall and traffic shaping (ALQ options specified), you can start configuring the transparent firewall. Basically, as the documentation says, you can achieve this by setting up bridge between two physical NIC and filtering packets on one of them, using pf.

It is possible to set one of the interfaces to have an IP address for administrative purposes (static / dhcp) or use another network interface. The later strategy was adopted.

The re0 and re1 (Realtek driver naming) will denote the two bridge interfaces while sis0 will be the administrative interface. For each of these interfaces create a file such as the ones below:

  1. #vi /etc/ifconfig.re0
  2. up
  1. #vi /etc/ifconfig.re1
  2. up

and the configuration interface:

  1. #vi /etc/ifconfig.sis0
  2. up
  3. dhcp

To configure the bridge to use cycle detection (STP) and packet filtering:

  1. #vi /etc/ifconfig.bridge0
  2. create
  3. !brconfig bridge0 add re1 add re0 up stp re1

Now you have to set up the /etc/rc.conf. A sample configuration file is:

  1. rc_configured=YES
  2. dhclient="YES"  #<- comment if you don't need DHCP for the configuration interface
  3. sshd="YES"
  4. hostname=mycomputer.mynetwork
  5. firewall_enable="YES"
  6. pf=YES                           #enable pf
  7. pf_rules=/etc/pf.conf        #pf configuration file
  8. pf_program="/sbin/pfctl"  
  9. pf_flags=""
  10. pflogd=YES
  11. inetd=NO  
  12. syslogd=YES
  13. pflog_enable="YES"                 #log network packets, similar to ulog on GNU/Linux
  14. pflog_logfile="/var/log/pflog"    #log file location
  15. pflog_program="/sbin/pflogd"
  16. pflog_flags=""

and … reboot. You’ve just built a bridge using NetBSD.

The last thing you have to do is to set the firewall rules. Please note that despite the fact that we have built a bridge, Layer 2 device, we have access to the whole packet information. This has to do with the way the bridge code uses the BPF interface to copy packets from one interface to the other.

The main feature that distinguishes PF from iptables is the fact that rules that don’t employ the “quick” keyword are not definitive. In iptables, the action taken by the firewall is given by the first matching rule. In PF the action is given by the last matching rule or a rule having the “quick” keyword.

Therefore

  1. #vi /etc/pf.conf
  2. block in all
  3. pass in inet proto tcp from any to any port ssh

will allow just ssh session to be established, while

  1. #vi /etc/pf.conf
  2. pass in inet proto tcp from any to any port ssh  
  3. block in all

will block any packets from entering the local network.

A feature similar to the one provided by ulog is given by:

  1. #vi /etc/pf.conf
  2. block in log (all to pflog0) all
  3. block out log (all to pflog0) all

which will block all the packets and log them to pflog0. The packets could be later retrieved from the pflog0 interface using tcpdump or from /var/log/pflog (as specified in rc.conf).

Another awesome feature is that this interface is clonable. That is if we create a file with the content:

  1. #vi /etc/pflog1
  2. up

a new (cloned) logging interface is created. NetBSD supports many such interfaces. We can then specify firewall rules that send packets to different logs.

  1. #vi /etc/pf.conf
  2. block in log (all to pflog0) all
  3. block out log (all to pflog1) all

Thats it folks ! I will write a more advanced firewall configuration in a next post.

Finding which process has opened a specific help

Posted by marian on October 18, 2009

There are a number of situations when one has to know the PID of the process that opened a port; this situations include, but are not limited to:

  • you design Web Applications, someting has when terribly wrong, and you need to kill the webserver; you can either search for its PID or you can use the fuser command:
    1. fuser -n tcp 80

    As a matter of fact, I have to kill Tomcat quite often.
    Another situation when you need to know the PID is when you think that your computer is being gacked :)

The “Wizard tool” tcpdump

Posted by marian on July 22, 2009

Shortly speaking TCPDUMP is an excellent tool for dumping the network traffic for latter analysis.
Personally I like:

  1. tcpdump -w sample.cap -s 0

This dumps all the network traffic to the file sample.cap while keeping the whole packets intact.
One should notice that using the “-s” option you can specify how many bytes from the start of packet will be retained.
The resulting file can be further interpreted and important conclusion can be drawn.