#author("2019-04-28T23:30:33+09:00","default:nowsky","nowsky") #author("2021-02-06T18:05:37+09:00","default:nowsky","nowsky") *dnsdist [#n2d45d2d] DNSに特化したリバース・フォワード兼用ロードバランサー。 バックエンド死活監視、ポリシールーティング、QoS制御などのLSLBが備える機能を実装している。 設定ファイルはLua言語で記述するので、環境に合わせてスクリプト主体の細かい制御も出来る。 DNSクエリ処理に限定すると、dnsdistはクエリ・フォワード動作に特化している為、 バックエンドに権威DNS・キャッシュDNSなどを構築する必要がある。 アプリケーションは単一バイナリ動作なので、機能を盛り過ぎるとバイナリが70MB程まで大きくなる。 必要な機能を抜粋して自前でソースビルドを行うと、バイナリ容量と使用メモリ容量の削減が出来る。 ~ *参考サイト [#ma8ed405] -[[powerdns+dnsdistの構築:+http://kyudy.hatenablog.com/entry/2016/12/27/193928]] -[[自宅環境にdnsdist 1.1.0を導入してみた。:+https://kometchtech.blog.fc2.com/blog-entry-2049.html]] ~ *インストール [#x03f304c] -&size(16){&font(b){1. ソースビルド};}; ソースビルドだと様々なディストリビューションで動作して汎用性が高いのでソースビルドする。 今回はopenSUSEでビルドを行っているが、CentOS/Debianでも同様の手順でビルド出来る。 下記のビルドオプションはフル機能を有効化している為、不必要な機能を削除するとバイナリが更に軽くなる。 # zypper install libedit-devel libsodium-devel systemd-devel fstrm-devel protobuf-devel boost-devel re2-devel # wget "https://downloads.powerdns.com/releases/dnsdist-1.3.3.tar.bz2" # tar jxvf dnsdist-1.3.3.tar.bz2 # cd dnsdist-1.3.3 # ./configure --prefix=/usr/local/dnsdist-1.3.3 \ --enable-dns-over-tls \ --enable-dnscrypt \ --enable-fstrm \ --enable-re2 \ --enable-systemd \ --with-ebpf \ --with-lua \ --with-net-snmp \ --with-protobuf \ --with-systemd \ --with-systemd-modules-load # make # make install # ln -s /usr/local/dnsdist-1.3.3 /usr/local/dnsdist -&size(16){&font(b){2. 起動準備};}; dnsdist専用ユーザで動作させる為、実行ユーザの作成とサービスファイルの準備を行う。 さらに、今回はDNSクエリログのローカル出力を有効化する為、ログディレクトリ作成、ログローテート設定も実施する。 バージョン1.5以上の環境でsystemd-notifyを使う環境では、ユーザ・グループ指定が出来なくなった。 この制御は、systemdでchroot同等の制御をしている事からエラーメッセージを出力する仕様に変わったため。 エラーを回避するにはユーザ・グループ指定を止めるか、systemd-simpleに変更する必要がある。 --[[dnsdist: don't start as root within a systemd environment:+https://github.com/PowerDNS/pdns/pull/7820]] :| #region(&color(#ff0000){ディレクトリ作成};) # mkdir /var/log/dnsdist # mkdir /usr/local/dnsdist/etc # ln -s /usr/local/dnsdist/etc /etc/dnsdist # groupadd dnsdist # useradd -d /var/log/dnsdist -s /sbin/nologin dnsdist # chown dnsdist.dnsdist /var/log/dnsdist # cp ${SOURCE}/dnsdistconf.lua /etc/dnsdist/dnsdist.conf.sample #endregion #region(&color(#ff0000){サービスファイル};) - systemd-notify # vi /usr/lib/systemd/system/dnsdist.service --- [Unit] Description=dnsdist DNS loadbalancer Documentation=https://dnsdist.org/ After=local-fs.target remote-fs.target network.target [Install] WantedBy=multi-user.target [Service] Type=notify Restart=on-failure EnvironmentFile=/etc/sysconfig/dnsdist ExecStartPre=/usr/local/dnsdist/bin/dnsdist --disable-syslog --check-config $OPTIONS ExecStart=/usr/local/dnsdist/bin/dnsdist --disable-syslog --supervised $OPTIONS ExecStop=/bin/kill -s QUIT $MAINPID ExecReload=/bin/kill -s HUP $MAINPID ## TUNING TasksMax=8192 LimitNOFILE=65536 - systemd-simple # vi /usr/lib/systemd/system/dnsdist.service --- [Unit] Description=dnsdist DNS loadbalancer Documentation=https://dnsdist.org/ After=local-fs.target remote-fs.target network.target [Install] WantedBy=multi-user.target [Service] Type=simple Restart=on-failure EnvironmentFile=/etc/sysconfig/dnsdist ExecStartPre=/usr/local/dnsdist/bin/dnsdist --disable-syslog --check-config $OPTIONS ExecStart=/usr/local/dnsdist/bin/dnsdist --disable-syslog --supervised -u $USER -g $GROUP $OPTIONS ExecStop=/bin/kill -s QUIT $MAINPID ExecReload=/bin/kill -s HUP $MAINPID ## TUNING TasksMax=8192 LimitNOFILE=65536 #endregion #region(&color(#ff0000){起動オプション};) # vi /etc/sysconfig/dnsdist --- USER="dnsdist" GROUP="dnsdist" OPTIONS="-C /etc/dnsdist/dnsdist.conf" #endregion #region(&color(#ff0000){ログローテート};) # vi /etc/logrotate.d/dnsdist --- /var/log/dnsdist/dnsdist.log { weekly compress rotate 4 missingok ifempty postrotate systemctl reload dnsdist > /dev/null endscript } #endregion ~ *コンフィグ [#he433c1c] 構築例ではdnsdistのコンフィグを &color(#ff0000){"/etc/dnsdist/dnsdist.conf"}; としている為、 下記コンフィグ例も同じファイルに設定を行う。 dnsdistの設定は単純な為、単にDNSロードバランサーとして稼働させるならば、 「DNSクエリ・クエリタイプ・接続元IPアドレス・パケット制御」の4項目を抑えれば設定出来る。 複数のポリシーを組み合わせる時は、MatchingPackets(Selectors)の &color(#ff0000){"AndRule/NotRule/OrRule"}; 条件、 バックエンドのサーバ設定は、Servers/Poolsの &color(#ff0000){"newServer/getServer"}; を利用する。 その他、細かい設定内容は公式ドキュメントの下記3項目を読めば大体判る。 -[[Configuration Reference:+https://dnsdist.org/reference/config.html]] -[[Loadbalancing and Server Policies:+https://dnsdist.org/guides/serverselection.html]] -[[Packet Policies:+https://dnsdist.org/rules-actions.html]] #region(&color(#ff0000){単純ロードバランサー};) ※ 実際の設定では頭の行番号("01: "など)を消す ============================================================================================ 01: -- BACKEND 02: check01 = "ns1.example.com." 03: check02 = "ns2.example.com." 04: newServer({address="10.0.10.1:53", pool="example", checkName=check01, mustResolve=true}) 05: newServer({address="10.0.10.2:53", pool="example", checkName=check02, mustResolve=true}) 06: 07: -- LISTEN 08: addLocal("10.0.0.1:53", {doTCP=true}) 09: 10: -- ACL 11: setACL("0.0.0.0/0") 12: 13: -- RULE 14: internet = newSuffixMatchNode() 15: internet:add(newDNSName("example.com.")) 16: 17: -- LOG 18: addAction(AllRule(), LogAction("/var/log/dnsdist/dnsdist.log", false, true, false)) 19: 20: -- POLICY 21: addAction(SuffixMatchNodeRule(internet), PoolAction("example")) 22: addAction(QTypeRule(dnsdist.TXT), PoolAction("example")) 23: addAction(AllRule(), RCodeAction(dnsdist.REFUSED)) |LEFT:50|LEFT:250|LEFT:600|c |CENTER:~LINE|CENTER:~PARAMETER|CENTER:~DESCRIPTION|h |&color(#2020ff){02行目};|&color(#2020ff){check01};|newServerで設定する監視先DNSサーバのFQDN設定。IPアドレス記述も可能| |&color(#2020ff){03行目};|&color(#2020ff){check02};|newServerで設定する監視先DNSサーバのFQDN設定。IPアドレス記述も可能| |&color(#2020ff){04行目};|&color(#2020ff){newServer};|プール名(example)にバックエンド(10.0.10.1:53)を、監視先FQDN(check01)で追加&br;監視先から"NOERROR RCODE"以外が返ってきたらエラー(監視失敗)とする| |&color(#2020ff){05行目};|&color(#2020ff){newServer};|プール名(example)にバックエンド(10.0.10.2:53)を、監視先FQDN(check02)で追加&br;監視先から"NOERROR RCODE"以外が返ってきたらエラー(監視失敗)とする| |&color(#2020ff){08行目};|&color(#2020ff){addLocal};|dnsdistが待受けるUDP用IPアドレス&br;doTCPを設定すると、同IPアドレスでTCP待受けも有効化出来る| |&color(#2020ff){11行目};|&color(#2020ff){setACL};|接続を許可するセグメント&br;setACLで複数記述、addACLで既存のACLに追加設定も出来る| |&color(#2020ff){14行目};|&color(#2020ff){newSuffixMatchNode};|サフィックス名とインスタンスの定義| |&color(#2020ff){15行目};|&color(#2020ff){newDNSName};|サフィックス名(internet)に、DNSドメイン名(example.com)を追加定義する| |&color(#2020ff){18行目};|&color(#2020ff){addAction/LogAction};|dnsdistが処理したDNSクエリログ保存先。addActionの中で必ず最初に設定する&br;パラメータを "false/true/false" にすると見やすい形で保存される| |&color(#2020ff){21行目};|&color(#2020ff){addAction/SuffixMatchNodeRule};|DNSクエリに "example.com(internetサフィックスで定義)" を含む時、&br;バックエンドの "example" プール(2~5行目で定義)に転送| |&color(#2020ff){22行目};|&color(#2020ff){addAction/QTypeRule};|DNSクエリタイプが "TXT(dnsdist.TXTで定義)" の時、&br;バックエンドの "example" プール(2~5行目で定義)に転送| |&color(#2020ff){23行目};|&color(#2020ff){addAction/AllRule};|上段の設定(addAction)で処理されなかったDNSクエリに対して、&br;REFUSED(リクエスト拒否)を返答する。設定の最後に記述する事を強く推奨| #endregion