Nat in linux kernel

Быстрый роутинг и NAT в Linux

Немного истории

Тема исчерпания адресного пространства IPv4 уже не нова. В какой-то момент в RIPE появились очереди ожидания (waiting list), затем возникли биржи, на которых торговали блоками адресов и заключались сделки по их аренде. Постепенно операторы связи начали предоставлять услуги доступа в Интернет с помощью трансляции адресов и портов. Кто-то не успел получить достаточно адресов, чтобы выдать «белый» адрес каждому абоненту, а кто-то начал экономить средства, отказавшись от покупки адресов на вторичном рынке. Производители сетевого оборудования поддержали эту идею, т.к. этот функционал обычно требует дополнительных модулей расширения или лицензий. Например, у Juniper в линейке маршрутизаторов MX (кроме последних MX104 и MX204) выполнять NAPT можно на отдельной сервисной карте MS-MIC, на Cisco ASR1k требуется лицензия СGN license, на Cisco ASR9k — отдельный модуль A9K-ISM-100 и лицензия A9K-CGN-LIC к нему. В общем, удовольствие стоит немалых денег.

IPTables

Задача выполнения NAT не требует специализированных вычислительных ресурсов, ее в состоянии решать процессоры общего назначения, которые установлены, например, в любом домашнем роутере. В масштабах оператора связи эту задачу можно решить используя commodity серверы под управлением FreeBSD (ipfw/pf) или GNU/Linux (iptables). Рассматривать FreeBSD не будем, т.к. я довольно давно отказался от использования этой ОС, так что остановимся на GNU/Linux.

Включить трансляцию адресов совсем не сложно. Для начала необходимо прописать правило в iptables в таблицу nat:

Операционная система загрузит модуль nf_conntrack, который будет следить за всеми активными соединениями и выполнять необходимые преобразования. Тут есть несколько тонкостей. Во-первых, поскольку речь идет о NAT в масштабах оператора связи, то необходимо подкрутить timeout’ы, потому что со значениями по умолчанию размер таблицы трансляций достаточно быстро вырастет до катастрофических значений. Ниже пример настроек, которые я использовал на своих серверах:

И во-вторых, поскольку по умолчанию размер таблицы трансляций не рассчитан на работу в условиях оператора связи, его необходимо увеличить:

Также необходимо увеличить и количество buckets для хэш-таблицы, хранящей все трансляции (это опция модуля nf_conntrack):

После этих нехитрых манипуляций получается вполне работающая конструкция, которая может транслировать большое количество клиентских адресов в пул внешних. Однако, производительность этого решения оставляет желать лучшего. В своих первых попытках использования GNU/Linux для NAT (примерно 2013 год) я смог получить производительность около 7Gbit/s при 0.8Mpps на один сервер (Xeon E5-1650v2). С того времени в сетевом стеке ядра GNU/Linux было сделано много различных оптимизаций, производительность одного сервера на том же железе выросла практически до 18-19 Gbit/s при 1.8-1.9 Mpps (это были предельные значения), но потребность в объеме трафика, обрабатываемого одним сервером, росла намного быстрее. В итоге были выработаны схемы балансировки нагрузки на разные серверы, но всё это увеличило сложность настройки, обслуживания и поддержания качества предоставляемых услуг.

Читайте также:  Linux ctrl работает как shift

NFTables

Сейчас модным направлением в программном «перекладывании пакетиков» является использование DPDK и XDP. На эту тему написана куча статей, сделано много разных выступлений, появляются коммерческие продукты (например, СКАТ от VasExperts). Но в условиях ограниченных ресурсов программистов у операторов связи, пилить самостоятельно какое-нибудь «поделие» на базе этих фреймворков довольно проблематично. Эксплуатировать такое решение в дальнейшем будет намного сложнее, в частности, придется разрабатывать инструменты диагностики. Например, штатный tcpdump с DPDK просто так не заработает, да и пакеты, отправленные назад в провода с помощью XDP, он не «увидит». На фоне всех разговоров про новые технологии вывода форвардинга пакетов в user-space, незамеченными остались доклады и статьи Pablo Neira Ayuso, меинтейнера iptables, про разработку flow offloading в nftables. Давайте рассмотрим этот механизм подробнее.

Основная идея заключается в том, что если роутер пропустил пакеты одной сессии в обе стороны потока (TCP сессия перешла в состояние ESTABLISHED), то нет необходимости пропускать последующие пакеты этой сессии через все правила firewall, т.к. все эти проверки всё равно закончатся передачей пакета далее в роутинг. Да и собственно выбор маршрута выполнять не надо — мы уже знаем в какой интерфейс и какому хосту надо переслать пакеты пределах этой сессии. Остается только сохранить эту информацию и использовать ее для маршрутизации на ранней стадии обработки пакета. При выполнении NAT необходимо дополнительно сохранить информацию об изменениях адресов и портов, преобразованных модулем nf_conntrack. Да, конечно, в этом случае перестают работать различные полисеры и другие информационно-статистические правила в iptables, но в рамках задачи отдельного стоящего NAT или, например, бордера — это не так уж важно, потому что сервисы распределены по устройствам.

Конфигурация

Чтобы воспользоваться этой функцией нам надо:

  • Использовать свежее ядро. Несмотря на то, что сам функционал появился еще в ядре 4.16, довольно долго он было очень «сырой» и регулярно вызывал kernel panic. Стабилизировалось всё примерно в декабре 2019 года, когда вышли LTS ядра 4.19.90 и 5.4.5.
  • Переписать правила iptables в формат nftables, используя достаточно свежую версию nftables. Точно работает в версии 0.9.0

Если с первым пунктом всё в принципе понятно, главное не забыть включить модуль в конфигурацию при сборке (CONFIG_NFT_FLOW_OFFLOAD=m), то второй пункт требует пояснений. Правила nftables описываются совсем не так, как в iptables. Документация раскрывает практически все моменты, также есть специальные конверторы правил из iptables в nftables. Поэтому я приведу только пример настройки NAT и flow offload. Небольшая легенда для примера: , — это сетевые интерфейсы, через которые проходит трафик, реально их может быть больше двух.

— начальный и конечный адрес диапазона «белых» адресов.

Конфигурация NAT очень проста:

С flow offload немного сложнее, но вполне понятно:

Вот, собственно, и вся настройка. Теперь весь TCP/UDP трафик будет попадать в таблицу fastnat и обрабатываться намного быстрее.

Результаты

Чтобы стало понятно, насколько это «намного быстрее», я приложу скриншот нагрузки на два реальных сервера, с одинаковой начинкой (Xeon E5-1650v2), одинаково настроенных, использующих одно и тоже ядро Linux, но выполняющих NAT в iptables (NAT4) и в nftables (NAT5).

На скриншоте нет графика пакетов в секунду, но в профиле нагрузки этих серверов средний размер пакета в районе 800 байт, поэтому значения доходят до 1.5Mpps. Как видно, запас производительности у сервера с nftables огромный. На текущий момент этот сервер обрабатывает до 30Gbit/s при 3Mpps и явно способен упереться в физическое ограничение сети 40Gbps, имея при этом свободные ресурсы CPU.

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

Источник

Arch Linux

You are not logged in.

#1 2018-08-07 04:49:32

[Solved] Network bridge nat not working after update

Hello, I ran pacman -Syu this evening and the nat bridge for my VM stopped working. The nat was setup via virt-manager, so I’m unsure of the exact details. The iptables command below probably shows how its setup.

Читайте также:  Удаленное администрирование для linux

net2 is the network I was using for my vm without any issues before this update. Now when I try to start the vm/bridge, I get this error:

after some poking around, I found that the iptable_nat module is not installed.

When I try to insert the mod, I get this error:

Any help would be appreciated.

Last edited by rytc (2018-08-08 00:28:10)

#2 2018-08-07 08:03:56

Re: [Solved] Network bridge nat not working after update

Really dumb question: did you reboot your machine after the kernel was updgraded?

#3 2018-08-07 09:42:14

Re: [Solved] Network bridge nat not working after update

same issue here. after rebooting firewalld does not start and rolling back to the previous version did not resolve the issue

i got around it hastily by disabling firewalld and restarting — working perfectly now but not the best solution. (needed urgent access to the VM)

Last edited by stanna (2018-08-07 09:44:41)

#4 2018-08-07 12:29:12

Re: [Solved] Network bridge nat not working after update

They suggest unloading the ‘iptable_nat’ module.
I haven’t yet had time to test these solutions but if you’re feeling adventures give it a try.

EDIT
Never mind I don’t think this is related to the current issue.

Last edited by sebkirller (2018-08-07 13:50:24)

#5 2018-08-07 12:58:12

Re: [Solved] Network bridge nat not working after update

Same problems. iptables is missing the table nat, iptables_nat module is not loaded in the kernel and using

fails as rytc described.

In my case this also disrupts the network/firewall configuration during boot. I need to restart firewalld,service before accessing the network.

#6 2018-08-07 13:13:19

Re: [Solved] Network bridge nat not working after update

Please post the pacman.log for the update that triggered this.

#7 2018-08-07 13:33:37

Re: [Solved] Network bridge nat not working after update

Ok so the problem is with the most current Linux kernel, 4.17.12, which does not include iptable_nat anymore. After I switched over to the LTS kernel 4.14.60-1, the iptable_nat came back and I can once again use the nat table.
So somewhere from around 4.14.60 and 4.17.12 the iptable_nat module got removed.

#8 2018-08-07 13:49:37

Re: [Solved] Network bridge nat not working after update

Here are the logs (there are reasonably anonymous right?):
https://pastebin.com/WXbbnRa0
One significant change that i do notice is that nftables was installed as a new package. I probably need to configure it to work with iptables?

#9 2018-08-07 13:55:45

Re: [Solved] Network bridge nat not working after update

Yes I did reboot a couple of times, here is pacman.log

Edit: yea, nftables was installed for me too

Edit2: I guess I just need to figure out how to setup the nat using nftables?

Last edited by rytc (2018-08-07 14:10:12)

#10 2018-08-07 15:59:05

Re: [Solved] Network bridge nat not working after update

Just to mention that I face a similar issue, and had to fight a few hours to solve this.

Issue is : it completely breaks docker, that fails to start with messages such as

which is a real pain as my arch machine is my work machine : can’t do without docker.

In my case, I first thought a kernel downgrade would solve things, but apparently it was not the solution.

I had to remove firewalld

no replacement found so far

Last edited by squalou (2018-08-07 17:34:16)

#11 2018-08-07 19:49:01

Re: [Solved] Network bridge nat not working after update

Try to use iptables instead of nftables in the default configuration.

Last edited by dapolinario (2018-08-07 21:09:16)

Arch Linux: The power in your hands!

#12 2018-08-07 21:12:12

Re: [Solved] Network bridge nat not working after update

#13 2018-08-08 00:27:56

Re: [Solved] Network bridge nat not working after update

Try to use iptables instead of nftables in the default configuration.

Читайте также:  Драйвер canon lbp 6020 для линукс

Awesome, that looks to have fixed it. Thanks!

#14 2018-08-08 06:53:24

Re: [Solved] Network bridge nat not working after update

Hi, just wanted to post that I got it working by setting FirewallBackend=iptables in /etc/firewalld/firewalld.conf fixed it for me. Thanks!

#15 2018-08-08 09:20:35

Re: [Solved] Network bridge nat not working after update

Try to use iptables instead of nftables in the default configuration.

Actually, this is kind of workaround.
nftables was installed as a dependency to firewalld where iptables is listed too. But installing nftables breaks iptable_nat module load if you have NAT rules in firewalld configuration and this stops firewalld from starting.
I blacklisted

those 4 modules and iptable_nat is able to load, but firewalld can’t start (didn’t change backend yet).
All other modules from iptables and nft can be loaded at the same time except NAT.
This is kind of bug of nft? My logic: if they are both listed as dep to one service, they should work together.

#16 2018-08-12 18:35:59

Re: [Solved] Network bridge nat not working after update

eth0:1’s solution partially worked for me. libvirt can now start its networks , but docker still fails (see Docker service wont start with firewalld) . EDIT: didn’t quite have the blacklist file right; it works now.

Last edited by backerman (2018-08-12 18:39:55)

Источник

Настраиваем NAT в Linux

В интернете куча статей, которые рассказывают, как же настроить страшные iptables, что бы раздать интернет по средствам NAT с одного компьютера на другой. У меня появилась такая потребность, в тот момент, когда на основном ПК стояла kubuntu 10.10, на втором WinXP. А по большому счету, все равно какая вторая ОС. Первый раз, написав эту статью, меня посетило чувство неудовлетворенности. Настроил NAT, но DNS и IP на машинах клиентах пришлось писать вручную. А это не по «одмински»! И вот я переписал статью. И так! Нам понадобятся небольшие знания работы с консолью, базовые понятия, что такое iptables. Все еще интересно? Прошу под спойлер…

Находим там интерфейс смотрящий в локальную сеть(eth0), и настраиваем его на необходимый IP. Я взял 11.1.1.1,получилось вот так:

Я подразумеваю, что интернет у вас уже работает, а значит, интерфейс eth1 уже настроен. Можем теперь поставить на машине-клиенте IP 11.1.1.2, маску 255.0.0.0 и перезапустить сетевые интерфейсы на сервере командой:

Теперь, настроим правила для iptables:

Потом открываем для редактирования файл /etc/sysctl.conf. Добавляем следующие строчки:

Вуаля. Шлюз готов к работе! Проведем тест работы NAT. Перезапускаем сетевые интерфейсы командой:

После этого на той машине, где мы ставили IP и сеть работала, поставим в настройках сетевой карты DNS адреса серверов. Можно провайдера, можно например OpenDNS: 207.68.222.222 и 207.68.220.220. После пытаемся зайти на любой сайт, и желательно не на один. Если все работает — считай пол работы сделано. У iptables есть, на мой взгляд, полезная вещь — после перезапуска системы — правила обнуляются. Что бы этого не произошло, нужно сохранить их:

Осталось дописать команду скрипт загрузки сетевых интерфейсов, которая будет подгружать наши настройки iptables. Выглядит она вот так:

Собственно на этом я прошлый раз и остановился. Но ведь наш сервер — далеко не полноценный роутер. Нужно вручную вписывать IP-шники и DNS. А вдруг DNS поменяется, прийдеть снова настраивать? Поэтому я решил продолжить.

4. Поднимим DNS и DHCP сервер. Есть простой и удобный вариант. Называется пакет dnsmasq. Работает демоном. Устанавливаем:

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

Теперь создаем новый конфиг, открывая его для редактирования:

Нам нужно будет вписать все 2 строчки, все остальное сервер сделает сам. Первая строка разрешает серверу принимать DNS запросы из локальной сети, а вторая описывает диапазон выдаваемых адресов, сетевую маску и время жизни IP адреса соотвественно:

А вот теперь осталось только перезапустить «сеть» и сам демон:

Источник

Оцените статью