UNIX a Internet

Firewally & Proxy

Autor: Jiří Hnídek / jiri.hnidek@tul.cz

Firewall

“Pojem firewall označoval původně protipožární zeď, která slouží pro oddělení ohně v budově, aby se nešířil dále.”

Proxy

“The authority to represent someone else, especially in voting.”

Dělení firewallů

  • Podle stavu: stavové/bezestavové
  • Podle síťové vrstvy, na které pracují
  • Podle implementace: kernel space/user space

Bezestavové firewally

  • Každý paket posuzuje zvlášť
  • Neudržuje si informace o spojení (např.: TCP spojení)
  • Vhodný na velké datové přenosy s velkým množstvím spojení (paměťová a výpočetní náročnost).

Stavový firewall

  • Udržuje si informace o stavu každého spojení.
  • Paměťově i implementačně náročnější.
  • Například u TCP si musí pamatovat: zdrojovu adresu+port, cílovou adresu+port, čas přijetí/odeslání posledního paketu.
  • U protokolu UDP nelze použít stejným způsobem (není to spojový protokol).
    • Pokud ovšem klient pošle UDP paket na adresu+port, tak stavový firewall propustí "odpověď".
  • Bezpečnější než bezestavový firewall - dokáže odfiltrovat pakety nepatřící do spojení.

Firewall a síťové vrstvy

  • Linková (MAC adresy)
    • Většinou na routeru
    • Ochrana proti podvržení IP adresy: ARP Spoofing, DHCP Snooping, atd.
  • Síťová vrstva (IPv4 a IPv6 adresy)
    • Filtrování provozu ven/dovnitř síťové prvku
    • Předávání provozu
  • Transportní vrstva (TCP, UDP, atd.)
    • Filtrování provozu na základě portů. Úzce souvisí se stavovým firewallem (TCP).
  • Aplikační vrstva (HTTP, FTP, SMTP, atd.)
    • Je prozkoumáván obsah přenášených dat.

Firewall v Linuxu

  • Pravěk: ipfwadm, ipchains
  • 2016: netfilter
    • Konfigurační nástroje: iptables, ip6tables, firewall-cmd
    • Další konfigurační nástroje: ebtables (linková vrstva), arptables (ARP), conntrack
  • Budoucnost: nftables

netfilter

  • Framework pro filtrování paketu od Linuxu 2.4
  • Skládá se z jaderných modulů (ip_tables, iptable_filter, iptable_mangle, ...) a nástrojů iptables/ip6tables
  • Netfilter má na záchytných bodech (hooks) v jádře zaregistrované callback funkce, které se volají pro každý paket procházející tímto záchytným bodem.
  • Nástroje iptables/ip6tables definují v uživatelském prostoru tabulky pravidel.

Vlastnosti netfilteru

  • Stavový i bezestavový IPv4/IPv6 paketový filter
  • NAT a maškaráda
  • Modulární systém

Záchytné body netfilteru

Netfilter definuje 5 záchytných bodů, kde se volají callback funkce:

  • NF_IP_PRE_ROUTING: při přijetí paketu před tím, než se rozhodne, jak se bude paket směrovat
  • NF_IP_LOCAL_IN: paket má cíl na daném stroji
  • NF_IP_FORWARD: paket se má předat dál
  • NF_IP_IP_LOCAL_OUT: paket byl vytvořen na daném stroji
  • NF_IP_POST_ROUTING: před odesláním mimo stroj.

Cesta paketu v jádře Linuxu

Než paket dorazí do socketu, tak jeho cesta může být hodně komplikovaná:

IPTables

  • Tabulky řetězců (chains) pravidel jak zacházet s paketem.
  • 5 základních řetězců odpovídají záchytným bodům netfilteru.
  • Lze definovat další řetězce pravidel.
  • Uživatel root může pravidla přidávat/měnit/mazat pomocí příkazu iptables a ip6tables

Základní řetězce pravidel

Iptables obsahují 5 základních řetězců pravidel:

  • PREROUTING je spouštěn: NF_IP_PRE_ROUTING
  • INPUT je spouštěn: NF_IP_LOCAL_IN
  • FORWARD je spouštěn: NF_IP_FORWARD
  • OUTPUT je spouštěn: NF_IP_LOCAL_OUT
  • POSTROUTING je spouštěn: NF_IP_POST_ROUTING

Tabulky pravidel

Iptables obsahují 5 tabulek s řetězci pravidel

  • filter: výchozí tabulka k filtrování paketů. Obsahuje základní řetězce pravidel: INPUT, OUTPUT a FORWARD
  • nat: tabulka pro NAT. Základní řetězce pravidel: PREROUTING, OUTPUT, POSTROUTING
  • mangle: tabulka pro změnu paketů: PREROUTING, INPUT, OUTPUT, FORWARD, POSTROUTING
  • raw: pravidla před tabulkou filter. Řetězce: PREROUTING, OUTPUT
  • security: pro SELinux. Řetězce: INPUT, OUTPUT, FORWARD

Teď se to trochu komplikuje, ale v praxi si člověk většinou vystačí s tabulkou filter a řetězcem INPUT.

Příklad pravidla

Pravidla (pro IPv4) můžeme vypsat pomocí:

iptables -t filter -L -v -n --line-numbers

Pro IPv6 pomocí:

ip6tables -t filter -L -v -n --line-numbers

Může vypsat spoustu pravidel. Jedním z nich bude třeba:

Chain IN_public_allow (1 references)
num   pkts bytes target     prot opt in     out     source               destination         
1        0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:22 ctstate NEW

Cíl (TARGET) pravidla

  • Každé pravidlo je ukončeno nějakým cílem (TARGET). Základní cíle jsou
    • ACCEPT: paket je v dané tabulce řetězců přijat
    • DROP: paket je zahozen
    • RETURN: paket již neprochází daným řetězcem pravidel a jeho zpracování se vrací do nadřazeného řetězce
  • Existují další cíle (LOG, MARK, TEE, TOS, REJECT, atd.). Více v man iptables-extensions
  • Některé cíle lze použít pouze v některých tabulkách.

Implicitní cíl

  • U základních řetězců je implicitní cíl ACCEPT
  • Prázné tabulky propustí všechny pakety a žádný paket nezmění.
  • Ve výchozím nastavení jsou řetězce pravidel prázdné
  • Uživatelsky definované řetězce implicitní cíl nemají
    • Můžeme využít cíl RETURN

Iptables - Best Practice

  1. Použít nějakou nadstavbu pro lidské bytosti
    • firewall-cmd příkaz pro definici pravidel.
    • firewall-config dost nepovedený program s GUI.
  2. Použít iptables s rozmyslem
    • V tabulce filter v chainu INPUT nastavit implicitní cíl na DROP.
    • Povolit jen běžící služby

Iptables - Příklad konfigurace

Uvažujeme nastavení na serveru, kde chceme povolit: ping, spojení na webový server (port 80) a vzdálenou správu pomocí SSH (port 22). Budeme tudíž nastavovat pouze tabulku filter a řetěz pravidel INPUT.

Iptables - s čistým štítem

Začneme tím, že smažeme všechna pravidla (IPv4):

iptables -t filter -F INPUT

Toto musíme udělat i pro protokol IPv6:

ip6tables -t filter -F INPUT

Kopírování příkazů pro IPv6 je pěkná otrava. Další příklady příkazů budou pouze pro IPv4.

Jelikož tabulka filter je defaultní, tak není nutné psát neustále parametr: -t filter.

Změna implicitního cíle

Implicitní cíl je v základním řetězci ACCEPT. Změníme ho na DROP:

iptables -P INPUT DROP

Povolujeme služby

Začneme povolením ICMP paketu se zprávou "Echo Request":

iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT

Povolíme TCP pakety přicházející na porty (80 a 22)

iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT

Tím jsme získali bezestavová firewall.

Iptables a stavový firewall

Iptables se většinou používají ve funkci stavového firewallu. K tomu účelu slouží module conntrack.

Tento modul si pamatuje všechna TCP spojení. Příklad:

iptables -F INPUT
iptables -P INPUT DROP
# Povolíme pakety patřící k existujícím spojením
iptables -A INPUT -m conntrack --state ESTABLISHED,RELATED -j ACCEPT
# Povolíme ping
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
# Povolíme SYN pakety pro nová spojení na povolené služby
iptables -A INPUT -m conntrack -ctstate NEW -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -m conntrack -ctstate NEW -p tcp --dport 80 -j ACCEPT

Conntrack a existující spojení

Existující spojení lze vypsat pomocí:

cat /proc/net/nf_conntrack

Další omezení

Například v případě SSH nechcete, aby bylo možné se na daný stroj přihlásit z celého internetu. Možnost připojit se je vhodné omezit na nějakou (důvěryhodnou) podsíť:

iptables -A INPUT -m conntrack -ctstate NEW -s 147.230.0.0/16 \
	-p tcp --dport 22 -j ACCEPT

Spojení lze omezit jen na vybrané síťové rozhraní:

iptables -A INPUT -i eth0 -m conntrack -ctstate NEW \
	-p tcp --dport 80 -j ACCEPT

Omezujeme počet požadavků

Počet požadavků za časové období (sekunda, minuta, atd.) lze omezit například pomocí modulu limit:

iptables -A INPUT -p icmp --icmp-type echo-request \
	-m limit --limit 1/s --limit-burst 10 -j ACCEPT 

Omezí počet ICMP paketů "Echo Request" na 10 za sekundu.

V případě zahlcení od většího množství strojů z nějaké podsítě je možné použít modul connlimit:

iptables -p tcp --syn --dport 80 -s 147.230.0.0/16 \
	-m connlimit --connlimit-above 16 -j REJECT

Pozor: Používat s rozmyslem, aby nedošlo k omezení regulárního provozu.

Iptables jako služba

  • Na starších linuxových distribucích (RedHat/CentOS 4/5/6 i jiných) se pravidla iptables nastavovalala pomocí init skriptu.
  • Tento init skript se staral i o restartování, znovunačtení konfigurace vypnutí, apod.
  • Restatování nebo znovunačtení konfigurace mělo za následek např. zrušení spojení, vynulování čítačů, apod.

Firewalld a firewall-cmd

  • Na RedHat/CentOS 7 se o nastavení pravidel iptables stará démon firewalld.
  • Firewalld stále používá iptables pro nastavení řetězců pravidel.
  • Pro konfiguraci pravidel se ale používá příkaz firewall-cmd a jeho syntaxe je odlišná od iptables.
  • Firewalld přichází s koncepcí bezbečnostních zón.
    • Příklad: na notebooku můžete mít jiná pravidla doma, v práci, v kavárně.
  • Někteří staromilci firwalld vypínají a používají starý init skript iptables.

Firewall-cmd

Další informace k nalezení na http://jirihnidek.github.io.

NAT

“Die, IPv4. Die!.”

Hole Punching

Stavový firewall není všemocný. Na následujícím kódu si ukážeme, že se lze za určitých podmínek připojit na port, který není na stavovém firewallu explicitně povolen.

https://gist.github.com/jirihnidek

Děkuji za pozornost. Nějaké otázky?

Reference

Seznam zajímavých odkazů k tomuto tématu: