4.4. Firewall module

The firewall modules needs to allow other modules to insert custom NAT and filtering rules. It has a limited API that lets modules modify the filtering rules. For example, if a module needs to connect to HTTP servers in the internet, it could call addOutputRule and the firewall will open the necessary ports.

However this mechanism is not very flexible since there may be modules with very specific needs. The squid module needs to set up several NAT and filtering rules for its transparent mode of operation.

The EBox::FirewallObserver class was created for these complex cases. Whenever the firewall is restarted it asks all modules that inherit from EBox::FirewallObserver to see if they want to insert custom rules. Modules can insert any rules they want, with the iptables syntax, the only thing they cannot control is where exactly those rules are placed, the firewall modules keeps several hooks along the different chains and tables where it will put these custom rules.

EBox::FirewallObserver defines two methods:

firewallHelper should return undef (the default behavior) or an object of type EBox::FirewallHelper. This class defines several functions that return rules that the firewall will insert in each one of the hook places defined for this purpose.

The syntax of the rules provided by the modules is simple: just use the same syntax you would use in the iptables command line but exclude the chain, the table and the iptables command at the beginning.

These are the methods defined in EBox::FirewallHelper, each one of them for a different type of rule, all of them return a reference to an array that holds the rules:

prerouting

Rules returned by this method are added to the PREROUTING chain in the nat table. You can use them to do NAT on the destination address of packets.

postrouting

Rules returned by this method are added to the POSTROUTING chain in the nat table. You can use them to do NAT on the source address of packets.

forward

Rules returned by this method are added to the FORWARD chain in the filter table. You can use them to filter packets passing through the firewall.

input

Rules returned by this method are added to the INPUT chain in the filter table. You can use them to filter packets directed at the firewall itself.

output

Rules returned by this method are added to the OUTPUT chain in the filter table. You can use them to filter packets originated in the firewall itself.

Warning

You should be careful with the firewall rules you write, as they may open serious security holes in eBox.

If you need more information on how iptables and Netfilter work, check the NAT Howto and the Packet filtering Howto in the Netfilter web site. Example 4.3 shows the output implementation in the EBox::FirewallHelper defined by the squid module.

Example 4.3. Creating custom firewall rules

sub output
{
        my $self = shift;
        my $sq = EBox::Global->modInstance('squid');
        my @rules = ();
        push(@rules, "-m state --state NEW -p tcp --dport 80 -j ACCEPT");
        push(@rules, "-m state --state NEW -p tcp --dport 443 -j ACCEPT");
        return \@rules;
}

usesPort receives three arguments: protocol, port and network interface. This method is used to ask modules if they use a certain tcp or udp port, it lets the firewall know if it's a good a idea to let a port redirection be created or not. It returns true if the module uses the given port and undef otherwise.