戻る

ZNC解説

Mar 8, 2020

IRCはそのまま使うには不便なのは自明. チャンネルから切断している間のログはなく, 自分のネットワークのホストは丸見えになってしまうので, クライエントから直接IRCサーバーへつなぐのではなくVPNサーバーなどリモートサーバーにbouncerを起動させることでこれらの問題を解決する. 今回はbouncerとしてメジャーなZNCを使う方法について解説したい.

インストール

多くのLinux環境に対応している. Archならば pacman -S znc でインストールできる. 今回znc 1.7.5のバージョンで解説している. バージョンにより若干異なるが概ねは指示を読めば大丈夫だろう.

今回 https://tom.busby.ninja/setting-up-znc-IRC-bouncer-to-use-tor/ を全面的に参考にしている. ここよりも参照先を見た方が丁寧だろう.

IRCサーバーのユーザー登録

IRCサーバーの多くでユーザー登録ができ, また推奨されている. IRCサーバーのユーザー登録してからZNCのネットワークを構成するという順でないといけない. 今回yamadaというユーザーで登録したい場合で解説する. パスワード登録の方法で解説しているが, 気が向いたらCertFPでの認証も解説するかもしれない.

freenodeの場合


/server add freenode chat.freenode.net/6697 -ssl

https://freenode.net/kb/answer/registration はfreenodeの公式ドキュメントだが, それを読むのも面倒という人のためにコマンドだけ抽出.


/nick yamada
/msg NickServ REGISTER password yamada@email.com 

するとメールが送られてくるはずなので指示に従うだけ.

https://freenode.net/kb/answer/weechat を参考にSASLを設定.


/set irc.server.freenode.sasl_mechanism PLAIN
/set irc.server.freenode.sasl_username <nickname>
/set irc.server.freenode.sasl_password <password>
/save

freenodeのチャンネルの探し方は次のコマンドで. https://freenode.net/kb/answer/findingchannels に書いてあるが.


/msg alis LIST *searchterm*

zncユーザー作成

ルートユーザーでzncを起動するのはとても危険なので, zncユーザーを作りznc専用のアクセスのみ許可するようにしてセキュリティを担保する. https://wiki.znc.in/Running_ZNC_as_a_system_daemon を参考にすればよいが, ここでも説明をかく. まず次のコマンドでzncユーザーを作成する.


sudo useradd --create-home -d /var/lib/znc --system --shell /sbin/nologin --comment "Account to run ZNC daemon" --user-group znc

普段見慣れないオプションがあると思うが, --create-homeは-mと等価, -dで/var/lib/zncをホームディレクトリとして指定. --systemはsystem用のアカウントでこのアカウントからの様々なファイルへのアクセスを制限させる. --shell /sbin/nologin はこのzncユーザーから他のユーザーへログインできないアカウントなる. --user-groupも見慣れない感じだが, -Uと等価, -gと若干違ってこのユーザー名と同じグループを作成してそのユーザーをそのグループに入れる. つまりzncユーザーとzncグループを作成し, zncユーザーはzncグループに属するということだ. しかしながらこのオプションは指定しなくても勝手にグループは作成されるものだが, この--systemオプションがついていると実は/etc/login.defsを読まないのでこのデフォルトの設定は全てオフになってしまう為このように明示的にグループ作成をオプションに入れないといけない.

https://qiita.com/LostEnryu/items/9b0c363877581dc1171f nologinについてはここも参考になる.

zncで使うデータを入れるディレクトリはデフォルトでは~/以下に入れてしまうが, /var/lib/znc で扱う方が安全なので次のオプションでzncをセットアップ.


sudo -u znc /usr/bin/znc --datadir=/var/lib/znc --makeconf

ZNCのネットワーク構成

znc --makeconfで一つのIRCサーバー(ネットワーク)へ接続するデーモンを構成できる. 今回yamadaというnicknameで解説する. ZNCへのポートを6667以外に適当に選んでおく. 今回1123にした. 6667を避ける理由はwebadminを起動させるため.


% sudo -u znc /usr/bin/znc --datadir=/var/lib/znc --makeconf                                                     [1]
[ .. ] Checking for list of available modules...
[ ** ]
[ ** ] -- Global settings --
[ ** ]
[ ?? ] Listen on port (1025 to 65534): 1123
[ ?? ] Listen using SSL (yes/no) [no]:
[ ?? ] Listen using both IPv4 and IPv6 (yes/no) [yes]:
[ .. ] Verifying the listener...
[ ** ] Unable to locate pem file: [/var/lib/znc/znc.pem], creating it
[ .. ] Writing Pem file [/var/lib/znc/znc.pem]...
[ ** ] Enabled global modules [webadmin]
[ ** ]
[ ** ] -- Admin user settings --
[ ** ]
[ ?? ] Username (alphanumeric): yamada
[ ?? ] Enter password:
[ ?? ] Confirm password:
[ ?? ] Nick [yamada]:
[ ?? ] Alternate nick [yamada_]:
[ ?? ] Ident [yamada]:
[ ?? ] Real name (optional):
[ ?? ] Bind host (optional):
[ ** ] Enabled user modules [chansaver, controlpanel]
[ ** ]
[ ?? ] Set up a network? (yes/no) [yes]: no
[ ** ]
[ .. ] Writing config [/var/lib/znc/configs/znc.conf]...
[ ** ]
[ ** ] To connect to this ZNC you need to connect to it as your IRC server
[ ** ] using the port that you supplied.  You have to supply your login info
[ ** ] as the IRC server password like this: user/network:pass.
[ ** ]
[ ** ] Try something like this in your IRC client...
[ ** ] /server <znc_server_ip> 1123 yamada:<pass>
[ ** ]
[ ** ] To manage settings, users and networks, point your web browser to
[ ** ] http://<znc_server_ip>:1123/
[ ** ]
[ ?? ] Launch ZNC now? (yes/no) [yes]: no

とりあえず今はネットワークも構成せずzncを起動しない.

weechatからZNCへ繋ぐ

次のコマンドでfreenode用のZNCサーバーをweechatに追加する. これでZNCサーバーへ自動ログインができる.


/server add znc_freenode <ZNCサーバーのIPアドレス>/1123 \
  -username=yamada/freenode -password=password

systemdに登録して自動で起動するようにする

サーバーを再起動させた後zncを起動するためにいちいちzncコマンドを打つのは面倒臭いので登録する. systemdユニットを作る. /etc/systemd/system/znc.serviceを作成し以下を記述.


[Unit]
Description=ZNC, an advanced IRC bouncer
After=network-online.target
     
[Service]
ExecStart=/usr/bin/znc -f --datadir=/var/lib/znc
User=znc
     
[Install]
WantedBy=multi-user.target

systemdユニット起動.


sudo systemctl enable znc.service
sudo systemctl start znc.service

webadminへ行き, 6697ポートを追加, freenodeのネットワークを構成する. nickname, ホストなどを設定 ここは参照先を参考にしてほしい.

構成し終わったら, https://wiki.znc.in/Weechatに従ってweechatからzncへsslを使って通信できる様にしたい. まずsslを発行する.


sudo -u znc cat /var/lib/znc/znc.pem | openssl x509 -sha512 -fingerprint -noout | tr -d ':' | tr 'A-Z' 'a-z' | cut -d = -f 2
162f9c92f80b048efb1ec06d4d04edab9fb7c399c36a2879a23994197970c8fbcefbe264401ea626b600b01e04bf99a4b483cdfd16ca4246de7958bad54bda11

次のweechatのコマンドでweechatとzncでssl通信をする. my.bouncer.netはもちろんzncを入れるサーバーのipアドレス.


/server add freenode-znc my.bouncer.net/6697 -ssl -username=yamada/freenode -password=password 
/set irc.server.freenode-znc.ssl_fingerprint 162f9c92f80b048efb1ec06d4d04edab9fb7c399c36a2879a23994197970c8fbcefbe264401ea626b600b01e04bf99a4b483cdfd16ca4246de7958bad54bda11
/save
/connect freenode-znc

weechatではzncコマンドは外部コマンドなので安全性のためからデフォルトで無効になっている.


/set irc.network.send_unknown_commands on

もしくはaliasを作る


/alias add znc /quote znc

zncコマンドでfreenodeのsslを信用する. fingerprintはバッファで指示されたものをコピペ.


/znc AddTrustedServerFingerprint e9:db:e1:0c:79:66:a8:da:0c:84:18:bc:81:59:6c:87:b0:25:7f:b4:80:2d:94:25:d6:40:2c:dc:96:03:51:c8

プラグインを入れてみる.


/script install zncplayback.py

後からZNCの設定を変更したい

/zncコマンドを使ってネットワークを追加できる. 上で設定したネットワークはfreenode用だったが, ネットワークは複数設定できる. ここでは例としてgrepnetのircサーバーを https://grepnet.org/ に従って追加する. まずweechatでzncに繋ぐ.

/znc addnetwork grepnet
/znc jumpnetwork grepnet
/znc addserver irc.grepnet.org +6697
/znc connect

ログについて

なぜかログについて解説している記事が皆無なのだが, それではzncを導入した意味がなくなってしまう. ログ管理こそzncの真髄なのだから. まずログモジュールを次のコマンドで入れる. モジュール自体はzncにもともと入っている.


/znc LoadMod log

このモジュールを使うには, /msg *log コマンドで*logというバッファが開かれる. そこでHelpとうてば使えるコマンドが表示される. しかしこのコマンド達はルールの設定をするためのものでありログを読むものではない. じゃあログをどうやって読むか. ログが置かれている場所はzncを起動しているサーバーの/var/lib/znc/users/$USER/moddata/log/ 以下にあるが, IRCクライエントでログを読みたい. ログの場所は実はモジュールのロードの仕方によって異なることに注意. デフォルトではユーザーの文脈でlogを管理するはず. https://wiki.znc.in/Log にログの管理場所の詳細がある. ここではbacklog外部モジュールを利用してzncのログを読めるようにする. https://github.com/FruitieX/znc-backlog/blob/master/README.md の指示に従う. 私の場合は/user/lib/znc/にモジュールをおいた.


git clone https://github.com/FruitieX/znc-backlog
cd znc-backlog
make
cp backlog.so /user/lib/znc/ 

backlogモジュールを読み込む.


/znc LoadMod backlog

ログを読み込むパスを指定する. ユーザーの文脈では次のようにパスを設定すればいいはず.


/msg *backlog LogPath /var/lib/znc/users/$USER/moddata/log/$NETWORK/$WINDOW/*.log

エイリアスを指定.


/alias add bl msg *backlog $channel $1

あとはログを見たいバッファで/blとすれば良い.

weechat側でログを管理する必要がなくなったので, weechatのログをオフにする.


set logger.level.irc 2

zncのコマンドの扱い

今までznc特有のコマンドは /zncをつけていたが, /zncコマンドを一回使うと*statusバッファが開かれているはずだ. このstatusバッファでは/zncをつけなくても単に例えばaddnetwork grepnetとするだけでgrepnetで飛ベたりする. この様にバッファによってコマンドの文脈が変わるということが, ircの一つ難しいところなので意識しなくてはならない. /msg *log コマンドの意味は *log というバッファにコマンドを送るということだと推測できる. 例えば*logバッファ以外のバッファにいたとする. そこで次のコマンドをうつ.


/msg *log listrules

すると*logバッファに行ってみるとそこでlistrulesした時と同じ結果になっているだろう. また, *logバッファでhelpを見れば分かる通り, コマンド名はListRulesで説明されている. しかしながら全て小文字でもコマンドをちゃんと解釈してくれるので, listrulesでokと言うわけだ.

モジュールについて

ログについて解説したが, もう一度説明をまとめる. logはモジュールなのだから, /znc LoadMod log としなければ/msg log としても*logバッファは起動されない. モジュールをまず導入するには次のコマンドする. *statusバッファにいないなら/znc を先頭につける.


LoadMod <モジュール名>

次に, このモジュールのバッファを開きたいとする. そのためには次のコマンドする.


/msg *<モジュール名>

すると*<モジュール名>というバッファが開かれるのでそこへ行き, そのモジュールで使えるコマンドを確認するには次のコマンドする.


help

Controlpanelモジュール

webadminで設定をする他にcontrolpanelモジュールという標準モジュールを使うことでzncの設定ができる.


/znc LoadMod controlpanel

pushモジュール

https://github.com/jreese/znc-push

日本サーバーへ入るための文字コード

日本サーバーはutf-8ではなくISO-2022-JPという文字コードで扱うところが多いので, 文字コードを適切に設定しなくてはならない. この設定をしないと/join #チャンネル名 をしてもなぜか無人だったり入れなかったりする. これは別の文字コードでjoinしているので別チャンネルという扱いになっているからで, zncではなぜか文字化けしていないのにこういう現象が起きる. ここでは例としてjpnetというネットワーク名でzncに登録したことにする. 今回weechatとznc間はutf-8で, zncとjpnetはISO-2022-JPでやりとりすることになる. https://wiki.znc.in/Charset を見ればわかるが, ここでも説明する. 次のコマンドするだけで良い. もちろんusername, jpnetは自分が決めたものの名前を入れる. 重要なのはweechatは何も文字コードの設定をしないということだ. znc側に任せるのだ.


/msg *controlpanel SetNetwork Encoding username jpnet ISO-2022-JP

参考記事

https://blog.handlena.me/entry/2013/01/20/185717/ zncはサーバーごとにアカウントかと思いきや実は複数サーバーに接続できるという話.
http://kawamuray.hatenablog.com/entry/2013/08/12/213005 ZNCでよく使うコマンド.
https://flusp.ime.usp.br/others/2019/01/14/chatting-on-irc-with-weechat-and-znc/ 連携を含めてちゃんと解説してくれる貴重な記事.
http://noaboutsnote.hatenablog.com/entry/znc_slack