Вопрос или проблема
Я пытаюсь добавить разделение DNS к туннелю wireguard (но это не совсем вопрос о wireguard).
У меня есть команда PostUp: resolvectl dns %i 10.160.20.15
, которая переводится как: resolvectl dns wg0 10.160.20.15
, и она не работает.
Когда я просто запускаю эту команду от имени root, ничего не меняется. В статусе resolvectl не добавлен DNS-сервер. Если я включаю уровень ведения журнала DEBUG, я получаю МНОГО сообщений в journalctl
, но не вижу объяснения неудачи.
Это слишком долго, чтобы вставить сюда; но единственное поле error-message
во всех журналах, которое не заполнено n/a
, это Link lan0 is managed
, и у него есть другое поле error-name
со значением org.freedesktop.resolve1.LinkBusy
.
lan0
– это название моего основного Ethernet (переименованное в netplan
), и, насколько я могу судить, оно не должно быть связано с этой командой?
Если я наивен и каким-то образом lan0
участвует, как мне сделать его не занятим (неконтролируемым); чтобы я мог установить DNS на другом интерфейсе?
ИЗМЕНЕНИЕ:
Нашел следующее на org.freedesktop.resolve1:
org.freedesktop.resolve1.LinkBusy
Запрашиваемое изменение конфигурации не могло быть выполнено, потому что systemd-networkd(8) уже взял под контроль интерфейс и предоставил конфигурационные данные для него.
Поэтому я догадываюсь, что мне нужно знать, что означает, когда networkd
берет на себя управление? И как вернуть управление обратно?
После множества разочарований я обнаружил, что добавление пользовательского DNS к (по крайней мере) интерфейсу wireguard зависит от порядка.
т.е.:
Вы должны указать домен поиска, прежде чем сможете указать сервер.
Не знаю, почему, и подозреваю, что это временная ошибка; но если вы указываете:
[Interface]
PostUp = resolvectl dns %i 10.100.100.5
PostUp = resolvectl domain %i ~mydomain.com
(и/или просто выполнить эти команды, как только wg0 запущен). Ничего на самом деле не происходит. Ошибок нет, но никакого изменения в выводе resolvectl
нет.
Однако, если изменить порядок и указать домен перед DNS-сервером, это работает прекрасно.
Поэтому правильный фрагмент для конфигурационного файла wireguard должен выглядеть так:
[Interface]
PostUp = resolvectl domain %i ~mydomain.com
PostUp = resolvectl dns %i 10.100.100.5
Также обратите внимание (вне темы данного вопроса), что встроенная техника wireguard:
[Interface]
DNS = 10.100.100.5, ~mydomain.com
тоже не работает, потому что пытается использовать старый resolvconf
, который действительно не работает с systemd (да, есть режим эмуляции).
Информация о версиях:
- Debian: bookworm
- resolvectl: systemd 252 (252.30-1~deb12u2)
+PAM +AUDIT +SELINUX +APPARMOR +IMA +SMACK +SECCOMP +GCRYPT -GNUTLS +OPENSSL +ACL +BLKID +CURL +ELFUTILS +FIDO2 +IDN2 -IDN +IPTC +KMOD +LIBCRYPTSETUP +LIBFDISK +PCRE2 -PWQUALITY +P11KIT +QRENCODE +TPM2 +BZIP2 +LZ4 +XZ +ZLIB +ZSTD -BPF_FRAMEWORK -XKBCOMMON +UTMP +SYSVINIT default-hierarchy=unified
Ответ или решение
Проблема, с которой вы столкнулись, связанная с командой resolvectl
и добавлением DNS-сервера для интерфейса WireGuard, довольно сложна, но давайте разберём её по шагам.
1. Контекст проблемы
Вы используете команду resolvectl dns %i 10.160.20.15
для настройки DNS в контексте WireGuard. При выполнении этой команды от имени пользователя root, никакие изменения не видны в статусе resolvectl
. Запуская отладку, вы видите множество сообщений в journalctl
, но они не помогают в решении проблемы. Вы также упоминаете, что видите ошибку Link lan0 is managed
с кодом org.freedesktop.resolve1.LinkBusy
, что указывает на то, что интерфейс lan0
уже управляется системой systemd-networkd
.
2. Природа проблемы
Ошибку LinkBusy
вызывает то, что интерфейс уже занят другим процессом, в данном случае systemd-networkd
. Этот процесс отвечает за управление сетевыми интерфейсами и применяет свои конфигурации. Если он уже применил определённые DNS-настройки к интерфейсу, resolvectl
не сможет внести изменения, поскольку конфликты в управлении подключением приведут к ошибке.
3. Решения проблемы
a. Убедиться, что интерфейс не управляется
Чтобы выяснить, управляется ли интерфейс lan0
systemd-networkd
, проверьте файл конфигурации, связанный с ним. Вам нужно убедиться, что соответствующий конфигурационный файл под /etc/systemd/network/
или /etc/netplan/
не содержит неправильных настроек.
Если вы хотите сделать интерфейс lan0
unmanaged, добавьте в конфигурацию:
[Link]
Unmanaged=yes
Затем перезапустите systemd-networkd
:
sudo systemctl restart systemd-networkd
После этого команда resolvectl
должна начать работать корректно.
b. Порядок команд в конфигурации WireGuard
Вы также упомянули о том, что порядок выполнения команд имеет значение. Для обеспечения корректного функционирования необходимо сначала указать доменное имя, а уже потом DNS-сервер. Вот правильный порядок:
[Interface]
PostUp = resolvectl domain %i ~mydomain.com
PostUp = resolvectl dns %i 10.100.100.5
Это может звучать странно, но порядок вызовов влияет на обработку конфигурации systemd-resolved
. Баг, о котором вы упоминаете, может возникнуть из-за неэффективной обработки вызовов и порядок команд действительно важен.
4. Дополнительная информация
Вы также отметили, что метод, встроенный в WireGuard, для указания DNS не работает. Это связано с тем, что WireGuard, используя старую систему resolvconf
, конфликтует с systemd-resolved
. В этом случае рекомендуется придерживаться управления через resolvectl
, чтобы избежать конфликтов.
Заключение
Справляться с сетевыми интерфейсами и DNS может быть непросто, особенно когда вы имеете дело с различными системами управления. Если вы столкнётесь с дальнейшими проблемами, всегда проверяйте управление интерфейсами с помощью системного networkd
и убедитесь, что ваши команды настраиваются в правильном порядке. Надеюсь, это поможет вам решить вашу проблему с resolvectl
и настройкой DNS для WireGuard.