iptables - ОК, ** сейчас ** я делаю это правильно?

Это продолжение предыдущего вопроса, где я спросил, верен ли мой конфиг iptables.

Система CentOS 5.3.

Ожидаемый результат: заблокировать все, кроме ping, ssh, Apache и SSL.

Основываясь на советах xenoterracide и других ответах на вопрос (спасибо, ребята), я создал этот скрипт:

# Establish a clean slate
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
iptables -F # Flush all rules
iptables -X # Delete all chains

# Disable routing. Drop packets if they reach the end of the chain.
iptables -P FORWARD DROP

# Drop all packets with a bad state
iptables -A INPUT -m state --state INVALID -j DROP
# Accept any packets that have something to do with ones we've sent on outbound
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# Accept any packets coming or going on localhost (this can be very important)
iptables -A INPUT -i lo -j ACCEPT
# Accept ICMP
iptables -A INPUT -p icmp -j ACCEPT

# Allow ssh
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# Allow httpd
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# Allow SSL
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# Block all other traffic 
iptables -A INPUT -j DROP

Теперь, когда я перечисляю правила, я получаю...

# iptables -L -v
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       all  --  any    any     anywhere             anywhere            state INVALID 
    9   612 ACCEPT     all  --  any    any     anywhere             anywhere            state RELATED,ESTABLISHED 
    0     0 ACCEPT     all  --  lo     any     anywhere             anywhere            
    0     0 ACCEPT     icmp --  any    any     anywhere             anywhere            
    0     0 ACCEPT     tcp  --  any    any     anywhere             anywhere            tcp dpt:ssh 
    0     0 ACCEPT     tcp  --  any    any     anywhere             anywhere            tcp dpt:http 
    0     0 ACCEPT     tcp  --  any    any     anywhere             anywhere            tcp dpt:https 
    0     0 DROP       all  --  any    any     anywhere             anywhere            

Chain FORWARD (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 5 packets, 644 bytes)
 pkts bytes target     prot opt in     out     source               destination

Я запустил его, и я все еще могу войти, так что это хорошо. Кто-нибудь замечает что-то серьезное?

3 ответа

Решение

Выглядит хорошо по большей части. Главное, что вы, вероятно, должны использовать iptables-save и iptables-restore, а не повторные запуски iptables. Метод iptables-save/restore предоставляет элементарные массовые обновления (например, транзакции базы данных), поэтому вы знаете, что ничто не может войти (или НЕ войти), потому что ваши изменения iptables были наполовину завершены, когда поступили сетевые пакеты. Внесение этого изменения также позволит вам сбросить исходные политики ACCEPT, поэтому он просто устанавливает предпочтительную политику (предпочтительно DENY), а затем отдельные правила (исключения, которые приняты).

Кроме того, вы можете захотеть посмотреть на блокировку ICMP немного больше (а не просто разрешить все). Я слышал, что некоторые аспекты ICMP в наши дни довольно хитры. Лично я не думаю, что это того стоит, так как от ICMP зависит многое от диагностики и управления трафиком.

По поводу замечания womble "не используйте iptables": я бы не сказал, что вы не должны использовать iptables (или iptables-save/restore) напрямую, но я бы рекомендовал вместо этого взглянуть на FERM. По сути, это просто iptables, с более выразительным и менее повторяющимся языком, плюс поддержка переменных. Например, ваши команды iptables:

iptables -P INPUT ACCEPT
...
# Allow ssh
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# Allow httpd
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# Allow SSL
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

Выглядело бы больше так в ferm:

# allow some incoming TCP
chain INPUT {
    policy ACCEPT;
    proto tcp dport (ssh httpd https) ACCEPT;
}

Намного лучше, а?;)

Наконец, НЕ запускайте SSH на порте по умолчанию 22. Переместите его на другой адрес (отредактируйте файл конфигурации и перезагрузите sshd). Вы можете сделать это даже при подключении через ssh, но лучше использовать другой метод доступа при работе с ssh или правилами брандмауэра (на основе консоли, предоставляемой виртуальными выделенными хостами). Также обратите внимание на настройку что-то вроде fail2ban. Но я бы не использовал его без фиксированного IP-адреса (со своей стороны) и специальных правил брандмауэра, чтобы разрешить мне доступ, несмотря ни на что, перед любой блокировкой, которую делает fail2ban.

Выглядит хорошо, мое личное предпочтение было бы добавить

-m state --state NEW

к этим правилам

# Allow ssh
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# Allow httpd
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# Allow SSL
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

И измените политику по умолчанию на INPUT, FORWARD на DROP, делая

# Block all other traffic 
iptables -A INPUT -j DROP

избыточный

Я бы сказал, что если вы используете iptables напрямую, вы делаете это неправильно.

Другие вопросы по тегам