Documente Academic
Documente Profesional
Documente Cultură
Iptables
Introducere
Kernelul Linux este capabil să implementeze mecanisme avansate de ltrare a tra cului de
rețea. Prin aceste mecanisme se pot implementa rewall-uri moderne, așa numitele stateful
rewalls sau new-generation rewalls. Generația anterioară, numită stateless rewalls,
asigura ltrarea pachetelor bazată în principal pe adresele sursă și destinație din câmpurile IP
și port. Firewall-urile moderne urmăresc o conexiune pe toată durata ei de viață și pot
discrimina între diferitele stagii în care se a ă conexiunea astfel încât se poate opri o
întreagă serie de atacuri care puteau desfășurate cu ușurință împotriva generației vechi.
Proiectul Net lter (subsistemul din kernel care permite connection-tracking și implicit
stateful rewall) a fost inițiat de Paul “Rusty” Russel în timpul dezvoltării kernelului 2.3.x.
Net lter constă într-o serie de 5 hook-uri în stiva TCP/IP astfel încât se pot înregistra module
kernel pentru a manipula pachetele care traversează aceste hook-uri.
Hooks
În programare, mecanismul de hooks acoperă o gamă de tehnici folosite pentru a modi ca
funcționarea unui sistem de operare, a aplicațiilor sau ale altor componente software, prin
interceptarea apelurilor de funcții și a mesajelor sau a evenimentelor transmise între
componentele de mai sus. Este important de reținut că aceste mecanisme permit modi cări
în timpul funcționării respectivelor componente software, după ce ele au fost lansate în
execuție. Cele 5 hook-uri folosite pentru implementarea rewall-urilor in kernelul Linux sunt
PREROUTING, INPUT, FORWARD, OUTPUT și POSTROUTING.
PREROUTING
Toate pachetele, fără excepție, ajung în PREROUTING, singura condiție ind ca header-ul IP să
e valid. Aici se pot implementa translațiile de port (NAPT, Port Address Translation) și
adresă IP (DNAT, Destination Network Translation).
INPUT
În LOCAL INPUT ajung toate pachetele care au ca destinație nală sistemul local și este
ultimul hook pe care acestea îl traversează, înainte de a consumate de procesul cărora le
sunt destinate.
FORWARD
Pachetele care sunt rutate de către sistem către o altă destinație trec prin acest hook.
OUTPUT
LOCAL OUTPUT este primul hook întâlnit de pachetele care sunt generate de procesele
locale.
POSTROUTING
După ce a fost decisă interfața și destinația spre care este trimis un pachet (routing decision),
acesta ajunge în POSTROUTING. Aici se poate implementa translația de adresă sursă (SNAT
sau Source Network Address Translation). Toate pachetele care părăsesc mașina locală, fără
excepție, ating acest hook.
dacă destinația este sistemul local atunci pachetul trece prin PREROUTING, apoi INPUT;
dacă este transmis de un proces local atunci se duce în OUTPUT, după care în
POSTROUTING;
dacă pachetul doar traversează mașina în drum spre altă destinație atunci traseul este
PREROUTING, FORWARD, POSTROUTING.
Funcții callback
Pentru ecare hook se pot înregistra funcții callback, ecare cu o anumită prioritate care dă
ordinea în care va apelată funcția respectivă. Funcțiile returnează următoarele valori:
Stări
Stările în care se poate a a o conexiune de rețea (state) sunt: NEW, ESTABLISHED, RELATED
și INVALID.
NEW
Conexiunea este în curs de stabilire și pachetul a parcurs cu succes secvența validă de inițiere
— de exemplu, în cazul unei conexiuni TCP, a fost primit pachetul SYN — dar nu a fost încă
primit un răspuns.
ESTABLISHED
Conexiunea a fost stabilită deoarece prin rewall au trecut pachete valide de inițiere și
stabilire a conexiunii în ambele direcții.
RELATED
Un pachet care este în legătură cu o conexiune stabilită deja, se a ă în această stare.
INVALID
Pachetele care nu urmează regulile unei conexiuni sunt marcate astfel.
Componente
Un program din userspace care asigură managementul modulului Net lter este iptables.
Pentru ecare pachet se pot crea reguli (rules) care descriu comportamentul rewall-ului
atunci când un astfel de pachet îl traversează (target).
Regulile pot grupate în seturi de reguli (chains). Unele seturi sunt prede nite iar altele pot
create de utilizator.
Seturile de reguli sunt parcurse în ordine iar dacă un pachet îndeplinește criteriile pentru care
o regulă se aplică atunci pachetul va trimis spre target-ul speci cat de regulă iar
traversarea regulilor se oprește aici. Dacă pachetul nu se potrivește niciunei reguli atunci se
aplică regula implicită (policy).
Tabela FILTER
Aceasta este tabela implicită și conține 3 seturi prede nite ( ecare set se mapează peste
hook-ul corespunzător descris anterior):
INPUT
OUTPUT
FORWARD
# iptables -L -v
Chain INPUT (policy DROP 6 packets, 264 bytes)
pkts bytes target prot opt in out source destination
1650 200K ACCEPT all -- any any anywhere anywhere
state RELATED,ESTABLISHED
0 0 ACCEPT tcp -- eth+ any anywhere anywhere
tcp dpt:ssh
639 38340 ACCEPT all -- tun+ any anywhere anywhere
2 184 ACCEPT icmp -- any any anywhere anywhere
Tabela NAT
Are în compunerea sa 3 seturi prede nite:
PREROUTING
POSTROUTING
OUTPUT
Regulile din seturile tabele NAT pot trimite pachetele către următoarele target-uri:
# iptables -t nat -L -v
Chain PREROUTING (policy ACCEPT 866 packets, 55062 bytes)
pkts bytes target prot opt in out source destination
Tabela MANGLE
Această tabelă servește modi cării pachetelor prin alterarea următoarelor câmpuri:
# iptables -t mangle -L -v
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Tabela RAW
Această tabelă folosește marcării pachetelor care nu ar trebui să ajungă în sistemul de
connection tracking și unicul target este NOTRACK. Tabela RAW are 2 seturi, PREROUTING și
OUTPUT, așa cum o arată și comanda de mai jos:
# iptables -t raw -L -v
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Sintaxa
Sintaxa generală este următoarea:
Table poate una din tabelele prede nite (FILTER, NAT, MANGLE sau RAW) sau o tabela
de nita de utilizator.
Comenzi
Comenzile speci că acțiunea pe care dorim s-o efectuăm. O regulă conține de obicei o
singură comandă.
Adaugă una sau mai multe reguli la chain-ul speci cat. Dacă speci căm un nume de host care
se rezolvă în mai multe adrese IP, va adăugată câte o regulă pentru ecare adresă IP.
Veri că dacă o regulă care se potrivește speci cației există deja, returnând un cod de succes
sau de eroare. Regulile existente nu sunt alterate.
Șterge una sau mai multe reguli din chain-ul speci cat. Comanda acceptă speci cațiile regulii
care va ștearsă sau alternativ se poate da numărul acestei reguli.
Inlocuiește o regulă in chain-ul indicat. Dacă sursa sau destinația se rezolvă în mai multe
adrese IP, comanda va eșua. Regulile sunt numerotate începând de la 1.
Listează toate regulile din chain sau din toate chain-urile, dacă nu este speci cat nici unul
( lter este implicit). Pentru a a șa regulile în detaliu, se folosește iptables -L -v
Aduce la zero contoarele de pachete și de octeți din chain-ul speci cat sau din toate chain-
urile precum și din regula speci cată. Se poate folosi împreuna cu -L, --list (list) pentru a a șa
contoarele înainte de a șterse.
Șterge un chain de nit de utlizator. Nu trebuie sa mai existe o referință la acel chain iar
acesta trebuie sa nu conțină nicio regulă. Dacă nu este speci cat niciun argument, atunci
comanda va încerca sa ștearga toate chain-urile de nite de utilizator.
Setează un target implicit (politică) pentru acel chain. Doar chain-urile implicite pot avea pot
avea o politică și niciun chain nu poate politică.
-h
Parametri
[!] -p, --protocol protocol
Protocolul de rețea la care se referă regula. Poate : tcp, udp, udplite, icmp, esp, ah, sctp sau
"all”. Este acceptată și o valoare numerică ce reprezintă unul din protocoalele anterioare sau
un alt protocol (de exemplu 1 pentru ICMP, 6 pentru TCP etc.). Este permis și un nume de
protocol din /etc/protocols. "!" în fața protocolului înseamnă NOT. "all" (sau valoarea
numerică 0) desemnează toate protocoalele și este valoarea implicită.
Indică sursa, care poate o rețea/mască, un nume de host, sau o adresă IP. Numele de host
sunt rezolvate o singură dată, înainte ca regula sa e inserată. Se poate folosi și --src ca alias.
Dacă sunt speci cate mai multe adrese cu -A sau -D, atunci pentru ecare adresă va creată
sau ștearsă o regulă.
Speci că o extensie care testează o proprietate speci că.Testele sunt evaluate de la stânga la
dreapta și dacă un test returnează fals atunci evaluarea se oprește.
Speci că unde va trimis pachetul dacă regula este validată. Poate un chain de nit de
utilizator, o extensie sau un target prede nit (ACCEPT, DROP, QUEUE sau RETURN).
Numele interfeței pe care a fost primit pachetul (doar pentru pachetele care intră în INPUT,
FORWARD și PREROUTING). "!" folosit înaintea numelui de interfață, inversează sensul. Dacă
numele interfeței se termină în “+” atunci orice interfață care incepe cu acel nume se va
potrivi. Dacă omitem numele interfeței atunci regula se va aplica oricărei interfețe.
Numele interfeței pe care va trimis pachetul (numai pentru pachetele din FORWARD,
OUTPUT și POSTROUTING). "!" și "+" au aceeași semni cație ca mai sus.
Alte opțiuni
-v, --verbose
-w, --wait
Pentru a împiedica mai multe instanțe ale iptables să ruleze în același timp, programul
încearcă să obțină exclusivitate. Dacă nu reușește va abandona execuția. Această opțiune va
face ca iptables să aștepte până când va obține exclusivitatea.
-n, --numeric
-x, --exact
--line-numbers
Când listează regulile, adaugă numere de linie în fața lor, corespunzătoare poziție in chain a
acelei reguli.
--modprobe=command
La adăugarea sau inserarea regulilor în chain, apelează comanda speci cată pentru a încărca
modulele necesare.
Exemple
A șarea regulilor din tabela implicită ( lter), împreună cu numerele de linie:
# iptables -n -L -v --line-numbers
Chain INPUT (policy DROP 113K packets, 4517K bytes)
num pkts bytes target prot opt in out source destination
1 6418K 813M ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0
state RELATED,ESTABLISHED
2 0 0 ACCEPT tcp -- eth+ * 0.0.0.0/0 0.0.0.0/0
tcp dpt:22
3 1576 94560 ACCEPT all -- tun+ * 0.0.0.0/0 0.0.0.0/0
4 3946 226K ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0
# iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 7000:7010 -j ACCEPT
fgxremote:~/test# iptables -L INPUT -n -v --line-numbers
Chain INPUT (policy DROP 149K packets, 6097K bytes)
num pkts bytes target prot opt in out source destination
1 6553K 851M ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0
state RELATED,ESTABLISHED
2 0 0 ACCEPT tcp -- eth+ * 0.0.0.0/0 0.0.0.0/0
tcp dpt:22
3 1576 94560 ACCEPT all -- tun+ * 0.0.0.0/0 0.0.0.0/0
4 3946 226K ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0
5 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0
state NEW tcp dpts:7000:7010
Trimiterea mesajelor de log într-un șier (în mod normal acestea se trimit la consolă):
Studiu de caz
Compania ABC oferă servicii de comunicare publică pentru clienții săi. Deoarece informațiile
schimbate cu ajutorul poștei electronice sau publicate pe portalul de clienți conțin date
con dențiale, ABC preferă să opereze propria infrastructură pentru serviciile Internet.
Sediul central este conectat la Internet prin 2 legături oferite de 2 provideri diferiți, o
legătură terestră peste bră optică și o conexiune ADSL. Aceasta din urmă este destinată
accesului la Internet a utilizatorilor din rețeaua internă.
Serviciile publicate în Internet sunt: DNS, SMTP, IMAP, HTTP(S). Serverele care rulează aceste
servicii se a ă intr-o rețea separată (DMZ 172.22.22.0/24) cu ajutorul a două rewall-uri
implementate cu Linux/iptables.
#!/bin/sh
# Configurations
#
IPTABLES="/usr/sbin/iptables"
# erase all chains that's not default in filter and nat table.
#
$IPTABLES -X
$IPTABLES -t nat -X
$IPTABLES -t mangle -X
FO_IFACE='eth0'
FO_IP='1.2.3.4'
ADSL_IFACE='eth1'
DMZ_IFACE='eth2'
DMZ_IP='172.22.22.1'
# Bad packets
# Here we create a new chain called ‘bad_tcp_packets’
$IPTABLES -N bad_tcp_packets
# which rejects packets that arrive for the first time having both SYN and ACK set
$IPTABLES -A bad_tcp_packets -p tcp --tcp-flags SYN,ACK -m state --state NEW -j REJE
CT --reject-with tcp-reset
# or don’t have the SYN flag set
$IPTABLES -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j DROP
# MANGLE
# here we mark the packets coming from the LAN users to later route them through the
ADSL interface
$IPTABLES -t mangle -A PREROUTING -p ALL -m iprange --src-range 192.168.168.100-200
-j MARK --set-mark 2
# PREROUTING
# redirect all incoming DNS queries to our DNS authoritative server
$IPTABLES -t nat -A PREROUTING -i $FO_IFACE -p udp --dport 53 -j DNAT --to-destinati
on 172.22.22.10
# the AXFR (zone transfer) requests from our slave DNS servers are allowed and redir
ected
$IPTABLES -t nat -A PREROUTING -i $FO_IFACE -p tcp -s 4.5.6.7 --dport 53 -j DNAT --t
o-destination 172.22.22.10
$IPTABLES -t nat -A PREROUTING -i $FO_IFACE -p tcp -s 5.6.7.8 --dport 53 -j DNAT --t
o-destination 172.22.22.10
# here we accept email from the world and redirect it to our SMTP server in the DMZ
$IPTABLES -t nat -A PREROUTING -i $FO_IFACE -p tcp --dport 25 -j DNAT --to-destinati
on 172.22.22.11
# this is the SMTP submission port which our users send mail through it
$IPTABLES -t nat -A PREROUTING -i $FO_IFACE -p tcp --dport 587 -j DNAT --to-destinat
ion 172.22.22.11
# and this is the IMAP over TLS service that fetches the email
$IPTABLES -t nat -A PREROUTING -i $FO_IFACE -p tcp --dport 993 -j DNAT --to-destinat
ion 172.22.22.11
# HTTP requests are redirected to the web server. Please note that the digital certi
ficate used with the web server should match the name and IP address of this machine
and not of the real server in the DMZ
$IPTABLES -t nat -A PREROUTING -i $FO_IFACE -p tcp --dport 80 -j DNAT --to-destinati
on 172.22.22.12
$IPTABLES -t nat -A PREROUTING -i $FO_IFACE -p tcp --dport 443 -j DNAT --to-destinat
ion 172.22.22.12
# INPUT
# responses to packets originated from this system
$IPTABLES -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# SSH connections could only be made from the inside
$IPTABLES -A INPUT -i $DMZ_IP -p tcp -m state --state NEW -m tcp -s 192.168.168.253
--dport 22 -j ACCEPT
$IPTABLES -A INPUT -i $DMZ_IP -p tcp -m state --state NEW -m tcp -s 192.168.192.253
--dport 22 -j ACCEPT
# everything else goes to trash
$IPTABLES -A INPUT -p tcp -j bad_tcp_packets
# FORWARD
# pass the responses to connections initiated from the inside
$IPTABLES -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
# DNS queries
$IPTABLES -A FORWARD -p udp -d 172.22.22.10 --dport 53 -j ACCEPT
# DNS zone transfer requests
$IPTABLES -A FORWARD -p tcp -s 4.5.6.7 -d 172.22.22.10 --dport 53 -j ACCEPT
$IPTABLES -A FORWARD -p tcp -s 5.6.7.8 -d 172.22.22.10 --dport 53 -j ACCEPT
# SMTP
$IPTABLES -A FORWARD -p tcp -d 172.22.22.11 --dport 25 -j ACCEPT
# email submission
$IPTABLES -A FORWARD -p tcp -d 172.22.22.11 --dport 587 -j ACCEPT
# read emails using IMAP over TLS
$IPTABLES -A FORWARD -p tcp -d 172.22.22.11 --dport 993 -j ACCEPT
# OpenVPN connections
$IPTABLES -A FORWARD -p tcp -d 172.22.22.2 --dport 1194 -j ACCEPT
# not matching the above rules? must be junk
$IPTABLES -A FORWARD -p tcp -j bad_tcp_packets
# POSTROUTING
# make our DMZ servers appear as having an external IP address
$IPTABLES -t nat -A POSTROUTING -s 172.22.22.0/24 -o $FO_IFACE -j SNAT --to-source
$FO_IP
# the ADSL interface has a dynamic address, therefore we need to use MASQUERADE to m
ake sure the packets leave with the correct IP address
$IPTABLES -t nat -A POSTROUTING -s 192.168.168.0/24 -o $ADSL_IFACE -j MASQUERADE
fw-dmz
#!/bin/sh
# Configurations
#
IPTABLES="/usr/sbin/iptables"
#
# reset the default policies in the filter table.
#
$IPTABLES -P INPUT ACCEPT
$IPTABLES -P FORWARD ACCEPT
$IPTABLES -P OUTPUT ACCEPT
#
# reset the default policies in the nat table.
#
$IPTABLES -t nat -P PREROUTING ACCEPT
$IPTABLES -t nat -P POSTROUTING ACCEPT
$IPTABLES -t nat -P OUTPUT ACCEPT
#
# reset the default policies in the mangle table.
#
$IPTABLES -t mangle -P PREROUTING ACCEPT
$IPTABLES -t mangle -P POSTROUTING ACCEPT
$IPTABLES -t mangle -P INPUT ACCEPT
$IPTABLES -t mangle -P OUTPUT ACCEPT
$IPTABLES -t mangle -P FORWARD ACCEPT
#
# flush all the rules in the filter and nat tables.
#
$IPTABLES -F
$IPTABLES -t nat -F
$IPTABLES -t mangle -F
#
# erase all chains that's not default in filter and nat table.
#
$IPTABLES -X
$IPTABLES -t nat -X
$IPTABLES -t mangle -X
# enable IP forwarding
sysctl -w net.ipv4.ip_forward=1
DMZ_IFACE='eth0'
DMZ_IP='172.22.22.2'
LAN_IFACE='eth1'
LAN_IP='192.168.168.1'
# PREROUTING
# these are the packets forwarded by the upstream firewall to the internal OpenVPN s
erver
$IPTABLES -t nat -A PREROUTING -i $DMZ_IFACE -p tcp --dport 1194 -j DNAT --to-destin
ation 192.168.168.12
# servers in the DMZ send their logs to the centralized log server inside
$IPTABLES -t nat -A PREROUTING -i $DMZ_IFACE -p tcp --dport 6514 -j DNAT --to-destin
ation 192.168.168.11
# FORWARD
# allow responses to the inside requests
$IPTABLES -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
# allow OpenVPN
$IPTABLES -A FORWARD -p tcp -d 192.168.168.12 --dport 1194 -j ACCEPT
# permit syslog packets
$IPTABLES -A FORWARD -p tcp -d 192.168.168.11 --dport 6514 -j ACCEPT