Назад | Перейти на главную страницу

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

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

Система CentOS 5.3.

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

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

# 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

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

По большей части выглядит хорошо. Главное, что вам, вероятно, следует использовать 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 напрямую в все, вы делаете это неправильно.