VPN — это замечательная штука, которая повышает твою анонимность и безопасность. Но постоянно сидеть под VPN может быть неудобно: хочешь, например, зайти в интернет-банк со своего реального IP, но на закачке стоит пара новых эпизодов любимого сериала. В Linux можно решить эту проблему при помощи механизма network namespaces и туннелировать трафик отдельных приложений. Сейчас я покажу, как это сделать.
 

Немного о Linux namespaces

В Linux реализована функция пространства имен (namespace), которая отвечает за изоляцию разных ресурсов системы. Она вовсю применяется в проектах контейнеризации, например таких как Docker. Существует несколько типов пространств имен: pid, net, mnt, user, uts, ipc.

Нас интересует пространство имен для сетей (netns), которое изолирует сетевые ресурсы. Для каждого netns можно назначать: свои интерфейсы, наборы IP-адресов и портов (сокеты), таблицы маршрутизации, правила файрвола и так далее. Есть возможность перемещать интерфейсы из одного netns в другой. Физический интерфейс (например, eth0) может находиться одновременно только в одном netns.

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

 

Введение в курс

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

 

База netns

За контроль netns отвечает утилита ip из пакета iproute2. Для соединения netns между собой можно использовать пару виртуальных интерфейсов veth. Рассмотрим пример создания нескольких netns и их соединения. Для этого выполним

$ sudo ip netns add ns_1
$ sudo ip netns add ns_2

Наличие этих netns смотри командой ip netns list или просто ip netns, так как list — действие по умолчанию. Добавим виртуальную пару при помощи команды

$ sudo ip link add dev virt01 type veth peer name virt02
Управление netns и veth с помощью ip
Управление netns и veth с помощью ip

Интерфейсы добавились, теперь переместим virt01 в netns ns_1, а virt02 — в ns_2.

$ sudo ip link set virt01 netns ns_1
$ sudo ip link set virt02 netns ns_2

Если не появилось сообщений об ошибках, значит, все прошло успешно. Для выполнения команды внутри netns используется команда

$ sudo ip netns exec <имя netns> <команда для выполнения>

Например, посмотреть список доступных интерфейсов внутри netns ns_1 можно при помощи

$ sudo ip netns exec ns_1 ip link

Почитав man, узнаем, что выполнять команды ip внутри netns можно при помощи $ sudo ip -n <имя netns>, а значит, $ sudo ip netns exec ns_1 ip link заменяем на $ sudo ip -n ns_1 link.

Удостоверимся, что интерфейсы перенеслись в нужные netns
Удостоверимся, что интерфейсы перенеслись в нужные netns

По умолчанию интерфейсы, созданные или перемещенные в netns, пребывают в отключенном состоянии, даже lo.

Добавим нашим интерфейсам virt01 и virt02 по IP-адресу и переведем их в состояние UP. Для этого воспользуемся «прокачанной» командой, подсмотренной в man:

$ sudo ip -n ns_1 addr add 10.0.0.1/24 dev virt01
$ sudo ip -n ns_2 addr add 10.0.0.2/24 dev virt02
$ sudo ip -n ns_1 link set dev virt01 up
$ sudo ip -n ns_2 link set dev virt02 up
$ sudo ip -n ns_1 addr show
$ sudo ip -n ns_2 addr show
Соединяем вместе нашу виртуальную пару
Соединяем вместе нашу виртуальную пару

Как я уже говорил, у каждой netns своя таблица маршрутизации, проверим это.

Действительно, таблицы отличаются
Действительно, таблицы отличаются

Для проверки связи между ns_1 и ns_2 воспользуемся командой ping.

$ sudo ip netns exec ns_1 ping -c 4 10.0.0.2
Соединение установлено успешно
Соединение установлено успешно

Как ты помнишь, адрес 10.0.0.2 принадлежит интерфейсу virt02, который находится в ns_2. Похожим способом netns соединяют с физическим eth0.

 

Выполнение команд и запуск процессов внутри netns

Как ты помнишь, команды внутри netns выполняются при помощи

$ sudo ip netns exec <имя netns> <команда>

Чтобы не писать все это каждый раз, запустим bash!

$ sudo ip netns exec ns_1 bash

После этого все команды будут исполняться внутри netns — заодно и проверим ситуацию с файрволом. Чтобы вернуться, пиши exit или CTRL + D.

Список правил пуст
Список правил пуст

У меня всегда присутствуют правила в файрволе, так что это точно отдельный набор. 😉

Перейдем к примеру с возвращением физического интерфейса в initial netns. Для этого проверим текущее расположение enp0s3 и перенесем его в ns_2.

$ sudo ip link set dev enp0s3 netns ns_2
Как видно, enp0s3 больше нет в init netns
Как видно, enp0s3 больше нет в init netns

Поднимем его в netns ns_2 и запустим WireShark от имени пользователя (eakj) там же.

$ sudo ip -n ns_2 link set dev enp0s3 up
$ sudo ip -n ns_2 link
$ sudo ip netns exec ns_2 sudo -u eakj wireshark 2>/dev/null &
WireShark запущен в netns ns_2
WireShark запущен в netns ns_2

Теперь удалим netns ns_2 и посмотрим, вернется ли enp0s3 в initial netns:

$ sudo ip netns del ns_2
enp0s3 не освободится, пока процесс WireShark не будет завершен, даже несмотря на удаление ns_2
enp0s3 не освободится, пока процесс WireShark не будет завершен, даже несмотря на удаление ns_2

Закроем WireShark и посмотрим, даст ли это результат.

После завершения процесса enp0s3 вернулся в initial netns
После завершения процесса enp0s3 вернулся в initial netns

Этого должно быть достаточно, чтобы понять, как работают netns и как ими управлять. Перейдем к OpenVPN.

 

Разбираемся с OpenVPN

Не так давно я писал о том, как поднять собственный OpenVPN на арендованном сервере. Если ты следовал гайду, то у тебя уже настроен клиентский файл, который можно использовать. Конфигурационные файлы других VPN-провайдеров тоже подойдут, так как никаких изменений на сервере делать не придется.

 

Изменение клиентского конфига

Познакомимся с новыми директивами OpenVPN.

  1. ifconfig-noexec — запрещает клиенту автоматическое выполнение ifconfig для добавления IP-адреса интерфейсу tun. Вместо этого передаст нужные параметры в качестве переменных окружения.
  2. route-noexec — та же ситуация, что и с ifconfig-noexec, только вместо IP он не будет добавлять маршруты. Необходимые параметры передадутся.
  3. route-up /полный/путь/к/скрипту отправит на скрипт переменной окружения $script_type строку route-up.
  4. up /полный/путь/к/скрипту — то же, что и route-up, только передаст строку up после поднятия интерфейса tun/tap. Выполняется до директивы user, которая должна понизить наши привилегии.
  5. down /полный/путь/к/скрипту — то же, что и route-up, только строку down, после удаления интерфейса tun/tap. Выполняется после директивы user!
  6. script-security 2 позволит исполнять кастомные скрипты.

Полный список передаваемых переменных окружения можно посмотреть в man openvpn, секция Environmental Variables.

Надеюсь, ты обратил внимание на жирный шрифт. Директива up добавит наш netns, down — удалит. Для добавления и удаления netns нужны права рута. Это не проблема в случае с up, поскольку она исполняется перед user, а та, в свою очередь, понижает права до nobody. А вот с down явно будут проблемы, так как пользователь nobody не сможет удалить netns. Поэтому первым делом в клиентском конфиге закомментируй или удали строчки

user nobody
group nobody

и добавь новые директивы. Пример немного измененного скрипта из прошлой статьи:

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

Вариант 1. Оформи подписку на «Хакер», чтобы читать все материалы на сайте

Подписка позволит тебе в течение указанного срока читать ВСЕ платные материалы сайта. Мы принимаем оплату банковскими картами, электронными деньгами и переводами со счетов мобильных операторов. Подробнее о подписке

Вариант 2. Купи один материал

Заинтересовала информация, но нет возможности оплатить подписку? Тогда этот вариант для тебя! Обрати внимание: этот способ покупки доступен только для материалов, опубликованных более двух месяцев назад.


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

  1. inkognito.o

    16.01.2018 at 05:49

    большое спасибо за статью. Было очень интересно!

Оставить мнение

Check Also

Целенаправленная социальная инженерия. Нестандартные техники введения в заблуждение

В предыдущей статье мы разобрали массовые атаки. Но их применимость ограничена: пентестер …