Как стать автором
Обновить

Комментарии 25

Не очень хороший способ реабилитироваться, начиная статью с «однако карма ушла в минус, поэтому сейчас попытаюсь реабилитироваться»
У вас в теме «recovery mode» значок, всем и так всё понятно)

Есть несколько достаточно спорных моментов, например зачем squid? Пожалуйста уберите простыню конфигов под теги. Почему в балансировщиках не используете sticky-address (чем чревато неиспользование рассказать?), например
nat from 10.0.0.0/20 to !<no_nat> -> { ($ext_if1) ($ext_if2) } round-robin sticky-address

из них выкинута. Вместо нее появляются две строки:

pass out route-to ($ext_if $gw1) from $int_if to any
pass out route-to ($ext_if2 $gw2) from $int_if to any

Я бы заменил их на, так оба канала постоянно активны и переключать нужно только GW:
pass out on $ext_if1 route-to ($ext_if2 $ext_gw2) from $ext_if2 to !<no_nat>
pass out on $ext_if2 route-to ($ext_if1 $ext_gw1) from $ext_if1 to !<no_nat>

<no_nat> — адреса, на которые натить не нужно.
Добавим к этому простой скрипт проверки каждого канала и можем оставлять в автоматическом режиме, нам станут не страшны падения одного из линков.
Не совсем понял для чего Вам ALTQ в ядре? Еще могу придраться к выпускающим правилам на интерфейсе. Статья, очень спорная, как туториал для новичков во фре категорически не рекомендую, но за старания плюс.
Не совсем понял для чего Вам ALTQ в ядре?
Изначально комп был старый, очень медленный. И ALTQ в ядро пришлось вставить из-за загрузки ЦП на 7-15%.
За комментарий по поводу правил спасибо, у себя в pf.conf поправил, работает.
Добавим к этому простой скрипт проверки каждого канала и можем оставлять в автоматическом режиме
скрипт в кроне: ping -S gw1/gw2 ip_router1/ip_roter2
И все же зачем squid, тем более на слабой машине — это лишняя прослойка. sticky-address — решит вашу проблему с
#Например, клиент-банки или тендерные площадки чувствительны к смене ip-адреса при балансировке.

Еще пинговать шлюз не показатель, иногда бывает такая неприятность когда шлюз живой а вот у провайдера интернет прилег, как правильный вариант делаем пинг 3х разных точек в мире, если хоть до одной пинг есть, канал считаем живым. Еще в переключалку я бы добавил ситуации:
1) Оба канала активны — балансируем всех, кроме исключений, через round-robin sticky-address
2) лег первый канал — поменяли шлюз, отключили балансировщик, вообще всех пустили через второй канал
3) лег второй канал — всех со второго канала перебросили на первый.
4) легли оба канала — проверяем доступность точек в мире через первый канал, если нет меняем шлюз, проверяем доступность через второй канал, если снова нет ждем (на Ваше усмотрение промежуток) уходим в рекурсию.

Вот набросал для Вас простенький скрипт переключения, может пригодится:
#!/bin/sh
PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin
#Ip адреса на интерфейсах разных каналов.
INT1="192.168.88.99"
INT2="192.168.89.99"
#Какой внешний адрес проверяем для определения жив ли канал.
testaddress="8.8.8.8" #Для 3х адресов, надо чуть поменять
#Шлюзы по умолчанию для каждого из каналов
GW1="192.168.88.1"
GW2="192.168.89.1"
#Куда складывать лог.
logfile=/var/log/canalchange.log

fl=`date "+%H:%M:%S %d-%m-%Y"`

tester=0;
itest1=`/sbin/ping -S $INT1 -c 3 $testaddress  | grep "64 bytes" | wc -l`;
itest2=`/sbin/ping -S $INT2 -c 3 $testaddress  | grep "64 bytes" | wc -l`;

if [ ! -f "/tmp/countGW.tmp" ]
then
echo 3 > /tmp/countGW.tmp
fi

oldtest=`cat /tmp/countGW.tmp`

if (test $itest1 -gt "0")
     then
     let tester=tester+1
     fi

if (test $itest2 -gt "0")
         then
     let tester=tester+2
         fi

#Если последняя проверка такая же как предыдущая, то ничего не делаем
if [ $oldtest = $tester ]; then
exit;
else 
         if  [ $tester = 3 ]; then
         cp /etc/pf.conf3 /etc/pf.conf
         /sbin/route change default $GW1
     echo ${fl}" OK" >> $logfile
     echo 3 > /tmp/countGW.tmp
         fi

         if  [ $tester = 2 ]; then
         cp /etc/pf.conf2 /etc/pf.conf
         /sbin/route change default $GW2
     echo ${fl}" CHANAL 1 DOWN" >> $logfile
         echo 2 > /tmp/countGW.tmp
     fi

         if  [ $tester = 1 ]; then
         cp /etc/pf.conf1 /etc/pf.conf
         /sbin/route change default $GW1
     echo ${fl}" CHANAL 2 DOWN" >> $logfile
         echo 1 > /tmp/countGW.tmp
     fi

         if  [ $tester = 0 ]; then        
     echo ${fl}" CHANAL 1 DOWN and CHANAL 2 DOWN" >> $logfile

# Если лежат оба то при каждом запуске скрипта меняем дефолтный, ведь неизвестно какой подымется первым
         if  [ $(/usr/bin/netstat -rn | awk '/default/ {print $2}') == $GW1 ]; then 
         /sbin/route change default $GW2
         else
         /sbin/route change default $GW1
         fi

         fi

/etc/rc.d/pf restart
     
fi

/etc/pf.conf3 — конфиг для 2х активных каналов
/etc/pf.conf2 — когда только второй канал активен
/etc/pf.conf1 — только первый канал активен.
Почему так, а не только смена гетвея, можно предусмотреть разные параметры шейперов и QoS для разных ситуаций.
Скрипт в крон, раз в минуту, для большинства небольших фирм такой скорости реакции бедет достаточно с головой (лень было придумывать вертушку и демонизацию скрипта).
С Вашего позволения добавлю от себя в скрипт следующее:
конфиги могут лежать заготовленные заранее, где угодно. У меня pf.conf основной, pf.conf.er — канал 2, pf.conf.trans — канал 1.
Скрипт переключения будет работать, но правила файрволла лучше перезагружать через pfcrtl. Например у меня так:
/sbin/pfctl -e -f /etc/pf.conf.er
#у меня почему-то change default не работает.
/sbin/route del default
/sbin/route add default $GW1

SQUID появился позже, на более мощной машинке. Пусть будет, раз собрал.
А в остальном я такой шедевр тестирования канала вряд ли бы родил.
Ну это я так на коленке набросал, само собой где брать конфиги, как перезапускать правила и менять дефолт — ньюансы. Уберите в статье листинг весь под теги, ну пожалуйста, читать вырвиглазно. Кстати, если нужна ассиметричная балансировка как у Вас, 2 разных канала, можно использовать костыль типа
nat from 10.0.0.0/20 to !<no_nat> -> { ($ext_if1) ($ext_if2) ($ext_if1) } round-robin sticky-address

, то-есть чем жирнее канал, тем чаще он выпадает, может это можно и красивее как-то реализовать, но мне сейчас на ум не приходит.
Уберите в статье листинг весь под теги, ну пожалуйста, читать вырвиглазно

тег «code» — ? он там стоит.
«source lang=«bash»»
«/source»
Как вариант, очень тяжело читать сплошняком.
вот если бы то же самое, но посредством ipfw…
А там еще проще. Шаги следующие:
1. NAT-им интерфейсы
natd -p 8668 -a ip1
natd -p 8669 -a ip2

2. Заворачиваем пакеты из локалки в нат
ipfw add divert 8668 ip from any to ip1 recv if1
ipfw add divert 8669 ip from any to ip2 recv if2
3. Round-Robin
ipfw add prob 0.5 divert 8668 ip from 192.168.0.0/16 to any xmit if1 keep-state

ipfw add divert 8669 ip from 192.168.0.0/16 to any xmit if1 keep-state
ipfw add fwd gw1 ip from ip1 to any out xmit if1 (если default на if1)
ipfw add fwd gw2 ip from ip2 to any out xmit if1
Вот и все.

PF явно быстрее и надежнее трудится на благо офиса.
PF быстрее? Используйте ipfw kernel nat и будет Вам мультипроцессорное счастье.
Опыт работы с ipfw у меня закончился на FreeBSD 6.3. Потом переполз на PF, пока не вижу причин возвращаться обратно. Если вот с PF словлю проблемы, которые для меня закончились бы головной болью с бегами к шлюзу и обратно (как было с ipfw), тогда задумаюсь о переходе.
Кстати, зашел в чулан-серверную включить кондиционер и понял, что я даже не помню, где стоит системный блок шлюза.
Это тоже самое что сказать «Опыт с ZFS у меня закончился на FreeBSD 7 и далее я не вижу причин возвращаться обратно»

В самом openbsd pf уже устарел.
Да PF удобен синтаксисом, согласен, но его плюсы не обойдут плюсы ipfw2 в наше время.
Хотя конечно с некоторыми решениями команды ipfw я теперь не согласен (как например отказ делать match string).
А как же классическое: пока работает не трогай?
Честно, меня не тянет что-то обновлять, а то начнется веселье в виде слетевшего подсчета трафика, пробросы для клиент-банков и тендеров по-новой делать и т.п. ерунду. Вот на новом объекте будем экспериментировать, благо в этом году осенью сдача.
Это вариант, если использовать не kernel nat. Также уже есть опция global но корректно настроить с пробросами и шейпером, этот вариант, у меня не получилось.
На PF для моего понимания ALTQ оказались проще. Сейчас канал широкий, даже потребность рубить торренты отпала.
Демократия в офисе обеспечивает печеньки админу.
Приведу старый конфиг-файл для pf с приоритетами трафика. По-моему что-то там было не настроено, нашел в папке «разобрать». По аналогии можно сделать полосы пропускания для чего угодно, назначив портам приоритеты:

cat pf.conf.altq

int_if=«re1»
ext_if=«re0»
int_net=«10.1.1.0/24»
freeBSD=«10.1.1.30»
icmp_types="{ echoreq, unreach}"
http=«80»
https=«443»
ssh=«22»

gw1=«192.168.63.25»

set block-policy drop
set skip on lo
scrub in all

#Канал был 4Мб, полосу сделал 3Мб, а 1Мб оставлял под почту, которая крутилась на шлюзе на exim + fetchmail.
altq on $ext_if cbq bandwidth 3Mb queue { qssh, qhttp, qdns, qack, qftp }
queue qhttp bandwidth 88% priority 6 cbq (default borrow)
queue qssh bandwidth 3% priority 5 cbq (borrow)
queue qdns bandwidth 3% priority 5 cbq (borrow)
queue qack bandwidth 3% priority 6 cbq (borrow)
queue qftp bandwidth 3% priority 2 cbq (red)

nat on $ext_if inet from any to any -> ($ext_if)
pass in on $int_if route-to ($ext_if $gw1) from $int_net to any no state

block all

pass out on $int_if from $int_if to any keep state
pass out on $int_if from $int_net to any keep state

pass out on $ext_if from $ext_if to any keep state

pass out on $int_if from $int_if to any keep state

pass in log on $ext_if proto { tcp, udp } from any to $freeBSD port $http keep state
pass in log on $ext_if proto { tcp, udp } from any to $freeBSD port $https keep state
pass in log on $ext_if proto { tcp, udp } from any to $freeBSD port $ssh keep state

#IN ALTQ
pass in on $ext_if inet proto { tcp,udp } from any to $ext_if port 2222 queue ( qssh, qack )
pass in on $ext_if inet proto { tcp,udp } from any to $ext_if port 80 queue qhttp
pass in on $ext_if inet proto { tcp,udp } from any to $ext_if port 53 queue qdns
pass in on $ext_if inet proto { tcp,udp } from any to $ext_if port { 21 30000:35000 } queue qftp

#OUT ALTQ
pass out on $ext_if inet proto { tcp,udp } from $ext_if to $ext_if port 2222 queue ( qssh, qack )
pass out on $ext_if inet proto { tcp,udp } from $ext_if to $ext_if port 80 queue qhttp
pass out on $ext_if inet proto { tcp,udp } from $ext_if to $ext_if port 53 queue qdns
«Со стороны провайдера были установлены шлюзы, через которые реализую DMZ на «ловушки» для хакеров» — а можно поподробнее про это? Вы что-то ставили на площадке у провайдера?
Провайдером выданы хвосты с pppoe, которые в его же шкафах воткнуты в TP-Link TL-R860.Из него выходит два кабеля — в мой шлюз и в фейковый комп. На тп-линках устанавливаем DMZ на фейковую машину, запрещаем настраивать их с WAN и с LAN, кроме с LAN1 (шлюза).
Ставим тачку с двумя интерфейсами, в один хвост одного провайдера, в другой хвост другого провайдера. Запрещаем все доступы по-максимуму, в том числе ssh. Однако открываем соответствующие порты типа 80, 443, 22 и так далее. В машинку воткнут монитор и клавиатура, на борту freebsd 8.
Все атаки из-вне прилетают на него, так как порты открыты; а результата не будет.
Ну и собственно всегда можно понять, что кто-то чего-то хочет от моей машины по радующему глаз монитору в углу. На реальных серверах я не держу мониторы.
P.S. этой ловушкой трудится как раз первый шлюз, «спасибо, что живой».
Принцип понятен, но не совсем ясно как это физически выглядит, можно небольшую схемку набросать? Например здесь www.draw.io/ Спасибо.
Не силен. Держите, что получилось:
О мисье знает толк в извращениях. Защищать фрю от атак из вне фейковой машиной — это что-то новое. ssh по ключам, file2ban, ацесс листы и прочее и прощай лишний гудящий ящик. Я бы еще и роутер выкинул, то-есть приход сразу на фрю от провайдеров, за шлюзом свич с абонентами. Если фря — только шлюз, то систему на флешку монтировать в ридонли, логи на офисную помойку. Уменьшаем количество точек отказа, упрощаем структуру сети для понимания, снижаем энергопотребление. На логи парсер и алярму в мониторинг при аномалиях, смотреть в реальный монитор для отлова атак — это, простите, охренеть.
Ага, я такой )
В связи с прошлым опытом пришел к такому извращению, в связи с тем, что не силен в защите и мониторинге рабочей машины. А так проблем нет, а на заводе 250 Ватт в пике на 1 комп никто не замечает.
Не силен. Еще раз пробую выложить, что получилось
Если нужно балансировать только HTTP, то всё это можно упростить до вот такого:

1. Ставим SQUID 3.2

2. делаем в конфиге что-то, типа этого:
acl fifth random 1/5
acl quarter random 1/4
acl third random 1/3
acl half random 1/2

tcp_outgoing_address 10.1.1.1 fifth
tcp_outgoing_address 10.1.1.2 quarter
tcp_outgoing_address 10.1.1.3 third
tcp_outgoing_address 10.1.1.4 half
tcp_outgoing_address 10.1.1.5


Получаем равномерную балансировку по пяти каналам.
Для трафика, который заведен в SQUID
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории