Настройка br0без VPN

Настройка br0без VPN

Я пытаюсь заставить весь трафик от гостя (Windows или Linux) проходить через VPN хоста (Linux). Чтобы убедиться, что у гостя нет доступа к интернету за пределами VPN, я устанавливаю соединение на хостовой системе, что создает новый интерфейс tun0. VPN-туннель отлично работает на хосте.

Настройка br0без VPN

Чтобы получить интернет без VPN в гостевой системе, я создаю устройство-мост br0и подключаюсь enp7s0к нему. Таким образом, интернет работает в гостевой системе.

ip link add name br0 type bridge
ip link set br0 up
ip link set enp7s0 master br0

На хосте vnet5устройство было добавлено и подключено к мосту br0. Но в то же время пинг с хоста на удаленный больше не работает.

## On the Host
sudo ip a
# ...
# 14: vnet5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br0 state UNKNOWN group default qlen 1000
# link/ether ab:ab:ab:ab:ab:ab brd ff:ff:ff:ff:ff:ff
# inet6 fe80::fc54:ff:fe92:5aa9/64 scope link
# valid_lft forever preferred_lft forever
ping www.google.com
# ping: www.google.com: Temporary failure in name resolution
ping 8.8.8.8
# From 192.168.1.100 icmp_seq=1 Destination Host Unreachable

Затем я запускаю VM virt-managerи проверяю соединение. У гостя есть интернет:

## On the Guest
ip a
# 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
# ...
# 2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
#     link/ether 52:54:00:92:5a:a9 brd ff:ff:ff:ff:ff:ff
#     inet 192.168.1.221/24 brd 192.168.1.255 scope global dynamic noprefixroute enp1s0
#        valid_lft 67432sec preferred_lft 67432sec
ping www.google.ch
# PING www.google.ch (172.217.168.35) 56(84) bytes of data.
# 64 bytes from zrh04s14-in-f3.1e100.net (172.217.168.35): icmp_seq=1 ttl=117 time=2.47 ms

Полагаю, вместо настройки ip link set enp7s0 master br0я мог бы также создать правила маршрутизации между br0и enp7s0.

С VPN и tun0интерфейсом

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

ip link set enp7s0 nomaster
sudo openvpn my_vpn_tcp.ovpn
# ...
# Initialization Sequence Completed
sudo ip a
# ...
# 3: enp7s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
# link/ether ab:ab:ab:ab:ab:ab brd ff:ff:ff:ff:ff:ff permaddr ab:ab:ab:ab:ab:ab
# inet 192.168.1.100/24 brd 192.168.1.255 scope global dynamic noprefixroute enp7s0
# valid_lft 82702sec preferred_lft 82702sec
# ...
# 10: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 500
# link/none
# inet 10.7.7.5/24 scope global tun0
# valid_lft forever preferred_lft forever
# ...
# 12: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
# link/ether 72:eb:06:e5:1e:5a brd ff:ff:ff:ff:ff:ff
# inet6 fe80::70eb:6ff:fee5:1e5a/64 scope link
# valid_lft forever preferred_lft forever

Без дополнительных действий на хосте используется VPN-подключение, и это нормально.

ping www.google.com
# PING www.google.com (172.217.168.3) 56(84) bytes of data.
# 64 bytes from lala.net (172.217.168.3): icmp_seq=1 ttl=117 time=9.64 ms
# ...
ping www.google.com -I tun0
# PING www.google.com (172.217.168.3) from 10.7.7.5 tun0: 56(84) bytes of data.
# 64 bytes from lala.net (172.217.168.3): icmp_seq=2 ttl=117 time=10.0 ms
# ...
ping www.google.com -I enp7s0
# PING www.google.com (172.217.168.3) from 192.168.1.100 enp7s0: 56(84) bytes of data.
# 64 bytes from lala.net (172.217.168.3): icmp_seq=1 ttl=115 time=4.59 ms
# ...

Но как уже было сказано, я не могу добавить tun0к br0. И из-за этого у гостя также нет интернета.

sudo ip link set tun0 master br0
# RTNETLINK answers: Invalid argument

Я искал решения, но не смог найти ничего подходящего, или мой случай немного отличается и требует большего понимания сетевых технологий, которого у меня нет. Напримерэтот(который не выполнил работу) илиэтот(это не совсем соответствует моему случаю).

решение1

В одном вопросе два вопроса, и они на самом деле не зависят друг от друга. Я все равно отвечу на оба.

Кроме того, noprefixrouteопция адреса намекает, что часть конфигурации сети управляется некоторым дополнительным инструментом (например, NetworkManager) для добавления маршрутов. Этот ответ не будет пытаться иметь дело с интеграцией в сетевые инструменты. Это включает в себя работу с конфигурацией DHCP, которая может переопределить изменения позже, если не будет перенастроена должным образом. Многие настройки исчезают, когда интерфейс отключается или удаляется, и их нужно делать снова, поэтому это лучше всего делать в различных хуках из различных сетевых инструментов, которые отвечают.

Настройка br0без VPN

Интерфейс, установленный как порт моста, теряет свое участие в маршрутизации.

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

  1. передать фрейм конкретному устройствуобработчик приема, если таковые имеются,
  2. передать кадр глобальному или специфичному для устройстваобработчик протокола(например, IPv4, ARP, IPv6).

Для мостового интерфейса,ядро настроило обработчик приема, специфичный для устройства, br_handle_frame(). Эта функция не позволит никакой дополнительной обработки в контексте входящего интерфейса, за исключением кадров STP и LLDP, или если включено «brouting». Поэтому,the обработчики протоколов никогда не выполняютсяв этом случае.

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

Предположим, что шлюз по умолчанию OP — 192.168.1.1/24. Перепишем это для первого случая:

ip link add name br0 up type bridge
ip link set dev enp7s0 master br0

ip address flush dev enp7s0
# previous command will also have removed all associated routes as a side effect
ip address add 192.168.1.100/24 dev br0
# previous command added the LAN route too as a side effect (no noprefixroute here)
ip route add default via 192.168.1.1

Благодаря этому и хост, и виртуальная машина могут получить доступ к Интернету.

Обратите внимание, что для части VM, vnet5это также порт моста и также не участвует в маршрутизации. Хост просто переключает кадры между VM и маршрутизатором (192.168.1.1): маршрутизация не задействована.

С VPN и tun0интерфейсом

OpenVPN использует драйвер TUN/TAP (предоставляемый в Linux модулем ядраtun). Водитель может предоставить:

  • либо интерфейс TAP уровня 2

    Он ведет себя как устройство Ethernet и может быть настроен как порт моста Ethernet: он vnet5создается гипервизором виртуальной машины.

  • или интерфейс TUN уровня 3

    Он не включает информацию о кадре (Ethernet MAC-адрес) и не обрабатывает кадры, а имеет дело только с протоколами на уровне 3 или выше: IPv4 или IPv6. Таким образом, его нельзя установить как порт моста Ethernet. Это OP, tun0созданные OpenVPN в режиме TUN.

OpenVPN также может использовать режим TAP, который может быть подключен через мост, но для этого требуется перенастроить удаленныйсерверсторона тоже и вся сетевая схема: удаленный сервер также будет частью локальной сети 192.168.1.0/24. OP, похоже, не имеет над ней контроля.

Давайте рассмотрим, что можно сделать с интерфейсом TUN OP: это будет сделано на уровне 3: маршрутизация, а не на уровне 2.

Повторное использование предыдущей настройки только для доверенных виртуальных машин

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

Если виртуальной машине можно доверять и ее можно перенастроить, можно продолжить, br0как описано выше, применить любую настройку OpenVPN на основе br0(заменив любую enp7s0ссылку на br0) и сделать это после того, как виртуальная машина будет запущена (с адресом 192.168.1.221) и VPN будет включен:

  • на хосте

    С использованиеммаршрутизация на основе политики/источникачтобы выбрать другой результат маршрута для этого конкретного источника:

    ip rule add from 192.168.1.221 lookup 1000
    ip rule add iif tun0 lookup 1000
    ip route add 192.168.1.0/24 dev br0 table 1000
    ip route add default dev tun0 table 1000
    

    Установить как маршрутизатор:

    sysctl -w net.ipv4.ip_forward=1
    

И в случае, если ни одно подобное правило NAT еще не обрабатывает этот случай:

  iptables -t nat -A POSTROUTING -s 192.168.1.221 -o tun0 -j MASQUERADE
  • на (Linux) виртуальной машине используйте хост в качестве шлюза вместо маршрутизатора хоста

    ip route flush to default
    ip route add default via 192.168.1.100
    

Рекомендуется для ненадежных виртуальных машин: не устанавливайте основной интерфейс хоста в качестве порта моста.

Это упрощает контроль трафика виртуальной машины, tun0поскольку она не будет видеть те части сети, в которые ей не следует вмешиваться.

  • изменить настройки виртуальной машины для использования ее собственной IP-сети

    Пример: 192.168.100.0/24 и статический IP 192.168.100.2/24 (вместо DHCP сети хоста), со шлюзом по умолчанию 192.168.100.1. На виртуальной машине Linux:

    ip address add 192.168.100.2/24 dev enp1s0
    ip route add default via 192.168.100.1
    
  • На хосте начните с начальной конфигурации (без мостового соединения enp7s0)

    Можно было бы даже обойтись нулевым мостом ниже (т.е. напрямую, ip address add 192.168.100.1/24 dev vnet5не vnet5устанавливая порт моста), ноlibvirtможет сделать это более трудным.

    Просто выделите мост для виртуальных машин (здесь используется адрес 192.168.100.1/24, хотя обычноlibvirtпредоставляет мост по умолчанию virbr0с 192.168.122.1/24):

    ip link add name br0 up type bridge
    ip address add 192.168.100.1/24 dev br0
    ip link set dev vnet5 master br0
    

    А также используйтемаршрутизация политикидля изменения поведения трафика, связанного с VM(s) для двух задействованных интерфейсов: br0и tun0. Как обычно, это включает в себя несколько дублирований и изменений существующих маршрутов в альтернативной таблице маршрутизации. Здесь tun0предполагается обслуживание только хоста и его VM(s). Конечная цель: все, что приходит со стороны VM, направляется на сторону tun, все, что приходит со стороны TUN, направляется на сторону VM, игнорируя любую ненужную сторону.

    ip rule add iif br0 lookup 2000
    ip rule add iif tun0 lookup 2000
    ip route add 192.168.100.0/24 dev br0 table 2000
    ip route add default dev tun0 table 2000 # layer 3 interfaces don't need a gateway
    

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

    Установить как маршрутизатор:

    sysctl -w net.ipv4.ip_forward=1
    

    Затем завершите с NAT, поскольку удаленный сервер OpenVPN не знает о 192.168.100.0/24:

    iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -o tun0 -j MASQUERADE
    

Если виртуальная машина по-прежнему должна иметь доступ к локальной сети 192.168.1.0/24:

  • обновите таблицу 2000 еще раз, чтобы учесть это

    Дублируем маршрут локальной сети из основной таблицы в таблицу 2000:

    ip route add 192.168.1.0/24 dev enp7s0 table 2000
    
  • и снова добавьте адекватное правило МАСКАРАДА

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

    iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -o enp7s0 -j MASQUERADE
    

    (Можно выполнить факторизацию некоторых правил iptables).

Связанный контент