В моей домашней лаборатории основная платформа виртуализации - Proxmox VE. Так как это все же дом, к интернету она подключена вместе со всеми остальными устройствами через обычный роутер с прошивкой OpenWRT.  

В большинстве экспериментов я практикую подход "если что-то пойдет не так... разберемся, а потом просто перезапустим терраформ". В ходе очередного такого эксперимента мне понадобилось перенастроить пару вещей глубоко внутри OpenWRT роутера, и внезапно пришло понимание, что домашний роутер совсем не эфемерный ресурс. На вопрос: «Если я окирпичу роутер, то смогу ли я его оживить без отвертки, паяльника и, самое главное, без доступа в интернет?» ответ был «¯\_(ツ)_/¯».  

Раз такое дело, сначала нужно потренироваться на кошках, а значит, нам понадобится эмулятор маршрутизатора OpenWRT. Причем arm64 версия, так как пакетная база между arm и x86 может существенно отличаться. На просторах интернета я не встретил инструкции, которая бы заработала сразу и была бы легко автоматизируема. Надеюсь, данный гайд заработает у вас "из коробки", а сэкономленное время пойдет на эксперименты.

Нам понадобится:

  • root-доступ к Proxmox VE. В моем случае v8.2.2.

  • доступ к репозиторию прошивок OpenWrt. В моем случае v23.05.3.

План эксперимента:

  • Сначала попробуем эмуляцию Openwrt x86_64 как запасной вариант, если следующий шаг не удастся.

  • Затем мы настроим Proxmox для эмуляции версии Openwrt для arm64.

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

Шаг 1: OpenWRT x86_64

В каталоге с релизами, выбираем версию, затем targets -> x86 -> 64. В консоли Proxmox (я использовал Shell в GUI, но нет причин, чтобы не заработало и через ssh) скачиваем squashfs-combined-efi версию и распаковываем архив:

cd /var/lib/vz/template/iso

wget -c https://downloads.openwrt.org/releases/23.05.3/targets/x86/64/openwrt-23.05.3-x86-64-generic-squashfs-combined-efi.img.gz

gunzip openwrt-23.05.3-x86-64-generic-squashfs-combined-efi.img.gz

Disclaimer: выбранный путь хранения образа, возможно, не best practice, но он присутствует на Proxmox ноде по умолчанию. Также у меня storage называется local-zfs, если у вас другой путь, то просто замените local-zfs на свой в параметрах --efidisk0 и --scsi0 в командах ниже.

Собственно, уже можно создавать машину

qm create $(pvesh get /cluster/nextid) \
--name "openwrt-amd64" \
--description "openwrt-amd64" \
--arch x86_64 \
--tags "openwrt" \
--bios ovmf \
--efidisk0 file=local-zfs:4,efitype=4m,pre-enrolled-keys=0 \
--sockets 1 \
--cores 2 \
--memory 256 \
--vga type=serial0 \
--serial0 socket \
--boot order=scsi0 \
--scsihw virtio-scsi-pci \
--scsi0 file=local-zfs:0,import-from="/var/lib/vz/template/iso/openwrt-23.05.3-x86-64-generic-squashfs-combined-efi.img" \
--net0 model=virtio,bridge=vmbr0,firewall=1,link_down=0,mtu=1

и запускать

qm start <VM ID> ; qm terminal <VM ID>

Если все закончилось хорошо, то в терминале увидим примерно следующее:

BusyBox v1.36.1 (2024-03-22 22:09:42 UTC) built-in shell (ash)

  _______                     ________        __
 |       |.-----.-----.-----.|  |  |  |.----.|  |_
 |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
 |_______||   __|_____|__|__||________||__|  |____|
          |__| W I R E L E S S   F R E E D O M
 -----------------------------------------------------
 OpenWrt 23.05.3, r23809-234f1a2efa
 -----------------------------------------------------
=== WARNING! =====================================
There is no root password defined on this device!
Use the "passwd" command to set up a new password
in order to prevent unauthorized SSH logins.
--------------------------------------------------
root@OpenWrt:/$ cat /etc/os-release 
NAME="OpenWrt"
VERSION="23.05.3"
ID="openwrt"
ID_LIKE="lede openwrt"
PRETTY_NAME="OpenWrt 23.05.3"
VERSION_ID="23.05.3"
HOME_URL="https://openwrt.org/"
BUG_URL="https://bugs.openwrt.org/"
SUPPORT_URL="https://forum.openwrt.org/"
BUILD_ID="r23809-234f1a2efa"
OPENWRT_BOARD="x86/64"
OPENWRT_ARCH="x86_64"
OPENWRT_TAINTS=""
OPENWRT_DEVICE_MANUFACTURER="OpenWrt"
OPENWRT_DEVICE_MANUFACTURER_URL="https://openwrt.org/"
OPENWRT_DEVICE_PRODUCT="Generic"
OPENWRT_DEVICE_REVISION="v0"
OPENWRT_RELEASE="OpenWrt 23.05.3 r23809-234f1a2efa"

выходим из терминала через ctrl+o, подчищаем за собой и переходим к следующему шагу

qm stop <VM ID> ; qm destroy <VM ID>

Шаг 2: OpenWrt ARM64

В релиз ноутах к PVE 8.1 упоминается, что для эмуляции (U)EFI биоса в виртуальных машинах на ARM64 нужно установить пакет pve-edk2-firmware-aarch64:

apt install pve-edk2-firmware-aarch64

В каталоге с релизами, выбираем версию, затем targets -> armsr -> armv8.  

В консоли Proxmox скачиваем squashfs-combined версию и распаковываем архив:

cd /var/lib/vz/template/iso

wget -c https://downloads.openwrt.org/releases/23.05.3/targets/armsr/armv8/openwrt-23.05.3-armsr-armv8-generic-squashfs-combined.img.gz

gunzip openwrt-23.05.3-armsr-armv8-generic-squashfs-combined.img.gz

Создаем машину следующей командой:

qm create $(pvesh get /cluster/nextid) \
--name "openwrt-aarch64" \
--description "openwrt-aarch64" \
--tags "openwrt" \
--arch aarch64 \
--bios ovmf \
--efidisk0 file=local-zfs:4,efitype=4m,pre-enrolled-keys=0 \
--sockets 1 \
--cores 2 \
--memory 256 \
--vga type=serial0 \
--serial0 socket \
--boot order=scsi0 \
--scsihw  virtio-scsi-pci \
--scsi0 file=local-zfs:0,import-from="/var/lib/vz/template/iso/openwrt-23.05.3-armsr-armv8-generic-squashfs-combined.img" \
--net0 model=virtio,bridge=vmbr0,firewall=1,link_down=0,mtu=1

загружаем

qm start <VM ID> ; qm terminal <VM ID>

И если и в этот раз нас ждал успех, то в терминале увидим что-то вроде:

BusyBox v1.36.1 (2024-03-22 22:09:42 UTC) built-in shell (ash)

  _______                     ________        __
 |       |.-----.-----.-----.|  |  |  |.----.|  |_
 |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
 |_______||   __|_____|__|__||________||__|  |____|
          |__| W I R E L E S S   F R E E D O M
 -----------------------------------------------------
 OpenWrt 23.05.3, r23809-234f1a2efa
 -----------------------------------------------------
=== WARNING! =====================================
There is no root password defined on this device!
Use the "passwd" command to set up a new password
in order to prevent unauthorized SSH logins.
--------------------------------------------------
root@OpenWrt:/$ cat /etc/os-release 
NAME="OpenWrt"
VERSION="23.05.3"
ID="openwrt"
ID_LIKE="lede openwrt"
PRETTY_NAME="OpenWrt 23.05.3"
VERSION_ID="23.05.3"
HOME_URL="https://openwrt.org/"
BUG_URL="https://bugs.openwrt.org/"
SUPPORT_URL="https://forum.openwrt.org/"
BUILD_ID="r23809-234f1a2efa"
OPENWRT_BOARD="armsr/armv8"
OPENWRT_ARCH="aarch64_generic"
OPENWRT_TAINTS=""
OPENWRT_DEVICE_MANUFACTURER="OpenWrt"
OPENWRT_DEVICE_MANUFACTURER_URL="https://openwrt.org/"
OPENWRT_DEVICE_PRODUCT="Generic"
OPENWRT_DEVICE_REVISION="v0"
OPENWRT_RELEASE="OpenWrt 23.05.3 r23809-234f1a2efa"

выходим из терминала через ctrl+o, подчищаем за собой и переходим к добавлению сетевых интерфейсов.

qm stop <VM ID> ; qm destroy <VM ID>

Шаг 3: превращаем виртуалку в маршрутизатор

В данный момент на виртуальном OpenWRT есть всего лишь один сетевой интерфейс, который автоматически подключается в br-lan и инициализируется через DHCP-сервер на реальном роутере. Чтобы сделать маршрутизатор маршрутизатором, нам нужно добавить как минимум еще один сетевой интерфейс. Для этого в ProxmoxVE создадим Linux Bridge интерфейс vmbr1.  

Через шелл:

cp /etc/network/interfaces /etc/network/interfaces.new

cat <<EOF>>/etc/network/interfaces.new
auto vmbr1
iface vmbr1 inet static
        address 192.168.1.0/24
        bridge-ports none
        bridge-stp off
        bridge-fd 0
EOF

systemctl start pvenetcommit

systemctl restart networking

или же путь через Proxmox GUI: Datacenter->pve->System->Network->Create, Apply Configuration

Если в OpenWRT доступны два сетевых интерфейса, первый (eth0) будет назначен как LAN, а второй (eth1) как WAN. Чтобы смоделировать типичную домашнюю сеть и избежать интерференции между DHCP-серверами, нам нужно, чтобы Proxmox интерфейс vmbr1 стал eth0 в OpenWRT, а Proxmox интерфейс vmbr0 стал eth1.

Учитывая вышеизложенное, команда для создания машины станет такой:

qm create $(pvesh get /cluster/nextid) \
--name "openwrt-aarch64" \
--description "openwrt-aarch64" \
--tags "openwrt" \
--arch aarch64 \
--bios ovmf \
--efidisk0 file=local-zfs:4,efitype=4m,pre-enrolled-keys=0 \
--sockets 1 \
--cores 2 \
--memory 256 \
--vga type=serial0 \
--serial0 socket \
--boot order=scsi0 \
--scsihw  virtio-scsi-pci \
--scsi0 file=local-zfs:0,import-from="/var/lib/vz/template/iso/openwrt-23.05.3-armsr-armv8-generic-squashfs-combined.img" \
--net1 model=virtio,bridge=vmbr0,firewall=1,link_down=0,mtu=1 \
--net0 model=virtio,bridge=vmbr1,firewall=1,link_down=0,mtu=1

Запускаем:

qm start <vmid>; qm terminal</vmid>

проверяем:

root@OpenWrt:/$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    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: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master br-lan state UP qlen 1000
    link/ether bc:24:11:25:4f:f2 brd ff:ff:ff:ff:ff:ff
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP qlen 1000
    link/ether bc:24:11:dc:6b:e7 brd ff:ff:ff:ff:ff:ff
    inet 10.1.2.105/24 brd 10.1.2.255 scope global eth1
       valid_lft forever preferred_lft forever
    inet6 fe80::be24:11ff:fedc:6be7/64 scope link 
       valid_lft forever preferred_lft forever
4: br-lan: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
    link/ether bc:24:11:25:4f:f2 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.1/24 brd 192.168.1.255 scope global br-lan
       valid_lft forever preferred_lft forever
    inet6 fd4f:be36:41c0::1/60 scope global noprefixroute 
       valid_lft forever preferred_lft forever
    inet6 fe80::be24:11ff:fe25:4ff2/64 scope link 
       valid_lft forever preferred_lft forever
root@OpenWrt:/$ cat /etc/config/network 

config interface 'loopback'
        option device 'lo'
        option proto 'static'
        option ipaddr '127.0.0.1'
        option netmask '255.0.0.0'

config globals 'globals'
        option ula_prefix 'fd4f:be36:41c0::/48'

config device
        option name 'br-lan'
        option type 'bridge'
        list ports 'eth0'

config interface 'lan'
        option device 'br-lan'
        option proto 'static'
        option ipaddr '192.168.1.1'
        option netmask '255.255.255.0'
        option ip6assign '60'

config interface 'wan'
        option device 'eth1'
        option proto 'dhcp'

config interface 'wan6'
        option device 'eth1'
        option proto 'dhcpv6'

Как можно видеть, wan-интерфейс привязан к eth1, который получил от реального маршрутизатора адрес 10.1.2.105.

OpenWRT по умолчанию открывает порты для управления только на стороне lan, и правильно делает! Но мы же это все затеяли для рисковых опытов, поэтому, чтобы упростить дальнейшую настройку, откроем порты 22, 80, и 443 на стороне wan, что ни в коем случае не стоит повторять на реальном железе:

uci add firewall rule
uci set firewall.@rule[-1].name='Allow-Admin'
uci set firewall.@rule[-1].enabled='true'
uci set firewall.@rule[-1].src='wan'
uci set firewall.@rule[-1].proto='tcp'
uci set firewall.@rule[-1].dest_port='22 80 443'
uci set firewall.@rule[-1].target='ACCEPT'
uci add firewall rule
uci commit firewall  
service firewall restart

Проверяем подключение по ssh с хоста в физической сети:

$ ssh root@10.1.2.105
The authenticity of host '10.1.2.105 (10.1.2.105)' can't be established.
ED25519 key fingerprint is SHA256:VkLVqOud2GArohqiV+cHh1uIWXKVbpBJFHQJjUhrKzg.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.1.2.105' (ED25519) to the list of known hosts.


BusyBox v1.36.1 (2024-03-22 22:09:42 UTC) built-in shell (ash)

  _______                     ________        __
 |       |.-----.-----.-----.|  |  |  |.----.|  |_
 |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
 |_______||   __|_____|__|__||________||__|  |____|
          |__| W I R E L E S S   F R E E D O M
 -----------------------------------------------------
 OpenWrt 23.05.3, r23809-234f1a2efa
 -----------------------------------------------------
=== WARNING! =====================================
There is no root password defined on this device!
Use the "passwd" command to set up a new password
in order to prevent unauthorized SSH logins.
--------------------------------------------------
root@OpenWrt:~#

Работает! Можно уверенно воплощать самые смелые фантазии на вашем роутере.

Вместо заключения

В моем случае виртуальный роутер помог без мучительных откатов реального устройства разобраться, как на OpenWRT поднять DNS зону для локальной сети с динамическим обновлением записей (RFC 2136).  

Об этом "приключении на 20 минут" расскажу в следующей статье.

Комментарии (4)


  1. NZakh61
    03.07.2024 20:41

    Опыт поинтереснее: поднять виртуальный роутер на RouterOS или на pfsense , а также bind


    1. HellKaim
      03.07.2024 20:41

      Вообще не вопрос, если мы говорим про RouterOS x86.

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

      Для этого создадим образ и пропишем его в конфигурации машины вот так:

      qemu-img create -f raw /var/lib/vz/images/100/ros_disk.img 6442450944
      ide0: /var/lib/vz/images/100/ros_disk.img,serial=00000000000000000001,model=VMware%20Virtual%20IDE%20Hard%20Drive

      Ну и далее, пошаманив с mbr и перезалил это на заранее созданный "нормальный" диск, который точно так же нужно привести к размеру

      qm resize 100 ide0 6442450944

      И вуаля, все будет работать.

      Правда, там не будет FastTrack, ну да и ладно!

      pFSense и OPNsense заводятся вообще без вопросов. Хоть ты туда бридж, хоть PCI path through - все заработает.

      Если же речь про arm версию, то а) ЗАЧЕМ?! и б) накладные расходы будут выше.


  1. CitizenOfDreams
    03.07.2024 20:41

    смогу ли я его оживить без отвертки, паяльника и, самое главное, без доступа в интернет?

    Мы же про домашний роутер? Что за дом такой, где может не оказаться отвертки, паяльника и интернета?


  1. Dupych
    03.07.2024 20:41

    У меня маршрутизация на Mikrotik.

    Внутренний маршрутизатор до серверов на виртуальном Mikrotik 7.15.2 .