Материал из Wiki.X-news.org
Перейти к: навигация, поиск

Policy routing или раздаем инет через 2 или более интерфейсов (ipfw, pf)


Настройка policy routing В данной статье рассматривется тот случай, когда на сервере имеется два сетевых интерфейса через которые, в зависимости от тех или иных обстоятельств, будет идти трафик в интернет. Сразу оговорюсь что в данный момент времени я использую pf, а примеры с использованием ipfw приведены учитывая прошлый опыт, поэтому могут быть не столь полными. Также я надеюсь что (в случае с ipfw) имеется опыт настройки natd и соответствующих правил. Для pf также приветствуется знание синтаксиса :).


В общем случаем конфигурация используется следущая:

  rl0 - 10.10.10.254 (ip - шлюз провайдера .1, наш ip 10.10.10.10)
  rl1 - 20.20.20.254 (ip - шлюз провайдера .2, наш ip 20.20.20.10)
  rl2 - 30.30.30.30 (ip - адрес в локальной сети)Приступим. 
  
  
    IPFW
    Запускаем nat на интерфейсах: 
    
     natd -a 10.10.10.10 -p 8668 
     natd -a 20.20.20.20 -p 8778Далее создаем правила для файрвола: 
     
     ipfw add divert 8668 ip from 30.30.30.100 to any 
     #в данном случае вместо 30.30.30.100 можно подставить ip тех кого пускать через данный интерфейс
     #или вместо any написать то, куда люди будут ходить через данный интерфейс
     ipfw add divert 8778 ip from 30.30.30.0/24 to any 
     #аналогично первому комментарию
     #
     #сам policy
     ipfw add fwd 10.10.10.254 ip from 10.10.10.10 to any 
     ipfw add fwd 20.20.20.254 ip from 20.20.20.10 to any 
     #возвращаем пакеты
     ipfw add divert 8668 ip from any to 10.10.10.10 
     ipfw add divert 8778 ip from any to 20.20.20.10Привожу ещё один пример, в котором 1 пользователь ходит в сеть через первый канал и видит локальные ресурсы второго провайдера, а остальные наоборот: 
                   
     ipfw add divert 8778 ip from 30.30.30.100 to 100.100.100.0/24 
     #100.100.100.0/24 внутренняя сеть провайдера номер 1
     ipfw add divert 8668 ip from 30.30.30.100 to any
     ipfw add divert 8668 ip from 30.30.30.0/24 to 110.110.110.0/24
     ##110.110.110.0/24 внутренняя сеть провайдера номер 2
     ipfw add divert 8778 ip from 30.30.30.0/24 to any
     ipfw add fwd 10.10.10.254 ip from 10.10.10.10 to any
     ipfw add fwd 20.20.20.254 ip from 20.20.20.10 to any
     ipfw add divert 8668 ip from any to 10.10.10.10
     ipfw add divert 8778 ip from any to 20.20.20.10Вот собственно и всё.
                  
                  
     Дописать pbr для доступа к сервисам с внешних интерфейсов и динамические правила для ipfw 
                  
      PF
     Теперь pf, привожу кусок моего конфига:
    (в данном случае возможно придется настроить обычную маршрутизацю, в зависимости от поставленной задачи)
                    
                    
      #Внешние и внутренний интерфейсы.
      #
      ext_if_a        = "rl0" #первый провайдер
      ext_if_b        = "rl1" #второй провайдер
      int_if          = "rl2" #локалка
      #Шлюзы для каналов.
      #
      ext_gw_a        = "10.10.10.254" #для tun0
      ext_gw_b        = "20.20.20.254" #для tun1
      net             = "30.30.30.0/24" #локалка
      #TCP/UDP сервисы, обслуживаемые маршрутизатором, то к чему имеется доступ на внешних интерфейсах
      #
                     tcp_svc         = "990" #как пример, что то нужно вписать иначе будет биг ошибка :)
                     udp_svc         = "6000" #аналогично
                     #Натим, важный момент, именно тут определяется кого куда пускать
                     #Синтаксис ната, грубо говоря, таков: nat on _интерфейс_ from _откуда_ to _куда_ -> _интерфейс_или_ип_адрес
                     #
                     nat on $ext_if_a from {$net} -> ($ext_if_a:0)
                     nat on $ext_if_b from {$net} -> ($ext_if_b:0)
                     #Разрешаем сети ходить в интернет, всё остальное блокируем
                     #
                     block in on { $ext_if_a $ext_if_b }
                     block return-rst in on { $ext_if_a $ext_if_b } proto tcp
                     pass out on { $ext_if_a $ext_if_b } keep state
                     #Исходящие пакеты в канал, соответствующий адресу источника. Здесь и начинается policy
                     #
                     pass out route-to ($ext_if_a $ext_gw_a) from ($ext_if_a) to !(self:network) \
                     keep state
                     pass out route-to ($ext_if_b $ext_gw_b) from ($ext_if_b) to !(self:network) \
                     keep state
                     #А вот policy для входящих пакетов на внешние интерфейсы
                     #
                     pass in on $ext_if_a reply-to ($ext_if_a $ext_gw_a) proto udp \
                     to port { $udp_svc } keep state
                     pass in on $ext_if_a proto udp from ($ext_if_a:network) to port { $udp_svc } \
                     keep state
                     #
                     pass in on $ext_if_a reply-to ($ext_if_a $ext_gw_a) proto tcp \
                     to port { $tcp_svc } flags S/SA keep state
                     pass in on $ext_if_a proto tcp from ($ext_if_a:network) to port { $tcp_svc } \
                     flags S/SA keep state
                     #
                     pass in on $ext_if_b reply-to ($ext_if_b $ext_gw_b) proto udp \
                     to port { $udp_svc } keep state
                     pass in on $ext_if_b proto udp from ($ext_if_b:network) to port { $udp_svc } \
                     keep state
                     #
                     pass in on $ext_if_b reply-to ($ext_if_b $ext_gw_b) proto tcp \
                     to port { $tcp_svc } flags S/SA keep state
                     pass in on $ext_if_b proto tcp from ($ext_if_b:network) to port { $tcp_svc } \
                     flags S/SA keep state