The Gypsum Declarative Firewall Tool

Gypsum is a tool that I wrote for myself to write firewall rules in a declarative fashion.

Gypsum takes a YAML file as input and produces a shell script full of iptables commands as output.

Gypsum is implemented in python.  You can browse gypsum's source code.  Browsing the code of gypsum's unit tests may help you understand how I use it and how it could be extended. 

You can download the gypsum source code.  It doesn't have a license on it now, but if it would be useful, let me know and I'll slap a GPL3 header on there.  You can also download the unit tests and the simple policy file required to run them.

To try gypsum for yourself download gypsum.py and simplepolicy.yml to the same directory and run, at the command line:

python gypsum.py simplepolicy.yml

To run the unit tests download testgypsum.py and simplepolicy.yml to the same directory and run, at the command line:

python testgypsum.py

Gypsum policy files are YAML documents.  The top level should be a list, each element of the list represents an access level. The following is a complete gypsum policy with only one security level:

-

access: Restricted
servers:
- { ip: 192.168.0.10, port: [http, https] }
clients:
- { ip: 192.168.1.0/24 }
 
Each security level is dictionary (or hash if you speak PERL) with three required keys:  The value of the item with key access is an arbitrary name you choose for the access level.  This will be used in the chain names of the iptables output for readability's sake.  The value of the item with key servers is a list as is the value of the item with key clients.

Each element of a server or client list can be a dictionary or the keyword "ANY." The keyword ANY in the client list for an access level means that any packet that doesn't match a more specific rule in the firewall will be handled at that access level.  The keyword ANY in the server list for an access level means that any packet from a client granted that level of access will be allowed through. If a dictionary appears in the client list of an access level it represents rules for matching what clients are granted access to that access level.  If a dictionary appears in the server list of an access level it represents the rules for matching what servers can be accessed by clients at that level of access. Valid keys in a dictionary appearing in a client or server list are ip and port.  The value of ip can be an IP address in dotted quad notation(e.g. 192.168.0.10), a network in CIDR notation(e.g. 192.168.0.0/24 or 172.16.0.128/29) or a range of IP addresses represented by the starting IP address in dotted quad notation followed by a dash followed by the ending IP address also in dotted quad notation(e.g. 192.168.1.1-192.168.1.5) or a YAML list of any of these.  The value of the port field can be an integer TCP port number(e.g. 22), a service name that can be resolved to a TCP port number via the getservbyname C library function(e.g ssh or https), or a protocol followed by a slash followed by a port or service name (e.g. udp/domain, udp/1234 or tcp/8080) or a YAML list of any of these. An exclamation point at the beginning of one of the above strings inverts the sense of the match.

For the future:

I'm interested in extending gypsum to produce pf output and output for other firewall applications.  I would like to experiment with ways to test firewall performance and modify gypsum to produce performance optimized output.

I would like to try to modify gypsum to produce host specific output from a shared configuration. This would allow me to provide only the information that that host needs to enforce it's own firewall rules. This feature would allow secure centralized management of host based firewalls at the same time as the routing or bridging firewalls that connect those hosts.

The same configuration that gypsum uses to produce manage a firewall application could also be used to produce and evaluate real world tests or availability monitors.  I've done most of my firewall testing with nmap, nmap and netcat or with awkward iptables hacks.  I'd like to be able to run some automated sanity checks without so much pain.

If you have ideas for gypsum, or gypsum inspires any related thinking, I'd love to hear about it.  Patches are welcome, too.
comments powered by Disqus