-
Notifications
You must be signed in to change notification settings - Fork 19
Home
It's still a stupid name. Suggestions are still welcome! Anyway, we might as well keep our architecture plans here.
The library we're using is a Python binding to the C NetfilterQueue library. It has two classes:
-
NetfilterQueue
- a queue of packets from the kernel waiting for a routing decision from us.-
bind(queue_num, callback)
- bind toqueue_num
. Also, sets thecallback
for each packet that arrives in the queue. -
unbind()
- unbind our queue -
run()
- block waiting for packets, calling the callback function for each packet.
-
-
Packet
-
get_payload()
- Gets the packet payload. -
get_payload_len()
- Gets the payload length -
accept()
- Send the packet back to the kernel to be forwarded up the network stack. -
drop()
- Block this packet from going further.
-
The callback function takes a single argument, an instance of Packet
.
I'm going to stick mostly to the design that IPTables has. The way IPTables works, in a nutshell, is that it has these things called "chains". A packet enters the "INPUT" chain, and gets matched against each rule in the chain sequentially. A rule has a predicate, and an action (which is a jump to a new chain). The first rule in the chain that the packet matches, it follows. The "ACCEPT" and "DROP" chains are the final destinations for packets. Here is a simple example:
Input Chain
- If TCP Packet, goto TCP chain
- If UDP Packet, goto UDP chain
- If it's an ICMP packet, do the proper response
- Otherwise, goto DROP
TCP Chain
- If it's with an existing connection, goto ACCEPT
- If it's an incoming connection, goto DROP
- If it's invalid, goto DROP
UDP Chain
- Goto ACCEPT
OK, so here's going to be our class architecture for this (of course, suggestions are more than welcome).
-
PyWall
- the main firewall class.- Constructor - TBD, probably will just have the NFQueue number.
-
add_chain(name)
- add a chain with the given name. I don't think we need a chain class, as it's just a list of rules. -
add_rule(chain, rule)
- add a rule to the end of the chain. -
run()
- Callsrun
on the NetfilterQueue object. -
callback(packet)
- processes a packet: start at INPUT
-
Rule
- a rule class (or function). We can use functions for simpler rules, and classes for rules that need to share state.-
__call__(packet)
- apply the rule. ReturnFalse
if it doesn't match. Otherwise, return the name of the next chain for that packet.
-
I'm thinking we will want to write our own Packet class as well, with TCP and UDP subclasses. When we receive a packet, we can parse it into our own class, and that way the rules won't have to do packet mangling.
OK, so we'll need to implement the following rules:
- Source address
- Destination address
- Source port (TCP/UDP)
- Destination port (TCP/UDP)
- TCP flags
- TCP connection tracking
And probably some more, which we can come up with after we've completed the basics.