Как ограничить (открыть) подключение VPN-клиента для одного пользователя системы?

Вы можете немедленно активировать последнее фоновое задание, набрав:

fg

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

jobs

Затем вы можете вывести любое из заданий на передний план, используя индекс в первом столбце со знаком процента:

fg %

например:

вывод команды jobs показывает номер задания процесса

[1]+  Stopped                 ssh username@some_host
[2]   Stopped                 ssh username@another_host

Выведите любое из заданий на передний план, используя индекс:

fg%2
7
02.05.2019, 12:04
3 ответа

Частичный ответ (требует более подробной информации в вопросе):

Один из способов отличить «обычные» интернет-соединения от интернет-соединений NordVPN — создать сетевое пространство имен, запустить nordvpnв этом пространстве имен, а затем запустить все процессы, которые должны использовать эту VPN в этом пространстве имен.

Детали зависят от того, как вы хотите их использовать.:

  • Если у вас есть один пользователь, который всегда будет запускать NordVPN, вы можете создать это сетевое пространство имен при входе в систему, а также запускать все процессы для этого пользователя в этом сетевом пространстве имен. Как следствие, у этого пользователя никогда не будет «нормального» интернет-соединения.

  • Если у вас есть несколько пользователей, которые хотят использовать как «обычные» интернет-соединения, так и соединения NordVPN, вы можете написать сценарий, который создает эти пространства имен, запускает в нем NordVPN и предоставляет пользователю терминал, где он/она может запускать дополнительные приложения или, возможно, даже уже запускать приложения, такие как веб-браузер, в этом пространстве имен. Затем этот скрипт заменит команду connect.

Вероятно, существует множество других способов сделать это в зависимости от ваших требований. Поэтому, пожалуйста, отредактируйте вопрос и опишите свои требования/обстоятельства.

Для создания пространства имен необходимы права root. Это означает, что вам понадобится сценарий с setuid -root (, что может быть проблемой безопасности, если в сценарии есть ошибки ), вам может потребоваться предоставить пользователям sudoдоступ и т. д.

1
27.01.2020, 20:18

Как использовать vpn отдельно для разных пользователей:

Ситуация, когда пользователи используют разное пространство пользователя:

По умолчанию пользовательское пространство разделяет сеть(netns)и, таким образом, nordvpn connectне повлияет на другое пользовательское пространство, но это не стандартное функционирование пользовательской системы под Linux, вам нужно будет настроить другое пользовательское пространство. чтобы разделить сеть каждого пользователя; также сетевой интерфейс может существовать только в одном пространстве имен мостов или интерфейсе veth, а затем использоваться для туннелирования трафика между пользовательскими пространствами.

Ситуация, когда пользователи используют одно и то же пользовательское пространство:

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

VPN-подключение выполняется с новым виртуальным интерфейсом (tun или tap )и связано с основным сетевым интерфейсом (wifi или eth0 )... когда vpn-соединение инициализируется tun Интерфейс /tap создается, затем подключается к VPN-серверу и создает туннель, но это не означает, что все соединения туннелируются через интерфейс VPN, чтобы иметь классическое работающее VPN-соединение, сначала соединение инициализируется с виртуальным интерфейсом, затем добавлен маршрут , чтобы заставить все соединения проходить через интерфейс VPN, это называется маршрутизацией .

Зная эту информацию, решением было бы инициировать VPN-подключение без маршрутизации , а затем настроить маршрутизацию отдельно для каждого пользователя.для пользователей, которым не требуется VPN, никаких изменений не требуется; Необходимо добавить специальную маршрутизацию с маршрутом iptables/ip -для пользователей, которым необходимо использовать vpn. Другими словами, интерфейс VPN будет настроен, но он не будет интерфейсом по умолчанию (, поскольку правила маршрутизации vpn по умолчанию не будут применяться )

.

Ситуация VPN по умолчанию :[Команда подключения] > [Создать -Tun/Tap] > [Подключить Tun/Tap] > [Маршрут, чтобы сделать Tun/Tap интерфейсом по умолчанию]

VPN без маршрута :[Команда подключения] > [Создать -Tun/Tap] > [Подключить Tun/Tap]

VPN с пользовательским маршрутом :[Команда подключения] > [Создать -Tun/Tap] > [Подключить Tun/Tap] , затем добавить вручную или автоматически [Пользовательские маршруты]

Подключитесь к VPN без использования шага «маршрут», затем нажмите/настройте собственный маршрут. Это можно сделать с помощью маршрута iptables/ip -или с помощью файла настройки VPN conf.

Как настроить openvpn без отправки шлюза/маршрута по умолчанию:

Отредактируйте файл конфигурации vpn и добавьте директиву route-nopull. (если используется команда nordvpnдоступный файл конфигурации openvpn, вы можете редактировать их в соответствии с вашими потребностями, в противном случае вам нужно будет использовать openvpn или сетевой менеджер для подключения к вашему vpn)

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

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

4
27.01.2020, 20:18

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

Я бы также сказал, что для решений, специфичных для службы NordVPN, вы также можете попробовать обратиться к ним за поддержкой, потому что команда nordvpn не обязательно использует OpenVPN, она может использовать IPSec или даже PPTP/L2TP.

Однако для универсального решения OpenVPN, которое, по вашим словам, полностью совместимо с вашим сервисом NordVPN, я думаю, что лучшим подходом может быть использование политик маршрутизации, возможно, с несколькими вариантами.

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

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

Но необходимые инструменты для настройки обычно не устанавливаются во многих дистрибутивах Linux, поскольку рассматриваемая проблема не кажется той, которую можно решить, просто используя команды unshareили ip netns exec, потому что они позволяют видимость нового пространства имен только для тех процессов, которые выполняются с этого момента и в рамках этого сеанса команд, а не для всего существующего до -сеанса пользователя.

Кроме того, даже при установке необходимых инструментов для правильной настройки системы потребуется тщательная настройка, чтобы разделить каждого пользователя в своем собственном сетевом пространстве имен, используя одно и то же физическое сетевое устройство, а также разделяя сокеты домена unix -и службы, работающие для локального хоста. Настройка мостов (или маквланов ), подсетей, назначение адресов, возможно NAT и прочие сложности. Это, наверное, выполнимо,но скорее всего не просто сделать это прям и я думаю гораздо сложнее исходной задачи.


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

Он будет иметь следующие основные характеристики:

  • требуется (довольно )стандартная версия OpenVPN (, т. е. не сильно настроенная провайдером)
  • требуется iptables сопутствующее правило для маркировки соответствующего трафика на основе номера UID пользователя
  • может потребоваться тщательная интеграция, если используется -существующий брандмауэр или правила маршрутизации
  • Однако
  • не может идентифицировать процессы, запущенные пользователем через sudo(, потому что они запускаются с UID 0 )и командами setuid или в любом случае приложения запускаются от имени пользователя root. Это в основном не относится к типичному сценарию рабочего стола, но вполне может случиться и не будет обрабатываться должным образом (, т. е. часть трафика не пойдет в vpn )
  • .

Со всем можно справиться с помощью двух вспомогательных скриптов. Один будет использоваться для OpenVPN, другой будет использоваться для запуска самого openvpn.

Стандартный OpenVPN использует команду ipдля настройки устройства tun/tap и установки маршрутов, продвигаемых провайдером VPN. Проблема в том, что по умолчанию команда ipработает с основными таблицами маршрутизации, которые используются всей системой, включая всех ее пользователей.

Однако OpenVPN позволяет указать другую команду, которая будет использоваться для настроек, которые необходимо применить, поэтому мы можем предоставить оболочку над ip , которая просто работает с другими таблицами маршрутизации.

Такой (скрипт-обертка с предварительным названиемmyip.sh)может быть похож на:

#!/bin/bash -

my_session="$(ps -p $$ -o sid --no-header)" || exit 1
real_uid="$(ps -p $$ -o ouid --no-header || ps -p $my_session -o ruid --no-header || echo 0)"

real_ip_cmd=/sbin/ip

if [ $real_uid -ne 0 ] && [[ "$1" = ro* ]] ; then
    ! [ $2 ] && exec $real_ip_cmd "$1" list table $real_uid
    [[ "$2" =~ ^([adcfls]|rep).*$ ]] && exec $real_ip_cmd "$1" "$2" table $real_uid "${@:3}"
fi
exec $real_ip_cmd "$@"

Первые две строки служат для попытки получить настоящий UID, на котором работает OpenVPN. Мы используем этот UID в качестве идентификатора таблицы. Таким образом, каждый пользователь будет иметь свою собственную таблицу маршрутизации, когда он / она запускает vpn.

Блок if-then-fiперехватывает вызовы для routeнастроек (, имитируя способность команды ipпринимать сокращенные, но недвусмысленные ключевые слова ), и просто добавляет перед всеми такими командами, передаваемыми openvpn, параметр table, несущий идентификатор, равный реальному идентификатору пользователя. Все остальные ipкоманды (, т. е. не route), проходят без изменений.

Другой скрипт является оберткой для команды openvpn, настраивая все так, чтобы трафик, генерируемый пользователем, направлялся в соответствии с его отдельной таблицей. Суть этого скрипта-оболочки может быть включена в собственный файл конфигурации провайдера, что обеспечивает лучшую бесшовную интеграцию. Это поможет в случае, если кто-то захочет установить vpn non -в интерактивном режиме (, например. во время загрузки ). Однако при использовании этого скрипта-оболочки не требуется возиться с файлом конфигурации, и именно поэтому я решил представить эту версию.

Таким образом, такой отдельный скрипт-оболочка может быть таким:

#!/bin/bash

my_session="$(ps -p $$ -o sid --no-header)" || exit 1
real_uid="$(ps -p $$ -o ouid --no-header || ps -p $my_session -o ruid --no-header || echo 0)"
[ $real_uid -eq 0 ] && { echo "will not run for UID 0" >&2 ; exit 1; }

remove_tagging() {
        iptables -t mangle -D OUTPUT -m owner --uid $real_uid -j MARK --set-mark $real_uid
        ip rule del fwmark $real_uid
        ip route flush table $real_uid
} 2>/dev/null

trap 'remove_tagging' EXIT

source <(ip route | sed "s/^/ip route add table ${real_uid} /")

(
ip -o monitor | grep -qm 1 '^[0-9]\+: tun[0-9]\+[[:blank:]]\+inet '
ip rule add fwmark $real_uid lookup $real_uid
iptables -t mangle -A OUTPUT -m owner --uid $real_uid -j MARK --set-mark $real_uid
) &

openvpn --iproute myip.sh --config tunnel-config.ovpn

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

Затем у нас есть функция, которая будет запускаться при ВЫХОДЕ из скрипта. Функция удаляет настройки, установленные следующей оболочкой sub -.

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

Затем мы запускаем оболочку sub -, которая ожидает на устройстве tunXнастройки OpenVPN, а затем добавляет правила маршрутизации и сопутствующее правило iptables, которое с этого момента помечает трафик, генерируемый пользователем..Мы запускаем это в фоновом режиме, потому что нам нужно запустить OpenVPN на переднем плане на случай, если потребуется запросить имя пользователя и пароль.

Команда source, вспомогательная оболочка -(без конвейера ip -o monitor)и функция remove_tagging— это части, которые могут быть указаны в файле конфигурации vpn как (соответственно. Опции )up, route-upи route-pre-down. Это позволит полностью избавиться от этого скрипта-оболочки.

Наконец, мы запускаем настоящую команду openvpn , указав ей использовать наш собственный скрипт myip.shв качестве команды для настройки сети.


Возможным небольшим вариантом может быть использование более поздних версий пакета iproute2 (, который предоставляет команду ip), которые имеют параметр uidrangeдля использования вместо fwmarkв правилах маршрутизации.

Такой вариант, таким образом, исключит команды iptablesи заменит команду ip rule fwmark..командой ip rule uidrange ${real_uid}-${real_uid} lookup $real_uid(. То же самое касается соответствующей команды ip rule del..).


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

  • уникальный GID должен существовать для пользователя, как это обычно бывает во многих дистрибутивах Linux (, включая Ubuntu)
  • sudoзапуск с дополнительными параметрами(-g <user> -u rootили эквивалентной конфигурацией вsudoers)для сохранения исходного номера GID

Однако он по-прежнему не сможет идентифицировать процессы с UID 0, запущенные пользователем вне таких sudo.


Чтобы действительно решить проблему «процессов с UID 0», можно использовать cgroups, но, естественно, к этому предъявляются дополнительные требования:

  • iptables сопутствующее правило для маркировки соответствующего трафика с помощью специального модуля «cgroup» iptables, который еще не был доступен, например, в.Убунту 14.04
  • может конфликтовать с предварительно -существующими настройками cgroup

Используя контрольные группы, установка идентификатора сетевого -класса -может быть выполнена с помощью простого сценария, запускаемогоpam_exec.so

#!/bin/bash -e

uid=$(id -ru "${PAM_USER}")
mkdir -p /sys/fs/cgroup/net_cls/user/${uid} && echo $uid > /sys/fs/cgroup/net_cls/user/${uid}/net_cls.classid
echo $$ > /sys/fs/cgroup/net_cls/user/${uid}/cgroup.procs

, а затем добавьте следующую строку в нужные файлы конфигурации в разделе/etc/pam.d:

session optional    pam_exec.so /root/set-net-cls-id.sh

Приведенная выше строка может быть помещена в традиционный файл /etc/pam.d/common-session , чтобы охватить все сеансы, созданные с помощью любой интерактивной службы, такой как ssh, входы в консоль, среды рабочего стола и т. д.

При такой настройке команда iptables , которая будет использоваться в скрипте оболочки, будет:

iptables -t mangle -A OUTPUT -m cgroup --cgroup $real_uid -j MARK --set-mark $real_uid

и соответствующую команду удаления с -Dвместо -A.

Возможным вариантом решения cgroup может быть его интеграция в systemd, чтобы можно было использовать способность systemdобрабатывать cgroups напрямую, без использования pam_exec.

Обратите внимание, однако, что эта настройка cgroup не может хорошо работать с Ubuntu 14.04, потому что эта версия использовалась для установки cgroups для каждого сеанса пользователя и, таким образом, перезаписывала настройку, установленную этим решением. Вам скорее потребуется установить значение classid cgroup, созданной на -fly, для каждого сеанса, имя которого можно легко получить путем разбора вывода cat /proc/self/cgroup.

1
27.01.2020, 20:18

Теги

Похожие вопросы