Настройка шлюза на FreeBSD 7.3
Дано: Сеть 192.168.0.0/24, кабель провайдера (в моем случае от провайдерского media-конвертера оптики, так что с настройкой соединения париться не придется), старенький комп на супер-пупер проце ЦелерОН 1.7, с раритетным жестким диском на целых 10 Гб и диск с FreeBSD 7.3.Задача: Соединить все это в единое, нерушимое целое, "шоб все вертелось".
Не буду расписывать процесс установки ОС, ман по нему лежит на соседней полке, да и сложного в этом ничего нет. Начну с основного.
Общая настройка системы
Первое что нужно сделать - пересобрать ядро, поскольку многие нужные нам функции по дефолту отключены. Хотя... в принципе можно обойтись и без пересборки, а просто подгрузить нужные модули ядра в файле /boot/loader.conf, но я предпочитаю старый дедовский способ - так, имхо надежней.Идем в /usr/src/sys (сразу оговорюсь, что для этих целей при установке ОС обязательно нужно установить пакет сырцов sys), вспоминаем какая у нас архитектура и идем в соответствующий каталог. У меня х86, так что я иду в каталог i386/conf. Копируем общий конфиг в тот, с которым будем работать и открываем для редактирования:
Код: Выделить всё
# cp GENERIC GATE
#ee GATE
Код: Выделить всё
options IPFIREWALL #Включаем поддержку фаервола непосредственно в ядро
options IPFIREWALL_FORWARD #Разрешаем форвардинг пакетов
options IPFIREWALL_VERBOSE # Включаем логи
options IPFIREWALL_VERBOSE_LIMIT=100 #Ограничиваем повторяющиеся записи в логах
options DUMMYNET #Подключаем шейпер
options IPDIVERT #Разрешаем перенаправлять пакеты
Код: Выделить всё
# cd /usr/src
Код: Выделить всё
# make buildkernel KERNCONF=GATE
Код: Выделить всё
# make installkernel KERNCONF=GATE
Код: Выделить всё
# ee /etc/rc.conf
Код: Выделить всё
ifconfig_re0="inet xxx.xxx.xxx.xx netmask 255.255.255.252" #Внешняя карточка
ifconfig_rl0="inet 192.168.0.10 netmask 255.255.255.0" #Внутренняя карточка
defaultrouter="ххх.ххх.ххх.хх" #Прописываем шлюз (тот что выдал провайдер)
hostname="gate.localdomain" #имя_машины.домен.
gateway_enable="YES" #Включим режим шлюза
sendmail_enable="NONE" #Выключаем сендмыл - нам не нужна большая дырка в системе
firewall_enable="YES" #Включаем IPFW
firewall_script="/etc/ipfw" #Путь к нашему конфигу
firewall_logging="YES" # Вежливо просим его писать логи
natd_enable="YES" #Включаем демон natd (не люблю натить через ведро)
natd_interface="re0" #Вешаем natd на внешний интерфейс
squid_enable="YES" #Включаем Squid
sshd_enable="YES"
...
Так что опционально можно добавить в /etc/sysctl.conf следующие опции для предотвращения вышеописанного:
Черные дыры.
Код: Выделить всё
net.inet.tcp.blackhole=2
net.inet.udp.blackhole=1
Защита очереди сокета от SYN атак.
Основной из самых популярных атак остается SYN флуд, при которой очередь сокета атакуемого хоста переполняется некорректными попытками соединений. Для защиты от таких атак некоторые из UNIX поддерживают отдельные очереди для входящих запросов на соединение. Одна очередь для полуоткрытых сокетов (SYN получен, SYN|ACK послан), другая очередь для полностью открытых сокетов, ждущих вызова accept() от программы. Эти две очереди должны быть увеличены, чтобы атаки малой и средней интенсивности почти не влияли на стабильность и доступность сервера.
Код: Выделить всё
kern.ipc.somaxconn=1024
Атакующий может использовать IP redirect для изменения таблицы марщрутизации на удаленном хосте. В хорошо разработанной сети редиректы на конечные станции не должны требоваться. Оба - отправка и принятие редиректов должны быть отключены.
Код: Выделить всё
net.inet.icmp.drop_redirect=1
net.inet.icmp.log_redirect=1
net.inet.ip.redirect=0
net.inet6.ip6.redirect=0
На размер буфера приема и передачи TCP напрямую влияет параметр размера TCP окна. Увеличенный размер окна позволит более эффективно передавать данные, особенно при интенсивной передаче, такой как FTP и HTTP. Значение по умолчанию не является оптимальным и должно быть увеличено до 32768 байт. Это значение не должно быть более 64Кб.
Код: Выделить всё
sysctl -w net.inet.tcp.sendspace=32768
sysctl -w net.inet.tcp.recvspace=32768
Существует возможность, что атакующий создаст нехватку ресурсов или уменьшение производительности заполнив кэш маршрутизации IP с помощью неправильных записей в ARP таблице. Этот параметр рекомендуется выставить в 20 минут по умолчанию.
Код: Выделить всё
sysctl -w net.link.ether.inet.max_age=1200
С помощью маршрутизации отправителя атакующий может попытаться достигнуть внутренние IP адреса, включая адреса RFC1918. Важно отключить принятие пакетов маршрутизации отправителя для предотвращения незаметных проб вашей внутренней сети.
Код: Выделить всё
sysctl -w net.inet.ip.sourceroute=0
sysctl -w net.inet.ip.accept_sourceroute=0
Эти атаки работают с помощью отправки сообщения ICMP 8 0 (запрос ECHO) на широковещательный адрес с фальшивого адреса. Некоторые стеки IP ответят по умолчанию на такие сообщения. Это должно быть отключено.
Более того, если хост является фаерволом или роутером, то он не должен пропускать проямые широковещательные запрсы.
Код: Выделить всё
sysctl -w net.inet.icmp.bmcastecho=0
Существуют 2 вида проб. Запрос маски адреса может быть использован для определения размера блока сети и установки диапазона для дальнейших проб. Широковещательный запрос временного штампа (timestamp) - еще одно средство выявления хостов и определения их операционных систем (fingerprinting)
Код: Выделить всё
sysctl -w net.inet.icmp.maskrepl=0
Настройка IPFW
Создаем файл конфига /etc/ipfw и записываем в него наши правила:Код: Выделить всё
ee /etc/ipfw
Код: Выделить всё
#!/bin/sh
#Определяем переменные
IPFW="/sbin/ipfw"
EXT="re0" #Внешний интерфейс
INT="rl0" #Внутренний интерфейс
EXT_IP="xxx.xxx.xxx.xx" #Внешний IP
INT_IP="192.168.0.10" #Внутренний IP
LAN="192.168.0.0" #Наша локалка
MSK="24" #Маска нашей локалки
${IPFW} -f flush #Очищаем цепочки с правилами
${IPFW} add check-state #Проверяем динамические правила
#Разрешаем петлю
${IPFW} add allow ip from any to any via lo0
#Но запрещаем ей ломиццо наружу
${IPFW} add deny ip from any to 127.0.0.0/8
${IPFW} add deny ip from 127.0.0.0/8 to any
#Грохаем фрагменты пингов
${IPFW} add deny icmp from any to any frag
#Блокируем попытки доступа в локалку извне
${IPFW} add deny ip from any to ${LAN}/${MSK} in via ${EXT}
#Broadcast на внешнем интерфейсе нам тоже ни к чему
${IPFW} add deny log icmp from any to 255.255.255.255 in via ${EXT}
${IPFW} add deny log icmp from any to 255.255.255.255 out via ${EXT}
#DNS
${IPFW} add allow udp from any 53 to any via ${EXT}
#Разрешаем DNS входящий снаружи (только если на этой машине работает DNS-сервер)
${IPFW} add allow udp from any to any 53 via ${EXT}
#SSH (не думаете же вы, что юзать стандартный 22-й порт - хороший тон)
${IPFW} add allow tcp from any to ${EXT_IP} 7022 via ${EXT}
#Разрешаем пинги
${IPFW} add allow icmp from any to any icmptypes 0,8,11
#Заворачиваем стандартный пользовательский траф на прозрачный squid
${IPFW} add fwd 127.0.0.1:3129 tcp from ${LAN}/${MSK} to any 21,80,443 via ${EXT}
# Врубаем NAT в локалку
${IPFW} add divert natd ip from ${LAN}/${MSK} to any out via ${EXT}
${IPFW} add divert natd ip from any to ${EXT_IP} in via ${EXT}
#Разрешаем уже установленные соединения
${IPFW} add allow tcp from any to any established
# рубим траффик к частным сетям через внешний интерфейс
${IPFW} add deny ip from 10.0.0.0/8 to any out via ${EXT}
${IPFW} add deny ip from 172.16.0.0/12 to any out via ${EXT}
${IPFW} add deny ip from 192.168.0.0/16 to any out via ${EXT}
${IPFW} add deny ip from 0.0.0.0/8 to any out via ${EXT}
# рубим автоконфигуреную частную сеть
${IPFW} add deny ip from 169.254.0.0/16 to any out via ${EXT}
# рубаем мультикастовые рассылки
${IPFW} add deny ip from 224.0.0.0/4 to any out via ${EXT}
# рубаем мультикастовые рассылки
${IPFW} add deny ip from 240.0.0.0/4 to any out via ${EXT}
#Разрешаем выход с сервака
${IPFW} add allow ip from ${EXT_IP} to any out xmit ${EXT} #так как данный конфиг - всего лишь пример, я не буду здесь расписывать кому куда можно и т.д.
#От локалки у меня секретов нет )))
${IPFW} add allow tcp from any to any via ${INT}
${IPFW} add allow udp from any to any via ${INT}
${IPFW} add allow icmp from any to any via ${INT}
#Золотое правило - нах ибо нех!
${IPFW} add deny log all from any to any
Squid
Код: Выделить всё
# cd /usr/ports/www/squid
# make config
Собираем
Код: Выделить всё
# make install clean
Код: Выделить всё
# ee /usr/local/etc/squid/squid.conf
Код: Выделить всё
acl all src all
acl manager proto cache_object
acl localhost src 127.0.0.1/32
acl to_localhost dst 127.0.0.0/8 0.0.0.0/32
acl localnet src 192.168.0.0/24
acl Safe_ports port 80
acl Safe_ports port 21
acl Safe_ports port 443
acl Safe_ports port 1025-65535
acl BANNER url_regex banner reklama linkexch banpics us\.yimg\.com[\./]ad[s]?[\./]
acl CONNECT method CONNECT
http_access allow manager localhost
http_access deny manager
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localnet
http_access allow localhost
http_access deny BANNER
http_access deny all
http_port 3128
http_port 3129 transparent
hierarchy_stoplist cgi-bin ?
cache_dir ufs /usr/local/squid/cache 10 16 256
coredump_dir
cache_mem 10 Mb
ftp_user anonymous
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0
refresh_pattern . 0 20% 4320
logformat combined %>a [%tl] "%rm %ru HTTP/%rv" %Hs %<st "%{Referer}>h" "%{User-Agent}>h" %Ss:%Sh
access_log /usr/local/squid/access.log squid
visible_hostname gate.localdomain
error_directory /usr/local/etc/squid/errors/Russian-1251