Pyroman
=======

A flexible and fast firewall tool

**The good:**

* **Really fast** compared to sh+awk based solutions due to using `iptables-restore`
* **Rollback to previous firewall on error** to minimize risk of use
* Also useful in single-shot mode, for example with `iptables-persistent`
* Detailed **error reporting** to help configuring
* Easy syntax to add hosts, nats
* Designed for complex networks
* Written in easy to read python code
* Extensively documented (Python docstrings)
* You can add custom iptables rules when needed
* Lots of verification checks done before execution
* Designed to use the same configuration files on multiple hosts (e.g. failover firewalls or the destination host itself; it will detect if you are talking about a local or a remote host
* **extensible in python**, just write your code into the configuration files
* External firewall-verification script hook (e.g. to check connectivity)
* IPv6 support not thoroughly tested yet

**The bad:**

* Doesn't completely hide iptables complexity from the admin (good or bad?)
* Only iptables, no TC/Shaping, no IPsec, proxy arp setup, VPN, ifconfig (I use other tools for that, e.g. heartbeat)
* In many cases this may by now (due to advances in netfilter) be overkill compared to directly writing the iptables rules

To tease you a little more into testing, here's an example host configuration: ("dmz" is an interface alias - where the web server is connected to -, as are "INT", "DMZ" and "ANY" for clients on these interfaces)

```python
"""
A really simple webserver configuration.
These examples are just boring... ;-)
But without NAT they would be even more boring. ;-)
"""
# web server
add_host(
        name="web",
        ip="10.100.1.2",
        iface="dmz"
)
# offering, well, web service.
allow(
        client="ANY DMZ INT",
        server="web",
        service="www ssh ping"
)
# internal hosts may access FTP, too
allow(
        client="INT",
        server="web",
        service="ftp"
)
# setup NAT
add_nat(
        client="ANY INT",
        server="web",
        ip="12.34.56.80"
)
```
(Yes, this is a python script. No, you probably won't care to write your configuration in a programming language, will you?)

So one of the things that make pyroman very cool is this:
```
Saving old firewall...
**********************************************************************
Beginning firewall initialization...
**********************************************************************
An error occurred. Starting firewall restoration.
Firewall initialization failed. Rollback complete.
Firewall commit failed: Invalid ICMP type `12345', caused by rules/80_workstations.py:16
```

Yes: it restores the previous firewall, and gives me a filename and linenumber as well as a useful error message!
