NetNS: виртуальные сетевые среды Linux

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

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

Network Namespaces представляет собой мощный механизм, позволяющий создавать изолированные виртуальные сетевые окружения внутри одной физической машины. Каждое из этих окружений обладает своими собственными ресурсами сети, включая интерфейсы, адреса IP и таблицы маршрутизации. Это позволяет создавать изолированные сетевые пространства, которые независимы друг от друга и функционируют параллельно.

Изоляция сетевых окружений имеет множество практических применений. Она позволяет разработчикам и администраторам систем эффективно управлять и разворачивать приложения в изолированных средах, гарантируя их независимость и безопасность. Например, веб-серверы, базы данных и контейнеры могут функционировать в отдельных сетевых пространствах, не влияя друг на друга и не создавая конфликтов в использовании ресурсов.

Network Namespaces также обеспечивает гибкость и управляемость сети внутри каждого изолированного окружения. Можно настраивать маршрутизацию, фильтрацию пакетов и другие параметры, чтобы оптимизировать работу внутри каждого окружения.

Однако, вместе с преимуществами существуют и ограничения использования Network Namespaces. Это включает сложность конфигурации, потребность в понимании сетевых принципов и возможные проблемы совместимости с некоторыми приложениями и утилитами.

В этой статье мы рассмотрим основы Network Namespaces и простой пример их использования.

Основные компоненты NetNS

Network Namespaces (netns) в операционной системе Linux строятся на основе нескольких ключевых компонентов и обладают специфической архитектурой. Давайте рассмотрим основные компоненты более подробно:

  1. Namespace
    Network Namespace отвечает за изоляцию сетевых ресурсов. Каждая Network Namespace имеет свой набор сетевых интерфейсов, IP-адресов, таблиц маршрутизации и других сетевых компонентов. Процессы и приложения могут быть привязаны к конкретной Network Namespace, чтобы функционировать в изолированной сетевой среде.
  2. Интерфейсы
    Veth-пары: Виртуальные сетевые интерфейсы, представленные в виде пары, связанные между собой. Один интерфейс из пары может находится в основной Network Namespace, а другой - в изолированной Network Namespace. Veth-пары используются для связи между Network Namespaces или для подключения приложений к определенным сетевым окружениям.
    Bridge-интерфейсы: Мосты (bridges) позволяют объединять несколько сетевых интерфейсов вместе, чтобы они могли обмениваться данными. В каждой Network Namespace может быть свой собственный bridge-интерфейс, который обеспечивает внутреннюю связь между интерфейсами внутри Namespace.
  3. IP-адресация
    Каждая Network Namespace имеет свой собственный набор IP-адресов, который может быть назначен сетевым интерфейсам внутри Namespace. Это позволяет процессам и приложениям в разных Namespaces иметь собственные уникальные IP-адреса и обмениваться данными только в пределах своей изолированной сети.
  4. Маршрутизация
    Каждая Network Namespace имеет свои собственные таблицы маршрутизации, которые определяют, какие IP-адреса должны быть доставлены через какие сетевые интерфейсы. Это позволяет контролировать поток трафика внутри каждой изолированной сети и оптимизировать маршрутизацию внутри Network Namespace.

Создание и настройка NetNS

Процесс создания и удаления Network Namespaces требует привилегий суперпользователя или наличия соответствующих разрешений. Это позволяет управлять сетевыми ресурсами и обеспечивать изоляцию между Namespaces.

Создание Network Namespace

Для создания нового Network Namespace можно использовать команду ip netns add <namespace_name>. Здесь <namespace_name> - это имя, которое вы дадите неймспейсу.

# ip netns add vrouter-a
# ip netns add vrouter-b

Посмотреть список созданных неймспейсов можно командой ip netns ls:

# ip netns ls
vrouter-a
vrouter-b

Настройка интерфейса в NetNS

Внутри нового Namespace не будет существовать никаких интерфейсов по умолчанию, кроме петлевого lo. Вы можете прокинуть реальные интерфейсы хоста или добавить интерфейсы с помощью виртуальной пары интерфейсов (Veth pair) или моста (Bridge), а затем настроить их параметры с помощью инструментов, таких как ip или ifconfig.

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

# ip link set dev enp7s0 netns vrouter-a

Вариант 2. Создание виртуального интерфейса veth

Виртуальные сетевые интерфейсы всегда создаются как взаимосвязанная пара интерфейсов. Они могут действовать как туннели между сетевыми пространствами имен для создания моста к физическому сетевому устройству в другом пространстве имен, но также могут использоваться как автономные сетевые устройства. Для создания veth используйте команду:

# ip link add name veth0a type veth peer name veth0b

Пакеты отправленные в интерфейс veth0a немедленно будут получены интерфейсом veth0b.

Используйте созданную пару виртуальных интерфейсов для создания сетевого соединения между двумя неймспейсами. Для этого добавьте виртуальные интерфейсы в неймспейсы:

# ip link set dev veth0a netns vrouter-a
# ip link set dev veth0b netns vrouter-b

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

Назначение IP-адресов

Вы можете назначить IP-адреса внутренним интерфейсам внутри Network Namespace, используя команду ip addr add <ip_address>/<subnet> dev <interface>. Здесь <ip_address> - это IP-адрес, <subnet> - подсеть, а <interface> - интерфейс, к которому вы хотите привязать IP-адрес.

# ip netns exec vrouter-a ip addr add 192.168.77.1/30 dev veth0a
# ip netns exec vrouter-b ip addr add 192.168.77.2/30 dev veth0b

По умолчанию veth интерфейсы выключены, поэтому их нужно включить.

# ip netns exec vrouter-a ip link set veth0a up
# ip netns exec vrouter-b ip link set veth0b up

Проверьте состояние интерфейсов в неймспейсах.

# ip netns exec vrouter-a ip -br a
lo               DOWN           
veth0a@if5       UP             192.168.77.1/24 fe80::cc46:24ff:fe55:6e84/64
# ip netns exec vrouter-b ip -br a
lo               DOWN           
veth0b@if6       UP             192.168.77.2/24 fe80::c0fe:d8ff:fef5:911d/64 

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

# ip netns exec vrouter-b ping -c 3 192.168.77.1
PING 192.168.77.1 (192.168.77.1) 56(84) bytes of data.
64 bytes from 192.168.77.1: icmp_seq=1 ttl=64 time=0.057 ms
64 bytes from 192.168.77.1: icmp_seq=2 ttl=64 time=0.056 ms
64 bytes from 192.168.77.1: icmp_seq=3 ttl=64 time=0.057 ms

--- 192.168.77.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2036ms
rtt min/avg/max/mdev = 0.056/0.056/0.057/0.000 ms

Настройка маршрутизации

Чтобы определить какие IP-адреса через какие интерфейсы доступны внутри Namespace, необходимо настроить таблицы маршрутизации. Используйте команду ip route add <destination_network> via <gateway> dev <interface> для добавления правил маршрутизации.

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

host (1)------(172.16.0.0/24)-------(2) vrouter-a (1)-----(192.168.77.0/24)-----(2) vrouter-b

В этой схеме host соединен с vrouter-a виртуальным интерфейсом veth, один конец которого проброшен в неймспейс, а другой оставлен в глобальном неймспейсе хоста.

# ip link add name veth1 type veth peer name veth1a
# ip netns exec vrouter-a ip addr add 172.16.0.2/24 dev veth1a
# ip netns exec vrouter-a ip link set veth1a up
# ip addr add 172.16.0.1/24 dev veth1
# ip link set veth1 up

Vrouter-a является транзитным, поэтому на нем необходимо разрешить прохождение транзитного трафика.

# ip netns exec vrouter-a sysctl net.ipv4.ip_forward=1

Добавьте маршрут до сети 172.16.0.0/24 в неймспейс vrouter-b.

# ip netns exec vrouter-b ip route add 172.16.0.0/24 via 192.168.77.1

На хосте добавьте маршрут до сети 192.168.77.0.

# ip route add 192.168.77.0/24 via 172.16.0.2

Теперь можно протестировать хождение трафика c хоста до неймспеса vrouter-b утилитой ping.

# ping -c 3 192.168.77.2
PING 192.168.77.2 (192.168.77.2) 56(84) bytes of data.
64 bytes from 192.168.77.2: icmp_seq=1 ttl=63 time=0.071 ms
64 bytes from 192.168.77.2: icmp_seq=2 ttl=63 time=0.081 ms
64 bytes from 192.168.77.2: icmp_seq=3 ttl=63 time=0.081 ms

--- 192.168.77.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2035ms
rtt min/avg/max/mdev = 0.071/0.077/0.081/0.004 ms

Удаление Network Namespace

Для удаления Network Namespace используйте команду ip netns del <namespace_name> . Здесь <namespace_name> - это имя Namespace, который вы хотите удалить.

# ip netns del vrouter-a 
# ip netns del vrouter-b

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *