ejabberd 19.09.1をインストールしてクラスタリングする
「いまさらXMPP」と言われそうですが、オープンであることはそれだけで価値があることだと思います。
今回、XMPPサーバーのErlang実装である ejabberd をインストールしてクラスタリングしようと思います。 ejabberdはXMPPの他にMQTTとSIPも喋れるので我が家の萬のことに使えそうです。
とりあえず皆さんお手持ちのサーバーがあると思いますが、私は2台のサーバーにUbuntu Server 18.04 LTSをインストールして最新の状態にアップデートしておきました。 CentOSでもArch Linuxでも何でも大丈夫だと思います。 dpkgとrpmはバイナリパッケージが有りましたが、私はSource packageでインストールしていきます。
DNSサーバーもあると便利なのですが、ここでは省きます(私は設定しますが)。
Erlang/OTP 22のインストール
導入方法は何でもいいと思います。私はソースから入れてみます。
必要なパッケージは README.md
を確認してほしいのですが、私はこんな感じに入れています。書き漏らしているものがあったらスミマセン。
sudo apt install -y build-essential libssl-dev zlib1g-dev libncurses5-dev autoconf curl git
cd ~/ curl -L https://github.com/erlang/otp/archive/OTP-22.1.3.tar.gz | tar -zx cd otp-OTP-22.1.3 ./otp_build autoconf ./configure --prefix=/usr/local/erlang/22.1 \ --enable-smp-support \ --enable-m64-build \ --disable-sctp \ --enable-threads \ --enable-kernel-poll \ --enable-hipe \ --without-javac \ --without-wx \ --without-docs \ --without-odbc \ --disable-debug make -j2 sudo make install
インストール
cd ~/ curl -L https://github.com/processone/ejabberd/archive/19.09.1.tar.gz | tar -zx cd ejabberd-19.09.1
sudo apt install -y libexpat1-dev
さて ejabberd のビルドを始めます。
./autogen.sh ./configure --prefix=/usr/local/ejabberd \ --with-erlang=/usr/local/erlang/22.1 \ --enable-user=ejabberd \ --enable-group=ejabberd \ --enable-tools \ --enable-elixir \ --enable-zlib \ --enable-hipe \ --enable-sip \ --enable-stun make -j2 sudo make install sudo useradd -M -d /usr/local/ejabberd/ -s /usr/sbin/nologin ejabberd sudo chown ejabberd:ejabberd -R /usr/local/ejabberd sudo cp ejabberd.service /etc/systemd/system/ejabberd.service
設定
/usr/local/ejabberd/etc/ejabberd/ejabberd.yml
を適当に変更します。基本的に特殊な話はないですが、最初の hosts
のところはejabberdクラスタ全体としての(XMPPサーバーの)ホスト名です。
ここでは example.com
としていますので、jid@example.com
というJIDを使うことになります。
--- /usr/local/ejabberd/etc/ejabberd/ejabberd.yml.orig 2019-10-19 07:01:43.351109724 +0900 +++ /usr/local/ejabberd/etc/ejabberd/ejabberd.yml 2019-10-19 07:01:47.711079485 +0900 @@ -15,7 +15,7 @@ ### hosts: - - localhost + - "example.com" loglevel: 4 log_rotate_size: 10485760 @@ -36,7 +36,7 @@ max_stanza_size: 262144 shaper: c2s_shaper access: c2s - starttls_required: true + starttls_required: false - port: 5269 ip: "::" @@ -46,7 +46,7 @@ port: 5443 ip: "::" module: ejabberd_http - tls: true + tls: false request_handlers: /admin: ejabberd_web_admin /api: mod_http_api @@ -153,7 +153,7 @@ mod_fail2ban: {} mod_http_api: {} mod_http_upload: - put_url: https://@HOST@:5443/upload + put_url: http://@HOST@:5443/upload mod_last: {} mod_mam: ## Mnesia is limited to 2GB, better to use an SQL backend
続いて /usr/local/ejabberd/etc/ejabberd/ejabberdctl.cfg
を編集します。Erlangのノード名を指定します。
私は1号機のホスト名は xmpp1
, 2号機は xmpp2
としています。
--- /usr/local/ejabberd/etc/ejabberd/ejabberdctl.cfg.orig 2019-10-19 07:07:51.002048355 +0900 +++ /usr/local/ejabberd/etc/ejabberd/ejabberdctl.cfg 2019-10-19 07:07:54.230022994 +0900 @@ -134,7 +134,7 @@ # # Default: ejabberd@localhost # -#ERLANG_NODE=ejabberd@localhost +ERLANG_NODE=ejabberd@xmpp1 #. #' EJABBERD_PID_PATH: ejabberd PID file
xmpp1
, xmpp2
ともにお互いがお互いのホスト名を解決できるように、/etc/hosts
も設定しておきます。ここはDNSが自由に設定できるならそれでも構わないです。
例は省きます。
起動してみる
とりあえず xmpp1 だけ起動してみます。
sudo systemctl start ejabberd
ejabberdctl
を使ってステータスを見てみます。
sudo -u ejabberd -H /usr/local/ejabberd/sbin/ejabberdctl status
こんな結果が戻ればOKです。
The node ejabberd@xmpp1 is started with status: started ejabberd 0.0 is running in that node
XMPPのホスト名も確認します。example.com
が戻ればOKです。
sudo -u ejabberd -H /usr/local/ejabberd/sbin/ejabberdctl registered_vhosts
ユーザー登録してみる
dummy
ユーザーと dummy2
ユーザーを登録してみます。パスワードは pass123
にしました。
sudo -u ejabberd -H /usr/local/ejabberd/sbin/ejabberdctl register dummy example.com pass123 sudo -u ejabberd -H /usr/local/ejabberd/sbin/ejabberdctl register dummy2 example.com pass123
User dummy@example.com successfully registered
などと表示されれば登録できています。
試しにクライアントから接続してみます。接続先のサーバーはxmpp1のIPアドレスを直接指定します。
PidginというXMPPクライアントでの設定画面はこうなります。
dummy@example.com
と dummy2@example.com
を設定してどちらもオンラインにします。
お互いにユーザー追加をしてメッセージを送れれば大丈夫です。
2号機(xmpp2) もユーザー登録以外は同様の設定をして動かしておきます。
クラスタリング
/usr/local/ejabberd/.erlang.cookie
をxmpp1からxmpp2にコピーします。
一応 sha1sum /usr/local/ejabberd/.erlang.cookie
でハッシュ値を確認して、同一であることを確認します。
ファイルのオーナーも調整しておきます。
sudo chown ejabberd. /usr/local/ejabberd/.erlang.cookie
一旦ejabberdを再起動して
sudo systemctl restart ejabberd
クラスタに参加します。
sudo -u ejabberd /usr/local/ejabberd/sbin/ejabberdctl --no-timeout join_cluster 'ejabberd@xmpp1'
うまくいっていることを確認します。
$ sudo -u ejabberd -H /usr/local/ejabberd/sbin/ejabberdctl list_cluster ejabberd@xmpp1 ejabberd@xmpp2
xmpp1とxmpp2で情報が同期されているはずなので、確認します。xmpp2でコマンドを叩いてみます。
$ sudo -u ejabberd -H /usr/local/ejabberd/sbin/ejabberdctl registered_users example.com dummy dummy2
dummy@example.com
でxmpp1に、 dummy2@example.com
でxmpp2に接続してメッセージがやり取りできることを確認しておきましょう。
おわり
以前はejabberdのクラスタリングはmnesiaの同期操作を手作業でしないといけなかったのですが、最近のリリースではコマンドひとつでできるようになりました。 ぜひみなさんも高機能なXMPPで遊んでみてください。