WireGuard в LXC или в VM на Proxmox: где ему работать?
WireGuard может работать на хосте Proxmox, в контейнере или в VM. Решающие факторы — владение ядром, контроль над интерфейсом и восстановление.
WireGuard нужно ровно одно ядро, которому принадлежит его интерфейс, и этот факт снимает большую часть спора о размещении на Proxmox ещё до того, как в разговор войдёт производительность. LXC-контейнер — это представление пространства имён хостового ядра, а VM загружает собственное. Поэтому полезный вопрос не в том, какой вариант легче, а в том, какое ядро вы готовы менять и с каким путём восстановления можете жить. Ответьте на это, и выбор между хостом, контейнером и VM обычно делается сам.
Гость LXC работает внутри хостового ядра
Установка wireguard-tools в контейнере даёт программу управления, а не отдельное ядро. Создаваемый интерфейс wg0 регистрируется в сетевом стеке хоста и появляется в списке его модулей. Поэтому контейнер может пройти все проверки пакетов и всё равно упасть на первой команде wg, когда в ядре хоста нет модуля. А справка Proxmox по контейнерам описывает эту модель общего ядра вместе с границами пространств имён и привилегий, внутри которых вы работаете.
Второе ограничение — полномочия. Чтобы поднять интерфейс и привязать к нему адреса, нужны права сетевого администрирования внутри пространства имён, которому он принадлежит, а непривилегированный контейнер отображает эти права через своё пользовательское пространство имён, а не держит их напрямую. Никогда не беритесь сразу за полные привилегии; посмотрите, что контейнеру действительно поручено, и дайте именно это.
Ядро хоста — тоже общая зависимость. Обновление ядра Proxmox меняет реализацию WireGuard сразу под всеми контейнерами, что удобно, пока обновление и ожидания контейнера не разойдутся.
Хост, контейнер, VM: чем на самом деле владеет каждое размещение
Размещение на хосте помещает VPN в собственную сеть гипервизора. Маршруты, правила брандмауэра и туннель становятся частью восстановления хоста, и ошибка там может унести с собой интерфейс управления. Это приемлемо для маршрутизации инфраструктуры на хосте, до которого добираются через консоль, и болезненно на удалённой машине без доступа вне полосы.
Контейнер держит службу упакованной и перезапускаемой, по-прежнему одалживая ядро хоста. Он подходит для сознательно общей по ядру службы и даёт небольшую единицу для пересборки. Независимого ядра он не даёт, поэтому всё, что требует конкретной сборки модуля, указывает прочь от этого варианта.
| Placement | Kernel owner | Typical failure mode |
|---|---|---|
| Proxmox host | Hypervisor | A routing change breaks host management access |
| LXC container | Host kernel, container namespace | Missing capability or missing module at wg0 creation |
| Virtual machine | Guest kernel | Extra maintenance and a second patch cycle |
VM стоит больше памяти и ещё одной системы для патчей, а взамен туннель получает собственное ядро, собственную таблицу маршрутизации и границу снимка. Когда после плохого изменения откатывают именно VPN, этот снимок стоит накладных расходов.
Три условия, которые выбирают за вас
Если туннелю нужна версия ядра или функция WireGuard, которой нет у хоста Proxmox, остановитесь здесь и используйте VM. Более новое ядро в контейнер установить нельзя, и не стоит заменять ядро гипервизора ради одного гостя.
Если туннель — шлюз площадки для настоящих префиксов LAN, спросите, кому уже принадлежит обратный маршрут. Контейнер умеет маршрутизировать трафик, но его интерфейсы сидят в стеке хоста, поэтому хост в итоге несёт часть конфигурации, планировали вы это или нет. Размещение на хосте честно в этом отношении; размещение в контейнере часто нет.
Затем взвесьте радиус поражения от ошибки. Перезапустить контейнер дёшево, восстановить снимок VM предсказуемо, а починка сети хоста может потребовать физического доступа или консоли. Правильный выбор — тот, чей худший случай вы действительно сможете восстановить в тот час, когда он случится.
Четвёртый вопрос редко бывает решающим, но его стоит задать: нужно ли ещё чему-то на хосте видеть интерфейс туннеля? Если да, размещение на хосте или в контейнере оставляет эту видимость локальной, а VM заставляет вас маршрутизировать между гостем и хостом.
Докажите размещение, прежде чем пускать через него трафик
После установки подтвердите, какое ядро на самом деле обслуживает интерфейс и получил ли контейнер достаточно полномочий, чтобы его удержать:
$ pct config 101 | grep -E 'unprivileged|features'
unprivileged: 1
$ pct exec 101 -- wg show
interface: wg0
listening port: 51820
$ pct exec 101 -- ip -4 addr show wg0
inet 10.60.0.2/24 scope global wg0
Затем проверьте сторону пересылки с хоста, потому что одно рукопожатие доказывает лишь то, что туннель поднят. Используйте ip route get для адреса клиента и подтвердите, что следующий хоп и интерфейс соответствуют проекту, а обратный путь существует на дальней стороне.
Оставьте развёртывание с записанным владельцем: какое ядро несёт реализацию, какое пространство имён держит интерфейс и какие префиксы шлюзу разрешено пересылать. Эта фраза предотвращает больше инцидентов, чем любое сравнение трёх размещений по бенчмаркам.