29 sierpnia 2011

Podstawowa konfiguracja iptables dla serwera

Po instalacji systemu, w moim przypadku Debian, na którym mają zostać uruchomione usługi widoczne na zewnątrz sieci, powinniśmy skonfigurować firewalla.
Najważniejszą zasadą, której powinniśmy się trzymać przy tworzeniu naszej zapory ogniowej, jest blokowanie wszystkiego co nie jest niezbędne w działaniu naszych usług.

Na początek przygotujmy sobie miejsce pracy, czyli plik w którym będziemy zapisywać reguły iptables. Dzięki temu nie będziemy musieli wpisywać komend z konsoli.
# cd /etc/init.d
# touch firewall
# chmod 700 firewall
W pliku tym zapisujemy podstawową konfigurację, która wykonuje kilka niezbędnych rzeczy:

1) czyści wszystkie reguły
2) ustawia domyślne polityki na DROP
3) akceptuje połączenia zainicjowane przez serwer
4) akceptuje połączenie wychodzące i wchodzące na podanych portach

### BEGIN INIT INFO
# Provides: firewall
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start firewall daemon at boot time
# Description: Enable service provided by daemon.
### END INIT INFO 

IPTABLES="/sbin/iptables"
MODPROBE="/sbin/modprobe"

# Ladujemy mozliwosc sledzenia polaczen (potrzebne dla ftp etc.)
$MODPROBE ip_conntrack  # sledzienie polaczen -> cat /proc/net/ip_conntrack
#$MODPROBE ip_conntrack_ftp# odhashowac aby miec aktywne ftp

# interface
LAN="eth0"
INT_NET="x.x.x.x/x"

# adresy IP z dostępem do SSH, podajemy oddzielone spacjami
ADM="x.x.x.x"

# odblokowane porty INPUT
# podawac po przecinku np. "21,22,123"
# 80 - WWW
# 21 - FTP
I_TCP="21,80"
I_UDP=""

# Porty wychodzace z serwera OUTPUT
# 123 - NTP
O_TCP="21,22,80"
O_UDP="53,123"

case "$1" in
start|restart)

echo "Czyszczenie firewall'a..."
#czyszczenie regul
$IPTABLES -F
$IPTABLES -X

echo "Start firewall'a..."
#Odrzucamy domyslnie wszystie pakiety przychodzace
$IPTABLES -P INPUT DROP
$IPTABLES -P FORWARD DROP
$IPTABLES -P OUTPUT DROP

# pozwalamy na ruch na interfejsie lokalnym
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

# akceptujemy polaczenia zainicjowane przez serwer
$IPTABLES -A INPUT -m state --state INVALID -j LOG --log-prefix "DROP_INVALID: " --log-ip-options --log-tcp-options
$IPTABLES -A INPUT -m state --state INVALID -j DROP
$IPTABLES -A INPUT -i $LAN -m state --state ESTABLISHED,RELATED -j ACCEPT

$IPTABLES -A OUTPUT -m state --state INVALID -j LOG --log-prefix "DROP_INVALID: " --log-ip-options --log-tcp-options
$IPTABLES -A OUTPUT -m state --state INVALID -j DROP
$IPTABLES -A OUTPUT -o $LAN -m state --state ESTABLISHED,RELATED -j ACCEPT

### anti-spoofing rules
$IPTABLES -A INPUT -i eth0 ! -s $INT_NET -j LOG --log-prefix "SPOOFED_PKT: "
$IPTABLES -A INPUT -i eth0 ! -s $INT_NET -j DROP

# Ping
$IPTABLES -A INPUT -p icmp --icmp-type echo-request -j LOG --log-prefix "Ping: " --log-ip-options --log-tcp-options
$IPTABLES -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
$IPTABLES -A OUTPUT -p icmp --icmp-type echo-request -j ACCEPT

# SSH
if [ -n "$ADM" ] ; then
for IP in $ADM ; do
$IPTABLES -A INPUT -i $LAN -s $IP -p tcp --dport 22 --syn -m state --state NEW -j ACCEPT
done
fi

# Porty wychodzące
if [ -n "$O_TCP" ] ; then
$IPTABLES -A OUTPUT -o $LAN -m multiport -p tcp --dports $O_TCP --syn -m state --state NEW -j ACCEPT
fi

if [ -n "$O_UDP" ] ; then
$IPTABLES -A OUTPUT -o $LAN -m multiport -p udp --dports $O_UDP -m state --state NEW -j ACCEPT
fi

# odblokwanie portow TCP i UDP
if [ -n "$I_TCP" ] ; then
$IPTABLES -A INPUT -i $LAN -m multiport -p tcp --dports $I_TCP --syn -m state --state NEW -j ACCEPT
fi

if [ -n "$I_UDP" ] ; then
$IPTABLES -A INPUT -i $LAN -m multiport -p udp --dports $I_UDP -m state --state NEW -j ACCEPT
fi

# logowanie pakietow odrzuconych /var/log/messages
$IPTABLES -A INPUT ! -i lo -j LOG --log-prefix "DROP_INPUT: " --log-ip-options --log-tcp-options
$IPTABLES -A OUTPUT ! -o lo -j LOG --log-prefix "DROP_OUTPUT: " --log-ip-options --log-tcp-options
;;

stop)
echo "Zatrzymanie firewall'a..."
$IPTABLES -F
$IPTABLES -X
;;

clear)
echo "Czyszczenie firewall'a..., UWAGA! wszystko na ACCEPT!"
$IPTABLES -F
$IPTABLES -X
$IPTABLES -P INPUT ACCEPT
$IPTABLES -P FORWARD ACCEPT
$IPTABLES -P OUTPUT ACCEPT
;;

*)
N=/etc/init.d/$NAME
echo "Usage: $N {start|stop}" >&2
exit 1
;;

esac

exit 0

Aby nasz skrypt uruchamiał się razem z systemem, wykonujemy jeszcze komendę
# insserv firewall

Firewall uruchamia się poprzez wydanie komendy
# /etc/init.d/firewall start

Firewall zatrzymuje się poprzez wydanie komendy
# /etc/init.d/firewall stop
# iptables -L

Chain INPUT (policy DROP)
target     prot opt source               destination
 
Chain FORWARD (policy DROP)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Firewall czyści się poprzez wydanie komendy
# /etc/init.d/firewall clear
# iptables -L

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
 
Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Wyświetlenie wszystkich reguł iptables
# iptables -L

3 komentarze:

  1. Czy można liczyć na zaktualizowanie tych reguł? Gdyż użycie ich w dniu dzisiejszym skutkuje erorrami (czepia się linijek z logami), oraz całkowitą blokadą ruchu input i output.

    OdpowiedzUsuń
  2. Denerwują mnie takie jak ten artykuły bo wprowadzają w błąd. Napisz to porządnie !!

    OdpowiedzUsuń
  3. Co konkretnie wprowadza w błąd?

    Skrypty działają poprawnie w Debianie Squeeze (6), ostatnio używam wyłączenie SLES'a, ale postaram się zaktualizować w najbliższym czasie.

    OdpowiedzUsuń