Настройка firewall nat freebsd
FreeBSD provides a sample ruleset in /etc/rc.firewall which defines several firewall types for common scenarios to assist novice users in generating an appropriate ruleset. IPFW provides a powerful syntax which advanced users can use to craft customized rulesets that meet the security requirements of a given environment.
This section describes how to enable IPFW , provides an overview of its rule syntax, and demonstrates several rulesets for common configuration scenarios.
29.4.1.�Enabling IPFW
IPFW is included in the basic FreeBSD install as a kernel loadable module, meaning that a custom kernel is not needed in order to enable IPFW .
For those users who wish to statically compile IPFW support into a custom kernel, refer to the instructions in Chapter�8, Configuring the FreeBSD Kernel. The following options are available for the custom kernel configuration file:
To configure the system to enable IPFW at boot time, add the following entry to /etc/rc.conf :
To use one of the default firewall types provided by FreeBSD, add another line which specifies the type:
open : passes all traffic.
client : protects only this machine.
simple : protects the whole network.
closed : entirely disables IP traffic except for the loopback interface.
workstation : protects only this machine using stateful rules.
UNKNOWN : disables the loading of firewall rules.
filename : full path of the file containing the firewall ruleset.
If firewall_type is set to either client or simple , modify the default rules found in /etc/rc.firewall to fit the configuration of the system.
Note that the filename type is used to load a custom ruleset.
To enable logging, include this line:
There is no /etc/rc.conf variable to set logging limits. To limit the number of times a rule is logged per connection attempt, specify the number using this line in /etc/sysctl.conf :
After saving the needed edits, start the firewall. To enable logging limits now, also set the sysctl value specified above:
29.4.2.� IPFW Rule Syntax
When a packet enters the IPFW firewall, it is compared against the first rule in the ruleset and progresses one rule at a time, moving from top to bottom in sequence. When the packet matches the selection parameters of a rule, the rule's action is executed and the search of the ruleset terminates for that packet. This is referred to as “ first match wins ” . If the packet does not match any of the rules, it gets caught by the mandatory IPFW default rule number 65535, which denies all packets and silently discards them. However, if the packet matches a rule that contains the count , skipto , or tee keywords, the search continues. Refer to ipfw (8) for details on how these keywords affect rule processing.
CMD RULE_NUMBER set SET_NUMBER ACTION log LOG_AMOUNT PROTO from SRC SRC_PORT to DST DST_PORT OPTIONS
This section provides an overview of these keywords and their options. It is not an exhaustive list of every possible option. Refer to ipfw (8) for a complete description of the rule syntax that can be used when creating IPFW rules.
Every rule must start with ipfw add .
Each rule is associated with a number from 1 to 65534 . The number is used to indicate the order of rule processing. Multiple rules can have the same number, in which case they are applied according to the order in which they have been added.
Each rule is associated with a set number from 0 to 31 . Sets can be individually disabled or enabled, making it possible to quickly add or delete a set of rules. If a SET_NUMBER is not specified, the rule will be added to set 0 .
A rule can be associated with one of the following actions. The specified action will be executed when the packet matches the selection criterion of the rule.
allow | accept | pass | permit : these keywords are equivalent and allow packets that match the rule.
check-state : checks the packet against the dynamic state table. If a match is found, execute the action associated with the rule which generated this dynamic rule, otherwise move to the next rule. A check-state rule does not have selection criterion. If no check-state rule is present in the ruleset, the dynamic rules table is checked at the first keep-state or limit rule.
count : updates counters for all packets that match the rule. The search continues with the next rule.
deny | drop : either word silently discards packets that match this rule.
Additional actions are available. Refer to ipfw (8) for details.
When a packet matches a rule with the log keyword, a message will be logged to syslogd (8) with a facility name of SECURITY . Logging only occurs if the number of packets logged for that particular rule does not exceed a specified LOG_AMOUNT. If no LOG_AMOUNT is specified, the limit is taken from the value of net.inet.ip.fw.verbose_limit . A value of zero removes the logging limit. Once the limit is reached, logging can be re-enabled by clearing the logging counter or the packet counter for that rule, using ipfw reset log .
Logging is done after all other packet matching conditions have been met, and before performing the final action on the packet. The administrator decides which rules to enable logging on.
This optional value can be used to specify any protocol name or number found in /etc/protocols .
An optional source port can be specified using the port number or name from /etc/services .
The to keyword must be followed by the destination address or a keyword that represents the destination address. The same keywords and addresses described in the SRC section can be used to describe the destination.
An optional destination port can be specified using the port number or name from /etc/services .
Several keywords can follow the source and destination. As the name suggests, OPTIONS are optional. Commonly used options include in or out , which specify the direction of packet flow, icmptypes followed by the type of ICMP message, and keep-state .
When a keep-state rule is matched, the firewall will create a dynamic rule which matches bidirectional traffic between the source and destination addresses and ports using the same protocol.
The dynamic rules facility is vulnerable to resource depletion from a SYN-flood attack which would open a huge number of dynamic rules. To counter this type of attack with IPFW , use limit . This option limits the number of simultaneous sessions by checking the open dynamic rules, counting the number of times this rule and IP address combination occurred. If this count is greater than the value specified by limit , the packet is discarded.
Dozens of OPTIONS are available. Refer to ipfw (8) for a description of each available option.
29.4.3.�Example Ruleset
When first creating or testing a firewall ruleset, consider temporarily setting this tunable:
This sets the default policy of ipfw (8) to be more permissive than the default deny ip from any to any , making it slightly more difficult to get locked out of the system right after a reboot.
The firewall script begins by indicating that it is a Bourne shell script and flushes any existing rules. It then creates the cmd variable so that ipfw add does not have to be typed at the beginning of every rule. It also defines the pif variable which represents the name of the interface that is attached to the Internet.
The first two rules allow all traffic on the trusted internal interface and on the loopback interface:
The next rule allows the packet through if it matches an existing entry in the dynamic rules table:
The next set of rules defines which stateful connections internal systems can create to hosts on the Internet:
The next set of rules controls connections from Internet hosts to the internal network. It starts by denying packets typically associated with attacks and then explicitly allows specific types of connections. All the authorized services that originate from the Internet use limit to prevent flooding.
The last rule logs all packets that do not match any of the rules in the ruleset:
29.4.4.�Configuring NAT
FreeBSD's built-in NAT daemon, natd (8) , works in conjunction with IPFW to provide network address translation. This can be used to provide an Internet Connection Sharing solution so that several internal computers can connect to the Internet using a single IP address.
It is also possible to specify a configuration file which contains the options to pass to natd (8) :
The specified file must contain a list of configuration options, one per line. For example:
For more information about this configuration file, consult natd (8) .
The following example builds upon the firewall ruleset shown in the previous section. It adds some additional entries and modifies some existing rules in order to configure the firewall for NAT . It starts by adding some additional variables which represent the rule number to skip to, the keep-state option, and a list of TCP ports which will be used to reduce the number of rules:
The outbound rules are modified to replace the allow action with the $skip variable, indicating that rule processing will continue at rule 500 . The seven tcp rules have been replaced by rule 125 as the $good_tcpo variable contains the seven allowed outbound ports.
In this example, rules 100 , 101 , 125 , 500 , and 510 control the address translation of the outbound and inbound packets so that the entries in the dynamic state table always register the private LAN IP address.
On the inbound side, the ruleset has to deny bad packets and allow only authorized services. A packet which matches an inbound rule is posted to the dynamic state table and the packet is released to the LAN . The packet generated as a response is recognized by the check-state rule as belonging to an existing session. It is then sent to rule 500 to undergo NAT before being released to the outbound interface.
29.4.4.1.�Port Redirection
The syntax for -redirect_port is as follows:
In the above example, the argument should be:
Port ranges over individual ports can be indicated with -redirect_port . For example, tcp 192.168.0.2:2000-3000 2000-3000 would redirect all connections received on ports 2000 to 3000 to ports 2000 to 3000 on client A .
These options can be used when directly running natd (8) , placed within the natd_flags="" option in /etc/rc.conf , or passed via a configuration file.
For further configuration options, consult natd (8)
29.4.4.2.�Address Redirection
The -redirect_address syntax is as follows:
In the example, this argument would read:
Like -redirect_port , these arguments are placed within the natd_flags="" option of /etc/rc.conf , or passed via a configuration file. With address redirection, there is no need for port redirection since all data received on a particular IP address is redirected.
The external IP addresses on the natd (8) machine must be active and aliased to the external interface. Refer to rc.conf (5) for details.
29.4.5.�The IPFW Command
ipfw can be used to make manual, single rule additions or deletions to the active firewall while it is running. The problem with using this method is that all the changes are lost when the system reboots. It is recommended to instead write all the rules in a file and to use that file to load the rules at boot time and to replace the currently running firewall rules whenever that file changes.
ipfw is a useful way to display the running firewall rules to the console screen. The IPFW accounting facility dynamically creates a counter for each rule that counts each packet that matches the rule. During the process of testing a rule, listing the rule with its counter is one way to determine if the rule is functioning as expected.
To list all the running rules in sequence:
To list all the running rules with a time stamp of when the last time the rule was matched:
The next example lists accounting information and the packet count for matched rules along with the rules themselves. The first column is the rule number, followed by the number of matched packets and bytes, followed by the rule itself.
To list dynamic rules in addition to static rules:
To also show the expired dynamic rules:
To zero the counters:
To zero the counters for just the rule with number NUM :
29.4.5.1.�Logging Firewall Messages
Even with the logging facility enabled, IPFW will not generate any rule logging on its own. The firewall administrator decides which rules in the ruleset will be logged, and adds the log keyword to those rules. Normally only deny rules are logged. It is customary to duplicate the “ ipfw default deny everything ” rule with the log keyword included as the last rule in the ruleset. This way, it is possible to see all the packets that did not match any of the rules in the ruleset.
Logging is a two edged sword. If one is not careful, an over abundance of log data or a DoS attack can fill the disk with log files. Log messages are not only written to syslogd , but also are displayed on the root console screen and soon become annoying.
The IPFIREWALL_VERBOSE_LIMIT=5 kernel option limits the number of consecutive messages sent to syslogd (8) , concerning the packet matching of a given rule. When this option is enabled in the kernel, the number of consecutive messages concerning a particular rule is capped at the number specified. There is nothing to be gained from 200 identical log messages. With this option set to five, five consecutive messages concerning a particular rule would be logged to syslogd and the remainder identical consecutive messages would be counted and posted to syslogd with a phrase like the following:
All logged packets messages are written by default to /var/log/security , which is defined in /etc/syslog.conf .
29.4.5.2.�Building a Rule Script
Most experienced IPFW users create a file containing the rules and code them in a manner compatible with running them as a script. The major benefit of doing this is the firewall rules can be refreshed in mass without the need of rebooting the system to activate them. This method is convenient in testing new rules as the procedure can be executed as many times as needed. Being a script, symbolic substitution can be used for frequently used values to be substituted into multiple rules.
This example script is compatible with the syntax used by the sh (1) , csh (1) , and tcsh (1) shells. Symbolic substitution fields are prefixed with a dollar sign ($). Symbolic fields do not have the $ prefix. The value to populate the symbolic field must be enclosed in double quotes ("").
Start the rules file like this:
The rules are not important as the focus of this example is how the symbolic substitution fields are populated.
The same thing could be accomplished by running these commands by hand:
Questions that are not answered by the documentation may be sent to .
Send questions about this document to .
В этой статье я бы хотел привести примеры настройки NAT на ОС FreeBSD и провести некоторое сравнение способов, которые, по моему мнению, наиболее часто используются.
Для начала:
NAT (от англ. Network Address Translation — «преобразование сетевых адресов») — это механизм в сетях TCP/IP, позволяющий преобразовывать IP-адреса транзитных пакетов. Также имеет названия IP Masquerading, Network Masquerading и Native Address Translation.
Рассмотренные варианты:
— Демон Natd
— IPFilter (ipnat)
— PF nat
— ng_nat
— ipfw nat (kernel nat)
NAT с помощью natd
Из хендбука:
Демон преобразования сетевых адресов (Network Address Translation) во FreeBSD, широко известный как natd(8), является демоном, который принимает входящие IP-пакеты, изменяет адрес отправителя на адрес локальной машины и повторно отправляет эти пакеты в потоке исходящих пакетов. natd делает это, меняя IP-адрес отправителя и порт таким образом, что когда данные принимаются обратно, он может определить расположение источника начальных данных и переслать их машине, которая запрашивала данные изначально.
В /etc/rc.conf добавить
gateway_enable=«yes»
или в /etc/sysctl.conf добавить
net.inet.ip.forwarding=1.
em0 – внешний интерфейс
192.168.0.0/24 – внутренняя сеть
200.200.200.200 – внешний адрес
Также в /etc/rc.conf добавить:
natd_enable=«YES»
natd_interface=«em0»
natd_flags=""
В фаервол добавляем правила для divert:
/sbin/ipfw add divert natd ip from 192.168.0.0/24 to any out via em0
/sbin/ipfw add divert natd ip from any to 200.200.200.200 in via em0
Более подробно описано в Хендбуке.
NAT с помощью IPFilter (ipnat)
В ядре:
options IPFILTER
options IPFILTER_LOG
или подгрузить как модуль и не трогать ядро.
В /etc/rc.conf добавить
gateway_enable=«yes»
или в /etc/sysctl.conf добавить
net.inet.ip.forwarding=1.
Для ведения логов в syslog.conf добавить:
local0.* /var/log/ipmon.log
и запустить утилиту мониторинга работы IPFilter — ipmon с ключами -Dvas
-D – запуститься демоном
-v – детализировать
-a – отслеживать все устройства IPFilter
-s – через syslog
Если:
em0 – внешний интерфейс
192.168.0.0/24 – внутренняя сеть
200.200.200.200 – внешний адрес
То пример правил для Нат будет выглядеть так:
map em0 from 192.168.0.0/24 to any -> 200.200.200.200/32
Или без конкретизации адресов назначения:
map em0 192.168.0.0/24 -> 200.200.200.200/32
Если адрес динамический то можно сделать так:
map em0 192.168.0.0/24 -> 0.0.0.0/32
NAT с помощью pf
В /etc/rc.conf добавить
gateway_enable=«yes»
или в /etc/sysctl.conf добавить
net.inet.ip.forwarding=1.
Также в /etc/rc.conf добавить:
pf_enable=«YES»
pf_rules="/etc/pf.conf"
pf_program="/sbin/pfctl"
pf_flags=""
pflog_enable=«YES»
pflog_logfile="/var/log/pf.log"
pflog_program="/sbin/pflogd"
pflog_flags=""
Пример самого правила:
em0 – внешний интерфейс
192.168.0.0/24 – внутренняя сеть
200.200.200.200 – внешний адрес
В /etc/pf.conf:
nat on em0 from 192.168.0.0/24 to any -> (em0)
NAT с помощью ng_nat
В ядре:
options NETGRAPH
options NETGRAPH_IPFW
options LIBALIAS
options NETGRAPH_NAT
…и другие опции нетграфа если надо
Или просто подгрузить модули:
/sbin/kldload /boot/kernel/ng_ipfw.ko
/sbin/kldload /boot/kernel/ng_nat.ko
em0 – внешний интерфейс
192.168.0.0/24 – внутренняя сеть
200.200.200.200 – внешний адрес
Создание НАТ ноды:
ngctl mkpeer ipfw: nat 60 out
ngctl name ipfw:60 nat
ngctl connect ipfw: nat: 61 in
ngctl msg nat: setaliasaddr 200.200.200.200
В ipfw добавляем строчки для перенаправления трафика в созданную ноду:
/sbin/ipfw add netgraph 61 all from any to 200.200.200.200 in via em0
/sbin/ipfw add netgraph 60 all from 192.168.0.0/24 to any out via em0
далее
sysctl net.inet.ip.fw.one_pass=0
Все написанное оформить виде скрипта и засунуть в /usr/local/etc/rc.d с правами запуска для автозагрузки.
NAT с помощью ipfw nat
Поддержка ipfw nat появилась начиная с версии FreeBSD 7.0
В ядро:
options IPFIREWALL
options IPFIREWALL_DEFAULT_TO_ACCEPT
options IPFIREWALL_FORWARD
options IPFIREWALL_VERBOSE
options IPFIREWALL_VERBOSE_LIMIT=50
options IPFIREWALL_NAT
options LIBALIAS
В /etc/rc.conf добавляем
firewall_enable=«YES»
firewall_nat_enable=«YES»
firewall_type="/etc/firewall"
gateway_enable=«YES»
В /etc/sysctl.conf добавить:
net.inet.ip.fw.one_pass=1
em0 – внешний интерфейс
192.168.0.0/24 – внутренняя сеть
200.200.200.200 – внешний адрес
/sbin/ipfw add nat 1 config log if em0 reset same_ports
/sbin/ipfw add nat 1 ip from 192.168.0.0/24 to not table\(10\) via em0
/sbin/ipfw add nat 1 ip from any to 200.200.200.200 via em0
Где table 10 – не идет через нат
Некоторую статистику можно посмотреть так:
ipfw nat 1 show
Немного сравнения
Следует сказать, что ipfw, natd, ipf, ipnat отлично уживаются вместе. При этом нужно помнить особенности фильтров: ipfw срабатывает по первому совпадению, а ipf (без опции quick в правиле) – по последнему. Ну и всегда следует иметь в виду порядок прохождения пакета через фильтры. Так, если поддержка ipf собрана в ядре, то независимо от того, как запущен ipfw, в первую очередь пакеты будут проходить через правила ipf, а ipfw получит на вход только то, что будет им пропущено. Если же ipfw собран в ядре, а ipf подгружен как модуль, то правом первенства будет пользоваться ipfw.
Если рассматривать разницу и особенности то можно отметить следующее:
Natd:
— Подыхает становится не эффективен, когда трафик превышает 40-50 мегабит
— Реализация в виде демона
— Сложности при работе на нескольких интерфейсах
+ Простота настройки
+ Функциональность, гибкость
IPnat:
+ Простота настройки
+ «близость» к ядру
— При очень больших нагрузках нужен тюнинг
ng_nat:
— Сравнительно сложная настройка
— Не умеет redirect_port
+ Реализирован через libalias в ядре
+ Потребляет сравнительно немного ресурсов
Ipfw nat:
+ Скорость работы
+ Гибкость
+ Реализирован через libalias в ядре
UPD от nightfly:
— невозможность нормально без тонны алиасов натить из под пула
— невнятная статистика
+ наконец перестало течь
+ в отличии от иных умеет активное фтп изкоробки что позволяет не держать рядом фтп прокси
+ не страдает детскими болезнями типа приколов с одновременными pptp сквозь нат
Pf nat:
+ Скорость работы
+ Использование макросов для написания правил
— Проблемы с smp
Выводы
Я не буду отмечать никакой из выше описанных вариантов ввиду того, что тема немного холиварная, и мнения читателей могут не совпадать с моим. Я только попытался описать примеры настройки и сделать некоторое сравнение множества методов организации NAT на ОС FreeBSD. Также я не стал описывать матчасть по NAT, потому, что она есть здесь.
Распространенных вариантов NAT-а под FreeBSD есть довольно много. Это и natd, ipnat, pfnat, ng_nat либо как вариант «купи ASA 5550 и не выделывайся».
К сожалению, в последнее время мне попадалось очень мало хороших и главное доступных статей о ipfw nat который появился, если мне не изменяет память еще в 7.0.
Засим рассматривать под лупой сегодня будем мы именно его.
Истинным адептам pf под кат рекомендуется не заглядывать, чтобы не травмировать себя излишними знаниями.
Для начала объясню, почему именно ipfw nat
Во-первых, потому, что я сторонник простых и очевидных решений, поддерживаемость которых возможна практически с первого взгляда без длительных медитаций и размышлений на тему «а как это работает? Оо». К сожалению, я не могу отнести к таковым нетривиальные гибриды вида ipfw+pfnat.
Во-вторых документации по ng_nat и pfnat (nat on intif from somenet to any -> extif – Ы?) уже достаточно много.
В-третьих я использую ipfw, и люблю его – за простоту, наглядность, предсказуемость, dummynet а гибриды вида ipfw+pf+altq… в общем смотрим «Во-первых».
Матчасть.
Рассматривать ipfw nat мы будем на примере сферической конеобразной сети в вакууме изображенной чуть выше. Собственно по схемке все довольно понятно – оговоримся сразу что НАТить мы будем сеть 172.16.0.0/21, на em1 висит адрес, ну скажем 8.8.8.8 а внутренние ресурсы сети к которым нам не нужно осуществлять трансляцию адресов – такие как например, архивы порно корпоративные почтовые сервера и прочие нужные штуки будут жить с адресами скажем 8.8.8.9, 8.8.8.10
Функционал ipfw nat практически полностью дублирует функционал libalias, которую также используют natd, ng_nat.
Если очень грубо самоцель NAT-сервера сводится к подмене src-ip в пакетах, пришедших на внутренний интерфейс (в нашем случае em0) на адрес исходящего интерфейса (в нашем примере em1) и внесении в свою таблицу соответствий данных для обратного преобразования по приходу нужных пакетов в ответ. Далее все отрихтованые соответствующим образом пакеты улетают либо по дефолтрауту ну либо куда вам нужно (если, допустим, наворотили PBR).
Итого в базовом варианте нам нужно следующее
Перебрать ядро с поддержкой ipfw, ipfw nat, libalias ну и дальше по вкусу
После чего вставляем нечто похожее на это:
ident NAT
options IPFIREWALL
options IPFIREWALL_DEFAULT_TO_ACCEPT
options IPFIREWALL_FORWARD
options IPFIREWALL_VERBOSE
options IPFIREWALL_VERBOSE_LIMIT=50
options IPFIREWALL_NAT
options LIBALIAS
options ROUTETABLES=2
options DUMMYNET
options HZ="1000"
Собираем и устанавливаем новое ядро предусмотрительно забекапив старое
В /etc/rc.conf добавляем
firewall_enable="YES"
firewall_nat_enable="YES"
dummynet_enable="YES"
firewall_type="/etc/firewall"
Что как бы должно намекать на то, что инициализацию ipfw мы будем проводить при помощи /etc/firewall который хочется чтобы в простейшем случае выглядел, например, так:
Для успокоения совести можно сделать еще в /etc/sysctl.conf что-то типа
net.inet.ip.fw.one_pass=1
net.inet.ip.fastforwarding=1
net.inet.tcp.maxtcptw=40960
kern.ipc.somaxconn=4096
kern.ipc.nmbclusters=65536
net.inet.tcp.nolocaltimewait=1
net.inet.ip.portrange.randomized=0
После перезагрузки все должно бы заработать. Проверяется работоспособность этого всего очень просто методом
ipfw nat 1 show
nat 1: icmp=271, udp=45462, tcp=61534, sctp=0, pptp=0, proto=1, frag_id=2 frag_ptr=0 / tot=107270
Вот такую вот скудную статистику в сравнении с pfctl –sa, при помощи параметра log собирает ipfw nat.
Кратко пробежимся по опциям скудные знания о которых мы можем почерпнуть из man:
if — интерфейс на котором будет производиться трансляция адресов
log — включает логирование «исчерпывающей» статистики по внутренним соединениям которую мы уже видели (ipfw nat1 show)
reset — намекает на то что при изменении интерфейса следует очищать внутреннюю табличку
deny_in — запрещает пропускать пакеты извне для которых не найдено соответствий во внутренней табличке.
same_ports — по возможности оставлять оригинальные порты в исходящих пакетах (рекомендуется включить)
unreg_only — проводить маскировку только пакетов пришедших из «нереальных» сетей.
redirect_addr intip extip — предписывает заворачивать трафик приходящий на extip к машине с intip. Сходным образом работают опции redirect_port и redirect_proto полезные для «вынесения» за NAT некоторых машин с нужными сервисами.
Крутиться оная при помощи опции ядра KVA_PAGES (максимум 512 что соответствует 2Гб для i386).
Как-то субъективно, при хорошенькой нагрузке на канале (у меня вылазит при >350-400Mbit/s) может требоваться периодический рестарт экземпляра nat-а, в целях высвобождения памяти, которую съедают таблички оного. Думаю, собака порылась в медленных механизмах отстреливания просроченных сессий. Рестарт можно делать элементарным скриптиком вида:
Также как водиться все наступают на грабли с тем, что сам по себе libalias категорически не дружит с аппаратными считалками контрольных сумм а также с tcp segmentation offload, засим конфигурить карточки изначально рекомендую похожим образом:
cat /etc/rc.conf | grep ifconfig
ifconfig_em1="inet 8.8.8.8 netmask 255.255.255.0 -rxcsum -txcsum -tso"
Вот собственно и все. Работает все прозрачно, не имеет изначально болезней с сервисами типа pptp, ftp (pfnat) и не страдает удручающей медлительностью за счет переключений в юзерспейс (natd). Единственное чего действительно может не хватать – это нормального способа nat-ить из под пула адресов. Единственное что в этом случае приходит в голову это наплодить множество экземпляров на алиасах, но выглядит, это не так красиво как скажем у pfnat.
Как-то сумбурно получилось но надеюсь наглядно.
На тему следующей статьи напрашивается вопрос – а кому-то было бы интересно увидеть пошаговое руководство по установке биллинга с разрулом трафика на удаленных NAS-ах и аккаунтингом на netflow? Ну собственно как решения свободно масштабируемого по горизонтали в отличии от всего того что я описывал в предыдущих статьях? Или написать о чем-то менее узко специфичном?
P.S. Мне тут намекнули что я запарил уже использовать в своих примерах под видом «реальной» айпишки dns google. Да я в курсе про RFC3330 где сказано что «192.0.2.0/24 is assigned as „TEST-NET“ for use in documentation and example code», но как-то не знаю, нагляднее для самого себя получается что-ли :)
Привет всем, кому интересна ОС FreeBSD! После летне-отпускного отсутствия начинаю новый цикл статей. Надеюсь, будет занимательно и полезно.
Для тех, кто тут впервые, поясню, что являюсь разработчиком российского Интернет-шлюза Интернет Контроль Сервер, реализованного на базе FreeBSD. А потому, изнанка этой операционки, ее фишки и тонкости администрирования - то, с чем я сталкиваюсь ежедневно и делюсь с вами.
В предыдущей серии статей мы рассмотрели файрвол PF. Оценили возможности и настроили его для разных ролей. В новом цикле сделаем то же для файрвола IPFW. Как и с PF, начнем с краткого обзора и создания простой конфигурации для защиты веб сервера. В следующий статьях будем погружаться и усложнять конфигурацию постепенно, вводя новые типы правил и добавляя "мяса".
Ipfirewall - open source модуль, портированный на многие ОС. В этом списке FreeBSD, NetBSD, OpenBSD, SunOS, HP/UX и Solaris, Mac OS и даже Windows. Кроме того, часто используется для различных встраиваемых систем. Впервые появился в FreeBSD версии 2.0.
обработчик правил на уровне ядра, включающий систему учета пакетов
ipstealth (механизм редактирования TTL полей, защита от traceroute)
основанные на ALTQ средства управления QoS
механизмы управления пропускной способностью
основанная на таблице маршрутов система анти-спуффинга
встроенный NAT, PAT и LSNAT
поддержка IPv6 (с некоторыми ограничениями)
ipfw - пользовательская утилита для управления ipfirewall. С помощью этой утилиты происходит взаимодействие с модулем ядра. В дальнейшем я буду использовать ipfw и как имя утилиты, и как сокращение названия ipfirewall, для краткости и простоты, ну и просто потому, что так принято на просторах Интернета.
В ipfw конфигурация состоит из пронумерованных правил. Пакет проходит по правилам, начиная с меньшего номера к большему, до первого действия (к примеру allow или deny), после чего обработка прекращается. Чем-то похоже на iptables в Linux.
Управление и полезные настройки
Для включения ipfw в rc.conf необходимо добавить следующие строки:
ipfw с пустой конфигурацией по умолчанию блокирует все соединения. Чтобы не потерять доступ к серверу дополнительно нужно добавить в rc.conf
Эта строка укажет ipfw добавить в конфигурацию строку
Добавление правил происходит командой
Добавить простое правило, под номером 100, разрешающее весь трафик на всех интерфейсах
Структура правил, основные параметры
Общая структура правила не отличается особой сложностью:
Номер - порядковый номер правила, предпочтительно в конфигурации использовать номера не подряд, это позволит без проблем добавлять правила во время работы файрвола. Возможно добавление нескольких правил под одним номером. В этом случае они будут срабатывать в порядке добавления и ipfw delete удалит их все.
Действие назначенное совпавшему пакету. В этой статье мы рассмотрим
Эти действия равнозначны. Пропустить пакет, обработка завершается. Я буду использовать allow, для единообразия.
Так же равнозначны. Отбросить пакет. Буду использовать deny
Проверяет пакет по таблице динамических правил (соединений), никаких дополнительных опций не предполагает.
Протокол - tcp, udp, icmp, или любой другой протокол, описанный в /etc/protocols
Источник и Назначение - ip адреса, без комментариев. Кючевое слово all означает любой адрес. Ключевое слово me означает локальный адрес хоста.
Порт - номер порта для tcp и udp. Можно использовать имена сервисов, описанные в /etc/services
in|out - означают совпадение с входящими или исходящими пакетами.
via IF - совпадение с трафиком только одного интерфейса IF.
keep-state - ключевое слово, указывающее о необходимости создания динамического правила, которое разрешит обмен пакетами между источником и назначением.
limit - разрешать только N соединений, соответствующих правилу. Создаёт динамические правила подобно keep-state. Нельзя в одном правиле использовать limit и keep-state.
Простейшая конфигурация
Возьмем простейший веб-сервер в вакууме. Нам нужно открыть порты 22, 80, 443 для доступа извне. Исходящие соединения разрешим все.
Для сохранения конфигурации и загрузки правил мы будем использовать shell скрипт, указанный в rc.conf опцией firewall_script.
Фактически, этот shell скрипт содержит набор команд ipfw. Что позволяет использовать в написании конфигурации все преимущества shell. Особенно пригодятся переменные. К примеру:
При запуске файрвола будет выполнен этот скрипт, и соответствующие правила будут загружены.
Заключение
Мы разобрались с тем, что такое ipfw и запустили его. Рассмотрели простейшие правила фильтрации и научились с ними работать. А так же создали простую, но вполне рабочую конфигурацию файрвола, способную защитить наш сервер от угроз извне.
В следующей статье мы рассмотрим дополнительные опции фильтрации, усовершенствуем конфигурацию для защиты нашего веб-сервера. А пока у вас есть отличная возможность потестировать Интернет Контроль Сервер, тем более что полнофункциональная демо-версия доступна в течение 35 дней, а версия до 9 пользователей вообще бесплатная.
Перевод англицкого раздела handbook - касающийся IPFW. Прислал Andy.
Примечание: Данный раздел находится в разработке. Содержание всегда может быть неточным.
IPFIREWALL (IPFW) является поддерживаемым файрволлом FreeBSD, авторы и люди развивающие данное программное обеспечение являются добровольцами. Он использует правила наследования состояния и наследовние техники программирования для достижения того, что называется логикой Simple Stateful (простое состояние).
Пример набора правил для IPFW (находится в “ /etc/rc.firewall ” ) в стандартной инсталляции FreeBSD довольно прост, и не предусматривается его прямое использование, без модификации. Примеры не используют фильтрацию состояния, которое необходимо в большинстве настроек, поэтому оно не будет использоваться как основа для этого раздела.
Правила состояний IPFW подразумевают технически сложные возможности выбора, которые могут превзойти уровень знания обычного пользователя брендмауэра. IPFW предназначен для профессионального пользователя, или для технически продвинутого человека, увлеченного своим хобби, которому требуются улучшенные возможности выбора пакетов. Высокий уровень знаний о том, как различные протоколы используют и создают свои уникальные заголовки пакетов, необходим перед тем, как будет выпущена сила IPFW. Предоставление такого рода объяснений, выходит за рамки данной раздела руководства.
IPFW составлен из семи компонентов, первичный компонент - брэндмауэр управляющий списком правил на уровне ядра и интегрированная в него возможность пакетного учета, возможность ведения логов, "divert" правила которые взаимодействуют с NAT, и улучшенные специальные средства, траффик dummynet, возможность шейпинга, возможность перенаправления "fwd rule", возможность бриджа, возможность ipstealth.
28.6.1 Включаем IPFW
Загружаемый модуль содержит встроенную возможность протоколирования. Для того что бы включить ведение логов и установить предел отчета, есть строки которые нужно установить в “ /etc/sysctl.conf ” , добавляя эти значения ведение логов будет включено при следующей перезагрузке:
28.6.2 Опции ядра
Не обязательным является требование включения IPFW следующих опций при компиляции ядра, до тех пор пока вам не понадобилась возможность NAT. Они представлены здесь как дополнительная информация.
Эта опция включает IPFW как часть ядра
Включается лог пакетов которые прошли через IPFW и имеют установленное ключевое слово "log" в наборе правил.
Ограничивает число входящих пакетов зарегестрированных через syslogd. Вы можете захотеть использовать эту опцию во враждебном окружении, в которой вам потребуется протоколировать активность брэндмауэра. Эта возможность закроет возможные denial of service атаки, через флудинг syslog'а.
Эта опция позволит всему проходить через файрволл по умолчанию, неплохая идея если вы только начинаете настроивать файрволл.
Эти опции точно такие же как и для IPv4, только они для IPv6. Если вы не используете IPv6 вы возможно захотите использовать IPv6FIREWALL без всяких правил для блокировки все IPv6.
Эта опция включает использование NAT
Примечание: если вы не включаете IPFIREWALL_DEFAULT_TO_ACCEPT или набор ваших правил позволяет входящие пакеты, вы блокируете все пакеты идущие к вам и от вашей машины.
28.6.3 Опции “ /etc/rc.conf ”
Для выбора одного из правил по умолчанию, идущих с FreeBSD, выберите одно прочитав файл “ /etc/rc.firewall ” и внесите в него следующее:
Возможно использование двух разных путей, для загрузки разных правил для файрволла “ [bjipfw[/b] ” . Первое - это установка переменной “ firewall_type ” в абсолютном пути к файлу, которая содержит правила для файрвола без всяких опций командной строки для самого ipfw. Простой пример набора правил следующий:
С другой стороны, можно установить переменную “ firewall_script ” в абсолютном пути запускаемого скрипта, который содержит ipfw команды которые запускаются во время загрузки системы. Правильный набор правил в скрипте, будет эквивалентен набору правил в файле, показанному выше, следующий:
Внимание: Единственная вещь, которую сделает переменная “ firewall_logging ” , это присвоит “ 1 ” значению переменной “ net.inet.ip.fw.verbose ” в “ sysctl ” (смотрите секцию 28.6.1). В “ rc.conf ” нет переменной которая устанавливает ограничение на файл логов, но значение может быть установлено через переменную “ sysctl ” , вручную или из файла “ /etc/sysctl.conf ” :
Если ваша машина работает как гейт, то есть, осуществляет трансляцию адресов (NAT) через natd, пожалуйста обратитесь к секции 29.8, для информации относительно опций в “ /etc/rc.conf ” .
28.6.4 Команды IPFW
Команды ipfw - обычное средство для создания одного правила, или добавления или удаления активного внутреннего правила файрвола, пока он загружен. Проблема использования данного метода состоит в том, что пока ваша система не выключится или зависнет, все правила которые были добавлены, или изменены, или удалены, потеряются. Запись всех правил в файл и использование этого файла для загрузки правил во время загрузки системы, или массовое замещения выполняемых в данный момент правил файрволла, изменениями которые вы записали в файл - рекомендованный метод, который здесь используется.
Комманда ipfw все еще очень полезна, для вывода используемых правил файрвола на консольный экран. Считывающее средство IPFW, динамически создает счетчик для каждого правила, которое считает каждый пакет, который совпадает с правилом. В течении процесса проверки правила, список правил с счетчиком является одним из способов определить функционирование правила.
Последовательный список всех правил:
Список всех правил, с пометкой времени, когда правило последний раз совпадало:
Список собранной информации, количество совпавших с правилами пакетов, наряду с самими правилами.
Первая колонка, номер правил, сопровождаемая количеством совпавших исходящих пакетов, следующее за
номером входящих совпавших пакетов и затем, само правило.
Список динамических правил добавленных к статическим:
Так же показывает список истекших динамических правил:
Сбрасывает счетчики только для правила NUM:
28.6.5 Набор правил IPFW
Набор правил это группа правил ipfw написанных для пропускания или отбрасывания пакетов основанных на значениях содержащихся в самих пакетах. Двунаправленный обмен пакетов между хостами, включает диалог сессии. Набор правил устанавливает процесс пакета дважды: первый когда он пребывает из общего интернет хоста, и второй раз, когда он отправляется к общему хосту в интернете. Каждый сервис tcp/ip (т.е. telnet, www, mail, и так далее) предопределен в соответствии с протоколом и номером порта. Это основные критерии используемые при создании правил которые пропускают или отбрасывают сервисы.
Когда пакет входит в файрволл, он сопоставляется с первым правилом в наборе и увеличивается на единицу за количество перемещений сверху вниз в списке по возрастанию номера правила в порядке следования. Когда пакет совпадает с выбранными правилами, значение области действия правил выбрано, для этого пакета поиск правил заканчивается. В поиске это упоминается как "первое совпадение побеждает". Если пакет не совпадает ни с одним из правил, он ловится принудительно правилом по умолчанию в ipfw, с номером 65535 которое отбрасывает все пакеты без отправления назад по тому же пути.
Примечание: Поиск будет продолжен, после count, skipto и tee правил.
Инструкции содержащиеся здесь базируются на использовании правил, которые содержат состояния "keep state", "limit", "in"/"out", а так же через опции. Это основа написания правил и включаемых типов в набор правил файрволла.
Включаемый набор правил файрволла только позволяет проходить сервисам через совпадения с правилами. Таким образом, вы можете контролировать какие сервисы пройдут от вас в интернет, и какие сервисы получат доступ к вашей частной сети из интернета. Все остальное будет отброшено по умолчанию. Включаемые наборы правил намного более безопасны, чем исключающие наборы, и это единственный тип правил рассматриваемый здесь.
Внимание: Когда работаете с правилами файрволла будьте внимательны, вы можеть заблокировать себя.
28.6.5.1 Синатксис Правил
28.6.5.1.1 CMD
Каждое новое правило, должно предворяться “ add ” , для того что бы добавить правило во внутреннюю таблицу.
28.6.5.1.2 RULE_NUMBER
Каждое правило должно иметь номер правила, для работы с ним.
28.6.5.1.3 ACTION
Правило которое может быть ассоциировано с одним из следующих действий, которые будут запущены когда пакет совпадает с выбранным критерием правила.
Все это означает ту же самую вещь, которая позволяет пакетам, которые совпадают с правилом, выйти из обработки правил брэндмауэром. Поиск заканчивается на этом правиле.
Сравнивает пакет с динамической таблицей правил. Если найдено совпадение, выполняется действие, связанное с правилом которое создало это динамическое правило, иначе переходит к следующему правилу. Check-state не имеет критериев выбора. Если ни одно check-state состояние не найдено в наборе правил, динамическая таблица правил проверятся на первые keep-state или limit правила.
Оба слова значат тоже самое, что и отбрасывание пакетов которые совпадают с этим правилом. Поиск заканчивается на этом правиле.
28.6.5.1.4 Протоколирование
28.6.5.1.5 Отбор
Ключевое слово описаное в данном разделе используется для описания атрибутов пакета, который будет опрошен при определении совпадает правило с пакетом или нет. Следующие признаки общего назначения, даны для соответствия и должны использоваться в таком порядке:
или любые имена протоколов, содержащиеся в “ /etc/protocols ” , распознаются и могут быть использованы. Значение определенное в протоколе должно быть сопоставимо. Это обязательное требование.
Для протоколов которые поддерживают номера (такие как TCP или UDP). Обязательно нужно написать номер порта сервиса для совпадения. Имена сервисов (из “ /etc/services ” ) могут использоваться вместо значений номеров портов.
Совпадения для входящих или исходящих пакетов соответственно. in и out - ключевые слова и обязательное написание одного или другого как часть критерия совпадения.
Совпадающие пакеты проходящие через определенное имя интерфейса интерфейс. via - ключевое слово которое означает интерфейс который будет всегда проверяться как часть процесса совпадения.
Обязательное ключевое слово, которое распознает запрос о начале сессии для TCP пакетов.
Обязательное ключевое слово. После совпадения файрволл создаст динамическое правило, чье поведение по умолчанию состоит в том, что бы было совпадение двунаправленного траффика между IP адресом или портом источника и приемника по тому же самому протоколу.
Файрволл будет позволять только N соединений с тем же набором параметров, какие определены в правилах. Один или больше исходных и приемных адрессов может быть определено. "limit" и "keep-state" не могут быть использованы в том же правиле. "limit" дает ту же самую функцию состояния как и "keep-state" плюс собственные функции.
28.6.5.2 Опция правил состояний
Фильтр состояний расценивает траффик, как двунаправленный обмен пакетами включая сессию. Он умеет определять установлена ли сессия между оригинальным отправителем и назначением следющим за правильной процедурой двунаправленного обмена. Любые пакеты, которые не соответствуют заголовкам сессии, автоматически отвергаются.
"check-state" используется для определения, в какой момент, в наборе правил IPFW, пакет должен быть проверен в таблице динамических правил. При совпадении, пакет покидает файрвол и продолжает свой путь, новое правило создается динамически для следующего ожидаемого пакета при обмене в течении этой двунаправленной сессии. При несовпадении, пакет продвигается к следующему правилу.
Динамические правила уязвимы для SYN-flood атак, которые открывают большое количество динамических правил. Для предотвращения подобного рода атак, во FreeBSD добавлена новая опция названная limit. Эта опция используется для ограничения числа одновременных сессий, путем опроса полей источника и полей назначения, указанных в опции limit и использования IP адресов пакетов найденых там же, в поиске открытых динамических правил подсчитывая количество правил и IP адресов, если количество больше, чем значение переменной limit, пакет отбрасывается.
28.6.5.4 Создаем скрипт с правилами
Большинство опытных пользователей IPFW создают файл содержащий правила и пишут его на манер запускаемого скрипта. Главная выгода от этого - правила файрволла могут быть обновлены разом без необходимости перезагрузки системы для активации новых правил. Этот метод очень удобен при тестировании новых правил, так как процедура запуска может быть выполнена столько раз, сколько это необходимо. В скрипте вы можете использовать символическую подмену, для написания частоиспользуемых значений и подмены их во многих правилах. Вы увидите это в следующих примерах.
Синтаксис скрипта, который используется здесь, совместим c 'sh', 'csh', 'tcsh' оболочками. Поля с символической подменой, указываются в виде префикса, долларового знака '$' . Символические поля не имеют долларового знака. Значение записываемое в символическое поле должно быть заключено в "двойные кавычки".
Начните ваш файл с правилами, так:
28.6.5.5 Набор правил состояний
28.6.5.6 Пример включаемого набора правил
28.6.5.7 Пример NAT и набора правил состояний
Здесь приводятся дополнительные состояния конфигурации, для включения функции NAT в IPFW. В исходный код ядра должна быть добавлена опция 'option divert', к другим опциям IPFIREWALL, скомпилированым в произвольное ядро.
В дополнение к обычным опциям IPFW в файле “ /etc/rc.conf ” , должны быть добавлены следующие.
Использование правил состояния с правилами divert nat (Network Address Translation) сильно усложняет логику написания набора правил. Расположение правил 'check-state' и 'divert natd' в наборе правил становится критичным. Это уже не простая логика прохождения через поток. Используется новый тип действий называемый 'skipto'. Для использования команды 'skipto' обязательна нумерация каждого правила, исходя из этого, вы всегда знаете где номер правила "skipto" к которому вы переходите.
Cледующий, непрокоментированный пример, одного метода написания правил, выбранного для объяснения прохождения пакета через набор правил.
Процесс прохождения начинается с первого правила, в верхней строчки файла правил и увеличивается на одно правило за раз, ниже пока не достигнет конца, или пакет не будет проверен по критерию отбора на совпадение и пакет будет отпущен файрволлом. Важно заметить местоположение правил 100, 101, 450, 500, and 510. Эти правила управляют трансляцией исходящих и входящих пакетов и поэтому их keep-state записи в динамической таблице всегда регистрируют адрес частной локальной сети. Далее, обратите внимание на то, что все разрешающие и запрещающие правила определены в направлении движения пакета. Так же учтите, что исходящие запросы на начало сессии в правиле 500 для трансляции адресов.
Предположим, что пользователь локальной сети использует браузер для просмотра страниц. Web страницы используют 80 порт для соединений. Итак, пакет входит в файрволл, он не совпадает с правилом с номером 100, потому, что он выходит, а не входит. Он минует правило 101, потому что это первый пакет и у него нет keep-state записи в динамической таблице. Пакет наконец, добирается до правила 125, и совпадает с ним. Это исходящий пакет, идущий через интерфейс, смотрящий в интернет. Пакет все еще имеет адрес источника, который является адресом в частной локальной сети. При совпадении с правилом, производяться два действия. Опция keep-state запишет это правило в динамическую таблицу keep-state правил и выполнит указанное действие. Действие - это часть информации записаной в динамическую таблицу. В этом случае оно "skipto rule 500". Правило 500 транслирует сетевой IP адрес пакета и выпустит его. Запомните это, это очень важно. Этот пакет проделывает путь до пункта назначения и возвращается обратно, и попадает в начало набора правил. В этот раз, он совпадает с правилом 100 и IP адрес его пункта назначения транслируется обратно в его адрес в локальной сети. Затем он обрабатывается правилом check-state, он находится в таблице существующих сессий и выпускается в локальную сеть. Он идет к компьютеру в локальной сети, который посылал этот пакет и отправляет новый пакет запрашивая другой сегмент данных от удаленного сервера. В этот раз он проверяется правилом check-state, исходящая запись найдена, связанное действие выполняет "skipto 500". Пакет переходит к правилу 500, транслируется и выпускается наружу. С входящей стороны все что приходит, является частью существующей сессии и автоматически обрабатывается правилом check-state и должным образом помещается в правила divert natd. Все что мы должны сделать, это обратиться по адресу отбрасывающему пакеты и поддерживающему только авторизованные сервисы. Предположим, у нас есть сервер Apache работающий за файрволлом и мы хотим, что бы люди в интернете, могли получить доступ к веб сайту. Новый входящий пакет запроса совпадает с правилом 100, и его IP адрес в локальной сети транслируется для файрволла. Пакет проверяется на все гадкие штучки, на которые мы хотим его проверить и, наконец, совпадает с правилом 425. При совпадении, происходят две следующие вещи. Правило пакета записывается в динамическую таблицу keep-state, но на этот раз, все запросы о создании новой сессии, приходящие от исходного IP адреса, ограничены 2. Это защищает от DDoS атак на сервис работающий по определенному порту. Действие допускается, поэтому пакет отправляется в локальную сеть. По возвращению check-state правило расценивает пакет как принадлежащий существующей сессии и отправляет его на правило 500, для трансляции и последующего выпуска на выходной интерфейс.
Пример набора правил 1:
Написанное ниже, в значительной степени похоже, на написанное выше, но используется прокоментированный стиль написания правил, дабы помочь неопытным писателям правил IPFW, что правила делают.
Пример набора правил 2:
Garibaldi, 2007-06-09 в 13:36:26
Информация просто супер - впервый раз мне удалось найти подробное описание работы ipfw с натом. Огромное спасибо за проделанную работу.
Читайте также: