Фаерволы продолжение — часть 2
В предыдущей статье мы рассмотрели работу ufw и разобрали некоторые простые примеры. Сегодня речь пойдет об IPtables. Я не буду углубляться в принципы работы, это не википедия, зато покажу несколько реально полезных примером, которые помогут вам обезопасить сервер. Настройки которые будут предложены ниже используются в основном на серверах расположенных в зоне MZ или же на домашних машинах.
Я имею ввиду, что для серьезных продакшн серверов настройки фаерволов должны быть более тонкими и гибкими, чем я предложу вам, но это уже дело каждого. Например, на крупных серверах есть защита против ддосов, брут форсов и прочего. Кстати опцию как защитить 22 порт от брут форса я привел в прошлой статье. Примеры будут отображать настройку на двух системах, на Ubuntu\Debian и на Fedora 17. Для других дистрибутивов могут быть отличия. Если интересно, то поехали, вся необходимая инфа в продолжении.
Настройка IPtables в Ubuntu 12.04\Debian
Мой домашний сервер управляется системой Ubuntu 12.04 и он же смотрит в мир (т.е. у него есть интерфейс к которому привязан внешний IP).
Так как настроить IPtables, с чего начать? Начать надо с определения политик безопасности. Как было сказано ранее, в предыдущей статье, я придерживаю такой политики:
- Allow all outgoing connections (разрешить ВСЕ исходящие)
- Allow established connections (разрешить ВСЕ установленные)
- Deny all incoming connections (запретить ВСЕ входящие, т.е. все кроме того что мы откроем должно пресекаться на корню без суда и следствия)
- Deny all forward connections (запретить форвардинг)
Остальное уже настраивается по вкусу. В Ubuntu\Debian по умолчанию фаервол отключен. Проверить статус и посмотреть активные правила можно так:
$ sudo iptables -L
$ sudo iptables -L -v
$ sudo iptables -n -L -v --line-numbers
Сбросить все установленные прежде правила можно так:
$ sudo iptables -F
Создаем файл с правилами:
$ vi /etc/iptables.rules
Туда вносим следующие правила:
*filter
# Allows all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0
-A INPUT -i lo -j ACCEPT
-A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT
# Accepts all established inbound connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allows all outbound traffic
# You could modify this to only allow certain traffic
-A OUTPUT -j ACCEPT
# Allows HTTP and HTTPS connections from anywhere (the normal ports for websites)
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT
# Allows SSH connections
# THE -dport NUMBER IS THE SAME ONE YOU SET UP IN THE SSHD_CONFIG FILE
-A INPUT -p tcp -m state --state NEW --dport 30000 -j ACCEPT
# Now you should read up on iptables rules and consider whether ssh access
# for everyone is really desired. Most likely you will only allow access from certain IPs.
# Allow ping
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
# log iptables denied calls (access via 'dmesg' command)
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7
# Reject all other inbound - default deny unless explicitly allowed policy:
-A INPUT -j REJECT
-A FORWARD -j REJECT
COMMIT
Теперь активируем правила:
$ sudo iptables-restore < /etc/iptables.rules
Смотрим на результат:
$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere
REJECT all -- anywhere 127.0.0.0/8 reject-with icmp-port-unreachable
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh
ACCEPT icmp -- 192.168.0.0/16 anywhere icmp echo-request
LOG all -- anywhere anywhere limit: avg 5/min burst 5 LOG level debug prefix "iptables denied: "
REJECT all -- anywhere anywhere reject-with icmp-port-unreachable
Chain FORWARD (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT all -- anywhere anywhere
REJECT all -- anywhere anywhere reject-with icmp-port-unreachable
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere
Cохраняем правила:
$ sudo iptables-save > /etc/iptables.up.rules
Что-бы правила активировались после перезагрузки, делаем такой скрипт:
$ sudo vi /etc/network/if-pre-up.d/iptables
#!/bin/bash
/sbin/iptables-restore < /etc/iptables.up.rules
Даем скрипту права на выполнения:
$ sudo chmod +x /etc/network/if-pre-up.d/iptablesПояснения некоторых правил:
Разрешить исходящие установленные соединения:
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
Разрешить весь исходящий траффик:
-A OUTPUT -j ACCEPT
Разрешить соединения на порт 80,443:
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT
Запретить все входящие соединения и форвардинг:
-A INPUT -j REJECT
-A FORWARD -j REJECT
Универсальное правило, на разрешение пинга:
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
Разрешить SSH соединения на порту 30000 (протокол TCP):
-A INPUT -p tcp -m state --state NEW --dport 30000 -j ACCEPT
Это не полное объяснение, но по чуть-чуть картина сложится:
Настройка IPtables в Fedora 17
В Fedora 17 правила все те же, но их настройка и активация чуть иная. Тут все правила пачкой прописываются в файл: /etc/sysconfig/iptables
После чего делается стандартные рестарт на сервис:
# /etc/init.d/iptables restart
Или
# systemctl restart iptables.service
Или
# service iptables restart
Что-бы фаервол стартовал с системой делаем так:
# chkconfig iptables on
Некоторые примеры
Разрешить подключение к порту 22 только с определенной сети:
-A INPUT -m state --state NEW -m tcp -p tcp --source 192.168.98.0/24 --dport 22 -j ACCEPT
Закрыть пинг:
-I INPUT -i eth0 -p icmp -s 0/0 -d 0/0 -j DROP
Закрыть пинг на внешнем интерфейсе eth0:
-A INPUT -p icmp --icmp-type echo-reply -s 0/0 -i eth0 -j DROP
-A INPUT -p icmp --icmp-type destination-unreachable -s 0/0 -i eth0 -j DROP
-A INPUT -p icmp --icmp-type time-exceeded -s 0/0 -i eth0 -j DROP
Закрыть пинг на любом интерфейсе:
-A INPUT -p icmp -m icmp --icmp-type 8 -j DROP
Забанить IP адрес:
-A INPUT -s 65.55.44.100 -j DROP
Забанить доступ к 21 порту для определенного IP:
-A INPUT -s 65.55.44.100 -p tcp --destination-port 25 -j DROP
Забанить целую подсеть:
-A INPUT -s 192.168.98.0/24 -j DROP
Запретить все соединения на 80 порт (все интерфейсы, протокол TCP):
-A INPUT -p tcp --dport 80 -j DROP
Запретить все соединения на 80 порт внешнего интерфейса eth1, протокол TCP
-A INPUT -i eth1 -p tcp --dport 80 -j DROP
Закрыть весь исходящий трафик по направлению к неугодному IP:
-A OUTPUT -d <IP ADDRESS> -j DROP
К примеру я хочу забанить сайт www.facebook.com на шлюзе, что-бы с офиса не было к нему доступа:
# sudo nslookup facebook.com
Name: facebook.com
Address: 173.252.100.16
Name: facebook.com
Добавляю правило:
-A OUTPUT -d 173.252.100.16 -j DROP
Но это забанит только один из серверов, а мы хитрые, так что чекаем подсеть:
# host -t a www.facebook.com
www.facebook.com is an alias for star.facebook.com.
star.facebook.com has address 66.220.158.20
# whois 69.171.228.40 | grep CIDR
CIDR: 69.171.224.0/19
Баним:
-A OUTPUT -p tcp -d 69.171.224.0/19 -j DROP
Но можно и проще:
-A OUTPUT -p tcp -d www.facebook.com -j DROP
-A OUTPUT -p tcp -d facebook.com -j DROP
Забанить комп по MAC адресу (таблица ARP на шлюзе вам в помощь):
-A INPUT -m mac --mac-source 00:0F:EA:91:04:08 -j DROP
Открыть диапазон портов:
-A INPUT -m state --state NEW -m tcp -p tcp --dport 7000:7010 -j ACCEPT
Список полезных правил, понятно что ACCEPT, DROP, REJECT по желанию
Replace ACCEPT with DROP to block port:
## open port ssh tcp port 22 ##
iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 22 -j ACCEPT
## open cups (printing service) udp/tcp port 631 for LAN users ##
iptables -A INPUT -s 192.168.1.0/24 -p udp -m udp --dport 631 -j ACCEPT
iptables -A INPUT -s 192.168.1.0/24 -p tcp -m tcp --dport 631 -j ACCEPT
## allow time sync via NTP for lan users (open udp port 123) ##
iptables -A INPUT -s 192.168.1.0/24 -m state --state NEW -p udp --dport 123 -j ACCEPT
## open tcp port 25 (smtp) for all ##
iptables -A INPUT -m state --state NEW -p tcp --dport 25 -j ACCEPT
# open dns server ports for all ##
iptables -A INPUT -m state --state NEW -p udp --dport 53 -j ACCEPT
iptables -A INPUT -m state --state NEW -p tcp --dport 53 -j ACCEPT
## open http/https (Apache) server port to all ##
iptables -A INPUT -m state --state NEW -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -m state --state NEW -p tcp --dport 443 -j ACCEPT
## open tcp port 110 (pop3) for all ##
iptables -A INPUT -m state --state NEW -p tcp --dport 110 -j ACCEPT
## open tcp port 143 (imap) for all ##
iptables -A INPUT -m state --state NEW -p tcp --dport 143 -j ACCEPT
## open access to Samba file server for lan users only ##
iptables -A INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 137 -j ACCEPT
iptables -A INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 138 -j ACCEPT
iptables -A INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 139 -j ACCEPT
iptables -A INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 445 -j ACCEPT
## open access to proxy server for lan users only ##
iptables -A INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 3128 -j ACCEPT
## open access to mysql server for lan users only ##
iptables -I INPUT -p tcp --dport 3306 -j ACCEPT
Посмотреть что происходит с портом 22:
iptables -L INPUT -v -n | grep 22
И в заключении можно сказать, что я привел выше только самые общие, базисные примеры, на самом деле IPtables умеет делать много вещей.
- Инспекция пакетов
- Фильтрация траффика
- Транслирование адресов (NAT)
- и т.д.