Hlavní navigace

Ferm: firewall s lidskou tváří

8. 2. 2013
Doba čtení: 4 minuty

Sdílet

Dobrý nástroj pro psaní firewallových pravidel ušetří mnoho času a čím složitější firewall navrhujete, tím více jej uvítáte. Ferm je jedním z těch jednodušších, je napsaný v Perlu, má svou historii a konfigurační soubor s hlavou a patou. Podporuje IPv6 a zařídí, abyste nemuseli psát pravidla vícekrát.

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:

Root online školení

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.

Autor článku

Adam Štrauch je redaktorem serveru Root.cz a svobodný software nasazuje jak na desktopech tak i na routerech a serverech. Ve svém volném čase se stará o komunitní síť, ve které je již přes 100 členů.