Конфигурирование iptables

Доброго времени суток всем!
Уважаемый SATtva с год назад в рамках обсуждения настройки брандмауэра сказал, что виндовый способ мышления меня когда-нибудь погубит. Надеюсь, мне удалось изменить его (теперь ОС, загружающаяся по умолчанию, Debian) :)
После прочтения статей Oskar'а Andreasson'а в переводе Андрея Киселева, а также материалов (не всех ещё) с официального сайта iptables, некоторых других составил набор правил. Но, отдавая себе отчёт в том, что всевозможных тонкостей значительно больше, чем мне известно, хотел бы просить у профессионалов оценить степень защиты, даваемую нижеприведенными настройками для персонального компьютера, указать какие ещё правила для повышения защищённости можно добавить.
Например, так ли уж нужно использование помимо udp ещё и tcp протокола для связи с dns сервером в случае с персональнм компьютером?
[code]

#!/bin/sh
IPT="/sbin/iptables"
INET_IFACE="eth0"
UNPRIPORTS="1024:65535"
start_fw()
{
echo "1" > /proc/sys/net/ipv4/ip_forward
echo "1" > /proc/sys/net/ipv4/ip_dynaddr

$IPT -F
$IPT -X

$IPT -P INPUT DROP
$IPT -P FORWARD ACCEPT
$IPT -P OUTPUT DROP
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT
$IPT -A INPUT -m state ! -i lo --state NEW -j DROP
$IPT -A INPUT -s 127.0.0.1/255.0.0.0 ! -i lo -j DROP
$IPT -A INPUT -m state --state INVALID -j DROP
$IPT -A FORWARD -m state --state INVALID -j DROP
$IPT -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
$IPT -A OUTPUT -p tcp ! --syn -m state --state NEW -j DROP
$IPT -A INPUT -p UDP -s 0/0 --destination-port 138 -j DROP
$IPT -A INPUT -p UDP -s 0/0 --destination-port 113 -j REJECT
$IPT -A INPUT -p UDP -s 0/0 --source-port 67 --destination-port 68 -j ACCEPT
$IPT -A INPUT -p UDP -j RETURN
$IPT -A OUTPUT -p UDP -s 0/0 -j ACCEPT
$IPT -A INPUT --fragment -p ICMP -j DROP
$IPT -A OUTPUT --fragment -p ICMP -j DROP


$IPT -A INPUT -p icmp -m icmp -i $INET_IFACE --icmp-type source-quench -j ACCEPT
$IPT -A OUTPUT -p icmp -m icmp -o $INET_IFACE --icmp-type source-quench -j ACCEPT

$IPT -A INPUT -p icmp -m icmp -i $INET_IFACE --icmp-type echo-reply -j ACCEPT
$IPT -A OUTPUT -p icmp -m icmp -o $INET_IFACE --icmp-type echo-request -j ACCEPT

$IPT -A INPUT -p icmp -m icmp -i $INET_IFACE --icmp-type parameter-problem -j ACCEPT
$IPT -A OUTPUT -p icmp -m icmp -o $INET_IFACE --icmp-type parameter-problem -j ACCEPT

$IPT -A INPUT -p tcp -m tcp -i $INET_IFACE --dport 6000:6063 -j DROP --syn

$IPT -A INPUT -p tcp -m tcp -m multiport -i $INET_IFACE -j DROP --dports 783
$IPT -A INPUT -p tcp -m tcp -m multiport -i $INET_IFACE -j DROP --dports 3310
$IPT -A INPUT -p tcp -m tcp -m multiport -i $INET_IFACE -j DROP --dports 10000

$IPT -A OUTPUT -p udp -m udp -o $INET_IFACE --dport 53 --sport 1024:65535 -j ACCEPT
$IPT -A OUTPUT -p tcp -m tcp -o $INET_IFACE --dport 53 --sport 1024:65535 -j ACCEPT
$IPT -A INPUT -p udp -m udp -i $INET_IFACE --dport 1024:65535 --sport 53 -j ACCEPT
$IPT -A INPUT -p tcp -m tcp -i $INET_IFACE --dport 1024:65353 --sport 53 -j ACCEPT

$IPT -A OUTPUT -p tcp -m tcp -o $INET_IFACE --dport 113 --sport 1024:65535 -j ACCEPT
$IPT -A INPUT -p tcp -m tcp -i $INET_IFACE --dport 1024:65535 --sport 113 -j ACCEPT ! --syn
$IPT -A INPUT -p tcp -m tcp -i $INET_IFACE --dport 113 -j DROP

$IPT -A OUTPUT -p tcp -m tcp -o $INET_IFACE --dport 25 --sport 1024:65535 -j ACCEPT
$IPT -A INPUT -p tcp -m tcp -i $INET_IFACE --dport 1024:65535 --sport 25 -j ACCEPT ! --syn

$IPT -A OUTPUT -p tcp -m tcp -o $INET_IFACE --dport 110 --sport 1024:65535 -j ACCEPT
$IPT -A INPUT -p tcp -m tcp -i $INET_IFACE --dport 1024:65535 --sport 110 -j ACCEPT ! --syn

$IPT -A OUTPUT -p tcp -m tcp -o $INET_IFACE --dport 993 --sport 1024:65535 -j ACCEPT
$IPT -A INPUT -p tcp -m tcp -i $INET_IFACE --dport 1024:65535 --sport 993 -j ACCEPT ! --syn

$IPT -A OUTPUT -p tcp -m tcp -o $INET_IFACE --dport 995 --sport 1024:65535 -j ACCEPT
$IPT -A INPUT -p tcp -m tcp -i $INET_IFACE --dport 1024:65535 --sport 995 -j ACCEPT ! --syn

$IPT -A OUTPUT -p tcp -m tcp -o $INET_IFACE --dport 1024:65535 --sport 49928 -j ACCEPT
$IPT -A INPUT -p tcp -m tcp -i $INET_IFACE --dport 49928 --sport 1024:65535 -j ACCEPT ! --syn
$IPT -A OUTPUT -p udp -m udp -o $INET_IFACE --dport 1024:65535 --sport 49928 -j ACCEPT
$IPT -A INPUT -p udp -m udp -i $INET_IFACE --dport 49928 --sport 1024:65535 -j ACCEPT ! --syn


# $IPT -A OUTPUT -p tcp -m tcp -o $INET_IFACE --dport 22 --sport 1024:65535 -j ACCEPT
# $IPT -A INPUT -p tcp -m tcp -i $INET_IFACE --dport 1024:65535 --sport 22 -j ACCEPT ! --syn
# $IPT -A OUTPUT -p tcp -m tcp -o $INET_IFACE --dport 22 --sport 1020:1023 -j ACCEPT
# $IPT -A INPUT -p tcp -m tcp -i $INET_IFACE --dport 1020:1023 --sport 22 -j ACCEPT ! --syn

$IPT -A OUTPUT -p tcp -m tcp -o $INET_IFACE --dport 21 --sport 1024:65535 -j ACCEPT
$IPT -A INPUT -p tcp -m tcp -i $INET_IFACE --dport 1024:65535 --sport 21 -j ACCEPT ! --syn

$IPT -A OUTPUT -p tcp -m tcp -m multiport -o $INET_IFACE --sport 1024:65535 -j ACCEPT --dports 80,443
$IPT -A INPUT -p tcp -m tcp -m multiport -i $INET_IFACE --dport 1024:65535 -j ACCEPT --sports 80,443 ! --syn

$IPT -A INPUT -p tcp -m tcp -i $INET_IFACE --dport 1024:65535 --sport 20 -j ACCEPT
$IPT -A OUTPUT -p tcp -m tcp -o $INET_IFACE --dport 20 --sport 1024:65535 -j ACCEPT ! --syn
$IPT -A OUTPUT -p tcp -m tcp -o $INET_IFACE --dport 1024:65535 --sport 1024:65535 -j ACCEPT
$IPT -A INPUT -p tcp -m tcp -i $INET_IFACE --dport 1024:65535 --sport 1024:65535 -j ACCEPT ! --syn
$IPT -A OUTPUT -p tcp -m tcp -o $INET_IFACE --dport 23 --sport 1024:65535 -j ACCEPT
$IPT -A INPUT -p tcp -m tcp -i $INET_IFACE --dport 1024:65535 --sport 23 -j ACCEPT ! --syn
$IPT -A OUTPUT -p tcp -m tcp -o $INET_IFACE --dport 79 --sport 1024:65535 -j ACCEPT
$IPT -A INPUT -p tcp -m tcp -i $INET_IFACE --dport 1024:65535 --sport 79 -j ACCEPT ! --syn
$IPT -A OUTPUT -p tcp -m tcp -o $INET_IFACE --dport 43 --sport 1024:65535 -j ACCEPT
$IPT -A INPUT -p tcp -m tcp -i $INET_IFACE --dport 1024:65535 --sport 43 -j ACCEPT ! --syn
$IPT -A OUTPUT -p tcp -m tcp -o $INET_IFACE --dport 70 --sport 1024:65535 -j ACCEPT
$IPT -A INPUT -p tcp -m tcp -i $INET_IFACE --dport 1024:65535 --sport 70 -j ACCEPT ! --syn
$IPT -A OUTPUT -p tcp -m tcp -o $INET_IFACE --dport 210 --sport 1024:65535 -j ACCEPT
$IPT -A INPUT -p tcp -m tcp -i $INET_IFACE --dport 1024:65535 --sport 210 -j ACCEPT ! --syn
$IPT -A OUTPUT -p udp -m udp -o $INET_IFACE --dport 33434:33523 --sport 32769:65535 -j ACCEPT

$IPT -A OUTPUT -p udp -m udp -o $INET_IFACE --dport 67 --sport 68 -j ACCEPT
$IPT -A INPUT -p udp -m udp -i $INET_IFACE --dport 68 --sport 67 -j ACCEPT
}
[/code]

Спасибо



Комментарии
— unknown (26/07/2011 17:12, исправлен 26/07/2011 17:24)   

Если это


Для чего вы используете форвардинг? И включаете динамическую адресацию при том, что указан только интерфейс eth0? Получаете адрес по DHCP и пишете его в логи? Сервисы, которые у вас дропаются, они реально запущены на вашей машине?


Также, так ли уж оправдана политика DROP для OUTPUT с ограниченным числом разрешённых портов?


Действительно, не нужно.

— Geidrow (26/07/2011 17:53, исправлен 26/07/2011 18:02)   

1. Похоже, с форвардингом я погорячился.


2.

И включаете динамическую адресацию

из статьи

Если вам необходима поддержка динамического IP, (при использовании SLIP, PPP или DHCP) вы можете раскомментарить строку:
echo "1" > /proc/sys/net/ipv4/ip_dynaddr

Может, я неправильно что-то понимаю, но провайдер назначает именно динамические IP.
3.

Сервисы, которые у вас дропаются...

Ёмкий вопрос. Попробуем зайти с другой стороны.
Мне нужно обеспечить работу
торрент-клиента;
sip (Ekiga);
IM (Pidgin or Kopete);
mail (pop3, imap)
Сомнения вызывает вопрос о том по каким портам работают Ekiga и IM. Из непривилегированных портов я бы оставил открытыми только используемые вышеперечисленными приложениями.


4. Если я не желаю, чтобы моу машину пинговали, то


5. Чем отличаются параметры следующих команд (на некоторых ресурсах 1-ую приводят для запуска скрипта инициализации во время загрузки, на других – 2-ую):



Может, это связано с уровнями запуска. Какую использовать?


Также, так ли уж оправдана политика DROP для OUTPUT с ограниченным числом разрешённых портов?

не знаю

— Geidrow (26/07/2011 18:05)   
Получаете адрес по DHCP и пишете его в логи?

Получаю адрес по DHCP, в логи не пишу
— unknown (27/07/2011 10:41)   

  1. Да :-).
  2. Если обычный DHCP через eth0 (не считая особо извращённых случаев) работает без этой опции, то включать её специально нет необходимости.
  3. . Затем смотрите, что нужно прикрывать, если оно слушает по 0.0.0.0. А может лучше вообще отключить этот сервис или перенастроить, чтобы он не слушал входящие.
  4. Так тоже можно
  5. Курить новую систему запуска параллельных скриптов со всякими зависимостями для каждого уровня или забить на это. И написать свой скрипт для iptables, который положить в /etc/networks/if-pre-up.d

Насчёт политики: на локальной машине часто разрешают все исходящие. Программы часто меняются, требуют разных портов и т.д. Всё, что запускается локально изначально доверяемо, если не нужны особые подстройки.

P.S. Если не используете протокол IPv6, то при запуске передайте через LILO или GRUB параметр ipv6.disable=1
— Geidrow (27/07/2011 18:03)   
В ходе экспериментов произошло что-то странное.
Выполнил update-rc.d -f rc.iptables remove
Внёс изменения в настройки:
по сравнению с исходным файлом удалил строки, определяющие параметры работы с finger, whois, gorper, wais, traceroute (для портов 20,23,43,70,79,210).
Выполнил update-rc.d rc.iptables start 90 2 3 4 5. stop 10 0 1 6 .
Перезагрузил ОС
В итоге:

Брандмауэр запрещает, похоже, всё кроме dhcp и dns .

Ситуация разрешается заменой
$IPT -P OUTPUT DROP на
$IPT -P OUTPUT ACCEPT

Вопрос:
а как в первой конфигурации всё работало?
В конечном итоге я запутался в том как iptables работает.
Конечный вариант iptables таков

Это защита или одна сплошная уязвимость?
Гость (01/08/2011 15:51)   
О, тут анализируют iptables?! Прокомментируйте тогда мой конфиг, пожалуйста:



Пояснение: на целевой машине IP=192.168.0.2 есть неанонимный инет через NAT на IP=192.168.0.1 и анонимный инет через подключение к 192.168.0.3:8118. Соответственно, юзеры root и non_tor могут использовать только неанонимный инет и без ограничений, а анонимный юзер tor_user может коннектиться исключительно к 192.168.0.3:8118 и никуда более. Помимо того, неанонимный юзер может ходить по ssh на 192.168.0.3. Я нигде не ошибся?
Гость (09/09/2011 20:29)   
Для тех, кто забыл (сам такой):

  1. Выполняем
  2. и комментируем весь IPv6 в /etc/hosts, для надёжности:
Т.к. стандартный iptables трафик IPv6 не регулирует никак.
— unknown (10/09/2011 06:35)   
ipv6.disable=1 — передать этот параметр ядру при загрузке, предварительно вписав в GRUB. Самый надёжный способ отключения ipv6, остальное будет не нужно.
Гость (22/09/2011 10:35)   
ipv6.disable=1 вписывать в строку GRUB_CMDLINE_LINUX_DEFAULT или GRUB_CMDLINE_LINUX
Гость (27/09/2011 15:00)   
анонимный юзер tor_user может коннектиться исключительно к 192.168.0.3:8118 и никуда более.
Ваш аноним будет будет запускать браузеры и прочие шалости? Ицмп в интернеты рутам разрешены, и наверно /bin/ping суидный? Достаточно будет ошибки с выполнением произвольных команд (не говоря про выполнение кода) где-то в недрах запускаемых свистелок.
Гость (27/09/2011 16:51)   
Достаточно будет ошибки с выполнением произвольных команд (не говоря про выполнение кода) где-то в недрах запускаемых свистелок.
Не-а. Надо как минимум уязвимость вида local root. Странно было бы от неё защищаться исключительно конфигом iptables.

Ицмп в интернеты рутам разрешены, и наверно /bin/ping суидный?
Да, конечно. Суидных программ вообще много, если что.
Гость (27/09/2011 17:29)   
Не нужен рут, пынг запустят из дырявого браузера. Этим конфигом "одновременно" доставляют рутов и прочих анонимов в интернеты, вот что действительно странно.
— unknown (27/09/2011 17:51)   
А руту вообще можно что-то запретить не прибегая к SELinux'ам и прочим AppArmor'ам? Правила для рута — это защита от случайной ошибки, а не от злоумышленника, который стал рутом.

Хотя зачем руту вообще ходить в инет? Анонимов надо редиректить в Tor, остальных вообще в инет не пускать.
Гость (27/09/2011 18:06)   
Дырявый браузер не обеспечит рута и бинарник пинга не содержит ошибок в этой истории, но деанон уже тут.
Гость (27/09/2011 18:31)   
Достаточно будет ошибки с выполнением произвольных команд (не говоря про выполнение кода) где-то в недрах запускаемых свистелок.

Дырявый браузер не обеспечит рута и бинарник пинга не содержит ошибок в этой истории, но деанон уже тут.

А поподробней можно? И что имеется в виду под "недрами запускаемых свистелок"? Особенно хочется узнать, как tor_user через ICMP (он ему вообще запрещён fw'ом) получает деанон.
Гость (27/09/2011 21:21)   
Для посылки ицмп нужно открыть сырой сокет, открытие сырого сокета требует привелегий. В классическом варианте это достигается через суидный бинарник: создали сокет и сбросили привелегии, а дальше пишем и читаем оттуда любым анонимом. Но только ицмп пакеты принадлежат руту, а не анониму.
Запрещать надо руту (лучше просто всем, поскольку не логично запрещать что-либо конкретно руту).
Гость (28/09/2011 14:00)   
Хорошо, давайте немного заземлим эту дискуссию. Пусть я работаю под анонимным пользователем и хочу сам себя чисто программными автоматическими средствами деанонимизировать. Напишите мне скрипт или программу, которая, будучи запущенной под tor_user, пошлёт заданный ICMP-пакет на заданный адрес.

Я согласен, что ICMP лучше блокировать, но в данном конкретном случае я решил, что это не слишком опасно и потому оставил. Всё же интересно услышать детали — что вы имеете в виду.
Гость (28/09/2011 16:03)   

tor_user@harakiri:$ /bin/ping -c 1 deanon.complete
PING deanon.complete (66.66.66.66) 56(84) bytes of data.
64 bytes from deanon.complete (66.66.66.66): icmp_req=1 ttl=66 time=11 ms


deanon.complete ping statistics
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 11.312/11.312/11.312/0.000 ms
Гость (28/09/2011 17:40)   
Да, теперь всё понял. Сглючило меня :( Спасибо за замечание.

Действительно, владельцем ICMP пакетов будет всегда рут, кто бы их ни посылал. Оставлял чисто для быстрой проверки проблем с инетом и не подумал, хотя на стандартных конфигурациях всегда отключал ICMP. Видимо, ошибся из-за того, что забыл про привязку host:IP к конкретному протоколу. Стандартные краш-тесты тоже ничего не показали, т.к. резолвинг был закрыт из-за бана udp. Однако ж, по ICMP пакет должен был пойти, увы. Окончательно протестить не удалось — ICMP почему-то сейчас никак не работает, даже с отключенным fw.