セットアップした Zabbix フロントエンドで日本語が使えなかったので表示できるようにする

テスト運用していた Zabbix 2 系はまともに触らずに放置されていたのですが、Zabbix 3 系が出てきたので新しくサーバーをセットアップしました。やっぱりテスト運用ですが。

前に書いたシェルスクリプトでガツンとインストールして無事フロントエンドにログインできました。

フロントエンドにログインできたのはいいんですが、ユーザーの言語設定で日本語を選ぶことができなかったので選べるようにする設定変更をしました。

f:id:k-side:20160610160435p:plain

debian jessie で動く Zabbix 3.0.3 での設定です。

まずシステムの言語設定に日本語を追加します。

$ sudo vi /etc/locale.gen
ja_JP.UTF-8 UTF-8

ja_JP.UTF-8 UTF-8 のコメントを外すだけです。

そしてシステムに設定変更を反映させます。

$ sudo locale-gen

ついでにグラフで表示される日本語が豆腐になるのも直しておきます。

まずは日本語フォントをインストール

$ sudo apt-get install fonts-ipafont -y

Zabbix で認識されるフォントのディレクトリにシンボリックリンクを張ります。

$ sudo ln -s /usr/share/fonts/opentype/ipafont-gothic/ipagp.ttf /usr/share/zabbix/fonts/ipagp.ttf

Zabbix フロントエンドの設定にあるフォントの名前を、シンボリックリンクの名前に書き換えます。

$ sudo vi /usr/share/zabbix/include/defines.inc.php
define('ZBX_GRAPH_FONT_NAME',    'ipagp');

Zabbix サーバーと Apache2 を読み直して完了。

$ sudo service zabbix-server restart
$ sudo service apache2 reload

f:id:k-side:20160610160436p:plain

日本語も選べるようになりました。
おしまい。

ってシェルスクリプトでこのあたりもできるようにすると楽かもなー…。

MORIO Dojo 白帯の認定をいただきました

MORIO Dojo とは

MORIO Dojo って何かと言うと、IDCF クラウド アンバサダープログラムのことで、 IDCF クラウドの魅力を発信するアンバサダーの集まりですね。

このアンバサダープログラムでは IDCF クラウドの情報を発信する強さ(広さ?)に応じて段位があり、定められた要件をクリアして事務局に申請すると昇段することができるようです。

今回申し込むにあたって特段の活動はしてなかったので白帯での認定となりました。
白帯の認定要件に「ご自身のPCに、MORIOステッカーを貼っている」というものがありますが、入門の依頼と同時にステッカーの送付も依頼できるので、Qiita のアカウントやブログを持っていれば入門することができるようです。

IDCF クラウドを使っているのか

公開せずに WMS のサーバーとして利用しています。

light.S1 というプランで、現在は CPU 1コア 0.8GHz、メモリ 1GB で月額上限200円、その他に15GBのメインストーレジを付けて併せて500円(税抜き)です。安い。

IDCF クラウドでは通常の VPS とは異なり、仮想マシンが仮想ルーターの下にあり直接グローバルにさらされていないため、普通のファイアウォール設定の上に仮想ルーターがあればより安心だろうという安易な考えで使っています。
グローバル側からアクセスできるのは SSH で使うポートだけですが、作成した仮想マシンから VPN への接続をしているため VPN 側からは WMS サーバーへの接続が可能です。

ちょうど(?)この記事の内容をセットした感じです。

基盤地図情報WMS は農研機構も発信してくれていますが、自分で立てた方がレンダリングとか好きにできるからいいんですね。

他にもオブジェクトストレージなどのサービスが利用できるのでぼちぼち使って行ければなぁと思っているところです。

dynabook Satellite B354/25KB がやってきた

2年半くらい前に父親が買ったノートパソコンです。
スペックはこんな感じ

パーツ 型番等
CPU Core i5 4200M
RAM DDR3L 4GB
HDD 500GB
OS Windows7 Pro 64bit
液晶 15.6インチ 1,366×768 TFT
その他 Office Home and Business 2013

なんでも買った当初からあまり安定せず、何度かメーカーに相談して修理に出したもののやっぱり安定しなかったので持ってけと言われたものです。
使ってるんじゃないかと思いましたが、以前父親にあげた ThinkPad T61 が Windows10 で安定しているのでそっちを使うとのこと。CPU はが大分落ちるけどメモリが多くて SSD にしてあるのでそれほど気にならないらしい。

父親はヘビースモーカーなので、持って帰った後にアルコール除菌タイプのウェットティッシュで筐体を隅々まで拭き、ファブリーズを吹き付けてさらにウェットティッシュで拭き取り、無香空間と一緒にポリ袋に入れておいたらなんとか臭いが減りました。
稼働させるとまだ少しファンからタバコの臭いが出てくるので、できれば分解して掃除したいところですが。

メーカーが最初から入れている Windows に安定して使えるイメージがないので Windows 10 にアップグレードしました、設定等は引き継がずにクリーンインストールしています。

Core i5 4200M であれば、現在自宅でメインに使っている ThinkPad T420 の Core i7 2620M と概ね同じ程度の性能があります。
安定して動かせるようならその状態で父親に返して使ってもらう方がいいので、dynabook をメイン機にして ThinkPad T420 は仮想環境基盤として Hyper-V でも入れてみようかと思います。

Slack から Hubot 経由で会社にあるパソコンの電源をオンにする

会社の自分用サーバーで Hubot を動かして Slack からの命令でデスクトップパソコンにマジックパケットを飛ばします。

起動せたいパソコンは既に Wake on LAN の設定は終わっていて、スマホWoL クライアントからはマジックパケットを送って起動できるようになっています。
しかしこの方法ではパソコンとスマホが同じネットワーク上にないといけないので、出社してからモバイルルータのスイッチを切り、会社の Wi-Fi に接続されたのを確認してからアプリを起動してマジックパケットを送るというあんまりスマートではない運用でした。
Slack から起動命令を送ることができれば、会社に着く直前でモバイルルータに接続された状態であっても起動命令を送ることができるようになります。
もっとも、パソコンの電源スイッチを押すのは「始業時間くらいになってからでいいんじゃね」という本質的な問題を孕んでいます。

とりあえずその辺はおいといて、今回やった方法については下記の感じで。
環境としては debianKVM 上にセットした FreeBSD 10.3-RELEASE に設定します。

Slack や Hubot の設定に関するほとんどの部分はこちらのブログを参考にしています。

まずは Slack で Hubot Integration の設定をして起動コマンドを発行したいチャンネルに bot アカウントを /invite しておきます。
Hubot Integration の設定で表示される API Token を使うので適当にコピーしておく必要があります。

続いて FreeBSD 側の設定、まずは Node.js のインストール。

$ cd /usr/ports/www/node
$ sudo make config-recursive
$ sudo make install clean-denepds
$ node -v
v6.2.0

さらに npm をインストール。

$ cd /usr/ports/www/npm
$ sudo make config-recursive
$ sudo make install clean-depends
$ npm -v
3.9.2

Hubot のディレクトリを作って Hubot 関連をインストール。

$ cd ~
$ mkdir -p hubot/magic
$ cd ~/hubot/magic

$ sudo npm install -g coffee-script hubot
$ sudo npm install -g yo generator-hubot

Hubot を設定します。 Bot adapterslack にしておけばなんとかなるっぽいです。

$ yo hubot
Owner : Zoar
Bot name : magic
Description : A simple helpful robot for your Company
Bot adapter : slack

Slack と Hubot の疎通ができるか確認するスクリプトを書いて bot を起動します。

$ vi scripts/hello.coffee
module.exports = (robot) ->
   robot.hear /hello/, (msg) ->
      msg.send msg.random [
         'hello',
         'what?'
      ]
$ HUBOT_SLACK_TOKEN=%API TOKEN% ./bin/hubot --adapter slack

%API TOKEN% は Hubot Integration で表示された API Token を使います。
設定したチャンネルで hello を打って bot から反応があれば OK.

続いて Hubot からシェルスクリプトを動かせるかどうか確認します。

$ mkdir scripts/shell
$ vi scripts/shell/test.sh
#!/bin/sh
pwd
whoami
$chmod +x scripts/shell/test.sh
$ vi scripts/slack.coffee
module.exports = (robot) ->
  robot.respond /test_shell/, (msg) ->
    @exec = require('child_process').exec
    command = "sh /home/zoar/hubot/magic/scripts/shell/test.sh"
    msg.send "Command: #{command}"
    @exec command, (error, stdout, stderr) ->
      msg.send error if error?
      msg.send stdout if stdout?
      msg.send stderr if stderr?
$ chmod + x scripts/shell/test.sh

Hubot を再起動して Slack 側で bot に対して test_shell という@コメントを飛ばして bot から実行したコマンドと、Hubot のディレクトリ、 Hubot を実行しているユーザ名が返ってくれば OK.

今度は FreeBSD からマジックパケットを送信する net/wol をインストールします。

$ cd /usr/ports/net/wol/
$ sudo make config-recursive
$ sudo make install clean-depends
$ wol --version 
wol 0.7.1
<snip>

試しにマジックパケットを飛ばして起動させてみます。

$ wol -i 192.168.135.255 00:aa:11:bb:22:cc
Waking up 00:aa:11:bb:22:cc...

これで起動してくれれば Hubot から実行するスクリプトを書きます。

$ vi scripts/shell/wol.sh
#!/bin/sh
echo "Send magic packet to ProDESK600"
wol -i 192.168.135.255 00:aa:11:bb:22:cc
$ chmod +x scripts/shell/wol.sh

次は Slack のレスポンスを担当する Coffee スクリプト

$ vi scripts/slack.coffee
module.exports = (robot) ->
  robot.respond /wol_pc/, (msg) ->
    @exec = require('child_process').exec
    command = "sh /home/zoar/hubot/magic/scripts/shell/wol.sh"
    msg.send "Command: #{command}"
    @exec command, (error, stdout, stderr) ->
      msg.send error if error?
      msg.send stdout if stdout?
      msg.send stderr if stderr?

Hubot を再起動した後 botwol_pc というリプライを飛ばしてパソコンが起動すればOK.

会社最寄りの交差点で信号待ちしてる間に Slack からコメント送れば席に着くまでに起動しててくれると思います。
できればもうちょっと簡単にしたいところですが…。

FreeBSD にしたのは、たまたま動かしてるマシンの中で一番付加の小さいマシンだったからで特に宗教的な意味とかはないです。

ローカル DNS サーバとして Dnsmasq を設定した

ntpq の結果が返ってくるのが遅かった件で原因が名前解決にあったので、じゃあ DNS サーバー置くかという勢いで設定しました。

とはいえ BIND を設置するのもコスト高いよなと思ったので、簡単に設置できそうな Dnsmasq を設定することにしたわけです。

今回 DNS サーバーにしたマシンには既に NTP サーバーとして chrony、 Web サーバーとして Apache2、監視サーバーとして Zabbix、Zabbix のデータ保存用データベースとして MySQL が動いていますが、それ以外はなんの変哲もない debian 8.4 の x86 が動く ThinkPad X60s です。

手抜き設定です。

まずはインストール、apt-get で入れていきます。

$ sudo apt-get install dnsmasq -y

設定ファイルを編集して DNS サーバー自身の名前解決では /etc/resolv.conf の順番通りに問い合わせをするように変更します。

$ sudo vi /etc/dnsmasq.conf
static-order

/etc/resolv.conf を編集して外部 DNS サーバーよりもローカル DNS サーバーが上になるようにします。

$ sudo vi /etc/resolv.conf
nameserver 127.0.0.1
nameserver 8.8.8.8

LAN 内の名前解決には Dnsmasq のマシンの hosts ファイルが利用されるのでこれを編集して適当にマシン名と ip アドレスを書き込む。

$ sudo vi /etc/hosts
192.168.10.11   X60s
192.168.10.12   X40
192.168.10.14   debian
192.168.10.109  rpi

最初の 192.168.10.11 X60sDNS サーバー自身のアドレスです。 hosts ファイルの編集が終わったら Dnsmasq を再起動させる。

$ sudo service dnsmasq restart

試しに ThinkPad X40 (ホスト名は X40)の名前解決をしてみます。

$ nslookup x40
Server:         127.0.0.1
Address:        127.0.0.1#53

Name:   x40
Address: 192.168.10.12

ちゃんと返ってきました。
普通のドメインを名前解決できるか確認します。

$ nslookup www.yahoo.co.jp
Server:         127.0.0.1
Address:        127.0.0.1#53

Non-authoritative answer:
www.yahoo.co.jp canonical name = www.g.yahoo.co.jp.
Name:   www.g.yahoo.co.jp
Address: 183.79.231.182
Name:   www.g.yahoo.co.jp
Address: 182.22.59.229
Name:   www.g.yahoo.co.jp
Address: 182.22.63.230
Name:   www.g.yahoo.co.jp
Address: 124.83.235.204

大丈夫そうです。

いくらサーバーを設定しても他のマシンが参照してくれないので、他のマシンを設定して回ります。
なお、今回設定するのは全部 debian です。8系と7系が混じってますが、同じ設定でイケそうです。

$ sudo vi /etc/resolvconf.conf
name_servers=192.168.10.11 

もしくは

$ sudo vi /etc/network/interfaces
dns-nameservers 192.168.10.11

ついでに

$ sudo vi /etc/resolv.conf
nameserver 192.168.10.11
nameserver 8.8.8.8

今後マシンを増やしたりしたら NIC の設定でローカル DNS を見に行くように設定すれば大丈夫でしょう。

ntpq -p の結果が出るのが遅いので調べた

時刻合わせをしたくて ntp のデーモンを入れたはいいけど ntpq -p の結果が返ってくるまでの時間が結構かかっているマシンがありました。
当初は結果が出ないわけではないので放置していたのですが、 Zabbix で ntp の状況をモニタできるようにしようとしたところ、Zabbix Agent が ntpq を実行したときに値を取得できない状態となってしまいました(おそらくタイムアウトが発生して返り値が null になってる)。

結果を先に書くと ntpq -p ではなく ntpq -pn を実行するか、DNS なり hosts ファイルを編集すれば結果は早く返ってくるタイプの問題でした。
早く結果が返ってくれば Zabbix Agent が値をとれますね。

自分でやった解決手順をおおむねそのまま残しておきます。
環境は debian 7.10 x86、ntpq 4.2.6p5 です。

ntp.conf の設定はこんな感じ

$ grep -v -e "^#" -e "^$" /etc/ntp.conf
driftfile /var/lib/ntp/ntp.drift
statistics loopstats peerstats clockstats
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable
server 192.168.10.11
restrict -4 default kod notrap nomodify nopeer noquery
restrict -6 default kod notrap nomodify nopeer noquery
restrict 127.0.0.1
restrict ::1

ローカルの ntp サーバーを見に行ってます。

とりあえず ntpq の man からオプションを見てみる。

$ man ntpq
<snip>
   -4   Force  DNS  resolution of following host names on the command line to the IPv4 namespace.                                                             
                                                                                          
   -6   Force DNS resolution of following host names on the command line  to  the IPv6 namespace.                                                             
                                                                                          
   -c   The  following  argument  is interpreted as an interactive format command and is added to the list of commands to  be  executed  on  the  specified host(s). Multiple -c options may be given.                                  
                                                                                          
   -i   Force ntpq to operate in interactive mode. Prompts will be written to the standard output and commands read from the standard input.                  
                                                                                          
   -n   Output all host addresses in dotted-quad numeric format rather than  con‐verting to the canonical host names.                                        
                                                                                          
   -p   Print  a  list  of  the peers known to the server as well as a summary of their state. This is equivalent to the peers interactive command.
<snip>

-n オプションが名前の解決に関係するオプション。
ssh でも接続はできるけど接続までに時間かかるときには名前解決をさせないことで接続までの時間を短縮できたのでその辺かな。

そんなわけで実行してみる。

$ time ntpq -p
<snip>
real    0m5.035s
user    0m0.016s
sys     0m0.008s
$ time ntpq -pn
<snip>
real    0m0.027s
user    0m0.016s
sys     0m0.004s

明らかに早くなったので名前解決の関係で遅かったようです。

Zabbix で値をとれるようにするには

  1. Zabbix のテンプレートを編集して ntpq -p ではなく ntpq -pn を実行させる
  2. DNS サーバーをセットして正しく名前解決できるようにする
  3. hosts ファイルを編集してとりあえず名前解決できるようにする

1番目のテンプレート編集は、何ヶ所も書き換えないといけないのでやめておく。
2番目の DNS サーバーに関してはそもそもローカル DNS サーバーは置いてないし、参照しているプロバイダの DNS にローカルネットワークの情報は書き込めるわけがないのでやめておく。
消去法で3番目の hosts ファイル編集に落ち着きました。
マシンが名前解決に時間かかる根本の原因を押さえた方がいいかもしれませんが。

$ sudo vi /etc/hosts
192.168.10.11 X60s
$ time ntpq -p
<snip>
real    0m0.026s
user    0m0.016s
sys     0m0.008s

これでしばらく待っていると Zabbix フロントエンドからグラフを見られるようになったので、ちゃんと Zabbix Agent が値を取れるようになったみたいです。

おしまい。

OpenStreetMap Wiki カレンダーに登録するイベント文字列ジェネレーター

OpenStreetMap 関係のイベントはおおむね OpenStreetMap Wiki のカレンダーに登録されていますが、自分で登録するときに次のような感じで定められたフォーマットにしなければなりません。

{|
|-
| {{cal|conference}} || {{dm|Month Day}} || [URL International event] {{SmallFlag|float=none|Event name|Event-logo.png}}, [[Country]] {{SmallFlag|Country}}
|-
| {{cal|mapevent}} || {{dm|Month Day}} || National Event {{SmallFlag|Country}}
|-
| {{cal|social}} || {{dm|Month Day|Month Day}} || Local event, [[City]], [[Country]] {{SmallFlag|Country}} {{SmallFlag|City|Symbol of city.png}}
|}

ここで登録したイベントは 週刊 OSM に掲載されたりといろいろな部分で利用されるので簡単に登録したいのですが、上記のようなフォーマットを手動で編集すると時々カンマ忘れたりとかするのでジェネレーターでも作ってみるかと思ってそれらしい雰囲気の物を作成してみました。

Calendar format Creator Alpha

空白を埋めていくと下部の PRE 要素に文字列が表示されてきます。

まだこれで作成した文字列を突っ込んだこと無いですし、もっとパターンありそうなんですよね。

どっちにしてもカレンダーにイベントを登録したらプレビューとか OSMBC Calendar Preview あたりで登録したイベントが正しく表記されているかどうかは確認しないとだめですけどね。