最近、ローカルネットワークのDNSサーバーとして機能する dnsmasq をインストールしました。 dnsmasqは、ローカルDNSスタブリスナーが systemd-resolved からすでに使用しているポート53をリッスンします。
Systemd-resolvedを停止し、dnsmasqの実行後に再起動するだけでこの問題は解決します。ただし、再起動後に戻ります。systemd-resolvedは優先的に開始され、ポート53がすでに使用されているため、dnsmasqは開始されません。
最初の明白な質問は、どうやったらsystemd-resolvedがローカルDNSスタブリスナーを起動して、dnsmasqが使用できるようにポート53を保持すべきではないことを最もよく理解させるのでしょうか?
ただし、さらに興味深い質問は、2つのサービスがどのように連携することを一般的に意図しているのかということです。それらは並べて動作することを意図しているのですか、それともdnsmasqを使用している場合は邪魔な方法でsystemdで解決されているのですか?
systemd 232 (2017年にリリース)の時点で、/etc/systemd/resolved.conf
を編集して次の行を追加できます。
DNSStubListener=no
これにより、ポート53へのバインドがオフになります。
オプションについては resolved.conf manpage で詳しく説明しています。
システムが実行されているsystemdバージョンを確認できます。
systemctl --version
systemd-resolved
を使用すると、起動時にSudo systemctl disable systemd-resolved
が読み込まれないようにすることができます。
2つを一緒に実行する場合は、systemd-resolved
をリダイレクトして、ローカルホストをプライマリネームサーバーとして使用できます。これにより、外部DNSサーバーにアクセスする前に、すべてのクエリが解決のためにdnsmasqに送信されるようになります。これを行うには、nameserver 127.0.0.1
ファイルの先頭に/etc/resolv.conf
という行を追加します。これにより、systemdのローカルキャッシュも無効になります。
詳しくは Arch Linux wiki をご覧ください。私はこれをそこからコピーしましたが、かなりうまくカバーしています。
ただし、これは起動時のエラーを確実に回避するものではありません。つまり、systemd-resolvedが最初に起動した場合でも、dnsmasqは失敗します。 systemd
のバージョンが十分に新しい場合は、 Malvineous による回答を使用します。 systemd
のバージョンが古すぎる場合は、dnsmasqユニットを変更してこの問題を回避できます。[Unit]
セクションにBefore=systemd-resolved
を追加します。
この後、必要に応じて、上流のネームサーバー用に別の/etc/dnsmasq-resolv.conf
ファイルを作成し、-r
または--resolv-file
オプションを使用してそれを渡すか、上流のネームサーバーをdnsmasq構成ファイルに追加できます。 -R
または--no-resolv
オプションを使用します。この方法では、/etc/resolv.conf
にlocalhostのみがあり、すべてがdnsmasqを通過します。
Systemdのマンページから判断すると、スタブDNSサーバーを手動で無効にすることはできません。興味深いことに、systemdを230から231にアップグレードした後にのみ、説明されている問題に気付きました。
DHCP経由で受信した上流のDNSサーバーを処理するために必要なため、systemd-resolvedを無効にすることは私の選択肢ではありませんでした。
私の解決策は、開始する前にdnsmasqをsystemd-resolvedで停止させ、その後再び開始することでした。
/etc/systemd/system/dnsmasq.service.d/resolved-fix.conf
にドロップイン構成を作成しました:
[Unit]
After=systemd-resolved.service
[Service]
ExecStartPre=/usr/bin/systemctl stop systemd-resolved.service
ExecStartPost=/usr/bin/systemctl start systemd-resolved.service
これはややハックな解決策のようですが、機能します。
/etc/dnsmasq.confの行の先頭にある「#」を削除して、オプション「bind-interfaces」を有効にしました。
dnsmasqを再び開始できました:
私はこの議論によってこの解決策を指摘されました 解決済み:スタブリゾルバーを無効にするオプションを追加します
systemd
version 232
には、スタブリスナーを無効にするオプションがあります。 https://github.com/systemd/systemd/pull/4061 を参照してください。
デフォルトのUbuntu 18.04セットアップを使用している場合、これは[mayはsystemd-resolved
(デフォルトのDNSサーバー)とdnsmasq
の間の競合が原因で発生します。明示的に望んだためにdnsmasq
を故意に自分でインストールした場合は、systemd-resolved
を無効にする方法を説明するこの質問に対する他の回答の1つがおそらく役立つでしょう。 did n'tに明示的にdnsmasq
をインストールする場合は、lxd
を使用しているため、適切にインストールされている可能性があります。これは、実際にはlxd
を使用してコンテナーを管理しているためかもしれませんが、アプリのインストール時にスナップがlxd
を使用してユーザーを保護している可能性が高いです。私の観点からは、dnsmasq
を維持したいのですが(lxd
がそれを望んでいるため)、DNSサーバーとしてsystemd-resolved
も維持したいと考えています(Ubuntuチームが選択したものであり、自分よりも信頼しているためです)。
したがって、これは本来lxd
の問題のようです。もしそうなら、私がそれを修正した方法 lxd-usersメーリングリストの投稿 によると、これは:
$ lxc network edit lxdbr0
これにより、ターミナルエディタで設定が編集されます。次のようになります。
config:
ipv4.address: 10.216.134.1/24
ipv4.nat: "true"
ipv6.address: none
ipv6.nat: "true"
name: lxdbr0
type: bridge
3行追加します。
config:
ipv4.address: 10.216.134.1/24
ipv4.nat: "true"
ipv6.address: none
ipv6.nat: "true"
raw.dnsmasq: |
auth-zone=lxd
dns-loop-detect
name: lxdbr0
type: bridge
これにより、dnsmasq
によって実行されているlxd
がDNSループを検出するようになります。これは、少なくとも私にとっては問題を解決し、systemd-resolved
およびdnsmasq
を100%のCPUを使用して停止しました。
これは(X)Ubuntu 18.04 Bionicのソリューションです。
Dnsmasqをインストールする
Sudo apt install dnsmasq
ポート53でsystemd-resolvedリスナーを無効にします(アップグレード時に上書きされる可能性があるため、/ etc/systemd/resolved.confには触れないでください)。
$ cat /etc/systemd/resolved.conf.d/noresolved.conf
[Resolve]
DNSStubListener=no
それを再起動します
$ Sudo systemctl restart systemd-resolved
(または$ Sudo systemctl disable systemd-resolved.service
で完全に無効にする)
/etc/resolv.confを削除して、再度作成します。 resolv.confはデフォルトで/run/systemd/resolve/stub-resolv.confへのシンボリックリンクであるため、これは重要です。シンボリックリンクを削除しない場合、ファイルはsystemdによって再起動時に上書きされます(systemd-resolvedを無効にした場合でも)。また、NetworkManager(NM)は、systemdで解決された構成を検出するためのシンボリックリンクであるかどうかをチェックします。
$ Sudo rm /etc/resolv.conf
$ Sudo touch /etc/resolv.conf
NMによる/etc/resolv.confの上書きを無効にします(オプションrc-managerもありますが、NMマニュアルで説明されているにもかかわらず機能しません)。
$ cat /etc/NetworkManager/conf.d/disableresolv.conf
[main]
dns=none
そしてそれを再起動します:
$ Sudo systemctl restart NetworkManager
NMのresolv.confを使用するようにdnsmasqに指示します。
$ cat /etc/dnsmasq.d/nmresolv.conf
resolv-file=/var/run/NetworkManager/resolv.conf
そしてそれを再起動します:
$ Sudo systemctl restart dnsmasq
解決にはdnsmasqを使用します。
$ cat /etc/resolv.conf
# Use local dnsmasq for resolving
nameserver 127.0.0.1
両方のサービスが同じアドレスを使用しようとしている理由がわかりません。 Xubuntu 18.04.1で私の場合のようにそれらを配置することができます。その構成は次のとおりです。
xy@zq:~$ Sudo netstat -tulpn | grep 53
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN 13549/systemd-resol
tcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 9632/dnsmasq
私のdnsmasqを使用してsystemdを解決するには、次のように設定します。
#/etc/systemd/resolved.conf
[Resolve]
DNS=127.0.0.1
私のdnsmasq構成で、外部ネームサーバーを設定しました。
#/etc/dnsmasq.conf
nameserver x.x.x.x
nameserver y.y.y.y
すべてを再起動した後:
# Sudo systemctl restart systemd-resolved.service
# Sudo systemctl restart dnsmasq.service
systemd-resolvedは、デフォルトのDNSサーバーを次のdnsmasqに設定します。
#/etc/resolv.conf
nameserver 127.0.0.1
私はこのようにそれを解決しました:
/ etc/default/dnsmasqに次の行を追加またはコメント解除します。
IGNORE_RESOLVCONF=yes
ネームサーバーを定義するための独自の解決ファイル(/etc/resolv.personal)を作成します。ここでは任意のネームサーバーを使用できます。 https://www.opennic.org から2つ取得しました
nameserver 5.132.191.104
nameserver 103.236.162.119
/ etc/dnsmasq.confに、次の行を追加またはコメント解除します。
resolv-file=/etc/resolv.personal
次に、dnsmasqを再起動して、デフォルトのリゾルバーsystemd-resolvedを無効にします。
Sudo service dnsmasq restart
Sudo systemctl stop systemd-resolved
Sudo systemctl disable systemd-resolved
オンラインで見つかったソリューションを使用してdnsmasqを開始できませんでした。つまり、systemd-resolvedを無効にし、dnsmasq.confを変更して「バインドインターフェース」ではなく「バインドダイナミック」を実行しました。 network.serviceではなくnetwork-online.serviceの後でdnsmasqを開始することで、起動時にそれを開始することができました。
[Unit]
Description=dnsmasq - A lightweight DHCP and caching DNS server
Requires=network.target
Wants=nss-lookup.target
Before=nss-lookup.target
After=network-online.target #This line changed
Ubuntu 18.10 Cosmic Cuttlefishで私が(何時間も苦労して)機能したのは次のとおりです。これは、dnsmasq
の比較的堅牢なキャッシングメカニズムを利用し、 NGINXリゾルバーの脆弱性 を回避するために行いました。 Ubuntu Serverエディションを使用していることに注意してください(NetworkManager
/nmcli
ではなく、systemd-networkd
)これはAWS EC2で実行されているため、DNSとDHCPをデフォルトのEC2検索ドメインで動作させ続ける必要もありました。無効にしたくなかったsystemd-resolved
将来の更新にどのように影響するかはまったくわかりません。特に明記しない限り、ここではすべてがroot/Sudoとして実行されます(これは、EC2ユーザーデータとして渡されたときにデフォルトで発生します)。
## Configure dnsmasq to work with systemd-resolved
# Set static hostname with hostnamectl
hostnamectl set-hostname mydomainname
# Add an entry for the hostname to /etc/hosts
tee --append /etc/hosts <<EOF
127.0.0.1 mydomainname
EOF
# Disable stub listener for resolvconf and set DNS to loopback
tee --append /etc/systemd/resolved.conf <<EOF
DNSStubListener=no
DNS=127.0.0.1
EOF
# Tell dnsmasq to ignore resolvconf
tee --append /etc/default/dnsmasq <<EOF
IGNORE_RESOLVCONF=yes
EOF
# Create dropin directory
mkdir -p /etc/systemd/system/dnsmasq.service.d
# Create systemd dropin to make sure systemd-resolved stops before dnsmasq starts
tee /etc/systemd/system/dnsmasq.service.d/resolved-fix.conf <<EOF
[Unit]
After=systemd-resolved.service
[Service]
ExecStartPre=bin/systemctl stop systemd-resolved.service
ExecStartPost=bin/systemctl start systemd-resolved.service
EOF
# Create custom resolvconf with name servers (I usec cloudflare)
tee /etc/resolv.mydomainname <<EOF
nameserver 1.1.1.1
nameserver 1.0.0.1
nameserver [2606:4700:4700::1111]
nameserver [2606:4700:4700::1001]
EOF
# Configure dnsmasq
tee /etc/dnsmasq.d/mydomainname.conf <<EOF
# Region comes from:
# EC2_AVAIL_ZONE=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone)
# EC2_REGION=${EC2_AVAIL_ZONE%?}
domain=$EC2_REGION.compute.internal
resolv-file=/etc/resolv.mydomainname
listen-address=127.0.0.1
port=53
interface=lo
bind-dynamic
domain-needed
bogus-priv
dnssec
dns-forward-max=300
cache-size=1000
neg-ttl=3600
EOF
# Reload to pick up dropin
systemctl daemon-reload
# Stop systemd-resolved
systemctl stop systemd-resolved
# Start dnsmasq
systemctl restart dnsmasq
それを確認する 127.0.0.1#53
は解決に使用されており、DNSSECはDig +trace facebook.com
私の場合(他のマシンにDNSサービスを提供する必要がある)設定によってイーサネットインターフェースにのみバインドするようにdnsmasqに指示することによって(systemd-resolvdはループバックにバインドします)、問題を解決できました...
...
interface=eth0
...
bind-interfaces
dnsmasq.conf内