The Multi-Layer Firewall Daemon (mlfd)Author: James TayEmail: james@2longbeans.net Date: 27th June 2004 Updated: 1st Sept 2004 |
|
There are currently many solutions implementing firewalls for layers 2 to 4 (IP, TCP, UDP, etc). Many of them do a wonderful job filtering packets based on policies the administrator configures. Unfortunately, there are certain situations whereby the basis of implementing certain filter rules is not so straight forward, and thus cannot be automated. This may be due to complex business logic, changes in server workload conditions, or recognition of a certain attack pattern.
The objective of mlfd is to perform analysis of data at layers 4 and above. Many platforms (eg Solaris, Linux, etc) have builtin packet filter capability based on rules expressing policies in terms of layer 2 and layer 3. Mlfd's job is to continue the filter process by doing analysis on layers 4 to 7. The main problem of trying to firewall at this level is, there is absolutely no fixed manner of expressing policies. It will also be almost impossible to design a syntactical means of expressing policies. Since the variables and algorithms to determine allow or deny are almost infinite, mlfd does not attempt to actually perform this analysis. Instead, it passes data from layers 2 and 3 to dynamic modules which perform the actual analysis. Based on the results of this analysis, the modules will then advise mlfd on whether to apply filter policies at layer 2/3.
Nothing is better than a (naive) example. Let's say you are running a POP service and somebody on the Internet has decided to use your POP service to guess usernames and passwords on your server. As a responsible sysadmin, you've configured your POP server to lockout an account for 15 mins if you get more than 5 password failures in a 1 minute window. Let's say the attacker starts guessing passwords for user "john". Your POP server disables the account after 5 failures. In the meantime, the real "john" tries to POP his mail and fails. Well, as it turns out, this attacker isn't stopping and continues to throw password guesses. Poor "john" will never be able to POP his mail until the attacker stops, or you manually put an IP filter which blocks packets coming from the attacker. What you want, is a daemon which can monitor packets on the POP port, recognise POP password error messages and automatically insert packet filter policies to block out whatever IP he is coming from.
This is what mlfd is designed to do. A dynamic module is designed to understand messages in a POP conversation. Perhaps it observes a lot of "-ERR Login failed" responses repeatedly sent to a host on the Internet. It then tells mlfd, "please block packets from IP a.b.c.d for a duration of 1 hour." A packet filter policy is inserted by mlfd, and automatically removed after 1 hour.
Mlfd begins by spawning threads for each capture expression the user wants layer 7 analysis for. Packets captured within each thread are read off the wire by libpcap. Once captured, mlfd passes the packet to dynamically loadable modules which will perform analysis. The modules themselves, upon deciding on what needs to be done, can communicate with mlfd, advising it to perform an allow or deny action. Mlfd then interacts with the OS to enforce the actual packet filter policies. A module may also indicate to mlfd that a current TCP session should be immediately terminated. Mlfd will then inject a RST packet for that particular TCP session, causing it to shutdown immediately.
It is important to note that mlfd does not perform any analysis, but forms the infrastructure for providing a runtime environment to the modules which implement the actual firewall policies. Mlfd provides the following runtime services :
In layer 2/3 firewalls, IP policies form the rules by which allow/deny actions are performed. However, in mlfd, dynamic modules form the program logic which evaluates data in order to determine allow/deny actions. Thus adding or removing rules in mlfd is performed by loading or unloading modules during runtime.
Action starts when a packet is captured by the pcap expression specified within a particular thread. If not already done, mlfd loads the specified dynamic module and executes a function in the module. The module is passed the payload of the packet. After analysis, the module returns a structure to mlfd. Within this structure there may contain instructions for mlfd to manipulate packet filter policies. After this, the thread sleeps until the next packet is captured by pcap and the process repeats itself. At times, the code within a module needs to pass data it processed to its subsequent calls. Thus, mlfd provides a pseudo malloc facility which allows buffers used within a module to be passed into subsequent calls or subsequent modules within the stack.
Processing speed of the code within the modules is critical. Assuming a fastethernet network with small 100 byte packets, you will be receiving packets at a rate of 1 every 8 microseconds. On a 1 GHz CPU, this works out to 8000 clock cycles per packet. Since memory access probably will not always hit the CPU's L1/L2 cache, we'll assume an average of 40 cycles per memory operation. This gives you 200 cache-miss memory operations per packet. At the time of writing, mlfd has a worst case throughput of about 2Mbps. This has been tested using gcc -O2, and run on an Ultrasparc IIe. It consumes approximately 2,400 cpu cycles for every byte of data.
Mlfd is currently under development and is not ready for deployment. It currently can function as a proof of concept but there has been insufficient testing to fully explore its behavioral characteristics under various OSes and hardware platforms.
| Task | Date | Status |
| Config file parser | 6th July | Completed |
| Multithreaded packet capture is working. Config reloads on HUP | 13th July | Completed |
| MLFD_MALLOC and MLFD_FREE implemented. Pages retained after exit. | 17th July | Completed |
| Act on BLOCK requests from returning modules. | 23rd July | Completed |
| Inject RST upon request from returning modules. | 3th Aug | Completed |
| TCP sequence tracking. | 11th Aug | Completed |
| Packet reinjection upon modules giving the go-ahead. | 31st Aug | Completed |
| Remove IP filter policies upon program exit. | Future work... |
Mlfd has been tested to work under the following situations.
Mlfd does not work under the following situations.