avahiで自分のIPアドレスに複数のホスト名をエイリアスする
家のRaspberry Piにいくつかサーバーを立てていて、ポート番号を分けてアクセスしていたのだけど、番号だと分かりづらい。ホスト名でアクセスできるようにしたい。
DNSサーバーは立てずに、ホスト名は mDNS (avahi)で解決できるようにする。Raspbian Busterはデフォルトでavahiが動いているので、その設定を変える。
1つのIPアドレスに複数の名前を登録する
avahi は、/etc/avahi/hosts にホスト名-IPの組み合わせを書くと広報してくれる。ただし、同じIPアドレスのホストを複数登録できない。ホスト名.local はデフォルトで広報されるようになっているので、自分のホスト名にエイリアスをつけられない。追加するホスト名ごとにIPアドレスも追加してやればよいが、そういう事ではないような気がする。
/etc/avahi/hosts ではこのような制限があるが、avahi-utilsに入っている avahi-publishというコマンドで、-R --no-reverse
というオプションをつければ登録できる。こんな感じ:
avahi-publish -a -R aaa.hostname.local 192.168.1.9 & avahi-publish -a -R bbb.hostname.local 192.168.1.9 &
このコマンド、起動しっぱなしにしておかなくてはいけないらしく、バックグラウンドで動かしている点に注意。あと、上のコマンドだとログオフすると終了してしまうので注意。
自動化
ホストを起動したときに自動的に設定されるようにしたい。検索するとよく出てくる、systemdのサービスとして実行する方法を取る。{ホスト名}.localのサブドメインを設定するようにした。現在のIPアドレスは、eth0の"inet"から取ってくる。
$ cat /etc/systemd/system/avahi-subdomain@.service [Unit] Description=Publish %I.%H.local as alias for %H.local via mdns Requires=avahi-daemon.service After=avahi-daemon.service [Service] Type=simple ExecStart=/bin/bash -c "/usr/bin/avahi-publish -a -R %I.%H.local $(ip a show dev eth0 | awk '$1==\"inet\"{print $2}' | cut -d/ -f1)" Restart=on-failure RestartSec=3 [Install] WantedBy=multi-user.target
avahi-subdomain@{サブドメイン}.service でサービス登録&起動
$ systemctl enable --now avahi-subdomain@gr.service $ systemctl status avahi-subdomain@gr.service ● avahi-subdomain@gr.service - Publish gr.hostname.local as alias for hostname.local via mdns Loaded: loaded (/etc/systemd/system/avahi-subdomain@.service; enabled; vendor preset: enabled) Active: active (running) since Sun 2020-10-11 17:00:42 EDT; 1min 6s ago Main PID: 23264 (avahi-publish) Tasks: 1 (limit: 2065) CGroup: /system.slice/system-avahi\x2dsubdomain.slice/avahi-subdomain@gr.service └─23264 /usr/bin/avahi-publish -a -R gr.hostname.local 192.168.1.9
IPv6対応
サーバー(Raspberry Pi)もクライアント(Mac)も、IPv6を有効にしている。このとき、SafariはIPv6で名前解決して失敗したらIPv4にフォールバックしないのを忘れていた。IPv6も名前登録するようにする。
少しコマンドが長くなるので、シェルスクリプトを実行するように変更した。
$ cat /usr/local/bin/avahi-add-subdomain.sh #!/bin/bash set -e SUBDOMAIN=$1 HOSTNAME=$(uname -n) ADDRS=$(ip a show dev eth0 | awk '$1~/inet/{print $2}' | cut -d/ -f1) for ADDR in $ADDRS; do echo "Add $SUBDOMAIN.$HOSTNAME.local $ADDR" /usr/bin/avahi-publish -a -R $SUBDOMAIN.$HOSTNAME.local $ADDR& done wait
最後にwaitを入れないとバックグラウンドジョブが実行されない。スクリプト単体で実行すると問題ないのだけど。なぜだろう。。
$ cat /etc/systemd/system/avahi-subdomain@.service [Unit] Description=Publish %I.%H.local as alias for %H.local via mdns Requires=avahi-daemon.service After=avahi-daemon.service [Service] Type=simple ExecStart=/usr/local/bin/avahi-add-subdomain.sh %I Restart=on-failure RestartSec=3 [Install] WantedBy=multi-user.target