Я столкнулся с очень странной ситуацией с Hypriot OS.
Конфигурация сети:
+--------+ +------+-----+------+ +---------------------+ +-------+
+ laptop +--+ eth0 + br0 + eth1 +--+ router @ 10.98.76.1 +--+ tower +
+--------+ +------+-----+------+ +---------------------+ +-------+
|
+-------+ +----------------------+
+ wlan0 +-----+ router @ 192.168.0.1 +
+-------+ +----------------------+
Я пытаюсь заставить Raspberry Pi действовать как посредник между моим ноутбуком и роутером. У меня eth0 и eth1 подключены к мосту (br0), который создается при загрузке. eth0, eth1 и br0 находятся в сетевом пространстве имен, называемом «foo». wlan0 является основным претендентом в пространстве имен по умолчанию - docker на данный момент отключен, тогда как он обычно создает мост docker0 в пространстве имен по умолчанию.
Я нажимаю eth0 и eth1 в другое сетевое пространство имен, чтобы убедиться, что wlan0 может запускать ssh-клиент, и только wlan0 запускает упомянутый клиент - я не хочу, чтобы проводные интерфейсы использовали клиент ssh ни при каких условиях.
Я использую 'device-init.yaml' (часть device-init), чтобы запустить сценарий конфигурации сети.
Мой сценарий настройки сети выглядит следующим образом:
# Create a new namespace for the ethernet devices
ip netns add foo
# Create the bridge in the foo namespace and bring it up
ip netns exec foo ip link add name br0 type bridge
ip netns exec foo ip link set dev br0 up
# Bring down the ethernet devices
ip link set dev eth0 down
ip link set dev eth1 down
# Move the eth0/eth1 devices to the foo namespace
ip link set dev eth0 netns foo
ip link set dev eth1 netns foo
# Add the eth0/eth1 devices to the bridge
ip netns exec foo ip link set dev eth0 master br0
ip netns exec foo ip link set dev eth1 master br0
# Enable promiscuous mode
ip netns exec foo ip link set eth0 promisc on
ip netns exec foo ip link set eth1 promisc on
# Bring up the adapters within the foo namespace
ip netns exec foo ip link set dev lo up
ip netns exec foo ip link set dev eth0 up
ip netns exec foo ip link set dev eth1 up
# List the devices for posterity
netnsout=$(ip netns exec foo ip a)
echo "- Done running ip commands. Result: $netnsout"
После завершения загрузки я могу без проблем пинговать свой ноутбук с моей башни и мою башню с ноутбука. Я также могу без проблем получить IP-адрес на своем ноутбуке - мост работает так, как должен, позволяя трафику проходить через него.
Проблема: Я не могу запустить dhclient на eth1, eth0 или br0 и связаться с любым объектом в сети с Raspberry Pi.
Код, который я запускаю для получения IP-адреса на eth1:
$ ip netns exec foo dhclient eth1
Результаты после запуска dhclient:
$ ip netns exec foo ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 00:e0:4c:36:1e:fb brd ff:ff:ff:ff:ff:ff
inet6 fe80::60fc:16ff:fe9a:2e26/64 scope link
valid_lft forever preferred_lft forever
3: eth0: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UP group default qlen 1000
link/ether b8:27:eb:9e:8d:63 brd ff:ff:ff:ff:ff:ff
inet6 fe80::ba27:ebff:fe9e:8d63/64 scope link
valid_lft forever preferred_lft forever
4: eth1: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UP group default qlen 1000
link/ether 00:e0:4c:36:1e:fb brd ff:ff:ff:ff:ff:ff
inet 10.98.76.11/24 brd 10.98.76.255 scope global eth1
valid_lft forever preferred_lft forever
inet6 fe80::2e0:4cff:fe36:1efb/64 scope link
valid_lft forever preferred_lft forever
eth1 настроен с соответствующим IP-адресом.
Если я затем пингую что-нибудь, я получаю сообщение «Целевой хост недоступен»:
$ ip netns exec foo ping 10.98.76.1 (or .44 for laptop, .55 for tower)
Кроме того, на данный момент у меня нет внешнего доступа к wlan0. Я могу подключиться к беспроводному маршрутизатору и другим машинам в беспроводной сети, но, похоже, не могу выйти в Интернет.
Для справки, вот более подробная информация: Таблица arp:
$ ip netns exec foo arp
Address HWtype HWaddress Flags Mask Iface
10.98.76.1 (incomplete) eth1
Маршруты:
$ ip netns exec foo ip route show all
default via 10.98.76.1 dev eth1
10.98.76.0/24 dev eth1 proto kernel scope link src 10.98.76.11
Затем я опускаю мост:
$ ip netns exec foo ip link set dev br0 down
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: br0: <BROADCAST,MULTICAST> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
link/ether 00:e0:4c:36:1e:fb brd ff:ff:ff:ff:ff:ff
3: eth0: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UP group default qlen 1000
link/ether b8:27:eb:9e:8d:63 brd ff:ff:ff:ff:ff:ff
inet6 fe80::ba27:ebff:fe9e:8d63/64 scope link
valid_lft forever preferred_lft forever
4: eth1: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UP group default qlen 1000
link/ether 00:e0:4c:36:1e:fb brd ff:ff:ff:ff:ff:ff
inet 10.98.76.11/24 brd 10.98.76.255 scope global eth1
valid_lft forever preferred_lft forever
inet6 fe80::2e0:4cff:fe36:1efb/64 scope link
valid_lft forever preferred_lft forever
Но я все еще получаю сообщение «Destination Host Unreachable» при попытке эхо-запроса маршрутизатора или вышки. На данный момент, поскольку мост не работает, я, очевидно, ничего не могу сделать со своего ноутбука.
Если я затем удалю мост, я могу пинговать все в сети, как и ожидалось:
$ ip netns exec foo ip link delete dev br0
PING 10.98.76.1 (10.98.76.1) 56(84) bytes of data.
64 bytes from 10.98.76.1: icmp_seq=1 ttl=127 time=1.71 ms
64 bytes from 10.98.76.1: icmp_seq=2 ttl=127 time=0.894 ms
64 bytes from 10.98.76.1: icmp_seq=3 ttl=127 time=0.873 ms
На этом я в тупике. Та же самая установка работала на Raspbian, но не сработала на Hypriot. Следующий gitter делает выглядят почти идентично моей ситуации, однако я не есть дублированные устройства: https://gitter.im/hypriot/talk/archives/2016/06/02
Другие вещи, которые я пробовал, но которые не дали результатов: - Отключение eth0 и eth1 promisc - Включение br0 promisc - Создание пользовательского файла resolv.conf в /etc/netns/foo/resolv.conf - arping (см. Ниже)
$ ip netns exec foo arping -A -I eth1 10.98.76.11
ARPING 10.98.76.11
Timeout
Timeout
Timeout
Timeout
Timeout
Моя главная цель - сделать так, чтобы eth1 на Raspberry Pi использовал те же IP и MAC, что и мой ноутбук. При этом он должен по-прежнему передавать трафик на мой ноутбук и уважать любые запросы dhcp, которые могут быть у моего ноутбука, и т. Д. Я в конечном итоге собираюсь попытаться настроить туннель vpn между моим Raspberry Pi и башней, и все равно буду требовать пакеты сделать это через Raspberry Pi в мой ноутбук, но это произойдет после того, как я заставлю мост / устройства работать должным образом.
Чтобы повторить: это делает работать над Raspbian, и это меня действительно ставит в тупик. Пожалуйста, дайте мне знать, если требуется дополнительная информация, например, о запущенных службах (ничего, кроме значений по умолчанию для Hypriot, если я отключил докер) и т. Д.
На основании ответа от Wiebel Мне удалось исправить проблему, которая изначально не решалась. Я не знаю, как / почему он работает на Raspbian, так как он действительно не должен работать.
Я опубликую рабочий способ / правильный способ делать то, что я хочу ниже, на случай, если он может оказаться полезным для будущего переполнения:
# Ensure the traffic we send to the laptop goes through the right device
ip netns exec foo route add 10.98.76.44 dev eth0
# Enable forwarding on both devices
ip netns exec foo sysctl net.ipv4.conf.eth0.forwarding=1
ip netns exec foo sysctl net.ipv4.conf.eth1.forwarding=1
# Enable arp proxying on both devices
ip netns exec foo sysctl net.ipv4.conf.eth0.proxy_arp=1
ip netns exec foo sysctl net.ipv4.conf.eth1.proxy_arp=1
# Reload
ip netns exec foo sysctl --system
# Flush arp
ip netns exec foo -s -s neigh flush all
# Aggressively flush arp (the one above would do it, but this seems to be quick and thorough):
ip netns exec foo ip link set arp off dev eth0
ip netns exec foo ip link set arp off dev eth1
ip netns exec foo ip link set arp on dev eth0
ip netns exec foo ip link set arp on dev eth1
После выполнения вышеуказанного я могу без проблем получать доступ ко всем устройствам в сети и со всех них.
Если интерфейс является членом моста, вы не можете назначить IP-адрес самому интерфейсу, вам необходимо настроить адрес для моста.мост-stp-howto