Ferm je zkratkou pro „for Easy Rule Making“ a za chvilku poznáte, že svého jména dostojí. Ferm byl navržen pro správu komplexních firewallů s možností jejich pohodlné úpravy. Pravidla jsou popsána ve speciálním jazyku navrženém tak, aby se psala co nejlépe. Na pozadí se schovává přibližně 3000 řádků perlovského kódu. Společně s ferm je distribuována utilitka import-ferm, která dokáže vytvořit konfigurační soubor pro ferm z aktuálně nastavených pravidel v iptables.
Instalace
Většina distribucí má ferm v repositáři, nicméně třeba Debian obsahuje verzi 2.0.7 ze začátku roku 2010, takže určitě mrkněte na changelog, zda se vám něco z novějších verzí nebude hodit. Vzhledem k přítomnosti ferm v repositářích je instalace jednoduchá:
Debian/Ubuntu: apt-get install ferm
ArchLinux: pacman -S ferm
Gentoo: emerge ferm
Fedora/CentOS: yum install ferm
Po instalaci najdete konfigurační soubor fermu v /etc/ferm.conf. Restart pravidel se provádí init skriptem, který se postará i o včasné nahození.
/etc/init.d/ferm restart
Syntaxe
Konfigurační soubor má vlastní syntaxi přizpůsobenou svému účelu. K jejímu pochopení se podívejte na následující příklad, který je v mírně upravené podobě použit také jako motivační příklad na domovské stránce.
domain ip table filter {
chain INPUT {
policy DROP;
mod conntrack ctstate (RELATED ESTABLISHED) ACCEPT;
proto tcp dport (http ftp ssh) ACCEPT;
}
}
Těmito sedmi řádky zakážeme provoz na lokální stroj a povolíme pouze spojení, která byla iniciována ze strany stroje. K tomu se povolí porty pro SSH, FTP a web. Důležité je si všimnout řetězce identifikujícího paket. Například když budeme chtít povolit kohokoli, kdo přistupuje z adresy 10.0.0.1 a 10.0.0.2, možnosti jsou následující:
domain ip table filter chain INPUT saddr 10.0.0.1;
domain ip table filter chain INPUT saddr 10.0.0.2;
Pokud se nám to zdá jako mnoho řádek, použijeme:
domain ip table filter chain INPUT saddr (10.0.0.1 10.0.0.2);
Doména určuje, zda se jedná o IPv4 (ip) nebo IPv6 (ip6), a protože je výchozí IPv4 (ip), tak ji nemusíme psát.
domain ip table filter chain INPUT saddr (10.0.0.1 10.0.0.2);
Pravidlo by bylo navíc zbytečné, kdyby nebyla nastavena výchozí politika.
table filter chain INPUT {
policy DROP;
saddr (10.0.0.1 10.0.0.2) ACCEPT;
}
Všimněte si rozdílu při použití kulatých a složených závorek. Zatímco složené závorky říkají, že v tomto kontextu chcete uvést více pravidel, do kulatých závorek se dává seznam hodnot, jako jsou IP adresy nebo porty.
Ferm umí pracovat také s proměnnými a funkcemi. Proměnná se definuje takto:
@def $ip = 10.0.0.1;
A pak je možné ji použít v pravidle opět s dolarem:
table filter chain INPUT {
policy DROP;
saddr $ip ACCEPT;
}
Hodnotou může být port, IP adresa, několik portů, rozsah IP adres a podobně. Proti tomu funkce seskupují část pravidel, abyste je nemuseli opakovat. Například povolení služby pro IPv4 i IPv6 může řešit takováto funkce:
@def &ENABLE_SERVICE($port, $proto) = {
domain ip table filter chain INPUT proto $proto dport $port ACCEPT;
domain ip6 table filter chain INPUT proto $proto dport $port ACCEPT;
}
Je použita podobná syntaxe jako u proměnný, pouze přibyly parametry a hodnotou jsou pravidla. Přístup k web serveru povolíme třeba tímto způsobem:
&ENABLE_SERVICE(http, udp);
Pravidla, která funkce obsahují, se vloží na místo jejich volání. To znamená, že je nemusíte volat takto samostatně, ale můžete je zahrnout dovnitř table filter chain INPUT { .. }. Kompletní firewall nakonec může vypadat třeba takto:
table filter {
chain INPUT {
policy DROP;
mod conntrack {
ctstate INVALID DROP;
ctstate (RELATED ESTABLISHED) ACCEPT;
}
interface lo ACCEPT;
proto icmp ACCEPT;
saddr 10.1.3.0/24 ACCEPT;
}
chain OUTPUT policy ACCEPT;
chain FORWARD policy DROP;
}
domain ip6 table filter {
chain INPUT {
policy DROP;
mod conntrack {
ctstate INVALID DROP;
ctstate (RELATED ESTABLISHED) ACCEPT;
}
interface lo ACCEPT;
proto icmpv6 ACCEPT;
saddr 2002:542b:6802:1000::/64 ACCEPT;
}
chain OUTPUT policy ACCEPT;
chain FORWARD policy DROP;
}
&ENABLE_SERVICE(ssh, tcp);
&ENABLE_SERVICE(domain, tcp);
&ENABLE_SERVICE(domain, udp);
&ENABLE_SERVICE(9091, tcp);
&ENABLE_SERVICE(9981, tcp);
&ENABLE_SERVICE(9982, tcp);
&ENABLE_SERVICE(http, tcp);
&ENABLE_SERVICE(8080, tcp);
Pokud jste konfigurační soubor právě dotvořili, určitě ho chcete vyzkoušet. Předtím můžete ověřit, zda je vše syntakticky v pořádku a to pomocí programu ferm s parametrem -n. Když máte v konfiguračním souboru chybu, ferm vám sdělí kde a ukáže část kódu:
# ferm -n /etc/ferm.conf
Error in /etc/ferm.conf line 46:
domain ip6 table filter
{
chain INPUT
{
a <--
Unrecognized keyword: a
Když je vše v pořádku, stačí restartovat ferm pomocí init skriptu.
Tady by váš zájem o ferm rozhodně neměl opadnout, protože tento článek nemůže popsat všechny možnosti 12 let vyvíjeného skriptu. Určitě se podívejte na příklady na domovské stránce:
A nakonec to nejdůležitější, manuál ze stejného zdroje, kde jsou popsány všechny možnosti, které ferm nabízí.
Shrnutí
Ferm se nesnaží schovat komplexnost iptables a ip6tables, ale dává jí takovou formu, která se snadno čte a upravuje. Poslední verze byla vydána v prosinci minulého roku a každá další se objevuje po dvou až šesti měsících. Projekt je tedy aktivně vyvíjen i přes své stáří (12 let) a v další majoritní verzi (3.0) bychom se měli dočkat podpory pro traffic control (tc). Ferm by se tak mohl stát nástupcem dnes už mrtvého projektu tcng.