Ett lite större exempel på maskering

Nedan följer ett exempel på en Linuxdator med netfilter/iptables och två nätverkskort. Det ena nätverkskortet, eth1, kopplas till omvärlden och det andra, eth0, kopplas till det interna nätverket. Linuxdatorn kör ett antal tjänster som ska vara åtkomliga utifrån, ssh, mail, www. Från det interna nätverket ska webmin (port 10000) vara åtkomlig.

Tre tidsservrar, 1.2.3.4 1.2.3.5 och 4.3.2.1 ska brandväggens klocka synkroniseras mot.

På det interna nätverket finns en server med ssh och en webbserver som ska vara nåbara utifrån. För dessa vill vi sätta upp port forwarding på brandväggens utsida där 2020 ska gå till port 22 (ssh) på servern och 8080 ska gå till port 80 (webbserver) på servern.

Om det yttre nätet brandväggen är ansluten till kräver webbinloggning för att nå yttervärlden och använder interna adresser (10.0.0.0/8, 172.16.0.0/12 eller 192.168.0.0/24) för nameservrarna (DNS). Sätt WEBLOGON till webbinloggningsservern och DNSSERVERS till IP-adresserna till nameservrarna.

All windowsutdelningstrafik spärras i brandväggen. För inkommande trafik spärras även allt till NFS och till X-window-servrar.

I nedanstående script används pythonprogrammet NetCalc.py som ska ligga i någon katalog som finns med i din PATH.




Nedanstående script kan du även ladda ner härifrån.

#!/bin/sh

# Copyright 2003-2020 Kjell Enblom, Gnu General Public License version 2 (GPL) (http://www.gnu.org/)

# Firewall rules
# Brandväggsregler för en brandvägg med två nätverksinterface
# där maskering (NAT) görs av all trafik från det interna nätverket ut mot internet


############################# Gör dina inställningar här ########################################

# Sätt IPTABLES till sökvägen för kommandot iptables vilket kan vara
# t.ex. /sbin/iptables eller /usr/sbin/iptables
# Sätt IPTABLESSAVE till sökvägen för kommandot iptables-save
# t.ex. /sbin/iptables-save
IPTABLES='/sbin/iptables'
IPTABLESSAVE='/sbin/iptables-save'

# EXTERNAL ska sättas till namnet på det interface som sitter på utsidan
# INTERNAL ska sättas till namnet på det interface som sitter på insidan (mot det interna nätverket)
EXTERNAL='eth1'
INTERNAL='eth0'

# Sätt DYNAMICIP till ja om du för det externa interfacet får en
# adress dynamiskt via dhcp från din nätleverantör.
DYNAMICIP='nej'

# Tjänster som körs på brandväggen
# Ange protokoll,port
# För ICMP-trafik som ska släppas in till brandväggen skriv icmp,icmptyp
# Listan ska vara mellanslagseparerad. ICMP 3 Destination Unreachable och ICMP 11 Time Exceeded är bra att släppa in.
SERVICES='tcp,22 tcp,25 tcp,80 icmp,0 icmp,3 icmp,8 icmp,11'

# Om ssh (tcp port 22) är aktiverad ovan kan det vara bra att begränsa antalet uppkopplingar per tidsenhet för den
# för att minska risken att någon utifrån knäcker lösenord.
# Antal uppkopplingar per tidsenhet:
SSHHITCOUNT="10"
# Tidsenhet i sekunder t.ex. 10 minuter = 600 eller 1 timme = 3600.
SSHSECONDS="600"
# Ovan ger max ca 10 uppkopplingar under 10 minuter.


# Acess till tjänster på brandväggsdatorn som endast ska vara nåbar från det interna/lokala nätverket
# Ange protokoll,port
# För ICMP-trafik som ska släppas in till brandväggen skriv icmp,icmptyp
# Listan ska vara mellanslagseparerad
LOCALSERVICES='tcp,22 tcp,10000'

# NTP tidsserver/tidsservrar på Internet
# Skriv en mellanslagseparerad lista med IP-adresserna till de tidsservrar som ska användas
# Kommentera bort den om du ska synkronisera brandväggens klocka mot en tidsserver
# NTPSERVERS='1.2.3.4   1.2.3.5  4.3.2.1'

# DNS, nameservrar som ska vara tillgängliga för brandväggen och för de på det interna nätverket
# Skriv IP-adresserna som en mellanslagseparerad lista
DNSSERVERS='1.2.3.4 10.47.255.22'

# Webinloggningsserver
# Om webbinloggning krävs för att nå ut på nätet kan webbserverns adress skrivas in här
WEBLOGON='1.2.3.4'

# Port forward
# Trafik som kommer till en viss port på brandväggens utsida och som
# ska skickas vidare till en dator på det interna nätverket
# Listan ska vara mellanslagseparerad
#
# Ange på formen: protokoll,port-i-brandväggen,IP-på-lokala-nätverket,port-på-dator
# Exempel: all tcp-trafik som kommer till brandväggens utsida port 2022 ska till
# 192.168.22.17 port 22
# PORTFORWARD='tcp,2022,192.168.22.17,22'
PORTFORWARD='tcp,2022,192.168.22.17,22  tcp,21,192.168.22.17,21'

# Logga och kasta all övrig trafik?
# Om ja kommer all trafik som inte släpps fram att loggas och kastas
# Om nej kommer all övrig trafik att kastas utan att loggas.
LOGDROP='ja'

################################# Slut på inställningar ###########################################


# Sätt upp standardregler
$IPTABLES -P INPUT DROP
$IPTABLES -P FORWARD DROP
$IPTABLES -P OUTPUT ACCEPT


# Rensa bort gamla brandväggsregler
$IPTABLES -F
$IPTABLES -t nat -F
$IPTABLES -t mangle -F

# Rensa bort gamla kedjor
$IPTABLES -X
$IPTABLES -t nat -X
$IPTABLES -t mangle -X


# Om maskeringen är kompilerad som modul
# ladda modulerna iptable_nat och ip_conntrack
modprobe iptable_nat
modprobe ip_conntrack

# För att ESTABLISHED, RELATED ska fungera bra för FTP-trafik ladda
# nedanstående moduler. Om de ligger fast i kärnan kommentera bort raderna.
modprobe ip_conntrack_ftp
modprobe ip_nat_ftp 

# Raderna med modprobe ovan kan även stoppas in i någon annan lämplig fil
# som körs vid boot. Exempel /etc/rc.local eller /etc/rc.sysinit.

# Slå på routing
echo "1" > /proc/sys/net/ipv4/ip_forward

# Firewall rules
# Min egna IP-adress på  (yttre interface)
MEexternal=`/sbin/ifconfig $EXTERNAL |sed -n '/inet/s/^[ ]*inet addr:\([0-9.]*\).*/\1/p'`

# Min egna IP-adress på $INTERNAL (inre interface)
MEinternal=`/sbin/ifconfig $INTERNAL |sed -n '/inet/s/^[ ]*inet addr:\([0-9.]*\).*/\1/p'`
MEinternalmask=`/sbin/ifconfig $INTERNAL |sed -n '/inet/s/^.*Mask:\([0-9.]*\).*/\1/p'`

# Räkna ut nätadress för det interna nätverket med hjälp av IP och mask
# Den här kräver programmet NetCalc.py som ska ligga i en katalog som din PATH pekar ut
INTERNALNETWORK="`NetCalc.py --network $MEinternal/$MEinternalmask`"

# Min broadcastadress på eth0
MYBROADCASTeth0=`/sbin/ifconfig eth0 |sed -n '/inet/s/^.*Bcast:\([0-9.]*\).*/\1/p'`
# Min broadcastadress på eth1
MYBROADCASTeth1=`/sbin/ifconfig eth1 |sed -n '/inet/s/^.*Bcast:\([0-9.]*\).*/\1/p'`

# Skapa kedjan logdrop som loggar och kastar trafiken
$IPTABLES -N logdrop
$IPTABLES -A logdrop -j LOG
$IPTABLES -A logdrop -j DROP

# Logga och kasta nya TCP-paket som inte är SYN-paket
$IPTABLES -A INPUT -p tcp ! --syn -m state --state NEW -j LOG --log-prefix "NEW NOT SYN "
$IPTABLES -A INPUT -p tcp ! --syn -m state --state NEW -j DROP

$IPTABLES -A FORWARD -p tcp ! --syn -m state --state NEW -j LOG --log-prefix "NEW NOT SYN "
$IPTABLES -A FORWARD -p tcp ! --syn -m state --state NEW -j DROP


# Spärra windows-share-trafik så att den inte slipper ut från det interna nätverket
$IPTABLES -A FORWARD --in-interface $INTERNAL -p tcp  --destination-port 137:139 -j DROP
$IPTABLES -A FORWARD --in-interface $INTERNAL -p udp  --destination-port 137:139 -j DROP

# Spärra inkommande windowsshare-trafik, NFS-trafik och X-window trafik
$IPTABLES -A FORWARD --in-interface $EXTERNAL -p tcp  --destination-port 137:139 -j DROP
$IPTABLES -A FORWARD --in-interface $EXTERNAL -p udp  --destination-port 137:139 -j DROP
$IPTABLES -A INPUT --in-interface $EXTERNAL -p tcp  --destination-port 137:139 -j DROP
$IPTABLES -A INPUT --in-interface $EXTERNAL -p udp  --destination-port 137:139 -j DROP

$IPTABLES -A FORWARD --in-interface $EXTERNAL -p tcp  --destination-port 2049 -j DROP
$IPTABLES -A FORWARD --in-interface $EXTERNAL -p udp  --destination-port 2049 -j DROP
$IPTABLES -A INPUT --in-interface $EXTERNAL -p tcp  --destination-port 2049 -j DROP
$IPTABLES -A INPUT --in-interface $EXTERNAL -p udp  --destination-port 2049 -j DROP

$IPTABLES -A FORWARD --in-interface $EXTERNAL -p tcp  --destination-port 6000:6010 -j DROP
$IPTABLES -A INPUT --in-interface $EXTERNAL -p tcp  --destination-port 6000:6010 -j DROP



# Se till att DNS-trafik kommer fram
if [ -n "$DNSSERVERS" ]
then
   for nameserver in $DNSSERVERS
   do
     $IPTABLES -A INPUT --in-interface $EXTERNAL -p tcp --source $nameserver --sport 53 --destination-port 1024:65535 -j ACCEPT
     $IPTABLES -A INPUT --in-interface $EXTERNAL -p udp --source $nameserver --sport 53 --destination-port 1024:65535 -j ACCEPT
     $IPTABLES -A FORWARD --in-interface $EXTERNAL -p tcp --source $nameserver --sport 53 --destination-port 1024:65535 -j ACCEPT
     $IPTABLES -A FORWARD --in-interface $EXTERNAL -p udp --source $nameserver --sport 53 --destination-port 1024:65535 -j ACCEPT
   done
fi


# Se till att den eller de webinloggningsservar som eventuellt behövs för
# att komma ut på nätet är nåbara
if [ -n "$WEBLOGON" ]
then
   for WEBLOGONSERVER in $WEBLOGON
   do
       $IPTABLES -A INPUT --in-interface $EXTERNAL -p tcp --source $WEBLOGONSERVER  --source-port 80 --destination-port 1024:65535 -j ACCEPT
       $IPTABLES -A FORWARD --in-interface $EXTERNAL -p tcp --source $WEBLOGONSERVER --source-port 80 --destination-port 1024:65535 -j ACCEPT
   done
fi



# Spärra nät som är till för lokalt bruk 10.0.0.0/8,  172.16.0.0/12,  192.168.0.0/24
# Spärra trafik som kommer utifrån och som har en lokal adress som avsändar- eller mottagar-adress
if ! `echo $MEexternal | grep '^10\.' > /dev/null`
then
   $IPTABLES -A FORWARD --in-interface $EXTERNAL --source 10.0.0.0/8 -j DROP
   $IPTABLES -A INPUT --in-interface $EXTERNAL --source 10.0.0.0/8 -j DROP
fi

if ! `echo $MEexternal | grep '^172\.' > /dev/null`
then
   $IPTABLES -A FORWARD --in-interface $EXTERNAL --source 172.16.0.0/12 -j DROP
   $IPTABLES -A INPUT --in-interface $EXTERNAL --source 172.16.0.0/12 -j DROP
fi

if ! `echo $MEexternal | grep '^192\.' > /dev/null`
then
   $IPTABLES -A INPUT --in-interface $EXTERNAL --source 192.168.0.0/16 -j DROP
   $IPTABLES -A FORWARD --in-interface $EXTERNAL --source 192.168.0.0/16 -j DROP
fi

######################## Trafik till själva brandväggsdatorn ####################

# Logga och spärra ut netbus
$IPTABLES -A INPUT -p tcp --destination-port 12345 -j logdrop
$IPTABLES -A INPUT -p udp --destination-port 12345 -j logdrop

# Tillåt brandväggen att prata med sig själv
$IPTABLES -A INPUT --in-interface lo --source 127.0.0.0/8 -j ACCEPT
$IPTABLES -A INPUT --in-interface lo --source $MEexternal -d $MEexternal -j ACCEPT
$IPTABLES -A INPUT --in-interface lo --source $MEinternal -d $MEinternal -j ACCEPT

# Spärra ut avsändaradress 127.0.0.0/8 från omvärlden (som inte kommer
# från loopback)
$IPTABLES -A INPUT --in-interface ! lo --source 127.0.0.0/8 -j DROP

# Spärra trafik som kommer till broadcastadressen på yttre nätet
if [ $EXTERNAL = 'eth0' ]
then
   $IPTABLES -A INPUT -d $MYBROADCASTeth0/32 -j DROP
elif [ $EXTERNAL = 'eth1' ]
then
   $IPTABLES -A INPUT -d $MYBROADCASTeth1/32 -j DROP
fi


# Släpp in trafik till egna servertjänster
# Släpp in trafik till servertjänster på låga portar
# Tjänst protokoll klientportar serverport

for service in $SERVICES
do
   PROTOCOL=`echo $service | cut -d"," -f1`
   PORT=`echo $service | cut -d"," -f2`
   if [ $PROTOCOL = "icmp" ]
   then
       # Släpp in ICMP-trafik
       # För ICMP är PORT inte port utan ICMP-typ
       $IPTABLES -A INPUT -p icmp --icmp-type $PORT -j ACCEPT
   else
       $IPTABLES -A INPUT -m state --state NEW -p $PROTOCOL  --destination-port $PORT -j ACCEPT
       $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -p $PROTOCOL --destination-port $PORT -j ACCEPT
   fi
done


# Access till tjänster från det lokala nätverket
for service in $LOCALSERVICES
do
   PROTOCOL=`echo $service | cut -d"," -f1`
   PORT=`echo $service | cut -d"," -f2`
   if [ $PROTOCOL = "icmp" ]
   then
       # Släpp in ICMP-trafik
       # För ICMP är PORT inte port utan ICMP-typ
       $IPTABLES -A INPUT --in-interface $INTERNAL --source "$INTERNALNETWORK" -p icmp --icmp-type $PORT -j ACCEPT
   else
       # Tjänster som kör TCP, UDP
       $IPTABLES -A INPUT --in-interface $INTERNAL --source "$INTERNALNETWORK" -m state --state NEW -p $PROTOCOL   --destination-port $PORT -j ACCEPT
       $IPTABLES -A INPUT --in-interface $INTERNAL --source "$INTERNALNETWORK" -m state --state ESTABLISHED,RELATED -p $PROTOCOL --destination-port $PORT -j ACCEPT
   fi
done



if [ -n "$NTPSERVERS" ]
then
   for NTPSERVER in $NTPSERVERS
   do
      # Släpp in trafik från ntp-servern $NTPSERVER port 123 från utsidan
      $IPTABLES -A INPUT -p udp --source $NTPSERVER --sport 123 --destination-port 123 -j ACCEPT
   done
fi


# Släpp fram svarstrafik
$IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT


# Sätt begränsningar på antalet ssh-uppkopplingar
for service in $SERVICES
do
   PROTOCOL=`echo $service | cut -d"," -f1`
   PORT=`echo $service | cut -d"," -f2`
   if [ $PROTOCOL = "tcp" ] && [ $PORT == "22" ]
   then
       # Begränsa antalet ssh-uppkopplingar IN till t.ex. 10 st på 600 sekunder
       # Kommentera bort dessa två rader om du inte vill ha denna begränsning
       iptables -I INPUT -p tcp --dport 22 -i eth0 -m state --state NEW -m recent --set
       iptables -I INPUT -p tcp --dport 22 -i eth0 -m state --state NEW -m recent --update --seconds $SSHSECONDS --hitcount $SSHHITCOUNT -j DROP
       break
   fi
done


###################### Trafik ut/in mellan Internet och interna nätet ###########################


# FORWARDREGLER
# Spärra trafik som kommer till broadcastadressen
$IPTABLES -A FORWARD --in-interface eth1 -d $MYBROADCASTeth0/32 -j logdrop
$IPTABLES -A FORWARD --in-interface eth0 -d $MYBROADCASTeth1/32 -j logdrop

# Om trafiken ut från det interna nätverket har en annan avsändaradress än vad som används
# på det interna nätverket ska den kastas.
if [ -n "$INTERNALNETWORK" ]
then
   $IPTABLES -A FORWARD --in-interface $INTERNAL ! --source "$INTERNALNETWORK" -j logdrop
fi

# Släpp ut trafik från interna nätet, och släpp in svarstrafik
$IPTABLES -A FORWARD --in-interface $INTERNAL -j ACCEPT
$IPTABLES -A FORWARD --in-interface $EXTERNAL -m state --state ESTABLISHED,RELATED -j ACCEPT

# Lägg på maskering på utgående trafik som ska ut till Internet så att
# det ser ut som att det är brandväggens utsida som surfar
if [ "$DYNAMICIP" != 'ja' ]
then
   $IPTABLES -t nat -A POSTROUTING -o $EXTERNAL -j SNAT --to $MEexternal
else
   # Släpp in dhcp-trafik
   $IPTABLES -A INPUT -i $EXTERNAL -p tcp --source-port 67 --destination-port 68 -j ACCEPT
   #
   # Om adressen på yttre interfacet fås dynamiskt t.ex. dhcp (DYNAMIC=ja)
   # använd MASQUERADE
      $IPTABLES -t nat -A POSTROUTING -o $EXTERNAL -j MASQUERADE
   # Notera att MASQUERADE gör av med lite mer CPU-kraft än SNAT men den behövs när dhcp används.
   #
   # Vid användning av dhcp aktivera ip_dynaddr
      echo "1" > /proc/sys/net/ipv4/ip_dynaddr
fi

# Port forwarding
# Skicka vidare trafik till vissa portar på brandväggens utsida till datorer
# på det inre nätet
if [ -n "$PORTFORWARD" ]
then
  for portfwd in $PORTFORWARD
  do
     PROTOCOL=`echo $portfwd | cut -d"," -f1`
     FWPORT=`echo $portfwd | cut -d"," -f2`
     IP=`echo $portfwd | cut -d"," -f3`
     PORT=`echo $portfwd | cut -d"," -f4`
     $IPTABLES -t nat -A PREROUTING --in-interface $EXTERNAL -p $PROTOCOL --dport $FWPORT -j DNAT --to $IP:$PORT
     $IPTABLES -A FORWARD -p $PROTOCOL --destination-port $PORT -j ACCEPT
  done
fi


if [ "$LOGDROP" = 'ja' ]
then
   # Logga och spärra resten
   $IPTABLES -A INPUT -j logdrop
   $IPTABLES -A FORWARD -j logdrop
fi


# Om det är en RedHat spara iptables-reglerna i filen /etc/sysconfig/iptables
if [ -f "/etc/redhat-release" ]
then
   iptables-save > /etc/sysconfig/iptables
fi







Copyright © 2010-2024 Kjell Enblom.
This document is covered by the GNU Free Documentation License, Version 1.3

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License".