Transparent Squid + ipnat

Задача состоит в использовании прозрачного прокси-сервера в локальной сети. Операционная система – FreeBSD 6.3. Локальная сеть будет иметь доступ Интернет через Nat. Можно использовать ipnat и natd. Рассмотрим обе реализации. Собираем ядро с такими опциями:

options IPFIREWALL
options IPFIREWALL_VERBOSE
options IPFIREWALL_VERBOSE_LIMIT=100
options IPFIREWALL_DEFAULT_TO_ACCEPT
options IPFIREWALL_FORWARD
options IPDIVERT
options DUMMYNET
options TCP_DROP_SYNFIN
options IPFILTER
options IPFILTER_LOG

IPFIREWALL – включение в ядро ipfw;
IPFIREWALL_VERBOSE – ведение логов ipfw;
IPFIREWALL_VERBOSE_LIMIT=100 – максимальное количество записей в секунду в логах;
IPFIREWALL_DEFAULT_TO_ACCEPT – если нет правил – пакеты все проходят;
IPFIREWALL_FORWARD – для настройки форварда пакетов (необходим для transparent squid);
IPFIREWALL_FORWARD_EXTENDED – опция убрана в 6.2, если версия ниже – рекомендутся включить;
IPDIVERT – включение natd;
DUMMYNET – системное средство применяется для регулирования трафика, шейпера;
TCP_DROP_SYNFIN – отбрасывает пакеты SYN и FIN;
IPFILTER – включение в ядро ipfilter;
options IPFILTER_LOG – включение записи логов.

Что касается IPFILTER, то его можно загрузить как модуль, а не добавлять в ядро, но я добавляю, т.к. ipnat использую в качестве трансляции адресов. Если использовать одновременно файерволы ipfilter, pf и ipfw, то в такой последовательности они и будут обрабатывать правила, если они включены в ядро. Если они работают как модули, то порядок обработки будет таким в какой последовательности грузятся модули.

Итак, записываем в /etc/rc.conf поддержку ipnat, ipfilter и ipfw:

gateway_enable=”YES”
ipfilter_enable=”YES”
ipfilter_rules=”/etc/ipf.rules”
ipnat_enable=”YES”
ipnat_rules=”/etc/ipnat.rules”
ipmon_enable=”YES”
ipmon_flags=”-Dva /var/log/ipmon.log”
ipfs_enable=”YES”
firewall_enable=”YES”
firewall_quiet=”NO”
firewall_script=”/etc/rc.firewall.rules”
firewall_logging=”YES”
#natd_enable=”YES”
#natd_interface=”ed0″
#natd_flags=””

Тут сервер становится шлюзом (gateway_enable=”YES”),в качестве Nat используется ipnat, если кому ipnat не нравится, можно его закоментировать и раскомментироваться natd. ipmon – демон, который пишет логи работы ipnat. Правила ipfilter пишутся в /etc/ipf.rules, правила ipfw – /etc/rc.firewall.ruless. Смотрим /etc/ipnat.rules:

map ed0 192.168.210.0/24 -> 1.1.1.1/32 portmap tcp/udp 40000:60000
rdr fxp0 0/0 port 80 -> 192.168.210.1 port 8080 tcp
rdr ed0 from 195.64.224.0/19 to 1.1.1.1/32 port=5000 -> 192.168.210.8 port 7000 tcp

Тут ed0 – внешний интерфейс, 1.1.1.1 – его IP. Все запросы из сети 192.168.210.0/24 будут перенаправляться на 1.1.1.1 и при этом ipnat будет менять порты исходящие и подставлять из диапазона 40000-60000. Вторая строка обеспечивает редирект всех запросов на 80 порт на 192.168.210.1 порт 8080, на котром будет работать наш прозрачный squid. Третья строка делает проброс портов – пакеты, идущие на ed0 из сети 195.64.224.0/19 порт 5000 IP 1.1.1.1 перенаправляются на порт 7000 IP 192.168.210.8. После редактирования правил нужно рестартовать ipnat – /etc/rc.d/ipnata restart.

В случае использования natd и ipfw в /etc/rc.conf раскомментируем строки с natd и комментируем ipnat. В /etc/rc.firewall.rules добавляем:

#!/bin/sh
echo -n “Starting myfirewall…”
ipfw=”/sbin/ipfw”
${ipfw} add 100 fwd 192.168.210.1,8080 tcp from 192.168.210.0/24 to any 80
${ipfw} add 101 allow tcp from any 80 to $1.1.1.1 $1025-65535 in recv ed0 established
${ipfw} add 102 divert natd all from 192.168.210.0/24 to not 192.168.210.0/24 out xmit ed0
${ipfw} add 103 divert natd all from any to 1.1.1.1 in recv ed0

Первые 2 строчки обеспечивают работу прозрачного прокси, остальные две – натят все пакеты, идущие через ed0. После добавления правил необходимо рестартовать ipfw – /etc/rc.d/ipfw restart. Также нужно настроить правила фаервола, но об этом в другой статье. Теперь установим squid, текущая версия 2.6.18. Если планируется использовать squid как прозрачный, тоего нужно собрать с соответсвующей опцией SQUID_IPFILTER для ipfilter, для ipfw не нужно такой поддержки. Я собирал с такими опциями:

# cd /usr/ports/www/squid
# make install clean

WITHOUT_SQUID_LDAP_AUTH=true
WITH_SQUID_SASL_AUTH=true
WITH_SQUID_DELAY_POOLS=true
WITHOUT_SQUID_SNMP=true
WITH_SQUID_CARP=true
WITHOUT_SQUID_SSL=true
WITH_SQUID_PINGER=true
WITHOUT_SQUID_DNS_HELPER=true
WITH_SQUID_HTCP=true
WITHOUT_SQUID_VIA_DB=true
WITHOUT_SQUID_CACHE_DIGESTS=true
WITH_SQUID_WCCP=true
WITHOUT_SQUID_WCCPV2=true
WITHOUT_SQUID_STRICT_HTTP=true
WITH_SQUID_IDENT=true
WITHOUT_SQUID_REFERER_LOG=true
WITHOUT_SQUID_USERAGENT_LOG=true
WITHOUT_SQUID_ARP_ACL=true
WITHOUT_SQUID_PF=true
WITH_SQUID_IPFILTER=true
WITHOUT_SQUID_FOLLOW_XFF=true
WITH_SQUID_ICAP=true
WITHOUT_SQUID_AUFS=true
WITHOUT_SQUID_COSS=true
WITH_SQUID_KQUEUE=true
WITHOUT_SQUID_LARGEFILE=true
WITHOUT_SQUID_STACKTRACES=true

Добавляем в /etc/rc.conf squid_enable=”YES”, сам конфиг лежит /usr/local/etc/squid/squid.conf. Для поддержки прозрачного проксирования, начиная с версии 2.6 применяется строчка :http_port 192.168.0.1:8080 transparent. Для более древних версий:

httpd_accel_host virtual
httpd_accel_port 80 443
httpd_accel_with_proxy on
httpd_accel_uses_host_header on

Вот мой конфиг:

http_port 192.168.210.1:8080 transparent
error_directory /usr/local/etc/squid/errors/Russian-1251
#
#logs
#
cache_mem 32 MB
cache_dir ufs /usr/local/squid/cache 1000 16 256
cache_access_log /usr/local/squid/logs/access.log
cache_log /usr/local/squid/logs/cache.log
pinger_program /usr/local/libexec/squid/pinger
cache_store_log none
#
#ftp_passive on
icp_port 0
htcp_port 0
cache_swap_high 95
cache_swap_low 90
maximum_object_size 4096 KB
minimum_object_size 0 KB
cache_mgr admin@icc-ukraine.com.ua
visible_hostname ICC-Server.icc-ukraime.com.ua
logfile_rotate 5
append_domain .icc-ukraime.com.ua
tcp_outgoing_address 62.244.4.14
udp_outgoing_address 62.244.4.14
#
#ACL
#
#edit 11.02.08
hierarchy_stoplist cgi-bin ?
acl QUERY urlpath_regex cgi-bin \?
cache deny QUERY
#
acl all src 0.0.0.0/0.0.0.0
acl shaper src 192.168.210.36
acl manager proto cache_object
acl office src 192.168.210.0/24
acl admins src 192.168.210.2-192.168.210.9
acl net src 192.168.210.10-192.168.210.254
acl localhost src 127.0.0.1/255.255.255.255
acl to_localhost dst 127.0.0.0/8
acl SSL_ports port 443 563 5190
acl Safe_ports port 80 # http
acl Safe_ports port 21 # ftp
acl Safe_ports port 443 563 # https, snews
acl Safe_ports port 70 # gopher
acl Safe_ports port 210 # wais
acl Safe_ports port 1025-65535 # unregistered ports
acl Safe_ports port 280 # http-mgmt
acl Safe_ports port 488 # gss-http
acl Safe_ports port 591 # filemaker
acl Safe_ports port 777 # multiling http
acl CONNECT method CONNECT
acl access_denied dstdomain “/usr/local/etc/squid/access_denied”
http_access deny access_denied all
http_access allow manager localhost
http_access deny manager
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow admins all
http_access allow office all
http_access deny all
#
#Delay Pool
#
delay_pools 2
#
delay_class 1 1
delay_parameters 1 1000/1000
delay_access 1 allow shaper
delay_access 1 deny all
#
delay_class 2 1
delay_parameters 2 20000/20000
delay_access 2 allow net
delay_access 2 deny all

Есть пример конфига sample, там много интересных опций. Перед первым запуском надо создать кэш – в консоли squid -z. После этого перезагружаем сервер или стартуем сквид из /usr/local/etc/rc.d и наблюдаем за работой.

 Источник информации:
1. http://na.net.ua/forumna/index.php?s=2a753a1ed6e8f1acb87aee4ea2132abf&showtopic=2814&st=0
2. http://www.opennet.ru/base/sec/ipf_howto.txt.html
3. http://redacid.org.ua/ftp/media1/all_docs/new/services/opennet.rudocsrusipfw_pf_ipfilter.htm
4. http://ipfw.ism.kiev.ua/dummynet.html

© mick, 2008.