оригинал тут >>> http:/mydebianblog.blogspot.com.au/2010/05/swap-swap-linux.html

Все мы знаем, что swap-файлы в Linux делаются просто и легко - настолько просто, что иногда забываем, как это делается. Прежде, чем что-то создавать, хорошо бы узнать, сколько swap-пространства у нас уже имеется в системе - для этого следует дать команду в консоли от рута:

    # swapon -s

Результат будет в виде:

Filename Type Size Used Priority
/dev/hda1 partition 289128 0 -1


Описание вывода команды:

    Filename описывает имеющиеся у вас своп-пространства и где они находятся.
    Type указывает тип пространства: partition (раздел) или file (файл).
    Size сообщает общий размер Swap-пространств.
    Used говорит о том, сколько сейчас свопа задействовано.
    Priority указан приоритет, т.е. какие пространства системе использовать вначале.

Тот же самый результат мы получим по команде cat /proc/swaps

Создание swap-файла в Linux
1. Открываем консоль\терминал и получаем полномочия root или используем sudo:

    $ su

2. Думаем*, какой размер swap-файла нам нужен в мегабайтах. Подумавши, даём команду:

    sudo dd if=/dev/zero of=/swapfile bs=1M count=500

или

    # dd if=/dev/zero of=/swapfile bs=1M count=500

В команде dd для задания размеров можно использовать суффиксы K, M, G для килобайт, мегабайт и гигабайт соответственно. В данном примере это 500 Mегабайт файла подкачки.

    * Многие задаются фундаментальными вопросами бытия вроде "каков рекомендуемый размер swap в linux"? Можно не думать, а просто создать SWAP-файл по размеру оперативной памяти, периодически посматривая на её, подкачки, использование с помощью команды top. При необходимости добавить\уменьшить своппинг системе. Можно использовать несколько файлов подкачки.


3. Поясняем системе, что созданный пустой файл это всё-таки файл подкачки для Linux:

    sudo mkswap /swapfile

или

    # mkswap /swapfile


4. Подключаем созданный swap-файл:

    sudo swapon /swapfile

или

    # swapon /swapfile

При этом в выводе команды top или команды free должно появиться упоминание, что свопинга в системе поприбавилось. Чтобы отключить файл подкачки, пишем

    sudo swapoff /swapfile

или

    # swapoff /swapfile

Чтобы не подключать swap-файл или swap-раздел каждый раз, полезно занести запись в /etc/fstab следующего содержания:

    /swapfile none swap sw 0 0

На всякий случай отмечу, что каждый раз создавать swap-файл не нужно: просто подключаете и отключаете его с помощью swapon/swapoff. Работа со swap-разделами в Linux происходит аналогичным образом.


Приоритет SWAP-файлов
Создавать и использовать swap-файлов в Linux можно любое количество. При этом можно указать приоритет подключаемого swap-файла или раздела (хотя ядро умеет самостоятельно распределять по разделам/файлам подкачки).

Например, высший приоритет для файла подкачки задаётся так:

    swapon -p 1 /opt/swapfile

Приоритет является целым числом от 0 до 32767.


Очистка swap-пространства после ресурсоёмких приложений
Командой swapoff -a, запущенной от имени root, можно отключить использование всех разделов и файлов подкачки. После ввода команды содержимое свопа за несколько минут загружается обратно в оперативную память, а сам раздел подкачки отключается.
После загрузки содержимого свопа в оперативную память включем своп обратно командой swapon -a.


2. Системные настройки использования своппинга - Linux
За интенсивность обращения системы к swap-файлам и swap-разделам отвечает параметр swappiness, равный по умолчанию 60. Значение параметра может быть в пределах от 0 - наименьшее использование подкачки, до 100 - подкачка используется часто.

Насчёт оптимального значения параметра swappiness есть много разных мнений. Так, например, один из ведущих разработчиков ядра Эндрю Мортон считает, что для десктопа лучше ставить большое значение, чтобы всякое bloatware скинуть в своп и использовать оперативную память для чего-то нужного.

Чрезмерное значение здесь приведёт к интенсивному использованию swap-файла, что нежелательно. Слишком маленькое значение может привести к тому, что при заполнении памяти будет принудительно запущен OOMkiller (процесс, запускающийся при исчерпании памяти и убивающий наиболее ресурсоёмкие задачи).

Временно (до перезагрузки системы) изменить этот параметр можно с помощью команды:

    echo 50 > /proc/sys/vm/swappiness

Чтобы изменить значение по умолчанию, необходимо изменить параметр vm.swappiness:

    vm.swappiness=50

в файле /etc/sysctl.conf

Следует, впрочем, отметить, что со vm.swappiness сильно перегибать палку не стоит. При больших значениях система потеряет в отзывчивости (будет вытеснять память, с которой работают приложения, в своп, хотя оперативной памяти ещё много). При малых значениях система работает отзывчивей, но когда оперативная память заканчивается, система начинает активно свопиться и притормаживать.

Также можно попробовать увеличить\уменьшить объём потребляемой системой памяти за счёт изменения размеров дискового кеша. Уровень выделяемой под кеш памяти хранится в
/proc/sys/vm/vfs_cache_pressure
Значение по умолчанию: 100. Чтобы использовать меньше памяти под дисковые кеши (что вообще говоря не есть хорошая идея), ставим значение 50. Если, наоборот, хочется больше отзывчивости системы, увеличиваем размер кеша не скупясь:

    echo 1000 > /proc/sys/vm/vfs_cache_pressure

и далее продолжаем играться с параметрами вплоть до полного удовлетворения. Для того, чтобы настройки стали постоянными, заносим параметр

    vm.vfs_cache_pressure = 1000

в файл /etc/sysctl.conf и со следующей загрузки дисковые кеши будут смачно чавкать вашей оперативной памятью.

взял отсюда >>> http:/blog.tataranovich.com/2013/02/linux.html

Отключить ядро или несколько ядер процессора можно так:

$ echo 0 | sudo tee  /sys/devices/system/cpu/cpu1/online
$ dmesg

оригинал тут http://www.k-max.name/linux/princip-raboty-routing-policy-database/

 

Пару вступительных слов о маршрутизации

 

 Итак, из основных понятий сетей мы знаем, если сетевой пакет предназначен для локальной сети, к которой подключен интерфейс, то он направляется прямо в сеть. Маршрут для такого пакета создается автоматически при поднятии настроенного интерфейса. Если пакет предназначен не локальной сети, то ядро просматривает таблицу маршрутизации на наличие маршрута для данного пакета и отправляет по маршруту, в котором адрес назначения пакета соответствует заданному в маршруте параметру - на адрес шлюза, который указан в поле gateway в маршруте.  При этом, может существовать несколько маршрутов для данного пакета. В таком случае выбирается тот маршрут, в котором в заданной подсети меньше всего компьютеров. Если для текущего пакета маршрут не обнаружен, то он направляется на маршрут "по-умолчанию". Это классическая маршрутизация протокола IPv4, основанная на поиске маршрута по адресу назначения в заголовках IP.

 

Маршруты в  Linux могут появляться различными способами. Во-первых, как я уже говорил, при поднятии сетевого интерфейса появляется соответствующий маршрут в локальную сеть, куда смотрит интерфейс. Во-вторых, маршруты могут добавляться в ручную. Это называется статическая маршрутизация. В-третьих, маршруты могут формироваться динамически, базируясь на информации о топологии и состоянии сети, получаемой с помощью протокола динамической маршрутизации. Это называется динамической маршрутизацией. Динамической маршрутизацией в Linux заведует демон gated или routed, возможно еще какой-то о котором я не знаю

 

Классическую маршрутизацию на основе адреса назначения применяют в небольших сетях. Данную маршрутизацию можно сравнить с походом из дома, например, в торговый центр. При этом, дорога к торговому центру может быть разделена перекрестком и на перекрестке вы выбираете пойти вам на право или налево, основываясь лишь на том, по какой из дорог вы попадете к ТЦ.

 

 

 

Маршрутизация на основе политик (Policy Routing)

 

Продолжая нашу аналогию, представим что вы уперлись в пересечение шести дорог. Усложняя задачу, представьте, что одна из дорог - асфальтированная, и предназначена для легковых автомобилей, вторая - гравийная и предназначена для движения тракторов, третья - ... В данном случае, необходимо принять решение не только на том, КУДА необходимо попасть, но и на том за рулем какого транспортного средства вы находитесь, где вам будет комфортней ехать и многих других параметрах. Аналогично, основной принцип работы механизма маршрутизации на основе политик базируется на основе анализа любых полей IP-пакета, таких как адрес отправителя, IP протокол, порты транспортного протокола, или даже содержимого, а не только на основании адреса получателя.

 

Основу маршрутизации на основе политик составляют 4 понятия. Это традиционные понятия address (адрес) , routes (маршрут), Routing table (таблица маршрутизации), а так же новое в Policy Routing (и являющееся его основой) - rules (правила). Давайте разберем каждый из них.

 

 

 

Адрес (Address) определяет место назначения пакета и источник. Маршрут (routes) задает путь пакета, данное понятие не сильно отличается от традиционной маршрутизации. Соответственно, при задании маршрута так же, как и в традиционном способе (с помощью команды route) можно указать шлюз и несколько опций для маршрута, задаваемого для хоста или подсети. Среди опций можно выделить такие как: метрика (metric),  размер-TCP-окна (window) и др. В Policy Routing помимо стандартных параметров добавления маршрута появились так же опции, позволяющие указать исходящий адрес источника пакета, интерфейс или тип ICMP ответа. Таблица маршрутизации (Routing table) состоит из последовательного набора маршрутов.  Правила (rule) можно рассматривать, как своеобразный фильтр, который отбирает пакеты, удовлетворяющие определенным требованиям и подходящие - направляет по заданному маршруту.

 

 

 

Routing Policy DataBase (RPDB)

 

Механизм маршрутизации на основе политик впервые был реализован в ядре версии 2.1. Он так же называется "база данных политик маршрутизации" (он же Routing Policy DataBase (RPDB)). RPDB - это связанный набор маршрутов, таблиц маршрутизации и правил. Механизм маршрутизации и ip адресации в ядре Linux 2.1 был переписан чуть более чем полностью, в результате чего появилась возможность поддерживать до 255 таблиц маршрутизации и 2^32 правил маршрутизации. Это позволяет создать более чем 4 миллиарда правил, данная цифра перекрывает все пространство адресов IPv4. Другими словами, Вы можете определить правило управления каждым отдельным адресом, доступным во всем адресном пространстве IPv4.

 

 

 

Давайте рассмотрим некоторый пример, который далее позволит нам более детально разобраться в Routing Policy.  В классическом примере на хосте Linux имеется единственная таблица маршрутизации, в которой согласно правил и места назначения пакета ищется маршрут (адрес шлюза и/или физической интерфейс). Давайте предположим, что у нас есть 3 маршрута к некоторой сети назначения, путь через которые (маршруты) проходит по каналам разного качества, соответственно разная скорость. Предположим, в локальной сети есть некоторая группа компьютеров, которой нужна гарантированная скорость, а другой группе высокая скорость не нужна. Если у нас будет единственная таблица маршрутизации, то мы сможем указать лишь единственный маршрут к сети назначения, через единственны шлюз. Данный функционал реализуем в Policy Routing - маршрутизации на основе адреса отправителя пакета.  Это наиболее распространенный и часто применяемый метод маршрутизации. При этом, в правилах отбираются пакеты на основании принадлежности хоста-отправителя заданной в правиле подсети.

 

 

 

Давайте рассмотрим работу Routing Policy в схеме и разберем порядок работы:

 

1. Правила (rules)

 

Как видно, при маршрутизации первый элемент, через который проходит пакет - это набор правил. Каждое правило состоит из критерия отбора пакетов - своеобразный "фильтр" (например, from 2.1.7.100 - отбирает все пакеты с адресом отправителя 2.1.7.100) и действия над "подходящим" пакетом (например, lookup table_name2 - направляет пакет в таблицу маршрутизации с именем table_name2. Дословно: просмотреть table_name2).

 

 

 

При этом, каждый фильтр/критерий может состоять из указания исходного адреса, адреса получателя, входящего интерфейса, TOS и fwmark (поле TOS задает тип сервиса, что это и с чем его едят я ответить не готов, но могу направить в RFC 1349, fwmark - это метки, которые можно задать силами iptables/netfilter).

 

 

 

Действие, применяемое к пакету может возвращать неудачный результат, когда маршрут в заданной таблице не найден, в таком случае пакет переходит к следующему правилу.  При создании правила маршрутизации можно задать определенное действие над пакетом (не только направить в заданную таблицу). Действия подразделяются на следующие типы:

 

 

 

  • unicast (lookup) - просмотр указанной таблицы маршрутизации, если при создании правила не указан тип, то используется данный тип.
  • nat - правило преобразовывает адрес отправителя, без запоминания состояния соединения! (обычно используется совместно с соответствующей записью, маршрутизирующей данный пакет)
  • unreachable - выбросить пакет и вернуть сообщение ICMP о недоступности сети
  • prohibit - выбросить пакет и вернуть сообщение ICMP о запрещении доступа
  • blackhole - молча выбросить пакет (дословно - черная дыра)

 

 

 

Каждое правило имеет свой приоритет от 0 до 32767, в соответствии с которым ядро просматривает данные правила. При старте системы по умолчанию создаются следующие правила:

 

 

 

[root@rpdb ~]# ip rule list

0: from all lookup local

32766: from all lookup main

32767: from all lookup default

 

 

 

Правило с приоритетом 0 (ноль) действует для всех пакетов (from all) и направляет в таблицу маршрутизации local. Таблица local - специальная таблица маршрутизации, содержащая высокоприоритетные маршруты управления для локальных и широковещательных адресов. Правило 0 (ноль) является особенным, оно не может быть удалено или переопределено.

 

 

 

Правило с приоритетом 32766 действует так же для всех пакетов (from all) и направляет в таблицу main. Таблица main - основная таблица маршрутизации, содержащая все маршруты не имеющие политик (то есть работающие по классическому принципу - месту назначения пакета) . Это правило может быть удалено или переопределено в других (вышестоящих) правилах.

 

 

 

Правило с приоритетом 32767 действует так же для всех пакетов (from all) и направляет в таблицу default. Таблица default - по-умолчанию пуста и зарезервирована для использования. Может применяться для назначения маршрутов по умолчанию для пакетов, не направленных куда-либо в предыдущих правилах. Правило может быть удалено.

 

 

 

При добавлении правила в ручную, без указания приоритета (параметр  priority), новые правила будут получать номер с 32765 до 1.

 

 

 

Очень важно понимать разницу между правилом и таблицей маршрутизации. Правило маршрутизации указывает на таблицу. Несколько правил могут отправлять пакет к одной таблице маршрутизации. При этом, некоторые таблицы маршрутизации могут быть БЕЗ правила, указывающего на них (читай -  могут не использоваться).

 

 

 

Управление правилами осуществляется с помощью команды ip с ключом rule. Вот некоторые примеры:

 

 

 

[root@rpdb: ~]# # добавление правила, направляющего пакеты с хоста 192.168.100.1 в таблицу 5

[root@rpdb: ~]# ip rule add from 192.168.100.1 table 5 

[root@rpdb: ~]# # добавление правила для пакетов, помеченных netfilter меткой 4 в таблицу 4

[root@rpdb: ~]# ip rule add fwmark 4 table 4

[root@rpdb: ~]# # добавление правила для хоста 209.10.26.51 - пакеты будут "пропадать"

[root@rpdb: ~]# ip rule add blackhole from 209.10.26.51

 

 

 

2. Таблицы маршрутизации

 

 

 

Итак, следующим шагом на пути пакета по сетевой подсистеме ядра будет таблица маршрутизации, в которую пакет будет направлен соответствующим правилом. Ядро использует несколько таблиц маршрутизации с номерами от 1 до 255. Сопоставление номеров таблиц к их именам задается в файле /etc/iproute2/rt_tables. Фактически, задавать имена таблиц их номерным идентификаторам нет необходимости (в правилах можно просто использовать номера таблиц). По умолчанию при создании маршрута в Linux, если не задано имя таблицы, то используется таблица с ID 254 (main). Кроме таблицы main в ядре зарезервированы следующие имена:

 

 

 

[root@rpdb ~]# cat /etc/iproute2/rt_tables

255 local

254 main

253 default

0 unspec

 

 

 

Про main я уже сказал, но в ядре существует так же не менее важная таблица local с  ID 255, которая состоит из маршрутов для локальных и широковещательных адресов. Ядро поддерживает эту таблицу автоматически, и администраторы никогда не должны изменять ее содержимое и нет необходимости даже в нее заглядывать при нормальном функционировании. Назначение таблицы default я описывал выше при описании правил. Таблица unspec - это "псевдо-таблица", которая содержит в себе правила ВСЕХ таблиц маршрутизации системы. Именно по этому у нее номер ноль, который не входит в диапазон с 1 по 255.  Все таблицы маршрутизации ядра никак между собой не связаны, таким образом, у Вас может быть несколько идентичных маршрутов в различных таблицах, которые не будут конфликтовать. Нумерация таблиц большого значения не имеет. То есть все таблицы по сути имеют одинаковый вес и приоритет их определяется только заданными правилами.

 

 

 

Просмотреть содержимое таблицы можно командой ip (на примере таблицы main):

 

 

 

[root@rpdb ~]# ip route list table main

default via 10.0.0.254 dev eth0

10.0.0.0/16 dev eth0 proto kernel scope link src 10.0.0.2

 

 

 

3. Маршруты/правила

 

 

 

Попадая в какую-либо таблицу маршрутизации, пакет "просматривает" последовательно каждое правило. На данном шаге, дальнейшее направление пакета никак не отличается от "классического" определения маршрута по адресу назначения. Если в текущей таблице маршрут для пакета не обнаружен, то он (пакет) возвращается в базу данных маршрутизации на основе политик к следующему правилу. Стоит обязательно отметить, что существуют разные типы маршрутов (которые очень похожи с типами правил, но правила стоят несколько "выше" маршрутов):

 

 

 

  • unicast - обычный маршрут, определяет исходящий интерфейс и адрес следующего хопа для подсети/хоста назначения.
  • unreachable - пакет выбрасывается и посылается ICMP сообщение "host unreachable".
  • blackhole - пакет просто выбрасывается без возвращения какого-либо сообщения.
  • prohibit (дословно - запрещен) - пакет выбрасывается и посылается ICMP сообщение "administratively prohibited".
  • local - место назначения данного маршрута - локальный хост. В этом маршруте пакеты перемещаются локально.
  • broadcast - пакет пересылается в виде широковещательного сообщения
  • throw - специальный управляющий маршрут, используется совместно с правилами маршрутизации; Если пакет будет соответствовать данному маршруту, то поиск в этой таблице завершается, эмитируя что для данного пакета маршрут не найден и возвращается в RPDB для обработки в следующем правиле.
  • nat - адреса сети назначения преобразуются в соответствии с параметром via; маршрутизатор также обслуживает ARP запросы для этой сети; не предназначен для сжатия адресного пространства или разделения нагрузки; в частности, не хранит таблицу соединений и не заглядывает внутрь пакета; можно использовать при перенумерации сети; для обратного преобразования необходимо задать дополнительное правило маршрутизации "ip rule add from реальный-адрес nat виртуальный-адрес".
  • anycast - локальные адреса, которые нельзя использовать в качестве адресов источника. (непонятный мне тип маршрута)
  • multicast - Специальный тип, используемый для многоадресной маршрутизации. Он не присутствует в статичных таблицах маршрутизации.

 

 

 

Управление правилами в таблице маршрутизации осуществляется с помощью команды ip с ключом route.

 

 

 

Выбор IP-адреса для исходящих соединений

 

 

 

Выбор локального адреса для исходящих соединений в большинстве случаев системой осуществляется автоматически, исходя из имеющихся IP-адресов интерфейсов и таблиц маршрутизации. Во многих случаях сетевые сервисы (веб-сервер, почтовый сервер и др.) позволяют указывать исходный адрес с помощью конфигурационных файлов. Давайте рассмотрим пример. Пусть система имеет два интерфейса eth0(192.168.1.1/24) и eth1(192.168.56.102/24):

 

 

 

[root@rpdb ~]# ip addr show

1: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast

        state UP qlen 1000 link/ether 08:00:27:23:22:97 brd ff:ff:ff:ff:ff:ff

        inet 192.168.1.1/24 brd 192.168.1.255 scope global eth0

        inet6 fe80::a00:27ff:fe23:2297/64 scope link

        valid_lft forever preferred_lft forever

2: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast

        state UP qlen 1000 link/ether 08:00:27:fd:e5:aa brd ff:ff:ff:ff:ff:ff

        inet 192.168.56.102/24 brd 192.168.56.255 scope global eth1

        inet6 fe80::a00:27ff:fefd:e5aa/64 scope link

        valid_lft forever preferred_lft forever

 

 

 

Маршрут по умолчанию у данной системы - 192.168.56.1:

 

 

[root@rpdb ~]# ip route show

192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.1

192.168.56.0/24 dev eth1 proto kernel scope link src 192.168.56.102

default via 192.168.56.1 dev eth1

 

 

 

При такой конфигурации для исходящих соединений будет использоваться интерфейс eth1 и IP-адрес 192.168.56.102 (кроме соединений с узлами сети 192.168.1.0/24 — eth0 и IP-адрес 192.168.1.1). Ниже показан дамп сетевого пакета, отправленного командой ping -c 1 192.168.3.4:

 

 

 

[root@rpdb ~]# tcpdump -ne -i eth1 host 192.168.3.4

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode  listening on eth1, link-type EN10MB (Ethernet), capture size 65535 bytes

10:18:18.924084 08:00:27:fd:e5:aa > 0a:00:27:00:00:00, ethertype IPv4 (0x0800),

length 98: 192.168.56.102 > 192.168.3.4: ICMP echo request, id 960, seq 1, length 64

 

 

 

Однако, если добавить альтернативный маршрут для сети 192.168.3.0/24 через некоторый шлюз 192.168.1.254:

 

 

 

[root@rpdb ~]# ip route add 192.168.3.0/24 via 192.168.1.254

 

 

 

то, для пакетов, предназначенных узлу 192.168.3.4, будет использоваться интерфейс eth0 и исходящий адрес 192.168.1.1 (показан дамп сетевого пакета):

 

 

 

[root@rpdb ~]# tcpdump -ne -i eth0 host 192.168.3.4

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes

10:23:33.393706 08:00:27:23:22:97 > 00:00:00:00:00:aa, ethertype IPv4 (0x0800),

 length 98: 192.168.1.1 > 192.168.3.4: ICMP echo request, id 968, seq 1, length 64

 

 

 

Синтаксис команды ip route позволяет повлиять на выбор локального IP-адреса при соединении с удаленными системами. Для этого служит параметр src с указанием предпочитаемого IP-адреса (должен быть установлен на сетевом интерфейсе компьютера) для отправки пакетов на направление, определяемое в команде префиксом маршрутизации. Так, для указанной ниже конфигурации будет использоваться исходящий адрес 192.168.56.102 (кроме взаимодействия с узлами сети 192.168.1.0/24):

 

 

 

[root@rpdb ~]# ip addr show eth1

2: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000

         link/ether 08:00:27:fd:e5:aa brd ff:ff:ff:ff:ff:ff

         inet 192.168.56.102/24 brd 192.168.56.255 scope global eth1

         inet 192.168.1.10/24 brd 192.168.1.255 scope global eth1:1

         inet6 fe80::a00:27ff:fefd:e5aa/64 scope link

         valid_lft forever preferred_lft forever

[root@rpdb ~]# ip route show

192.168.1.0/24 dev eth1 proto kernel scope link src 192.168.1.10

192.168.56.0/24 dev eth1 proto kernel scope link src 192.168.56.102

default via 192.168.56.1 dev eth1

 

 

 

Для того, чтобы использовать исходный адрес 192.168.1.10 для соединения с узлами сети 192.168.3.0/24 следует использовать команду:

 

 

 

[root@rpdb ~]# ip route add 192.168.3.0/24 via 192.168.56.1 src 192.168.1.10 dev eth1:1

 

 

 

Таблица маршрутизации при этом будет иметь вид:

 

 

 

[root@rpdb ~]# ip route show

192.168.3.0/24 via 192.168.56.1 dev eth1 src 192.168.1.10

192.168.1.0/24 dev eth1 proto kernel scope link src 192.168.1.10

192.168.56.0/24 dev eth1 proto kernel scope link src 192.168.56.102

default via 192.168.56.1 dev eth1

 

 

 

Добавление альтернативного маршрута для "избранных" хостов

 

 

 

Рассмотрим классический пример, когда в локальной сети необходимо направить избранные хосты по альтернативному маршруту. Предположим, что в локальной сети 10.0.0.0/24 имеется некоторый шлюз с двумя интерфейсами, имеющими IP-адреса 10.0.0.1/24 - смотрит в локальную сеть, 12.13.14.15/24 - смотрит в глобальную сеть. Маршрут по умолчанию проходит через IP 12.13.14.1. При этом необходимо, чтобы хост 10.0.0.100 был направлен по маршруту 12.13.14.100. Для решения этой задачи, необходимо:

 

 

 

Добавить описание  дополнительной таблицы маршрутизации в файл /etc/iproute2/rt_tables (это действие необязательно, можно использовать просто номер таблицы)

 

 

 

# echo 100 newtable >> /etc/iproute2/rt_tables

 

 

 

Добавить правило, которое будет направлять пакеты с адресом отправителя 10.0.0.100 в описанную на прошлом шаге таблицу маршрутизации

 

 

 

# ip rule add from 10.0.0.100 lookup newtable

# # или

# ip rule add from 10.0.0.100 lookup 100

# # после выполнения данной команды список правил примет следующий вид

# ip rule show

0: from all lookup local

32765: from 10.0.0.100 lookup newtable

32766: from all lookup main

32767: from all lookup default

 

 

 

Добавить новый маршрут по умолчанию, отправляющий пакеты на хост 12.13.14.100 в новую таблицу маршрутизации

 

 

 

# ip route add default via 12.13.14.100 dev eth1 table newtable

# # после внесенных изменений необходимо очистить кэш маршрутов, чтобы ядро обновило информацию о новых маршрутах

# ip route flush cache

# # после данных изменений таблица newtable (id 100) будет иметь следующий вид

# ip route show table 100

default via 12.13.14.100 dev eth1

 

 

 

Давайте рассмотрим путь пакета, согласно наших правил. Хост 10.0.0.100 отправляет пакет некоторому узлу 7.8.9.10, соответственно, в заголовках пакета источник - 10.0.0.100, назначение - 7.8.9.10. На хосте 10.0.0.100 шлюз по умолчанию - 10.0.0.1, согласно данного правила пакет попадает на шлюз 10.0.0.1. Ядро, получив пакет последовательно с нулевого правила просматривает соответствие пакета заданным в правилах фильтрам/критериям. Пакет подходит под действие правила 0 (0: from all lookup local) и направляется в таблицу маршрутизации local. Но т.к. пакет не принадлежит локальной системе и он не широковещательный, то маршрут в данной таблице не найден и пакет возвращается в RPDB для просмотра следующего правила. Следующее правило на пути пакета -  32765: from 10.0.0.100 lookup newtable. Пакет под критерии данного правила подходит, поэтому направляется в таблицу newtable (id 100). Согласно данной таблицы все пакеты направляются на единственный маршрут по умолчанию - 12.13.14.100. Пакет уходит согласно этого правила на указанный хост. Следующие правила не обрабатываются. Обращаю внимание, что в данном разборе я не учитывал прохождение пакета через таблицы netfilter.

 

 

 

Краткие итоги

 

 

 

В статье я рассмотрел работу механизма Routing Policy DataBase (RPDB) - маршрутизации на основе политик. Я долго вникал в работу этого механизма и постарался изложить свое понимание всего происходящего в ядре. Доходчивой документации на русском языке по данному вопросу в сети я не нашел. Даже всеми хваленый LARTC не дает прозрачного понимания RPDB. Надеюсь, что мои мысли помогут вам понять основные принципы. Подводя итог всему вышесказанному можно свести основной смысл к тому, что пакет в порядке приоритета правил (от 0 до 32767) сверяется с каждым правилом и в случае, если подходит под заданные условия, над пакетом совершается какое-либо действие (обычно отправляется в указанную таблицу). Если пакет в заданной таблице находит свой маршрут, то он отправляется по заданному маршруту. Если не находит - возвращается к списку правил для обработки в следующем правиле. Управление всем этим делом осуществляется командой ip с различными параметрами. В дальнейших статьях я постараюсь рассмотреть более интересные примеры реализации маршрутизации на основе политик. Кроме того, я бы обязательно посоветовал вам почитать приведенные ниже ссылки для более глубокого ознакомления.

 

 

 

Что еще почитать

 

 

 

Хорошая статья о том, что такое маршрут по умолчанию - http://xgu.ru/wiki/Маршрут_по_умолчанию
RFC 1394 (что такое TOS и с чем его едят) - http://www.ietf.org/rfc/rfc1349.txt
Обязательно к прочтению (Policy Routing With Linux) - http://www.policyrouting.org/PolicyRoutingBook/ONLINE/TOC.html
Guide to IP Layer Network Administration with Linux - http://www.linux-ip.net/html/
Команда ip на буржуйском от русского автора - http://www.linux-ip.net/gl/ip-cref/
Linux Advanced Routing & Traffic Control HOWTO - http://www.opennet.ru/docs/RUS/LARTC/index.html

 

 

оригинал тут http://comicsguide.ru/content/view/62/54/

Большинство дистрибутивов Linux, впрочем как и UNIX, для настройки сети и маршрутизации используют команды ifconfig, arp и route. Однако в Linux, начиная с ядра 2.2, была полностью переделана сетевая система и были добавлены новые возможности, которые ранее требовали дополнительных утилит, такие как маршрутизация на основе правил, управление трафиком и т.д. К этим возможностям предоставляет доступ пакет программ iproute2, который в настоящее время входит в большинство современных дистрибутивов.

Утилита ip объединяет в себе возможности команд ifconfig, arp и route, рассмотрим синтаксис команды:

ip [Опции] Объект [ Команда [Аргументы команды] ]

где Опции - опциональные параметры, который влияют на общую работу утилиты или вывод результатов.

В настоящее время доступны следующие опции:

  • -V, -Version - выводит в стандартный вывод (stdout) версию программы ip
  • -s, -stats, -statistic - выводит статистическую информацию.
  • -f, - family - указывается перед идентификатором протокола, таким как inet (IPv4), inet6(IPv6) или link (Устройстов). Служит для выбора указания протокола, если протокол не указан, то по умолчанию протокол выбирается из параметров команд.
  • -4 - аналог параметра -family inet
  • -6 - аналог параметра -family inet6
  • -0 - аналог параметра -family link
  • -o, -oneline - каждая запись будет выводиться на новой строке.
  • -r - выводить на экран символические имена хостов.

Объект - это объект, с которым будут работать или получать о котором информацию. Объекты бывают следующими:

  • link - сетевое устройство
  • address - IPv4 или IPv6 адрес на устройстве.
  • neighbour - ARP адреса
  • route - машрутизация
  • rule - база данных правил машрутизации
  • madress - Multicast-адреса представляют собой особый подвид широковещательных адресов, позволяющих обращаться к группе машин, которые не обязательно должны быть в той же самой подсети. Они весьма полезны при сетевых голосовых переговорах и видеоконференциях. Поддерживаются многими, но не всеми картами Ethernet.
  • mroute - Multicast-пакетов.
  • tunnel - туннель через IP.

Команда описывает действие над Объектом.



ip link - конфигурация сетевого устройства.

Доступные команды: set и show (или list).

ip link set - изменение параметров сетевого устройства.

Аргументы:

  • dev - Имя интерфейса, с которым будем проводить какие-то манипуляции.
  • up (включить) или down (выключить) - включить или выключить сетевой интерфейс.
  • arp on или arp off - изменяет значение флага NOARP на устройстве.
  • multicast on или multicast off - изменяет флаг MULTICAST на устройстве.
  • dynamic on или dynamic off - изменяет флаг DYNAMIC на устройстве.
  • name - Изменяет имя устройства
  • txqueuelen Число или txqlen Число - изменяет длину передаваемой очереди.
  • mtu Число - изменяет значение MTU на устройстве.
  • address Адрес - изменяет адрес на устройстве.
  • broadcast Адрес или brd Адрес - изменяет широковещательный адрес на устройстве.

ip link show (list, ls, sh, lst, l) - показывает информацию об сетевом интерфейсе. Аргументы:

  • dev - Имя интерфейса с которым будем проводить какие-то манипуляции.
  • up - показать только включенные интерфейсы.

Примеры:

Выведем информацию о состоянии интерфейса eth0

# ip link ls dev eth0

В результате получим:

eth0: mtu 1500 qdisc cbq qlen 100
link/ether 00:04:61:92:21:1d brd ff:ff:ff:ff:ff:ff

Выведем статистику интерфейса eth0

#ip -s link ls dev eth0

2: eth0: mtu 1500 qdisc cbq qlen 100
link/ether 00:04:61:92:21:1d brd ff:ff:ff:ff:ff:ff
RX: bytes packets errors dropped overrun mcast
2891892504 15070935 0 0 0 0
TX: bytes packets errors dropped carrier collsns
3139067270 54387014 0 0 0 132934



ip address - управление адресами на интерфейсе.

Команда address имеет ряд псевдонимов: addr, a. Объект address - это адрес IPv4 или IPv6 протокола, связанный с каким-то устройством, чтобы оно могло работать с данными протоколами. Так же каждое устройство может иметь несколько IP адресов. Команда ip address показывает адреса, их свойства, а так же добавляет новые или удаляет старые.

ip address add - добавляет новый адрес.

Аргументы:

  • dev Имя - имя устройства.
  • local Адрес - адрес интерфейса.
  • peer Адрес - адрес удаленной машины при использовании протокола PPP.
  • broadcast Адрес - широковещательный адрес на интерфейсе. Вы можете использовать специальные символы "+" и "-", в этом случае широковещательный адрес получается путем установки/сброса бит в адрес хоста.
  • label Метка - каждый адрес может быть подписан строкой, однако следует помнить, что имя должно начинаться с имени устройства, затем после двоеточия идет сама метка.

Пример:

ip addr add 10.0.0.1/24 brd + dev eth0 label eth0:Alias

Данная команда добавляет адрес 10.0.0.1/24 с маской подсети 255.255.255.0 со стандартным широковещательным адресом и именем eth0:Alias.

ip address delete - удаляет адреса. Сокращения: delete, del, d.

Пример:

ip addr del 127.0.0.1/8 dev lo

Удаляет адрес 127.0.0.1/8 с устройства lo.

ip address show - выводит информацию об адресе. Сокращения: show, list, lst, sh, ls, l. Аргументы:

  • dev Имя - имя устройства.
  • to Префикс - вывести информация о адресах с заданным префиксом.
  • label Имя - вывести информацию об адресах с заданным именем.

Пример работы команды:

kuznet@alisa:~ $ ip addr ls eth0
3: eth0: mtu 1500 qdisc cbq qlen 100
link/ether 00:a0:cc:66:18:78 brd ff:ff:ff:ff:ff:ff
inet 193.233.7.90/24 brd 193.233.7.255 scope global eth0
inet6 3ffe:2400:0:1:2a0:ccff:fe66:1878/64 scope global dynamic
valid_lft forever preferred_lft 604746sec
inet6 fe80::2a0:ccff:fe66:1878/10 scope link
kuznet@alisa:~ $


ip route - управление таблицей машрутизации.

Сокращения: route, ro, r.

ip route add - добавить новый маршрут
ip route change - изменить маршрут
ip route replace - заменить маршрут

Сокращения: add, a; change, chg; replace, repl.

Аргументы:

  • to - назначение маршрута.
  • metric Число - задание метрики маршрута.
  • table Идентификатор таблицы - таблица связанная с маршрутом. Идентификатором таблицы может быть номер или строка из файла /etc/iproute2/rt_tables
  • dev Имя - имя устройства.
  • via Адрес - адрес перехода к следующему маршрутизатору
  • src Адрес - адрес источника
  • nexthop NEXTHOP - следующий переход в случае, если используется многоканальная маршрутизация.
  • via Адрес
  • dev Имя - имя устройства.
  • weight Число - вес маршрута, определяющийся шириной канала или качеством .

Примеры:

Добавляем маршрут к сети 10.0.0/24 через 193.233.7.65

ip route add 10.0.0/24 via 193.233.7.65

Добавим шлюз по умолчанию в случае использования двух каналов в зависимости от загрузки канала:

ip route add default scope global nexthop dev ppp0
nexthop dev ppp1

ip route delete - удалить маршрут.

Сокращения: delete, del, d.

Аргументы: Аргументы данной команды сходны с ip route add.

Пример:

Удаляем маршрут, созданный в предыдущем разделе.

ip route del default scope global nexthop dev ppp0
nexthop dev ppp1


ip rule - управление правилами машрутизации

Сокращения: rule, ru

Маршрутизация может производиться не только в зависимости от адреса получателя, но и по адресу источника, IP протокола и транспортного протокола. По умолчанию существуют 3 правила:

  • Таблица Local (ID 255) - специальная таблица маршрутизации с самым большим приоритетом, которая содержит таблицы для локальных и широковещательных адресов.
  • Таблица Main (ID 254) - обычная таблица маршрутизации.
  • Таблица Default (ID 253) - пустая по умолчанию таблица.

ip rule add - добавить новое правило.
Ip rule delete - удалить правило.

Сокращения: add, a; delete, del, d

Аргументы:

  • from - адрес источник
  • to - адрес получателя
  • iif Имя - имя интерфейса с которого будет получен пакет
  • fwmark Метка - метка пакета, устанавливаемая firewall.
  • table Идентификатор таблицы - таблица связанная с маршрутом. Идентификатором таблицы может быть номер или строка из файла /etc/iproute2/rt_tables
  • priority Число- приоритет таблицы.

Примеры:

Маршрутизировать пакеты с сети 192.203.80.0/24 согласно таблицы example.

ip ru add from 192.203.80.0/24 table example prio 220


Рассмотрим примеры использования маршрутизации на основе правил.

1. Пусть у нас есть два канала в интернет: быстрый модем с IP адресом 212.64.94.251, связанный PPP c 212.64.94.1, и медленный c 212.64.78.148, связанный PPP c 195.96.98.253. Надо пакеты одного пользователя отправлять через медленный модем. Для этого сформируем новое правило:

# echo 200 User >> /etc/iproute2/rt_tables
# ip rule add from 10.0.0.10 table John
# ip rule ls
0: from all lookup local
32765: from 10.0.0.10 lookup John
32766: from all lookup main
32767: from all lookup default

Далее назначаем для этого пользователя шлюз по умолчанию и очищаем кэш таблицы маршрутизации для того чтобы наши изменения вступили в действие.

# ip route add default via 195.96.98.253 dev ppp2 table John
# ip route flush cache

2. Необходимо направить весь трафик на 80 порт через сетевую карту eth0. Пометим пакеты, идущие на 80 порт.

# iptables -A PREROUTING -i eth0 -t mangle -p tcp --dport 80
-j MARK --set-mark 2

Создадим правила для помеченных пакетов.

# echo 202 www.out >> /etc/iproute2/rt_tables
# ip rule add fwmark 2 table www.out
# ip route add default via 10.0.0.2 dev eth0 table www.out
# ip route flush cache

оригинал тут http://www.k-max.name/linux/iptables-v-primerax/

Настройка netfilter/iptables для рабочей станции

 

Давайте начнем с элементарной задачи - реализация сетевого экрана Linux на десктопе. В большинстве случаев на десктопных дистрибутивах линукса нет острой необходимости использовать файервол, т.к. на таких дистрибутивах не запущены какие-либо сервисы, слушающие сетевые порты, но ради профилактики организовать защиту не будет лишним. Ибо ядро тоже не застраховано от дыр. Итак, мы имеем Linux, с настроенным сетевым интерфейсом eth0, не важно по DHCP или статически...

 

Для настройки сетевого экрана я стараюсь придерживаться следующей политики: запретить все, а потом то, что нужно разрешить. Так и поступим в данном случае. Если у вас свежеустановленная система и вы не пытались настроить на ней сетевой фильтр, то правила будут иметь примерно следующую картину:

 

netfilter:~# iptables -L

Chain INPUT (policy ACCEPT)

target prot opt source destination

 

Chain FORWARD (policy ACCEPT)

target prot opt source destination

 

Chain OUTPUT (policy ACCEPT)

target prot opt source destination

 

Это значит, что политика по умолчанию для таблицы filter во всех цепочках - ACCEPT и нет никаких других правил, что-либо запрещающих. Поэтому давайте сначала запретим ВСЁ входящие, исходящие и проходящие пакеты (не вздумайте это делать удаленно-тут же потеряете доступ):

 

netfilter:~# iptables -P INPUT DROP

netfilter:~# iptables -P OUTPUT DROP

netfilter:~# iptables -P FORWARD DROP

 

Этими командами мы устанавливаем политику DROP по умолчанию. Это значит, что любой пакет, для которого явно не задано правило, которое его разрешает, автоматически отбрасывается. Поскольку пока еще у нас не задано ни одно правило - будут отвергнуты все пакеты, которые придут на ваш компьютер, равно как и те, которые вы попытаетесь отправить в сеть. В качестве демонстрации можно попробовать пропинговать свой компьютер через интерфейс обратной петли:

 

netfilter:~# ping -c2 127.0.0.1

PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.

ping: sendmsg: Operation not permitted

ping: sendmsg: Operation not permitted

 

--- localhost ping statistics ---

2 packets transmitted, 0 received, 100% packet loss, time 1004ms

 

На самом деле это полностью не функционирующая сеть и это не очень хорошо, т.к. некоторые демоны используют для обмена между собой петлевой интерфейс, который после проделанных действий более не функционирует. Это может нарушить работу подобных сервисов. Поэтому в первую очередь в обязательном порядке разрешим передачу пакетов через входящий петлевой интерфейс и исходящий петлевой интерфейс в таблицах INPUT (для возможности получения отправленных пакетов) и OUTPUT (для возможности отправки пакетов) соответственно, в обязательном порядке:

 

netfilter:~# iptables -A INPUT -i lo -j ACCEPT 

netfilter:~# iptables -A OUTPUT -o lo -j ACCEPT

 

После этого пинг на локалхост заработает:

 

netfilter:~# ping -c1 127.0.0.1

PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.

64 bytes from 127.0.0.1 (127.0.0.1): icmp_seq=1 ttl=64 time=0.116 ms

 

--- 127.0.0.1 ping statistics ---

1 packets transmitted, 1 received, 0% packet loss, time 116ms

rtt min/avg/max/mdev = 0.116/0.116/0.116/0.116 ms

 

Если подходить к настройке файервола не шибко фанатично, то можно разрешить работу протокола ICMP:

 

netfilter:~# iptables -A INPUT -p icmp -j ACCEPT

netfilter:~# iptables -A OUTPUT -p icmp -j ACCEPT

 

Более безопасно будет указать следующую аналогичную команду iptables:

 

netfilter:~# iptables -A INPUT -p icmp --icmp-type 0 -j ACCEPT

netfilter:~# iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT

netfilter:~# iptables -A OUTPUT -p icmp -j ACCEPT

 

Данная команда разрешит типы ICMP пакета эхо-запрос и эхо-ответ, что повысит безопасность.

 

Зная, что наш комп не заражен (ведь это так?) и он устанавливает только безопасные исходящие соединения. А так же, зная, что безопасные соединения - это соединения из т.н. эфимерного диапазона портов, который задается ядром в файле /proc/sys/net/ipv4/ip_local_port_range, можно разрешить исходящие соединения с этих безопасных портов:

 

netfilter:~# cat /proc/sys/net/ipv4/ip_local_port_range

32768 61000

netfilter:~# iptables -A OUTPUT -p TCP --sport 32768:61000 -j ACCEPT

netfilter:~# iptables -A OUTPUT -p UDP --sport 32768:61000 -j ACCEPT

 

Если подходить к ограничению исходящих пакетов не параноидально, то можно было ограничиться одной командой iptables, разрешающей все исхолящие соединения оп всем протоколам и портам:

 

netfilter:~# iptables -A OUTPUT -j ACCEPT

netfilter:~# # или просто задать политику по умолчанию ACCEPT для цепочки OUTPUT

netfilter:~# iptables -P OUTPUT ACCEPT

 

Далее, зная что в netfilter сетевые соединения имеют 4 состояния (NEW, ESTABLISHED, RELATED и INVALID) и новые исходящие соединения с локального компьютера (с состоянием NEW) у нас разрешены в прошлых двух командах iptables, что уже установленные соединения и дополнительные имеют состояния ESTABLISHED и RELATED, соответственно, а так же зная, что входящие соединения к локальной системе приходят через цепочку INPUT, можно разрешить попадание на наш компьютер только тех TCP- и UDP-пакетов, которые были запрошены локальными приложениями:

 

netfilter:~# iptables -A INPUT -p TCP -m state --state ESTABLISHED,RELATED -j ACCEPT

netfilter:~# iptables -A INPUT -p UDP -m state --state ESTABLISHED,RELATED -j ACCEPT

 

Это собственно, все! Если на десктопе все же работает какая-то сетевая служба, то необходимо добавить соответствующие правила для входящих соединений и для исходящих. Например, для работы ssh-сервера, который принимает и отправляет запросы на 22 TCP-порту, необходимо добавить следующие iptables-правила:

 

netfilter:~# iptables -A INPUT -i eth0 -p TCP --dport 22 -j ACCEPT 

netfilter:~# iptables -A OUTPUT -o eth0 -p TCP --sport 22 -j ACCEPT

 

Т.е. для любого сервиса нужно добавить по одному правилу в цепочки INPUT и OUTPUT, разрешающему соответственно прием и отправку пакетов с использованием этого порта для конкретного сетевого интерфейса (если интерфейс не указывать, то будет разрешено принимать/отправлять пакеты по любому интерфейсу).

 

Настройка netfilter/iptables для подключения нескольких клиентов к одному соединению.

 

Давайте теперь рассмотрим наш Linux в качестве шлюза для локальной сети во внешнюю сеть Internet. Предположим, что интерфейс eth0 подключен к интернету и имеет IP 198.166.0.200, а интерфейс eth1 подключен к локальной сети и имеет IP 10.0.0.1. По умолчанию, в ядре Linux пересылка пакетов через цепочку FORWARD (пакетов, не предназначенных локальной системе) отключена. Чтобы включить данную функцию, необходимо задать значение 1 в файле /proc/sys/net/ipv4/ip_forward:

 

netfilter:~# echo 1 > /proc/sys/net/ipv4/ip_forward

 

Чтобы форвардинг пакетов сохранился после перезагрузки, необходимо в файле /etc/sysctl.conf раскомментировать (или просто добавить) строку net.ipv4.ip_forward=1.

 

Итак, у нас есть внешний адрес (198.166.0.200), в локальной сети имеется некоторое количество гипотетических клиентов, которые имеют адреса из диапазона локальной сети и посылают запросы во внешнюю сеть. Если эти клиенты будут отправлять во внешнюю сеть запросы через шлюз "как есть", без преобразования, то удаленный сервер не сможет на них ответить, т.к. обратным адресом будет получатель из "локальной сети". Для того, чтобы эта схема корректно работала, необходимо подменять адрес отправителя, на внешний адрес шлюза Linux. Это достигается за счет действия MASQUERADE (маскарадинг) в цепочке POSTROUTING, в таблице nat.

 

netfilter:~# iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

netfilter:~# iptables -A FORWARD -m conntrack --ctstate NEW -i eth1 -s 10.0.0.1/24 -j ACCEPT

netfilter:~# iptables -P FORWARD DROP

netfilter:~# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

 

Итак, по порядку сверху-вниз мы разрешаем уже установленные соединения в цепочке FORWARD, таблице filter, далее мы разрешаем устанавливать новые соединения в цепочке FORWARD, таблице filter, которые пришли с интерфейса eth1 и из сети 10.0.0.1/24. Все остальные пакеты, которые проходят через цепочку FORWARD - отбрасывать. Далее, выполняем маскирование (подмену адреса отправителя пакета в заголовках) всех пакетов, исходящих с интерфейса eth0.

 

Кроме указанных правил так же можно нужно добавить правила для фильтрации пакетов, предназначенных локальному хосту - как описано в прошлом разделе. То есть добавить запрещающие и разрешающие правила для входящих и исходящих соединений:

 

netfilter:~# iptables -P INPUT DROP

netfilter:~# iptables -P OUTPUT DROP

netfilter:~# iptables -A INPUT -i lo -j ACCEPT 

netfilter:~# iptables -A OUTPUT -o lo -j ACCEPT

netfilter:~# iptables -A INPUT -p icmp --icmp-type 0 -j ACCEPT

netfilter:~# iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT

netfilter:~# iptables -A OUTPUT -p icmp -j ACCEPT

netfilter:~# cat /proc/sys/net/ipv4/ip_local_port_range

32768 61000

netfilter:~# iptables -A OUTPUT -p TCP --sport 32768:61000 -j ACCEPT

netfilter:~# iptables -A OUTPUT -p UDP --sport 32768:61000 -j ACCEPT

netfilter:~# iptables -A INPUT -p TCP -m state --state ESTABLISHED,RELATED -j ACCEPT

netfilter:~# iptables -A INPUT -p UDP -m state --state ESTABLISHED,RELATED -j ACCEPT

 

В результате, если один из хостов локальной сети, например 10.0.0.2, попытается связаться с одним из интернет-хостов, например, 93.158.134.3 (ya.ru), при проходе его пакетов через шлюз, их исходный адрес будет подменяться на внешний адрес шлюза в цепочке POSTROUTING таблице nat, то есть исходящий IP  10.0.0.2 будет заменен на 198.166.0.200. С точки зрения удаленного хоста (ya.ru), это будет выглядеть, как будто с ним связывается непосредственно сам шлюз. Когда же удаленный хост начнет ответную передачу данных, он будет адресовать их именно шлюзу, то есть 198.166.0.200. Однако, на шлюзе адрес назначения этих пакетов будет подменяться на 10.0.0.2, после чего пакеты будут передаваться настоящему получателю в локальной сети. Для такого обратного преобразования никаких дополнительных правил указывать не нужно — это будет делать все та же операция MASQUERADE, которая помнит какой хост из локальной сети отправил запрос и какому хосту необходимо вернуть пришедший ответ.

 

Примечание: желательно негласно принято, перед всеми командами iptables очищать цепочки, в которые будут добавляться правила:

 

netfilter:~# iptables -F ИМЯ_ЦЕПОЧКИ

 

Предоставление доступа к сервисам на шлюзе

 

Предположим, что на нашем шлюзе запущен некий сервис, который должен отвечать на запросы поступающие из сети интернет. Допустим он работает на некотором TCP порту nn. Чтобы предоставить доступ к данной службе, необходимо модифицировать таблицу filter в цепочке INPUT (для возможности получения сетевых пакетов, адресованных локальному сервису) и таблицу filter в цепочке OUTPUT (для разрешения ответов на пришедшие запросы).

 

Итак, мы имеем настроенный шлюз, который маскарадит (заменяет адрес отправителя на врешний) пакеты во внешнюю сеть. И разрешает принимать все установленные соединения. Предоставление доступа к сервису будет осуществляться с помощью следующих разрешающих правил:

 

netfilter:~# iptables -A INPUT -p TCP --dport nn -j ACCEPT 

netfilter:~# iptables -A OUTPUT -p TCP --sport nn -j ACCEPT

 

Данные правила разрешают входящие соединения по протоколу tcp на порт nn и исходящие соединения по протоколу tcp с порта nn. Кроме этого, можно добавить дополнительные ограничивающие параметры, например разрешить входящие соединения только с внешнего интерфейса eth0 (ключ -i eth0) и т.п.

 

Предоставление доступа к сервисам в локальной сети

 

Предположим, что в нашей локальной сети имеется какой-то хост с IP X.Y.Z.1, который должен отвечать на сетевые запросы из внешней сети на TCP-порту xxx. Для того чтобы при обращении удаленного клиента ко внешнему IP на порт xxx происходил корректный ответ сервиса из локальной сети, необходимо направить запросы, приходящие на внешний IP порт xxx на соответствующий хост в локальной сети. Это достигается модификацией адреса получателя в пакете, приходящем на указанный порт. Это действие называется DNAT и применяется в цепочке PREROUTING в таблице nat. А так же разрешить прохождение данный пакетов в цепочке FORWARD в таблице filter.

 

Опять же, пойдем по пути прошлого раздела. Итак, мы имеем настроенный шлюз, который маскарадит (заменяет адрес отправителя на врешний) пакеты во внешнюю сеть. И разрешает принимать все установленные соединения. Предоставление доступа к сервису будет осуществляться с помощью следующих разрешающих правил:

 

netfilter:~# iptables -t nat -A PREROUTING -p tcp -d 198.166.0.200 --dport xxx -j DNAT --to-destination X.Y.Z.1

netfilter:~# iptables -A FORWARD -i eth0 -p tcp -d X.Y.Z.1 --dport xxx -j ACCEPT

 

Сохранение введенных правил при перезагрузке

 

Все введенные в консоли правила - после перезагрузки ОС будут сброшены в первоначальное состояние (читай - удалены). Для того чтобы сохранить все введенные команды iptables, существует несколько путей. Например, один из них - задать все правила брандмауэра в файле инициализации rc.local. Но у данного способа есть существенный недостаток: весь промежуток времени с запуска сетевой подсистемы, до запуска последней службы и далее скрипта rc.local из SystemV операционная система будет не защищена. Представьте ситуацию, например, если какая-нибудь служба (например NFS) стартует последней и при ее запуске произойдет какой-либо сбой и до запуска скрипта rc.local. Соответственно, rc.local так и не запуститься, а наша система превращается в одну большую дыру.

 

Поэтому самой лучшей идеей будет инициализировать правила netfilter/iptables при загрузке сетевой подсистемы. Для этого в Debian есть отличный инструмент - каталог /etc/network/if-up.d/, в  который можно поместить скрипты, которые будут запускаться при старте сети. А так же есть команды iptables-save и iptables-restore, которые сохраняют создают дамп правил netfilter из ядра на стандартный вывод и восстанавливают в ядро правила со стандартного ввода соответственно.

 

Итак, алгоритм сохранения iptables примерно следующий:

 

  • Настраиваем сетевой экран под свои нужны с помощью команды iptables
  • создаем дамп созданный правил с помощью команды iptables-save > /etc/iptables.rules
  • создаем скрипт импорта созданного дампа при старте сети (в каталоге /etc/network/if-up.d/) и не забываем его сделать исполняемым:

 

# cat /etc/network/if-up.d/firewall

#!/bin/bash

/sbin/iptables-restore < /etc/iptables.rules

exit 0

# chmod +x /etc/network/if-pre-up.d/firewall

 

Дамп правил, полученный командой iptables-save имеет текстовый формат, соответственно пригоден для редактирования. Синтаксис вывода команды iptables-save следующий:

 

# Generated by iptables-save v1.4.5 on Sat Dec 24 22:35:13 2011

*filter

:INPUT ACCEPT [0:0] 

:FORWARD ACCEPT [0:0]

.......

# комментарий

-A INPUT -i lo -j ACCEPT

-A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT

...........

-A FORWARD -j REJECT

COMMIT

# Completed on Sat Dec 24 22:35:13 2011

# Generated by iptables-save v1.4.5 on Sat Dec 24 22:35:13 2011

*raw

......

COMMIT

 

Строки, начинающиеся на # - комментарии, строки на * - это название таблиц, между названием таблицы и словом COMMIT содержатся параметры, передаваемые команде iptables. Параметр COMMIT - указывает на завершение параметров для вышеназванной таблицы. Строки, начинающиеся на двоеточие задают цепочки, в которых содержится данная таблица в формате:

 

:цепочка политика [пакеты:байты]

 

где цепочка - имя цепочки, политика - политика цепочки по-умолчанию для данной таблицы, а далее счетчики пакетов и байтов на момент выполнения команды.

 

В RedHat функции хранения команд iptables выполняемых при старте и останове сети выполняет файл /etc/sysconfig/iptables. А управление данным файлом лежит на демоне iptables.

 

Как еще один вариант сохранения правил, можно рассмотреть использование параметра up в файле /etc/network/interfaces с аргументом в виде файла, хранящего команды iptables, задающие необходимые правила.

 

Итог

 

На сегодня будет достаточно. Более сложные реализации межсетевого экрана я обязательно будут публиковаться в следующих статьях.

NewMixer (c) 2017