You are on page 1of 9

Lab 4: iptables forward rules, full firewall with

DMZ
Op het einde van het vorige labo hebben we een eerste test met routing ondernomen. Toen waren er nog
geen iptables rules bij betrokken.
Nu we zowel basic iptables als routing onder de knie hebben wordt het tijd om een vollediger
netwerksetup te implementeren. Hierbij zien we onze linux VM als de router en firewall voor de DMZ van
een klein bedrijfsnetwerk, zoals toegelicht in de slides bij dit hoofdstuk:
1. eth0: de uplink die je Linux host, en bij uitbreiding je bedrijfsnetwerkje, toegang geeft tot
internet

Note
Zie dit als een simulatie van de buitenwereld.

2. ethX: de range die je in labo 3 toegewezen kreeg, en waar we de te beschermen DMZ van
maken

Note
De andere vm's in je ethX range vormen een netwerkje van servers waar je selectief
toegang toe verleent (een DMZ).
Jouw eigen vm kan dienst doen als zo'n server in de setup van iemand anders.

Important
Vaak is een router unnumbered op de publieke interface (geen eigen IP), omdat hij van buitenaf
nooit rechtstreeks geadresseerd moet kunnen worden.
In ons voorbeeld is de publieke interface dezelfde als de management interface. Die is in onze
oefening dus wel numbered (192.168.116.xx), maar om er via vpn op te raken dien je naar
poort 5900 + xx of 7900 + xx te verbinden op het Howest-IP van de hypervisor, 172.21.18.24,
ipv rechtstreeks naar 192.168.116.xx te gaan. Dit wist je al.

1. Herstel eventueel je routing table, indien deze nog een host-route bevatte na de laatste vraag van
labo 3.
route del -host 172.21.28.24/32
Herstel ook je iptables naar initiele toestand:

iptables
iptables
iptables
iptables
iptables

-F
# flush all chains
-X
# delete all extra chains you might have created
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P FORWARD ACCEPT

2. Open in een teksteditor het bestand /etc/rc.local. We gaan hier voorlopig ons firewall script
plaatsen.
De gewenste content kunnen we boven exit 0 plaatsen.
3. In labo 2 hebben we de rules niet in logische volgorde aangemaakt, maar soms rules bovenaan
geinsert en soms verwijderd.
In een firewall script gaan we de rules toevoegen in de volgorde waarin ze in de chain moeten
terechtkomen. We hebben nu dus enkel optie -A nodig, en niet meer optie -I.
Begin met 3 commando's waarin je de 3 policies (INPUT, OUTPUT en FORWARD) op DROP zet,
zodat een aanval tijdens het draaien van het script niet mogelijk is. Wis ook bestaande chains en
hun inhoud.
Dit lijkt dus op vraag 1, maar nu zet je de commando's in een text file die uitvoerbaar is (shell script),
en ipv ACCEPT is de default policy nu DROP.
4. Zorg dat je script vervolgens routing inschakelt op je Linux VM (zie einde vorig labo). Je kunt
hiervoor echo of sysctl gebruiken.
Test je script (errors - werking), ook na elke volgende stap, mbv /etc/rc.local.
5. In labo 2 leerden we dat een default policy DROP steek houdt, omdat je dan zelf bepaalt welke
openingen gemaakt worden in de firewall, ipv alles open te laten en specifieke zaken dicht te
timmeren.
Wel is dit iets meer werk: veel netwerkverkeer is onschuldig, wenselijk of vereist voor een correcte
werking van onze server.
Voeg volgende rules toe (hint: nog geen forward rules nodig in deze vraag):
a. Om alle packets afkomstig van interface lo (loopback) naar binnen toe te laten, mits
zowel het source als destination IP in de reserved class A range 127.0.0.0/8 zitten.
b. Om alle packets bestemd voor interface lo (loopback) naar buiten toe te laten, met
dezelfde vereiste als in punt a voor source en destination IP.

Verklaring
Veel systeemservices communiceren onderling via een socket die enkel op de lokale
machine luistert, om makkelijk client en server gedeelte op een andere machine te kunnen
draaien. Voor al deze zaken is het dus vereist om communicatie van en naar de loopback
interface toe te staan.

6. Zoek het poortnummer gebruikt door ssh, door te greppen naar het woord ssh in /etc/services.
Overal waar UNIX tools zoals iptables, telnet, ... een poortnummer verwachten kun je ook een
naam gebruiken die in /etc/services gedefinieerd is.
Voeg nu een rule toe aan je script om ssh-verbindingen naar je server toe te laten, over het publieke
/ managementnetwerk eth0, maar alleen van IP 10.0.0.0/8 en 172.21.0.0/16.

Wees specifiek:
vermeld input interface met -i (want het is een input rule)
vermeld het correcte bestemmings-IP met -d (en laat je niet misleiden door de port
forwarding setup: je IP voor eth0 zie je met ip addr show eth0 of ifconfig eth0
en zal in de range 192.168.116.0/24 liggen)
beperk tot service ssh, dus poort 22, maar gebruik de naam uit /etc/services ipv het
getal 22 te gebruiken in je script; LET OP: je kunt geen poortnummer opgeven als je niet
ook aangeeft of het protocol TCP, UDP dan wel iets anders gebruikt wordt; ssh verloopt in
elk geval via het TCP-protocol
7. Volstaat deze net toegevoegde rule om via ssh over vpn of howest-LAN naar je machine te
verbinden?
Als je twijfelt zou je je script even kunnen uitvoeren om dit te testen:
chmod u+x /etc/rc.local
/etc/rc.local

# uitvoerbaar maken; zie file en process management


# het script draaien/testen

Indien je merkt dat je de verbinding verliest kun je een en ander rechtzetten via vnc en desgevallend
de corresponderende tweede iptables rule toevoegen aan je script.

Hint
Op dit moment zijn we input, output en (straks) forward rules aan het maken in de chains van
de filter table. Deze werken op een per-packet basis (stateless), dus daarom hebben we ook
een output rule nodig!
Maak deze rule dus ook in je script, in omgekeerde richting. Na opnieuw uitvoeren van je
script zou je nog steeds via ssh moeten kunnen verderwerken.

8. Pas beide rules van vraag 6 en 7 aan zodat de state module (-m parameter van iptables)
gebruikt wordt. We willen naar buiten toe enkel packets toestaan die al een antwoord zijn op een
reeds geopende ssh-verbinding naar ons.
Match daartoe enkel de buitengaande packets met state ESTABLISHED.
De binnengaande packets mogen state NEW of ESTABLISHED hebben, zodat de buitenwereld een
connectie met ons kan initieren, en het verdere verkeer in die richting ook toegelaten blijft.

Note
Packet filtering is nog steeds stateless, dus je hebt 2 rules nodig om netwerkverkeer in beide
richtingen mogelijk te maken, maar door de module state te gebruiken kunnen we wel
filteren op geassocieerde connection info, zoals wie de connectie geinitieerd heeft, ...

9. Sta icmp type echo response alsook request toe voor verkeer van en naar management/public
netwerk eth0, maar enkel voor lokale IP-adressen in dit netwerk (dus 192.168.116.0/24).
Dat lukte immers na het instellen van de DROP default policy niet meer.

Probeer of je opnieuw bv 192.168.116.57 of het ip van een medestudent kan pingen na opnieuw
draaien van je firewall script.

Important
Ook hier moet je zo specifiek mogelijk zijn:
vermeld interface (steeds -i voor input interface bij INPUT, -o voor output interface bij
OUTPUT, en allebei bruikbaar in de FORWARD chain)
vermeld IP range (-s igv source, -d igv destination)

10. Kun je ook je eigen IP pingen horend bij de ethX range die je configureerde in labo 3?
Dat zou moeten lukken.
11. Sta toe dat je server (of laten we het onze eigen router en firewall noemen) zelf als ssh-client
verbinding maakt met ssh servers naar eth0 en ethX. De antwoord-packets van ssh servers moeten
ook toegelaten worden; gebruik dus -m state en een combinatie van new en/of established.
Je hoeft geen onderscheid te maken op basis van interface of je server VM IP; we willen gewoon alle
outgoing ssh connecties naar overal toestaan.
12. Sta nu op soortgelijke wijze toe dat je server http-requests doet naar buiten. Hier willen we enkel
requests naar buiten toelaten, dus niet naar ethX (DMZ) en ook niet naar de gewone management
range 192.168.116.0/24 van eth0.
Laat zowel poort 80 als 443 toe.
13. Sta toe dat je server DNS requests uitvoert naar 192.168.116.1 via eth0. Je moet dus zowel TCP
als UDP verkeer naar poort 53 van 192.168.116.1 toestaan, evenals het antwoord in omgekeerde
richting.
14. Breng even je ethX interface terug down:
ifdown ethX
Vervang X door het tiental van je VM-nummer, of kies eth10 indien je VM-nummer kleiner is dan 10.
Het corresponderende IP is 10.116.x.y waarbij x = y / 10 en y = je VM-nummer.
15. Installeer alvast Apache op je VM (apt install apache2) zodat anderen later kunnen proberen of ze je
VM in zijn DMZ range kunnen bereiken.
Plaats een default index-pagina die de bezoeker vertelt dat DMZ server 10.116.x.y (met y = je VM-nr
en x = je VM-nr / 10) antwoordt.
Door het firewall script dat je tot nu toe gemaakt hebt zal hiermee rechtstreeks verbinden nog niet
lukken, noch via eth0 noch via DMZ. Ook staat je DMZ network interface nog af sinds punt 14. Wel
kun je met localhost verbinden om lokaal te testen, want in vraag 5 liet je verkeer van/naar de
loopback interface toe indien IP 127.x gebruikt wordt.
16. Nu proberen we de referentie-VM 57 te bereiken via zijn eth0 IP als gateway, maar met zijn IP in
eth5 als destination. Dit is dus 10.116.5.57.
Dit is een variant op de laatste oefening van labo 3. Nu hebben we een route nodig die zegt dat
packets naar 10.116.5.0/24 via 192.168.116.57 als gateway (router) verstuurd worden:
route add -net 10.116.5.0/24 gw 192.168.116.57

Nu
zou
je
bv
wget
http://10.116.5.57
moeten
w3m http://10.116.5.57 start een tekstbrowser naar deze url.

kunnen

uitvoeren,

of

Denkvraag: heb je dit eerder in het labo expliciet toegelaten of verboden (met een policy of rule), of
geen van beide? Geef aan welke rule(s), bv adhv het vraagnummer, of indien geen van beide,
waarom werkt het dan?
17. VM 57 luistert in elke range naar een IP dat eindigt op .57. Voeg een route toe naar een van de
andere extra interfaces (eth1-eth10 behalve eth5), met corresponderend subnet.
Bekijk even je huidige route table opnieuw met route -n of netstat -nr; je zult merken dat je 2
statische routes erbij gekomen zijn.
Nu zou je mbv w3m ook naar het IP van VM 57 in dit andere DMZ netwerk moeten kunnen
verbinden.
Er is geen verschil met punt 16; het enige opvallende is dat VM 57 in alle ranges aanwezig is. Jullie
zijn uiteraard vrij om ook extra ranges te bevolken zolang je het correcte IP-adres instelt.
VM 57 is in elk netwerk aanwezig om jullie de kans te geven routing naar een ander DMZ dan het
jouwe te testen met een correct ingestelde partner-VM, ongeacht in welk DMZ-netwerk je zelf zit (ie:
zelfs indien je zelf toevallig ook al eth5 had als DMZ netwerk).
18. Nu weten we dat routing binnen het netwerk werkt, want jullie hebben al enkele keren machine 57
als gateway gebruikt. We hebben deze weliswaar nog niet laten forwarden naar een andere
machine; 57 was steeds zelf de bestemmeling. We spreken pas van forwarding (en bijhorende
iptables chain) wanneer 57 een pakket van elders naar een andere host in een van zijn DMZs moet
afleveren.
Wel weet je nu hoe je met je eigen routing table kan bepalen naar welke interface of router verkeer
gestuurd wordt, en hebben we dit alvast kunnen uittesten in vorige 2 vragen en op het einde van
labo 3.
Verwijder terug de extra aangemaakte routes met route del zoals in vraag 1.
19. Er draait nog (minstens) een tweede VM in DMZ-netwerk eth5 (en ook de andere netwerken), met IP
10.116.x.55.
De machines 55 en 57 draaien quasi dezelfde firewall als in deze opgave, en zullen dus ook niet
toestaan dat je via 192.168.116.55 of 57 probeert te verbinden met ssh van binnen eth0 (maw vanaf
een vm zelf), omdat we dit allen belet hebben in vraag 6.
Probeer vragen 16-18 opnieuw, maar nu met machine 55, om je ervan te vergewissen dat er in elk
geval 1 klein DMZ-netwerkje is met daarin 2 linux vm's.
20. Nu wordt het tijd om een eerste serieuze test van Linux routing uit te voeren, want de laatste vraag
van labo 3 en vragen 16-17 zouden eigenlijk ook gewerkt hebben indien
/proc/sys/net/ipv4/ip_forward op machines 55 en 57 nog op 0 gestaan had.

Uitdaging
Ga dit zelf na met enkele vm's samen. Maak opnieuw vragen 16-19 en laat iemand proberen
zijn vm als referentie-router te configureren.
Dat wil zeggen dat die machine wel de DMZ interface moet aanzetten met ifup, maar ook
voorlopig iptables -P FORWARD ACCEPT om het nadenken over juiste iptables routing
rules nog even te kunnen uitstellen.

Hint
De persoon die een router opzet (ook al routen we nog niet, want je bent aan het testen of dit
alles zou werken met value 0 in /proc/sys/net/ipv4/ip_forward) kan volgende iptables
rules toevoegen aan het einde van het firewall script om incoming HTTP (enkel poort 80) toe te
staan rechtstreeks via de DMZ interface maar ook via een andere vm/router, uitgaande van bv
eth5 als DMZ:
# allow incoming http (port 80) to our DMZ ip at eth5
iptables -A INPUT -i $if -p tcp --dport 80 -m state \
--state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o $if -p tcp --sport 80 -m state \
--state ESTABLISHED -j ACCEPT
#(AND eth0 in case they are routing through us)
iptables -A INPUT -i eth0 -d 10.116.5.57/32 -p tcp \
--dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -s 10.116.5.57/32 -p tcp \
--sport 80 -m state --state ESTABLISHED -j ACCEPT

Note
Merk op dat de router vm nog geen enkele FORWARD rule gemaakt heeft (behalve om de
moeilijkheid uit te stellen een default ACCEPT forward policy) - want we waren nog niet echt
aan het routen; al bovenstaande werkt ook met de routing switch op 0.

21. De uitdaging was optioneel. Nu tonen we een voorbeeld van echte forwarding, waarbij je een
pakketje naar een DMZ host stuurt via een andere DMZ hoost. Daarna zorgen we dat je in dit
voorbeeld zelf als router kan fungeren.
Eerst nemen we onze DMZ interface en netwerkrange zelf (terug) in gebruik. In vraag 14 hadden we
deze immers uitgezet. Daarna gebruikten we alleen maar onze eigen routing table en een extra
statische route om een DMZ te bereiken via VM 57 als gateway, maar nu gaan we dit netwerk
rechtstreeks aanspreken langs ethX.

Recap
eth0 is ons management netwerk dat ons van buiten binnenlaat in onze VM, de VM zelf
access geeft tot internet, en ook toelaat om elkaars VM te "lenen" als router naar andere
DMZ's.
ethX is de DMZ die we in vorig labo voor je kozen obv je VM-nummer.

Breng eerst je DMZ terug up mbv ifup, en vergewis je ervan dat je de tijdelijke extra statische
routes terug verwijderd hebt.

22. Probeer nu via w3m te verbinden met http://10.116.x.57 waarbij x = je DMZ netwerknummer (ethX).
Waarom mislukt dit? Stel je net als in labo 3 de vraag welke route de machine gebruikt om naar de
bestemming te geraken. Vergelijk met de firewall rules (in /etc/rc.local of door de opgave te
herlezen), en zoek welke voorwaarde niet voldaan is.

Hint
Je hebt eerder enkel http-requests toegelaten naar eth0, maar nu ben je naar een andere
interface (nl DMZ: ethX) aan het verbinden.
Je zult dus de rules enigszins moeten uitbreiden en je firewall script nogmaals draaien.
Daarna zal de request werken.

23. Probeer VM 57 te bereiken via VM 55 als gateway (gebruik hiervoor de management-range van
eth0: 192.168.116.55).
Spreek VM 57 aan op een van zijn IPs buiten jouw DMZ range (ethX), maar niet op zijn
management-IP van eth0 (192.168.116.57). Stel hiervoor een tijdelijke statische route in.
Gebruik als test opnieuw w3m.
Indien je route tabel naar 192.168.116.55 doorverwijst voor de gekozen DMZ en de browser
antwoordt, is het verkeer via 55 gegaan zoals bedoeld. Vraag gerust ter verificatie; ik kijk dan even
mijn log na om te bevestigen of je request de juiste route volgt.

Note
Ditmaal
is
het
wel
vereist
(en
ook
het
geval)
dat
kernelvariabele
/proc/sys/net/ipv4/ip_forward value 1 heeft op VM 55, omdat deze nu wel packets
moet kunnen forwarden naar VM 57 via DMZ-netwerk.

24. Verwijder de testroute opnieuw. Nu je weet dat routing in de omgeving mogelijk is zou het moeten
lukken om je eigen vm als router te laten fungeren.
De vereiste kernel variabele staat in elk geval al op 1 na elke run van je firewall script, sinds de
implementatie van punt 4 van dit labo.
Volg de aanwijzingen bij de uitdaging van punt 20 om je firewall script zo aan te passen dat:
de default forward policy voorlopig op ACCEPT staat (alle routing toestaan zonder
controle; we verfijnen later)
binnenkomende http-requests (enkel poort 80) toegestaan worden op je eigen DMZ IP
Vergeet niet opnieuw /etc/rc.local uit te voeren om de nieuwe rules toe te passen.
25. Zoek mbv de VM-lijst en ping of nmap (of contact) een medestudent in dezelfde DMZ-range, of
gebruik even VM 57 in je DMZ netwerk als derde te bereiken testmachine.
Indien de firewall van beiden tot en met punt 24 up to date is zou je elkaars webserver rechtstreeks
moeten kunnen contacteren met w3m via het DMZ IP. Lukt dat niet, roep dan gerust hulp in.
26. Zoek nu iemand in een andere DMZ-range, die even wil proberen of het lukt om, met een statische
route via je management IP (eth0), de derde machine van vraag 25 te bereiken op diens DMZ IP.
Vraag me ook gerust om dit bij je vm te proberen.
7

27. We zijn er bijna!


Uiteraard is het niet de bedoeling om routing in alle richtingen ongeremd toe te staan.
In onze opstelling willen we dat de router enkel doorgeefluik speelt voor verkeer tussen zijn
verbonden DMZ en:
andere VMs in het eth0 management-netwerk enerzijds;
de buitenwereld, via een later te configureren vpn anderzijds (voorlopig buiten
beschouwing gelaten);
de enige DMZ "dienst" die voorlopig draait op onze geimproviseerde DMZ servers is de
minimale Apache die in punt 15 geinstalleerd werd
Concreet:
routing van eth0 (en corresponderende IP range) naar ethX (en corresponderende IP
range)
routing van ethX (en corresponderende IP range) naar eth0 (en corresponderende IP
range)
TCP, poort 80 (laat gerust state established/new gemakshalve even achterwege), interface
ethX, IP 10.116.x.y
verander de default forward policy in je script terug naar DROP, indien je die tijdelijk naar
ACCEPT gewijzigd had
Implementeer daartoe het policy-commando en de twee vereiste iptables forward rules (een voor de
heen-richting en een voor de terug-richting) in je firewallscript, en draai het opnieuw om de
wijzigingen toe te passen.
Controleer of je VM nog steeds verkeer kan routen naar andere machines (of VM 55 of 57) in je
DMZ, zoals je in vraag 26 deed.
28. Denkvraag: waarom zijn er geen maatregelen (zoals forward rules) nodig om de DMZ hosts
onderling te laten communiceren via hun DMZ netwerk?
29. Denkvraag: waarom kun je je eigen management IP (eth0) niet pingen en een ander IP van een host
die up is wel (bv 192.168.116.57)?
Los dit op door de rules in je script nog iets verder te verfijnen.

Hint
Het heeft met de netwerkinterface (-i of -o) te maken.

30. Reboot je VM en controleer of je rules na reboot daadwerkelijk geladen zijn in de kernel.


Met andere woorden: heeft /etc/rc.local (correct) gedraaid? Door de -e optie in de eerste lijn
van het script wordt het script meteen afgebroken bij een fout; ook kun je foutmeldingen at boot time
moeilijk zien omdat het scherm gewist wordt op het einde.
31. Indien je het script zo strikt mogelijk gemaakt hebt zul je op veel plaatsen het vaste IP van je eigen
machine op diverse interfaces tegenkomen.
Bewaar deze ip's in variabelen bovenaan het script en gebruik steeds de variabelen.
Bv:

IP_MGMT=192.168.116.57
IP_DMZ=10.116.5.57
iptables -A INPUT -p tcp -i eth0 ! -s 192.168.116.0/24 -d $IP_MGMT \
--dport 22 -j ACCEPT
iptables -A INPUT -p tcp -i eth5 -d $IP_DMZ --dport 22 -j ACCEPT

You might also like