====================================================================
Немного теории.
Итак, для обмена пакетами в сети - локальной или глобальной, каждому хосту (компьютеру, принтеру и т.п.) должен быть назначен ip-адрес, который идентифицирует данный хост в сети.
В связи с острой нехваткой IP- адресов, документом RFC1918 для частного использования были выделены определенные области адресного пространства.
Это одна сеть класса А (10.0.0.0 - 10.255.255.255.255), 16 сетей класса В (172.16.0.0 - 172.31.255.255), 256 сетей класса С (192.168.0.0 - 192.168.255.255).
Эти адреса никогда не выделяются глобально и в сети интернет просто игнорируются. Чтобы узлы, использующие частные адреса, могли получать доступ к сети Интернет, на пограничном маршрутизаторе организуется система NAT (Network Address Translation - трансляция сетевых адресов). Эта система перехватывает пакеты от локальных компьютеров и заменяет в них адрес отправителя реальным адресом. Ситема хранит таблицу преобразований между внутренними и внешними адресами, чтобы обратные пакеты могли поступить правильному адресату. Таким образом можно "свернуть" локальную сеть в частными ("серыми") адресами в один реальный IP адрес.
===================================================================
А теперь рассмотрим средства, которые есть в Linux и FreeBSD и методы реализации "сворачивания" частной сети в реальный адрес.
---------------------------
I.Как это сделать в Linux.
У вас есть локальная сеть, единственный выход в интернет (например, dial-up по ppp, хотя это не существенно) и шлюзовой компьютер с реальным выделенным IP-адресом (например, 1.2.3.4). На интерфейсе локальной сети этот компьютер имеет адрес 192.168.1.1. В локальной сети находится компьютер myhost с адресом 192.168.1.100, с которого вы хотите пользоваться интернет-браузером. Как это реализовать?
Вариант 1 (прозрачное проксирование): на компьютере firewall устанавливается proxy-сервер, все пакеты из локальной сети, адресованные на внешние http-серверы заворачиваются в этот proxy-сервер, который посылает запросы вовне со своего реального адреса 1.2.3.4, а полученные ответы пересылает обратно в локальную сеть. При этом браузер на машине myhost конфигурируется как для прямого соединения с интернетом, потому такое проксирование и называется прозрачным. С точки зрения удаленного http-сервера соединение устанавливается с вашего шлюза. С точки зрения браузера соединение устанавливается с удаленным сервером.
Вариант 2 (маскарадинг): у всех пакетов из локальной сети, адресованных вовне, адрес отправителя меняется на 1.2.3.4, а у приходящих в ответ пакетов адрес получателя заменяется на 192.168.1.100 и они пересылаются на машину myhost. С точки зрения удаленного сервера соединение устанавливается с вашим шлюзом. С точки зрения браузера соединение устанавливается с удаленным сервером.
Можно, конечно, поставить прокси-сервер. Но это требует времени и некоторых усилий по настройке самого сервера, и клиентских программ. Вдобавок, он обеспечивает работу только ограниченного набора протоколов. Маскарадинг позволяет избежать этих трудностей.
Первым делом надо включить форвардинг пакетов. При помощи команды cat /proc/sys/net/ipv4/ip_forward проверим, поддерживает ли ваше ядро форвардинг пакетов между интерфесами. Если вы получили "1", то все нормально, если "0", то надо скомандовать echo 1 > /proc/sys/net/ipv4/ip_forward и снова проверить при помощи предыдущей команды. Если все равно получаем "0", то вам нужно пересобрать ядро с поддержкой маршрутизации.
Итак, чтобы форвардинг пакетов начал работать, надо записать '1' в файл /proc/sys/net/ipv4/ip_forward:
echo 1 > /proc/sys/net/ipv4/ip_forward
Соответственно, если туда записать 0, то он работать перестанет. Эту строку рекомендуется вписать в какой-нибудь скрипт, автоматически запускаемый при загрузке системы. В SlackWare, например, достаточно сделать исполняемым файл /etc/rc.d/rc.ip_forward.
Теперь скомандуем, например:
#iptables -L INPUT
Это команда вывода списка правил в заданной цепочке, в данном примере предполагается вывод правил из цепочки INPUT. Если имя цепочки не указывается, то выводится список правил для всех цепочек.
Если в выводе встретится фраза наподобие "Perhabs iptables or your kernel needs to upgraded", это означает, что ваше ядро собрано без поддержки NAT и пакетного фильтра. Вам необходимо пересобрать ядро.
Дальше создаем файл, который будет содержать команды конфигурирования NAT и фильтра. Например, в SlackWare можно создать файл /etc/rc.d/rc.firewall и сделать его исполняемым. Сюда мы будем записывать наши правила для фильтрации пакетов. Подробное описание iptables имеется здесь http://www.opennet.ru/docs/RUS/iptables .
Я коснусь только вопросов трансляции сетевых адресов, которая может осуществляться методами SNAT или MASQUERADE.
SNAT (Source Network Address Translation) используется для изменения исходных адресов пакетов. С помощью этого действия можно скрыть структуру локальной сети, а заодно и разделить единственный внешний IP адрес между компьютерами локальной сети для выхода в Интернет. В этом случае брандмауэр, с помощью SNAT, автоматически производит прямое и обратное преобразование адресов, тем самым давая возможность выполнять подключение к серверам в Интернете с компьютеров в локальной сети.
Пример:
$IPTABLES -t nat -A POSTROUTING -o $INET_IFACE -j SNAT --to-source $INET_IP
Ключ --to-source используется для указания адреса, присваемового пакету. Все просто, вы указываете IP адрес, который будет подставлен в заголовок пакета в качестве исходящего. $INET_IFACE - ваш интерфейс, подключенный к провайдеру, INET_IP - адрес, выданный провайдером.
Маскировка (MASQUERADE) применяется в тех же целях, что и SNAT, но в отличие от последней, MASQUERADE дает более сильную нагрузку на систему. Происходит это потому, что каждый раз, когда требуется выполнение этого действия - производится запрос IP адреса для указанного в действии сетевого интерфейса, в то время как для SNAT IP адрес указывается непосредственно. Однако, благодаря такому отличию, MASQUERADE может работать в случаях с динамическим IP адресом, т.е. когда вы подключаетесь к Интернет, скажем через PPP, SLIP или DHCP.
Пример:
$IPTABLES -t nat -A POSTROUTING -o $INET_IFACE -j MASQUERADE
где $INET_IFACE - ваш интерфейс, подключенный к провайдеру.
Ссылки http://www.opennet.ru/base/net/iptables_howto.txt.html
http://www.opennet.ru/docs/RUS/iptables/index.html
=========================================================================
II.Как это сделать в FreeBSD.
В FreeBSD встроено три программных межсетевых экрана. Это IPFILTER (известный также как IPF), IPFIREWALL (известный также как IPFW) и PF (OpenBSD PacketFilter). В IPFIREWALL встроена поддержка ограничителя трафика DUMMYNET для контроля использования пропускной способности. В IPFILTER поддержка ограничителя трафика не встроена, но в тех же целях может использоваться ALTQ. IPF, IPFW и PF для контроля исходящих и входящих пакетов используют наборы правил, хотя и разными способами с разным синтаксисом правил.
> Q.: Что лучше использовать, natd или ipnat ?
A.: Политика трансляции для natd задается в IPFW, что дает большую гибкость в настройках и позволяет, например, выполнять несимметричную фильтрацию,
когда исходящие пакеты уходят через один интерфейс, а входящие приходят через другой.
Кроме того, natd поддерживает transparent proxy для протоколов FTP, IRC,ICMP, PPTP, RTSP, PNA, NetBios over TCP/IP и Cisco Skinny Station protocol,
а ipnat - только FTP, H.323, ipsec, NetBios over TCP/IP, raudio и rcmd.
Однако natd работает в userland и на каждый пакет выполняется 2 переключения контекста, что дает overhead, заметный на слабом железе (i486, i586).
В отличие от natd, ipnat потребляет значительно меньше процессорных ресурсов, ipnat можно настроить на GENERIC-ядре, подгрузив модуль ipl, а для
natd придется перекомпилировать ядро с опцией IPDIVERT и ipnat работает с любым пакетным фильтром, а для natd обязательно нужен ipfw.
Так что если у Вас слабое железо, Вы не хотите перекомпилировать ядро или не хотите использовать ipfw и функциональность ipnat Вас устраивает -
используйте ipnat.
> Q.: Что лучше использовать, IPFW, IPFilter или PF?
А.: Hеобходимо использовать IPFW если:
- нужно разделять или ограничивать полосу пропускания;
- нужно использовать divert-сокеты (для natd или tcpmssd)
- нужны правила с указанием uid/gid пакетов.
- нужна оптимизация сложного дерева правил (сложнее, чем head/group в ipf).
В противном случае - на Ваш выбор.
Пакетные фильтры можно использовать совместно в разных комбинациях. Hапример, можно использовать для фильтрации пакетов IPFilter, а для
управления полосой пропускания - DUMMYNET из IPFW.
--------------------------------------------------------
а)ipnat+ipf
1.Включение IPF
IPF включен в базовую систему FreeBSD в качестве отдельного загружаемого модуля. Система динамически загрузит модуль IPF, если в rc.conf указана переменная
Код: Выделить всё
ipfilter_enable="YES"
Модуль создается с включенным протоколированием и правилом по умолчанию block all (пропускать все). Для изменения правила по умолчанию не обязательно собирать ядро с новыми параметрами. Просто добавьте в конец набора правило, блокирующее все пакеты.
Сборка ядра с FreeBSD включением IPF не обязательна. Эта процедура представлена здесь в качестве дополнительной информации. При включении IPF в ядро загружаемый модуль не используется. http://www.freebsd.org/doc/ru_RU.KOI8-R/bo...PF-RULES-SCRIPT
Пример параметров настройки ядра для IPF находится в /usr/src/sys/conf/NOTES (/usr/src/sys/arch/conf/LINT для FreeBSD 4.X) и воспроизведен здесь:
Код: Выделить всё
options IPFILTER
options IPFILTER_LOG
options IPFILTER_DEFAULT_BLOCK
options IPFILTER включает поддержку межсетевого экрана ''IPFILTER''.
options IPFILTER_LOG включает протоколирование трафика через IPF путем записи его в псевдо-устройство протоколирования пакетов ipl для каждого правила, содержащего ключевое слово log.
options IPFILTER_DEFAULT_BLOCK изменяет поведение по умолчанию так, что блокируется каждый пакет, не соответствующий правилу pass.
Эти настройки будут работать только после сборки и установки нового ядра.
2.Итак, для активации IPF во время загрузки в /etc/rc.conf потребуется добавить следующие переменные:
Код: Выделить всё
ipfilter_enable="YES" # Запуск межсетевого экрана ipf
ipfilter_rules="/etc/ipf.rules" # Загрузка файла с правилами
ipmon_enable="YES" # Включение протоколирования IP monitor
ipmon_flags="-Ds" # D = запуск в виде даемона
# s = протоколирование в syslog
# v = протоколирование tcp window, ack, seq
# n = отображение имен IP и портов
Если за межсетевым экраном находится локальная сеть, использующая приватные IP адреса, для включения NAT потребуется добавить следующие переменные:
Код: Выделить всё
gateway_enable="YES" # Включение шлюза для локальной сети
ipnat_enable="YES" # Запуск функции ipnat
ipnat_rules="/etc/ipnat.rules" # Определение файла правил для ipnat
3. Создайте файл /etc/ipnat.rules и поместите в него строку:
Код: Выделить всё
map rl0 192.168.0.0/24 -> 123.123.123.123/32
rl0 - интерфейс с реальным IP (на котором будет производится трансляция),
123.123.123.123 - реальный IP выданный провайдером,
192.168.0.0/24 - блок адресов локальной сети.
У только что написанного нами правила есть один недостаток. В достаточно большом количестве случаев мы можем не знать IP адрес, назначенный нам провайдером (особенно при использовании интерфейсов tun0 или ppp0). К счастью, NAT способен понимать адрес 0/32, которым мы заменяем неизвестный нам IP адрес интерфейса:
Код: Выделить всё
map rl0 192.168.0.0/24 -> 0/32
Пример ipnat.rules:
Код:
#
# Interface:
# ep1 - external to cable modem
#
# NAT policy:
# + Use IP Filter FTP proxy
# + Use IP Filter IKE proxy
# + Use IP Filter RealAudio proxy
# + NAT UDP and TCP packets from internal hosts to external IP
# + NAT ICMP packets from internal hosts to external IP
#
# share and enjoy,
# hoang@muine.org
# Oct 25, 2001
#
# ------------------------------------------------------------
# Use ipfilter FTP proxy for the firewall doing transfer mode
# active.
# ------------------------------------------------------------
map ep1 0.0.0.0/0 -> 0.0.0.0/32 proxy port ftp ftp/tcp
# ------------------------------------------------------------
# Use ipfilter FTP proxy for hosts behind NAT doing transfer
# mode active.
# ------------------------------------------------------------
map ep1 192.168.1.0/24 -> 0.0.0.0/32 proxy port ftp ftp/tcp
# -----------------------------------------------------------
# Use ipfilter IKE proxy for ESP packets for hosts behind NAT
# IP Filter 3.4.21 and beyond only.
# -----------------------------------------------------------
map ep1 192.168.1.0/24 -> 0.0.0.0/32 proxy port 500 ipsec/udp
# -----------------------------------------------------------
# Use ipfilter RealAudio proxy for hosts behind NAT
# -----------------------------------------------------------
map ep1 192.168.1.0/24 -> 0.0.0.0/32 proxy port 7070 raudio/tcp
# -----------------------------------------------------------
# Map all internal UDP and TCP traffic to the external IP address
# -----------------------------------------------------------
map ep1 192.168.1.0/24 -> 0.0.0.0/32 portmap tcp/udp 40000:60000
# -----------------------------------------------------------
# Map all other traffic e.g. ICMP to the external IP address
# -----------------------------------------------------------
map ep1 192.168.1.0/24 -> 0.0.0.0/32
http://www.opennet.ru/base/net/ipnat_freebsd.txt.html
http://www.freebsd.org/cgi/man.cgi?query=i...LEASE+and+Ports
4.Создать правила для файрвола в /etc/ipf.rules
Пример ipf.rules:
Код:
#
# Interface:
# lo0 - loopback
# ep0 - internal to private network
# ep1 - external to cable modem
#
# Filtering policy ordering:
# + Block everything unless there are permit (pass) rules
# - Permit all loopback packets to flow freely
# - Permit all internal network packets to flow freely
# - Permit individual type of service to flow freely to outside world:
# ftp
# smtp
# whois
# dns
# http/https
# pop3
# traceroute
# ping
# dhclient
# + Since there are no permit(pass) rules at this stage, everything
# else is blocked!
#
# share and enjoy,
# hoang@muine.org
# Nov 26, 2001
#
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Interface: all
# Block all incoming and outgoing packets unless they're allowed later.
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
block in log all
block out log all
# -------------------------------------------------------------------------
# Interface: lo0
# Allow loopback to flow freely.
# -------------------------------------------------------------------------
pass in quick on lo0 all
pass out quick on lo0 all
# -------------------------------------------------------------------------
# -------------------------------------------------------------------------
# Interface: ep0
# Allow internal traffic to flow freely.
# -------------------------------------------------------------------------
pass in quick on ep0 all
pass out quick on ep0 all
# -------------------------------------------------------------------------
# -------------------------------------------------------------------------
# Interface: ep1
# Allow _internal_ and fw initiated connections from hosts behind NAT to
# outside world. Additional permit individual type of service to flow freely
# to outside world should be added in this section.
# -------------------------------------------------------------------------
# [passive ftp client to outside world step 1]
pass out quick on ep1 proto tcp from any to any port = 21 flags S keep state keep frags
# [smtp to outside world]
pass out quick on ep1 proto tcp from any to any port = 25 flags S keep state keep frags
# [whois to outside world]
pass out quick on ep1 proto tcp from any to any port = 43 flags S keep state keep frags
# [domain to outside world]
pass out quick on ep1 proto tcp from any to any port = 53 flags S keep state keep frags
pass out quick on ep1 proto udp from any to any port = 53 keep state keep frags
# [http to outside world]
pass out quick on ep1 proto tcp from any to any port = 80 flags S keep state keep frags
# [pop3 to outside world]
pass out quick on ep1 proto tcp from any to any port = 110 flags S keep state keep frags
# [https to outside world]
pass out quick on ep1 proto tcp from any to any port = 443 flags S keep state keep frags
# [passive ftp to outside world step 2 where the FTP server decides which port
# for ftp data back]
pass out quick on ep1 proto tcp from any to any port > 1023 flags S keep state keep frags
# [traceroute to outside world 1st stage: probing...man traceroute(8)]
pass out quick on ep1 proto udp from any to any port 33434 >< 33525 keep state keep frags
# [ping to outside world]
pass out quick on ep1 proto icmp from any to any keep state keep frags
# -------------------------------------------------------------------------
# Allow _external_ initiated connections from outside world to hosts behind
# NAT and the firewall.
# -------------------------------------------------------------------------
# [dhclient]
pass in quick on ep1 proto udp from any to any port = 68 keep state keep frags
# [traceroute to internal host 2nd stage: receiving error code of icmp-type 3
# (destination unreachable) and icmp-type 11 (time exceeded)]
pass in quick on ep1 proto icmp from any to any icmp-type 3 keep state keep frags
pass in quick on ep1 proto icmp from any to any icmp-type 11 keep state keep frags
# -------------------------------------------------------------------------
# Interface: ep1
# Since there are no permit(pass) rules at this stage, everything else is
# blocked!
# -------------------------------------------------------------------------
http://www.dreamcatcher.ru/docs/ipf_howto_rus.html
http://www.freebsd.org/cgi/man.cgi?query=i...LEASE+and+Ports
Ссылки:
http://www.opennet.ru/base/net/ipnat_freebsd.txt.html
http://www.opennet.ru/base/net/ipfilter_rus.txt.html
http://www.opennet.ru/base/net/ipf_conf.txt.html
или совсем просто http://www.opennet.ru/base/net/ipfilter_guide.txt.html
-----------------------------------------------------------------------------------------------
b)natd+ipfw
1.Внесение изменений в ядро.
В файле конфигурации ядра должны присутствовать следующие параметры:
Код: Выделить всё
#firewall
options IPFIREWALL
options IPFIREWALL_VERBOSE
options IPFIREWALL_VERBOSE_LIMIT=10
options IPDIVERT
options IPFIREWALL_DEFAULT_TO_ACCEPT
options DUMMYNET
Перекомпиляция ядра FreeBSD - простейшая задача (в отличии от ядра Линукс ), подробно описано в хэндбуке и на просторах интернета, останавливаться на этом не буду.
Если Вы в конфигурации ядра явно не указали
options IPFIREWALL_DEFAULT_TO_ACCEPT
в итоге при перезагрузке системы получите firewall который по умолчанию закрывает прохождение любого IP трафика по всем интерфейсам (т.е. не будет даже ping 127.0.0.1).
Вам необходимо в /etc/rc.conf указать, например
#(включаем использование firewall)
firewall_enable="YES"
#указываем что наши настройки firewalla находятся в rc.firewall в разделе #"OPEN")
firewall_type="OPEN"
# (шлюз до нашего ISP)
defaultrouter="10.1.1.1"
2.Внесение изменений в /etc/rc/conf
Код: Выделить всё
gateway_enable="YES"
firewall_enable="YES"
firewall_type="OPEN"
natd_enable="YES"
natd_interface="rl0"
natd_flags=""
При использовании вышеуказанных параметров в файле /etc/rc.conf при загрузке будет запущена команда natd -interface rl0. Эту команду можно запустить и вручную.
Замечание: Если для передачи natd набирается слишком много параметров, возможно также использовать конфигурационный файл. В этом случае имя настроечного файла должно быть задано добавлением следующей строки в /etc/rc.conf:
natd_flags="-f /etc/natd.conf"
По умолчанию используются правила из файла /etc/rc.firewall. Там уже имеются несколько заготовок Open,Client,Simple,Closed,Unknown. Можете использовать подходящие правила, дополнить их, написать свой набор правил, например, Company.
Можно вообще использовать другой файл, указав его в /etc/rc.conf
firewall_script="/etc/ipfw.rules"
в котором написать свой набор правил фильтрации пакетов.
Подробнее почитайте http://www.freebsd.org/doc/ru_RU.KOI8-R/bo.../firewalls.html
http://www.freebsd.org/doc/en/books/handbo...walls-ipfw.html
Пример:
-----------------------------------------------------
Код: Выделить всё
cat /etc/rc.conf
# -- sysinstall generated deltas -- # Tue Jul 5 20:04:46 2005
# Created: Tue Jul 5 20:04:46 2005
# Enable network daemons for user convenience.
# Please make all changes to this file, not to /etc/defaults/rc.conf.
# This file now contains just the overrides from /etc/defaults/rc.conf.
#forwarding
gateway_enable="YES"
#firewall
firewall_enable="YES"
firewall_quiet="YES"
firewall_type="OPEN"
#nat
natd_enable="YES"
natd_interface="rl0"
#
hostname="freebsd.workgroup"
ifconfig_rl0="DHCP"
ifconfig_rl1="inet 192.168.0.1 netmask 255.255.255.0"
inetd_enable="YES"
linux_enable="YES"
moused_enable="YES"
sshd_enable="YES"
usbd_enable="YES"
defaultrouter="10.1.1.1"
#dhcp-server (мой шлюз раздает клиентам в сети адреса ip)
dhcpd_enable="YES" # dhcpd enabled?
dhcpd_flags="-q" # command option(s)
dhcpd_conf="/usr/local/etc/dhcpd.conf" # configuration file
dhcpd_ifaces="" # ethernet interface(s)
dhcpd_withumask="022" # file creation mask
-----------------------------------------------------
Проверка правил для OPEN (мы его выбрали в rc.conf)
Код: Выделить всё
$ ipfw list
00050 divert 8668 ip from any to any via rl0
00100 allow ip from any to any via lo0
00200 deny ip from any to 127.0.0.0/8
00300 deny ip from 127.0.0.0/8 to any
65000 allow ip from any to any
65535 allow ip from any to any
http://www.hub.ru/modules.php?name=Pages&...page&pid=35
не забудем о безопасности - настроим файрволл
http://www.hub.ru/modules.php?name=Pages&...page&pid=37
пример сворачивания 2 сетей в 1 IP-адрес
http://www.hub.ru/modules.php?name=Pages&...page&pid=40