Документация по ОС FreeBSD Четверг, 28.03.2024, 21:25
Приветствую Вас Гость | RSS
Меню сайта

Категории каталога
IPFW [58]

Главная » Статьи » FireWall » IPFW

PF : разбираем конфиг для офисов. Часть 1 [2009]
OpenBSD Packet Filter (PF) — это очень функциональный фаервол, который может практически все, что может потребоваться от фаервола и даже больше. Давайте посмотрим каким образом его можно использовать в нашем офисе и какие выгоды мы получим.

   Наша сеть состоит из 4х пользовательских компьютеров и шлюза с двумя интерфейсами. Имеется симметричный канал в интернет 1Мбит. На шлюзе поднят транспарентый прокси squid с системой управления SAMS. Сервисы Интернет, к которым разрешено обращаться пользователям (кроме менеджера, он отрублен от инета) локальной сети следующие :
nntp, ntp, dns, www
все остальное запрещаем. Из разрешенного траффика www заворачиваем на прокси, остальное NAT'им.
Кроме того :
к одному из компьютеров требуется доступ извне, т.к. менеждер иногда работает из дома;
также и к SAMS нужно иметь доступ снаружи;
эффективно делим канал между пользователями;
есть доступ по ssh как изнутри так и снаружи;
защищаем все сервисы от атак dos, spoofing, а сервис ssh также и от bruteforce.

Схема нашей сети :

Пару слов о конфигурировании транспарентного прокси :
  • не забудьте собрать его с поддержкой SQUID_PF ;
  • к слушаемому порту добавьте параметр transparent;
    Например,
    http_port 8080 transparent
    на клиентских компьютерах ставим 192.168.0.133 в качестве основного шлюза;

    Скажу сразу, что шифрованный трафик завернуть через прокси не получится (см. здесь и в [9])

    Конфиг буду разбирать "по-секциям", целиком файл скачать можно тут

    1) Макросы :
    (макросы в PF это что-то наподобие строковых переменных в классических языках программирования,
    в которые можно записывать несколько значений. Записать несколько значений можно путем добавления обрамляющих скобок {} в которых список значений указывается через пробел или через запятую)
    int_if="re0" # внутренний интерфейс, имеет адрес 192.168.0.133
    ext_if="tun0" # внешний интерфейс, динамический белый адрес (подключение по pppoe)
    dns_serv="153.53.53.53" # адрес нашего DNS сервера
    proxy_if="lo0" # интерфейс, на котором слушает прокси
    proxy_port="8080" # порт прокси
    boss="192.168.0.168" # IP адрес компьютера босса
    buh="192.168.0.100" # IP адрес компьютера бухгалтера
    admin="192.168.0.25" # IP адрес компьютера администратора
    WinPeak="192.168.0.60" # IP адрес компьютера менеджера
    allowed_icmp_types="{ echoreq, unreach }" # разрешенные типы icmp сообщений.
    # Остались неизменными с прошлой статьи. Всякие icmp-редиректы ффтопку.
    #--
    # Cписок немаршрутизируемых адресов, с которых к нам
    # будут долбиться на внешний интерфейс, а мы их будем заботливо писать в лог.
    non_route_nets_inet="{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8, \
        169.254.0.0/16, 192.0.2.0/24, 0.0.0.0/8, 240.0.0.0/4 }"
    Запись интерфейсов в виде

    int_if="re0"

    и

    ext_if="tun0"

    имеет значительное преимущество перед записью непосредственно IP адресов, как минимум в двух случаях :
    {a} выдается динамический адрес
    {b} есть необходимость получить маску, установленную на интерфейсе.

    Что и имеет место быть в нашем конфиге. В первом случае, при использовании в правилах макроса

    $ext_if

    в правила подставиться IP адрес, динамически выданный интерфейсу tun0.

    Во втором случае, мы будем использовать маску подсети интерфейса re0, для определения границ нашей локальной сети. Записывается это так

    $int_if:network

    Хотелось бы отметить, что физическому внешнему интерфейсу re1 в целях безопасности вообще не назначено IP адреса.

    Следующая секция  
    2) таблицы

    table <BRUTEFORCERS> persist

    Таблицы в PF реализуют динамические списки значений. У нас всего одна таблица, в этот список попадают IP адреса тех, кто превысил лимит подключений в единицу времени к сервису ssh.

    3) Опции

    # тем, кто лезет туда куда не нужно вежливо сообщаем что нельзя
    set block-policy return
    set skip on lo0 # не проверяем на lo0
    # изменяем время для состояния установленного tcp соединения,
    # которое по-умолчанию черезчур большое (24часа)
    set timeout { frag 10, tcp.established 3600 }
    # перед тем, как отправить фрагментированный пакет дальше
    # сначала дожидаемся всех его частей
    scrub in all

    Если Вас досят — есть смысл поставить вместо "return"

    set block-policy drop

    Но делайте это после того, как Ваш конфиг отлажен, потому что такая политика внешне напоминает отказ сетевого оборудования и трудно определить что происходит — то ли это сеть глючит, то ли фаервол блокирует трафик.

    4) Трафик-шейпинг или очереди

    # реальная полоса 1Мбит, а здесь нужно ставить на несколько % меньше
    # ЭТО *ОЧЕНЬ* ВАЖНО! Иначе шейпинг не будет работать!!
    altq on $ext_if cbq bandwidth 970Kb queue \
     { qboss, qbuh, qadmin, qWinPeak, qssh, qdns, qntp, qack }
     queue qboss bandwidth 38% priority 2 cbq ( borrow )
     queue qbuh bandwidth 18% priority 2 cbq ( borrow )
     queue qadmin bandwidth 15% priority 2 cbq ( borrow )
     queue qWinPeak bandwidth 12% priority 3 cbq ( default borrow )
     queue qssh bandwidth 8% priority 4 cbq ( borrow )
     queue qdns bandwidth 2% priority 5 cbq ( borrow )
     queue qntp bandwidth 2% priority 7 cbq ( borrow )
     queue qack bandwidth 5% priority 6 cbq ( borrow )

    Сколько % нужно минусовать от реальной полосы — зависит от канала. На асимметричных каналах (например, ADSL) рекомендуются значения до 10% меньше, чем реальная полоса. Лично у меня в локальной сети работало и с 2% .
    Боссу даем 38% ширины канала, бухгалтеру 18% и себе 15%. Приоритеты траффика у нас троих одинаковые (priority 2), когда есть свободная полоса, разрешаем занимать ее (borrow).
       Чем больше priority тем меньше время, которое пакеты будут пребывать в очереди.
    При использовании очередей cbq максимальный priority, который можно поставить равен 7. Если не указывать priority, то по умолчанию она принимается равной 1.
       Трафик к удаленному рабочему столу компьютера WinPeak имеет бОльший приоритет (priority 3). Кроме того, здесь я поставил метку default, согласно синтаксису очередей cbq (одна такая должна быть в любом случае).
    ssh траффик имеет еще больший приоритет (priority 4) и гарантированную ширину канала 8%.
    dns запросы идут нечасто, так что получают (priority 5) и ширину в 2%.
       Запросы синхронизации времени (NTP) пускаем по очереди с максимально возможным в очередях cbq приоритетом, ширина канала 2%.
       И последнее что хотелось бы отметить, это легковесные ACKnowledgement пакеты (еще назыаются квитанциями о получении), которые отправляются получателем для подтверждении принятых пакетов. Очень важно чтобы эти пакеты не застревали в очереди, потому что у отправителя может сработать тайм-аут и он повторно отправит пакеты, на которые не получил подтверждений о получении; priority 6 и ширина канала 5% (т.к. по этой категории пойдут пакеты от ВСЕХ пользователей и сервисов нашей сети).

    5) NAT

    # NAT всех разрешенных портов, кроме www
    nat on $ext_if from $ext_if:network to any port { ntp, nntp, domain } -> $ext_if
    # www завернем на прокси
    rdr on $int_if proto tcp from $int_if:network to any port www \
     -> $proxy_if port $proxy_port
    # пробросим порт RDP внутрь нашей сети, на комп WinPeak (комп менеджера)
    rdr on $ext_if proto tcp from any to $ext_if port rdp -> $WinPeak port rdp

    # Единственное на чем хотелось бы заострить Ваше внимание
    # - это логичность следования секций.
    # Правила NAT и rdr срабатывают до правил фильтрации,
    # поэтому они и распологаются выше по конфигу.
    # И именно поэтому трафик, который пойдет от клиента по 80
    # порту мы пропускаем по правилу
    # pass in on $int_if  proto tcp from { $boss, $buh, $admin } to \
    # $proxy_if port >>>> $proxy_port <<<< порт 8080!
    # потому что когда будет обрабатываться это правило
    # rdr уже сработает и подменит 80й порт 8080м
    # (а также подменит IP адрес получателя)

    6) Правила фильтрации

    # хорошее начало любых правил :-P
    # Правда! (см. [7])
    block all
    
    # блокируем всяких нехороших людей
    # стандартный антиспуфинг средствами pf
    antispoof log quick for { lo0, $int_if, $ext_if }
    # те, кто ломится на внешний интерфейс с левыми адресами
    block drop in log quick on $ext_if from $non_route_nets_inet to any
    # умников, которые лезут на внутренний интерфейс с любых сетей
    # отличных от 192.168.0.0/24
    block drop in log quick on $int_if from !$int_if:network to any
    # пишем тех, кто ломится к нам на 25 порт. Облегчает работу по
    # определению зараженных компов в локальной сети
    block drop in log quick on { $int_if, $ext_if } proto tcp from any to any port smtp
    # агаааааа, а эти подбирали пароли к ssh
    block drop log quick from <BRUTEFORCERS>
    # всех пишем в лог
    # у меня набегает
    # 10 Мб логов за 5 дней (!), на сервере которому пытаются пролезть на порт smtp
    # и видимо подDoSивают. Главное не забыть настроить
    # ротацию логов man newsyslog.conf
    
    # ssh для локальных юзеров
    pass in on $int_if proto tcp from $int_if:network to $int_if port ssh \ 
     queue ( qssh, qack ) synproxy state ( max-src-conn-rate 1/60, \ 
     overload <BRUTEFORCERS> flush global )
    # и для пользователей с инета
    pass in on $ext_if proto tcp from any to $ext_if port ssh \
     queue ( qssh, qack ) synproxy state ( max-src-conn-rate 1/60, \ 
     overload <BRUTEFORCERS> flush global )
    
    # synproxy защищает наш сервис ssh от DoS атак, благодаря тому, что
    # сначала САМ устанавливает соединение 
    # (не допуская полуоткрытых состояний),
    # а потом передает установленное соединение сервису.
    # Имеет немного бОльшие накладные расходы по сравнению с keep
    
    # max-src-conn-rate numer/time interval
    # позволяет применить определенные действия
    # к превысившим ограничение по количеству подключений
    # за единицу времени. Здесь я указал максимум 1 подключение 
    # за 60 секунд. Все превысившие это ограничение заносятся в таблицу
    # BRUTEFORCERS и с ними разрываются (flush) установленные 
    # соединения по всем (global) портам. Обратитие внимание, что
    # 1/60 -- очень агрессивная настройка. Не попадитесь под нее сами.
    # В Вашем случае 5/300 возможно будет более актуальным.
    
    
    # разрешаем входящий трафик www, который пойдет через прокси. 
    # Нет смысла в разделении этого трафика по очередям cbq, т.к. :
    # 1. Можем зашейпить его с помощью squid delay pools
    # 2. PF не сможет определить принадлежность трафика к
    # к конкретному пользователю, после того как траф будет
    # пропущен через squid (ведь шейпинг у нас работает на $ext_if).
    pass in on $int_if proto tcp from { $boss, $buh, $admin } to \
     $proxy_if port $proxy_port
    
    # пропустим запросы синхронизации времени поступающие на
    # $int_if . Помещаем такие пакеты в самую быструю очередь.
    # Т.к. подтверждение о получении в UDP не высылается
    # то и не указываем вторым параметром имя очереди qack.
    # --
    pass in on $int_if proto udp from { $boss, $buh, $admin } to \
     any port ntp queue qntp keep state
    
    # Заметьте, что вторым параметром при указании очереди 
    # указывается имя очереди, по которой пойдут ACK пакеты
    # queue ( ИмяОчередиОсновныхПакетов, ИмяОчередиACK_Пакетов )
    #--
    # Для создания
    # состояний UDP пакетов имеет смысл указывать только
    # keep state. Остальные (modulate и synproxy) полезны
    # для tcp.
    
    # Новостные конференции USENET (nntp)
    # вот тут юзеры могут и покачать, шейпим однозначно!
    # от Босса
    pass in on $int_if proto tcp from $boss to any port nntp \
     queue ( qboss, qack ) modulate state
    # от Бухгалтера
    pass in on $int_if proto tcp from $buh to any port nntp \
     queue ( qbuh, qack ) modulate state
    # от -=Админа=-
    pass in on $int_if proto tcp from $admin to any port nntp \
     queue ( qadmin, qack ) modulate state
    
    # modulate -- это почти тот же keep с тем отличием, что
    # при установлении соединения будут сгенерированы
    # высококачественные Initial Sequence Number, которые
    # труднее угадать, соответственно труднее перехватить сессию.
    
    # DNS запросы идут по спец очереди qdns с высоким приоритетом
    # UDP не шлет ACK, qack не используем
    # от Босса
    pass in on $int_if proto udp from $boss to any port domain \
     queue qdns keep state
    # от Бухгалтера
    pass in on $int_if proto udp from $buh to any port domain \
     queue qdns keep state
    # от -=Админа=-
    pass in on $int_if proto udp from $admin to any port domain \
     queue qdns keep state
    
    # входящие соединения с компом WinPeak по порту rdp
    # защищаем с помощью synproxy 
    pass in on $ext_if proto tcp from any to $WinPeak port rdp \ 
     queue ( qWinPeak, qack ) synproxy state
    # теоретически здесь synproxy уже не нужен
    pass out on $int_if proto tcp from any to $WinPeak port rdp \
     queue ( qWinPeak, qack ) modulate state
    
    # выходящий через $ext_if ntp траффик
    # здесь пропишем очередь вручную для
    # пакетов, исходящих не из локальной сети, а 
    # непосредственно от сервера
    pass out on $ext_if proto udp from $ext_if to any port ntp \
     keep state queue qntp
    
    # выходящий через $ext_if nntp траффик (tcp)
    pass out on $ext_if proto tcp from $ext_if to any port nntp \
     modulate state
    
    # выходящий через $ext_if www траффик (tcp)
    pass out on $ext_if proto tcp from $ext_if to any port www \
     modulate state
    
    # выходящий через $ext_if dns траффик (udp)
    # здесь пропишем очередь вручную для
    # пакетов, исходящих не из локальной сети, а 
    # непосредственно от сервера
    pass out on $ext_if proto udp from $ext_if to \
     $dns_serv port domain keep state queue qdns
    
    # Возможность доступа к SAMS из внешней сети.
    # Логируем, 
    # защищаем с помощью synproxy .
    pass in log on $ext_if proto tcp from any to $ext_if \
     port www synproxy state
    
    # icmp
    pass log inet proto icmp all icmp-type $allowed_icmp_types

     


  • Источник: http://www.lissyara.su/?id=1833
    Категория: IPFW | Добавил: oleg (11.01.2009) | Автор: Grishun_U_S
    Просмотров: 1881 | Рейтинг: 0.0/0 |
    Всего комментариев: 0
    Добавлять комментарии могут только зарегистрированные пользователи.
    [ Регистрация | Вход ]
    Форма входа

    Beastie

    Друзья сайта

    Статистика

    Онлайн всего: 1
    Гостей: 1
    Пользователей: 0
    links

    Copyright MyCorp © 2024