2017年9月21日木曜日

Zabbixでログに記載されている数値を抽出して監視する

自宅ではsquid + squidGuardを組み合わせたプロキシサーバを使ってWebフィルタリングの機能を実装している。squidGuardではスクリプトを使ってフィルタリング対象のURL情報を更新しているが、いつ更新がされたかわからいので、更新が発生した際にZabbixにて検知できるようにすることにした。

squidGuardで利用しているURL更新スクリプトは、更新されたURL数をログに出力するので、そのURL数の情報を抽出して、Zabbixにてログ監視を行う。当然、squidGuard以外でも、ログに数値が出されるもの(例えばウィルススキャンの結果など)であれば、同様の方法で監視ができるようになる。

環境

今回の環境は以下の通りとなる。

------------------------------
・Zabbix: 2.2.19
・Squid Cache: Version 3.5.20
・SquidGuard: 1.4 Berkeley DB 5.3.21: (May 11, 2012)
------------------------------

アイテムを作成

まずは、監視対象のホストにアイテムを追加する。監視対象のログは以下のような内容となる。

2017-09-18 14:24:14 [1402] update: added 35 entries, deleted 0 entries

update: added XX entriesのXXの値を取り出して監視をすることにする。今回は以下のように設定した。

------------------------------
・名前:squidGuard
・タイプ:Zabbixエージェント (アクティブ)
・キー:
 log[/var/log/squidGuard/squidGuard.log,"update: added ([0-9]+)",,,skip,\1]
・データ型:ログ ※「数値」でも問題ないと思われる
・更新間隔(秒):30
・ヒストリ保存期間(日):7
・アプリケーション:OS
------------------------------


「保存」ボタンを押して、想定通りアイテムが作成されていることを確認する。


「キー」の設定について、もう少し詳しく説明する。logの構文は以下の通りとなる。

log[/path/to/file/file_name,<regexp>,<encoding>,<maxlines>,<mode>,<output>]

第1引数には監視対象をログのフルパスを指定する。

第2引数<regexp>にはログに含まれる取得対象の文字列を記載する。ここで、数値として取り出したい箇所に「([0-9]+)」を記載する。これは正規表現で「1桁以上の連続する数字」を表している。()で囲んでいる意味は後述する。

第5引数<mode>はall (デフォルト)とskipが選べる。allの場合は、監視対象ログの過去のログも遡って取得する。skipを指定すると、過去のログは取得しない。Zabbixサーバが停止している時間の監視漏れを防止したいのであればallとした方がよいのだが、過去のログが大量にある場合は、多数のログ取得・トリガーの実行が発生してZabbixが高負荷になる恐れがあるので注意する。

第6引数<output>に「\1」を指定する。これは第2引数で()で囲んだ箇所をアイテムの値として抽出するという設定となる。

トリガーを作成

次に、先ほど作成したアイテムに対するトリガーを作成する。

------------------------------
・名前:squidGuard
・条件式:
 {t3023ce72:log[/var/log/squidGuard/squidGuard.log,
  "update: added ([0-9]+)",,,skip,\1].last()}#0
・障害イベントを継続して生成:チェック
・深刻度:軽度の障害
------------------------------


条件式ビルダーで条件式を作成する場合は、以下のように設定する。


これでZabbix側の設定は完了となる。

監視テスト

試しに監視対象ログに文字列を書き込んで監視テストをしてみる。さくっとechoでログに文字列を書き込んでみる。

# echo "2017-09-18 14:24:14 [1402] update: added 35 entries, deleted 0 entries" >> /var/log/squidGuard/squidGuard.log

ログを確認する。下線部の情報がZabbixにアイテムとして取り込まれる想定となる、

# tail /var/log/squidGuard/squidGuard.log
------------------------------
2017-09-18 14:24:14 [1402] update: added 35 entries, deleted 0 entries
------------------------------

Zabbix側で「監視データ」→「最新データ」を表示し、先ほど設定した「squidGuard」のアイテムのヒストリを確認する。

以下の通り、値のみが取得できている。


「監視データ」→「トリガー」を確認すると、こちらも想定通りsquidGuardのトリガーが動作していることが確認できる。


以上で、設定は完了となる。

参考

・Zabbix Documentation 2.2 - 6 ログファイル監視
https://www.zabbix.com/documentation/2.2/jp/manual/config/items/itemtypes/log_items

2017年9月14日木曜日

ZabbixでSNMPを使ってネットワーク機器を監視する

ZabbixではSNMPを使って機器を監視する機能があり、特にネットワーク機器ではトラフィック量などを取得する場合に便利な機能となる。

今回は仮想ネットワークOSであるVyOSに対して、SNMPによる監視設定を行い、発生しているトラフィック量をZabbixのグラフで表示させる方法を記載する。

情報取得対象機器のSNMP設定確認

取得対象スイッチ側で、SNMPを使って情報取得ができることを事前に確認しておく。ZabbixのサーバOSにログインし、snmpwalkコマンドで確認すればよい。snmpwalkの使い方は以下の通り。

 snmpwalk  -v 2c -c <SNMP community名> <対象機器のIPアドレス>

snmpwalkを実行すると大量の情報が表示されるはずである。もし表示されないようであれば、情報取得対象の設定やコミュニティ名が誤っているなどが考えられるため、設定を確認しよう。

試しに私の環境でsnmpwalkすると以下のような表示結果となる。

# snmpwalk  -v 2c -c public 192.168.33.31
------------------------------
SNMPv2-MIB::sysDescr.0 = STRING: Vyatta VyOS 1.1.7
SNMPv2-MIB::sysObjectID.0 = OID: SNMPv2-SMI::enterprises.30803
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (503576852) 58 days, 6:49:28.52

~(中略)~

IF-MIB::ifNumber.0 = INTEGER: 3
IF-MIB::ifIndex.1 = INTEGER: 1
IF-MIB::ifIndex.2 = INTEGER: 2
IF-MIB::ifIndex.3 = INTEGER: 3
IF-MIB::ifDescr.1 = STRING: lo
IF-MIB::ifDescr.2 = STRING: VMware VMXNET3 Ethernet Controller
IF-MIB::ifDescr.3 = STRING: VMware VMXNET3 Ethernet Controller

~(中略)~

SCTP-MIB::sctpMaxAssocs.0 = INTEGER: 0
SCTP-MIB::sctpValCookieLife.0 = Gauge32: 0 milliseconds
SCTP-MIB::sctpMaxInitRetr.0 = Gauge32: 0
------------------------------

参考となるが、VyOS側のSNMPの設定は以下の通りになる。community名「public」をread-onlyで設定している。

# show service snmp
------------------------------
 community public {
     authorization ro
 }
 trap-source 192.168.33.31
 trap-target 192.168.33.22 {
 }
------------------------------


Zabbixにホストを登録

SNMPの情報が問題なく取得できることを確認したら、次にZabbix側の設定を行う。ZabbixにはSNMPで情報取得を行うためのテンプレートが存在するのでそれを利用する。

まず、監視対象ホストを登録する。「ホスト」タブの「SNMPインターフェース」の箇所に、IPアドレスとポート番号(通常は161)を設定する。


次に「テンプレート」タブにて「Template SNMP Device」を追加する。


最後に、「マクロ」タブにて、以下設定を実施する。

 {$SNMP_COMMUNITY} ⇒ <コミュニティ名>


以上でホストの登録は完了となる。

「Template SNMP Device」は自動的に対象機器のインターフェース情報をSNMPにて取得し、「アイテム」や「グラフ」を自動登録してくれる。これはディスカバリルールで設定されているのだが、このディスカバリルールは1時間(3600秒)間隔で動くので、しばらく待つ必要がある。

ifDescが重複した場合のエラーへの対処

VyOSの場合、ディスカバリルールにて、以下エラーメッセージが表示される場合がある。

------------------------------
Cannot create item: item with the same key "ifAdminStatus[VMware VMXNET3 Ethernet Controller]" already exists.
------------------------------


これは、SNMPのifDescrの値が重複している場合に発生する事象となる。エラーとなった場合は、インターフェースの情報が正しく取得できないので、修正対応を行う。

まず、「テンプレート」から「Template SNMP Interfaces」を選択する(SNMP DeviceではなくSNMP Interfacesを選択)。「ディスカバリルール」の「Network interfaces」を選択する。


下部に「複製」ボタンがあるので、ボタンを押して複製する。複製したものに対して、以下変更を加える。要はifDescrが同じ名前で重複してしまいエラーとなるので、ifIndexに変更することで回避するという対処となる。

 ・名前 : Network interfaces ifIndex
 ・キー : ifIndex
 ・SNMP OID : IF-MIB::ifIndex


なお、普通のスイッチであればifDescrが重複することなどはないと思われる。例えばCiscoスイッチであれば、”GigabitEthernet 0/0”といった値で表示される。

「Network Interfaces ifIndex」のディスカバリルールが作成後、重複して情報を取得しないように「Network Interfaces」のディスカバリルールは無効にしておく。


ホストの設定に戻り、「Template SNMP Device」のテンプレートについて、「リンクと保存データを削除」をしゴミデータの削除を行う。その後、再度「Template SNMP Device」の追加を行う。


1時間ほど待つと、特にエラーもなくSNMP情報の取得に成功するはず。インターフェース名は数字の連番で表示されるので、ややわかりづらくなるのが難点。


トラフィック量のグラフ

取得されたインターフェースのトラフィック量は、グラフにて確認できる。MRTGなどと同じように、Incoming traffic (ポートから見て入力方向)とOutgoing traffic (ポートから見て出力方向)が一つのグラフで表示されるという一般的なものであり、他の監視ソフトを使っている人であっても違和感はないだろう。


以上で設定は完了となる。

VyOSの仕様によりテンプレートの修正対応が必要だったが、普通のスイッチであれば、ホストを登録し「Template SNMP Device」のテンプレートをリンクするだけで設定が完了する。このようにZabbixでは、非常に簡単にネットワーク機器の監視が実現できる。

2017年9月8日金曜日

DFSレプリケーションを使ってファイルサーバーを同期する

Windowsのファイルを別のWindowsに同期する機能として、「DFSレプリケーション (以下、DFS-R)」の機能がある。DFS-Rはファイル単位ではなくブロック単位での差分を検出して同期するため、差分転送のデータ量が少ないといったメリットがある。

今回はWindows Server 2012を利用して、DFS-Rによるファイル同期を試してみることにする。

構成

構成は以下の通り。以下2台のサーバーは同一ドメインに属している必要がある。

 ・コピー元:ホスト名 t1202w212 / Windows Server 2012 Standard
 ・コピー先:ホスト名 t1201w212 / Windows Server 2012 Standard

DFS-Rは、コピー元からコピー先への一方行のレプリケーションを構成することとする。

手順

1. 役割の追加

2台のサーバーで以下役割の追加を行う。「DFSレプリケーション」を選択すると自動で表示される役割管理ツールも合わせてインストールしておく。

 ------------------------------
 ファイルサービスおよび記憶域サービス
  →ファイルサービスおよびiSCSIサービス
   →DFSレプリケーション
 ------------------------------

なお、以下画面では、DFSレプリケーション以外にも、ファイルサーバーの機能を追加しているが、レプリケーションするだけであれば必須ではない。


2. レプリケーショングループの作成

「サーバーマネージャー」→「ツール」から「DFSの管理」を選択する。DFSの管理の左ペインの「レプリケーション」を右クリックし、「新しいレプリケーション グループの作成」を選択する。

新しいレプリケーション グループ ウィザードが立ち上がるので、以下のように設定する。なお、一番最初に選ぶレプリケーション グループは、「汎用」と「データ収集用」とあるが、単純な2台のレプリケーションであれば、「データ収集用」を選べばよいらしい。
※「汎用」でできることは、今回は検証しておらず不明

 ------------------------------
 ・レプリケーション グループの種類:データ収集用
 ・レプリケーション グループの名前:任意
 ・ドメイン            :所属しているドメイン
 ・ブランチ サーバー       :コピー元のサーバーホスト名
 ・レプリケート フォルダー    :コピー元のフォルダーのパス
 ・ハブ サーバー         :コピー先のサーバーホスト名
 ・ターゲット フォルダー     :コピー先のフォルダーのパス
 ・スケジュール          :継続的にレプリケートする
 ・帯域幅             :最大
 ------------------------------


以上を適切に設定すると、レプリケーション グループの作成に成功する画面が表示される。


3. コピー先を読み取り専用にする

今回は一方行のレプリケーションとしたいのだが、DFS-Rは厳密には一方行の同期という設定は存在しないようだ。その代わりに、コピー先を読み取り専用とすることで、同等の機能を実現することが可能となる。

作成したレプリケーション グループを選択し、「メンバーシップ」タブにて、コピー先のフォルダーを右クリックし、「読み取り専用にする」を選択するだけでよい。



読み取り専用にした後、試しにコピー先のフォルダーに新しいフォルダーを作成しようとすると、以下の通りアクセス拒否されることがわかる。当たり前だが、「続行」ボタンを押してもアクセス拒否がされ、コピー先のフォルダーの変更ができないようになっている。


なお、読み取り専用の動作は、結局NTFSのアクセス権と同様の設定で制御しているようで、もし設定時にアクセスできるユーザーでログインしている場合は、一度ログオフしないと設定が反映されないので注意しよう。

2017年9月2日土曜日

iptables入門

Linuxで長らくパーソナルファイアーウォールとして利用されているiptablesではあるが、設定が面倒ですぐにサービスを止めてしまいがちである。とはいえ、セキュリティ上、無効化するのはよくないので、設定方法を簡単にまとめてみた。

設定概要

ファイアーウォールを設定する場合、基本的には以下の通りに設定する。

 INPUT方向 (外部 → サーバー) : デフォルト拒否。必要なポートのみ許可
 OUTPUT方向 (サーバー → 外部) : デフォルト許可

今回設定する内容を図示したものが以下となる。



設定手順

それではiptablesを設定していく。iptablesでは、一つ一つのルールをコマンドで設定していく。

1. ルールを全部削除する

既存のiptablesの設定が残っていると設定が綺麗にならないので、すべての設定を削除する。ただし、いきなり削除してしまうと、SSHといったリモート接続用の通信もできなくなってしまうので、デフォルトのポリシーをACCEPTに変えてから実施するようにする。

# iptables -P INPUT ACCEPT
# iptables -P OUTPUT ACCEPT
# iptables -F

なお、FORWARDは利用しないので、DROPにしておく。

# iptables -P FORWARD DROP

ルールを確認するコマンドは以下の通り。すべてのルールがない状態となっている。

# iptables -L
------------------------------
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy DROP)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
------------------------------

2. 共通のルールを追加する

まずは共通のルールとして2つのルールを設定する。1行目はサーバー側から外部に通信した際の確立した通信を許可するルールで、2行目はループバックアドレスの通信を許可するルールとなる。

# iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# iptables -A INPUT -i lo -j ACCEPT

「ESTABLISHED」は接続が確立してACKフラグの付いたパケットのことであり、TCPの3-WAYハンドシェイクで通信確立後のすべての通信を許可する。「RELATED」はFTP DATAなどの通信を許可するための設定らしいので、一応許可しておく。

また、pingの応答を許可するために、Echo Reply (Type 0)とEcho Request (Type 8)を許可するルールを追加する。

# iptables -A INPUT -p icmp --icmp-type 0 -j ACCEPT
# iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT

3. 個別のルールを追加する

後は要件に応じて必要なポートを開ける。コマンドは以下を定型文として覚えてしまえばよい。-mオプションと-pオプションのプロトコルはそろえること。

 iptables -A INPUT -m state --state NEW -m <tcp/udp> -p <tcp/udp> --dport <port> -j ACCEPT

「NEW」は接続開始要求時のSYNフラグのみが付いたパケットを許可する設定となる。接続確立後は、「ESTABLISHED」の状態(ACKフラグ)が付いたパケットとなるので、先に設定した「確立した通信を許可」のルールにて通信が許可される。

例として、私の環境では以下のように設定した。

# iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
# iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
# iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT
# iptables -A INPUT -m state --state NEW -m udp -p udp --dport 161 -j ACCEPT
# iptables -A INPUT -m state --state NEW -m udp -p udp --dport 162 -j ACCEPT
# iptables -A INPUT -m state --state NEW -m udp -p udp --dport 123 -j ACCEPT
# iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 10051 -j ACCEPT
# iptables -A INPUT -m state --state NEW -m udp -p udp --dport 514 -j ACCEPT

4. INPUTのデフォルトのポリシーをDROPに変更する

設定が完了したところで、デフォルトのポリシーをDROPに変更する。

# iptables -P INPUT DROP

最終的な設定を確認すると、以下の通りになる。

# iptables -L
------------------------------
Chain INPUT (policy DROP)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED
ACCEPT     icmp --  anywhere             anywhere            icmp echo-reply
ACCEPT     icmp --  anywhere             anywhere            icmp echo-request
ACCEPT     all  --  anywhere             anywhere
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:ssh
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:http
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:https
ACCEPT     udp  --  anywhere             anywhere            state NEW udp dpt:snmp
ACCEPT     udp  --  anywhere             anywhere            state NEW udp dpt:snmptrap
ACCEPT     udp  --  anywhere             anywhere            state NEW udp dpt:ntp
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:zabbix-trapper
ACCEPT     udp  --  anywhere             anywhere            state NEW udp dpt:syslog

Chain FORWARD (policy DROP)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
------------------------------

5. 問題なければ設定を保存

通信に問題がなさそうであれば、設定を保存する。

# service iptables save
------------------------------
iptables: ファイアウォールのルールを /etc/sysconfig/iptable[  OK  ]中:
------------------------------

設定が以下のファイルに反映されていることを確認する。

# cat /etc/sysconfig/iptables
------------------------------
# Generated by iptables-save v1.4.7 on Sat Sep  2 09:11:41 2017
*filter
:INPUT DROP [220:23012]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [1692:292692]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 0 -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
-A INPUT -p udp -m state --state NEW -m udp --dport 161 -j ACCEPT
-A INPUT -p udp -m state --state NEW -m udp --dport 162 -j ACCEPT
-A INPUT -p udp -m state --state NEW -m udp --dport 123 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 10051 -j ACCEPT
-A INPUT -p udp -m state --state NEW -m udp --dport 514 -j ACCEPT
COMMIT
# Completed on Sat Sep  2 09:11:41 2017
------------------------------

以上で設定は完了となる。

2017年8月28日月曜日

Raspberry Pi + DHT11 + Zabbixによる温度・湿度監視

自宅ではESXiをインストールした検証用PCとQNAPのNASが24時間稼働をしているが、夏の日中帯はクーラーを止めることもあって、室温がかなり高くなっていることが気になっていた。

そこで、Raspberry Piで検証用PC付近の温度と湿度を取得し、Zabbixに連携してグラフ化し、温度監視をすることにした。

必要なもの

Raspberry Pi本体は当然必要となる。導入方法については別記事を参照。

温度・湿度センサーはDHT11を選択した。DHT11は精度はそこまでよくないらしいが、非常に安い。

・DHT11のセンサー
http://amzn.to/2iwkWkH

なお、私はDHT11単体で購入するのではなく、以下のOSOYOOの「電子工作キット」を購入した。この中にはDHT11の他に配線を楽にするブレッドボード等も含まれるので、Raspberry Piでいろいろやる場合は、1個買っておいても損はない。




センサーを接続

それではセンサーを接続していこう。DHT11のPin配置は以下の通りとなる。

 1 VDD
 2 DATA
 3 NC (Not Connected)
 4 GND

Raspberry Piとの接続は、以下の通りとなる。

 1 VDD -> 3V3
 2 DATA -> GPIO17
 3 NC (Not Connected) -> 接続しない
 4 GND -> GND

接続図は以下の通りとなる。


DATAとGPIO17の間にはプルアップ抵抗として、10kΩの抵抗を挟む図となっているが、プルアップ抵抗がはじめから回路に含まれている一体型のDHT11もあり、そちらを利用する場合は不要となる(一体型の場合はNCのPinも省略されて、3Pinで構成されているものが多い模様)。

以下写真は、自宅環境の接続の状況。わかりづらいが、DHT11にあらかじめプルアップ抵抗が付いており、通電するとLEDも点灯する仕様になっている。


Pythonにて温度・湿度取得スクリプトを作成

温度と湿度の取得スクリプトを一から作るのは大変なので、gitを使って元となるスクリプトを入手する。

$ git clone https://github.com/szazo/DHT11_Python.git
------------------------------
Cloning into 'DHT11_Python'...
remote: Counting objects: 48, done.
Unpacking objects: 100% (48/48), done.
Checking connectivity... done.
------------------------------

ファイルを確認すると、dht11.pyとdht11_example.pyの2のスクリプトがある。dht11.pyが本体で、dht11_example.pyから呼び出してセンサーから温度と湿度を取得する、という作りになっている。

$ cd DHT11_Python/
$ ls -l
------------------------------
-rw-r--r-- 1 pi pi 1071  8月 19 13:16 LICENSE.md
-rw-r--r-- 1 pi pi  899  8月 19 13:16 README.md
-rw-r--r-- 1 pi pi    1  8月 19 13:16 __init__.py
-rw-r--r-- 1 pi pi 5969  8月 19 13:16 dht11.py
-rw-r--r-- 1 pi pi  464  8月 19 13:16 dht11_example.py
------------------------------

今回はdht11_example.pyを参考にして、Zabbix連携用のスクリプトを作成する。以下のように、温度、湿度の順でカンマ区切りで表示させるスクリプトを作成した。

$ cat dht11_get_temperature_humidity.py
------------------------------
import RPi.GPIO as GPIO
import dht11

# initialize GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.cleanup()

# read data using pin 14
instance = dht11.DHT11(pin=17)

result = instance.read()
if result.is_valid():
    print("%d,%d" % (result.temperature, result.humidity))
------------------------------

試しに実行すると、以下の通り温度と湿度が出力された。

$ python dht11_get_temperature_humidity.py
------------------------------
35,31
------------------------------

Zabbix Senderにてデータを送信

Zabbixに対してはZabbix Senderを使い、データ送信を行うこととする。Zabbix Senderを使えるようにあらかじめZabbix Agentをインストールしておこう。インストール方法はこちらを参照。

Zabbix Senderのコマンドの書式は以下の通りとなる。キー名は、別途Zabbix Server側の「アイテム」で設定する際の値と同一にする必要がある。

zabbix_sender -z <Zabbix ServerのIPアドレス> -s <ホスト名> -k <キー名> -o <値>

上記zabbix_senderを使って、温度・湿度情報を送信するシェルスクリプトを以下のように作成した。内容としては、Pythonのスクリプトで得られた温度・湿度情報をZabbix Senderの値に入れて飛ばすだけの簡単なものになっている。

$ cat get_temperature.sh
------------------------------
#!/bin/bash

home_dir="/home/pi/DHT11_Python"

value=$(python $home_dir/dht11_get_temperature_humidity.py)
echo $value
zabbix_sender -z 192.168.33.22 -s t3015rasp -k rasp_temp -o $(echo $value | cut -d"," -f 1)
zabbix_sender -z 192.168.33.22 -s t3015rasp -k rasp_humi -o $(echo $value | cut -d"," -f 2)

exit 0
------------------------------

上記スクリプトを5分間隔で実行するよう、cronに登録する。

$ crontab -l
------------------------------
*/5 * * * * /home/pi/DHT11_Python/get_temperature.sh
------------------------------

Zabbix Serverにてグラフ化と監視トリガーを設定

最後にZabbix Server側で受信設定を行う。

1. アイテムの作成

温度用のアイテムと湿度用のアイテムの2つを作成する。

------------------------------
◆温度用
・名前:Sensor Temperature
・タイプ:Zabbixとラッパー
・キー:rasp_temp
・データ型:数値 (浮動小数)
・単位:℃
・アプリケーション:Sensor (「アプリケーションの作成」で作成する)
------------------------------


------------------------------
◆湿度用
・名前:Sensor Humidity
・タイプ:Zabbixとラッパー
・キー:rasp_humi
・データ型:数値 (浮動小数)
・単位:%
・アプリケーション:Sensor
------------------------------


2. グラフの作成

1つのグラフで温度と湿度を両方表示できるようにする。

------------------------------
・名前:Temperature & Humidity
・アイテム 1: Template OS Raspbian: Sensor Temperature / Y軸:左
・アイテム 2: Template OS Raspbian: Sensor Humidity / Y軸:右
------------------------------


3. トリガーの作成

温度に関しては高温度となった際に、Zabbixでアラートとして検知できるように、トリガーを作成する。

------------------------------
・名前:High Temperature
・条件式:{Template OS Raspbian:rasp_temp.last()}>37
     ※下線部は監視閾値としたい温度に適宜変更する
・深刻度:軽度の障害
------------------------------


4. グラフの確認

最後にグラフが正常に表示されることを確認する。赤線が温度で緑線が湿度となる。以下の図は一週間ほど値を取得した結果のグラフとなる。設置場所が検証用PCやNASの近くなので、温度が常に30℃以上と高めとなっている。


非常に当たり前の結果ではあるが、人が外出する日中は温度・湿度が上昇し、帰宅後クーラーをONにすると温度・湿度が急激に下がるということがわかった。

以上で、Raspberry Piを使って、温度・湿度センサーによる監視を実現することができた。今後は、取得した温度・湿度情報をもとに、クーラーや扇風機を制御できるようにしたいとも考えている。

参考

・DHT11 (Raspberry Pi) by piddlerintheroot in raspberry-pi

2017年8月24日木曜日

Raspberry PiにZabbix Agentをインストールする

Raspberry Piで取得したセンサー情報をZabbixに連携して監視できるようにしたいと思い、とりあえずZabbix Agentをインストールすることにした。

今回使用するRaspberry PiのOSはRaspbianとなり、バージョンは以下となる。

$ lsb_release -a
------------------------------
No LSB modules are available.
Distributor ID: Raspbian
Description:    Raspbian GNU/Linux 8.0 (jessie)
Release:        8.0
Codename:       jessie
------------------------------

apt-getで簡単インストール

Raspbianへのzabbix-agentはapt-getで簡単にインストールできる。

$ sudo apt-get install zabbix-agent
------------------------------
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています       
状態情報を読み取っています... 完了
以下の追加パッケージがインストールされます:
  libpci3 pciutils
以下のパッケージが新たにインストールされます:
  libpci3 pciutils zabbix-agent
アップグレード: 0 個、新規インストール: 3 個、削除: 0 個、保留: 0 個。
595 kB のアーカイブを取得する必要があります。
この操作後に追加で 1,883 kB のディスク容量が消費されます。
続行しますか? [Y/n] y

~(中略)~

libpci3:armhf (1:3.2.1-3) を設定しています ...
pciutils (1:3.2.1-3) を設定しています ...
zabbix-agent (1:2.2.7+dfsg-2+deb8u3) を設定しています ...

Creating config file /etc/zabbix/zabbix_agentd.conf with new version
libc-bin (2.19-18+deb8u10) のトリガを処理しています ...
systemd (215-17+deb8u7) のトリガを処理しています ...
------------------------------

バージョンを確認すると、2.2.7となっていた。2014年10月の記載があり、予想よりも古いエージェントがインストールされるという印象。

$ zabbix_agentd -V
------------------------------
Zabbix Agent (daemon) v2.2.7 (revision 50148) (24 October 2014)
Compilation time: Aug 12 2017 04:46:02
------------------------------

apt-getが使えない場合のインストール (※未検証)

インターネットへの接続ができずapt-getによるインストールができない場合は、直接ファイルを落としてインストールする。ダウンロード先は以下となる。

http://mirrordirector.raspbian.org/raspbian/pool/main/p/pciutils/
libpci3_3.2.1-3_armhf.deb
pciutils_3.2.1-3_armhf.deb

http://mirrordirector.raspbian.org/raspbian/pool/main/z/zabbix/
zabbix-agent_2.2.7+dfsg-2+deb8u3_armhf.deb

上記3つのファイルをダウンロードして、"dpkg -i"でインストールすればよいはず。

$ sudo dpkg -i libpci3_3.2.1-3_armhf.deb
$ sudo dpkg -i pciutils_3.2.1-3_armhf.deb
$ sudo dpkg -i zabbix-agent_2.2.7+dfsg-2+deb8u3_armhf.deb

Zabbix Agentの初期設定

/etc/zabbix/zabbix_agentd.confに必要な設定を記載する。この設定ファイルはコメント行も含めると、かなり長いものとなっているが、実際に必要な設定は以下のみとなる。

$ cat /etc/zabbix/zabbix_agentd.conf | grep -v -e "^#" -e "^$"
------------------------------
PidFile=/var/run/zabbix/zabbix_agentd.pid
LogFile=/var/log/zabbix-agent/zabbix_agentd.log
LogFileSize=1
Server=<Zabbix ServerのIPアドレス>
ServerActive=<Zabbix ServerのIPアドレス>
Hostname=<Agetn側のホスト名 ※Zabbix Serverに登録するホスト名と合わせる>
AllowRoot=1   ←★注
Include=/etc/zabbix/zabbix_agentd.conf.d/
------------------------------

注) AllowRoot=1はZabbix Agentをroot権限で実行する設定となり、セキュリティ上は非推奨の設定となる。しかし、ログ監視の対象ログがroot以外読み取り不可となっている場合(/var/log/messagesなど)は監視ができなくなるため、あえて有効にしている。当然、そのような監視が不要であれば設定しない方がよい。

設定が終わったら、Zabbix Agentを再起動する。

$ sudo systemctl restart zabbix-agent.service

Zabbix Server側の監視設定

次にZabbix Server側でホストの登録を行う。

まずは、Raspbian用のテンプレートとして、「Template OS Raspbian」を作る。といっても、RaspbianはLinuxなので、Zabbixに標準で存在するTemplate OS Linuxにリンクするだけで完成。このテンプレートをベースに将来的にRaspbian特有の監視設定を追加できるようにする。


次に、ホストの登録を行う。ホスト名とIPアドレスを正しく設定し、テンプレートタブにて先ほど作成した「Template OS Raspbian」とリンクすればよい。



これで問題なければ監視ができるはず。試しに最新データを見てみると、以下の通り各種情報の取得に成功していることがわかる。



2017年8月20日日曜日

Linuxの設定ファイルの#から始まるコメント行を消して設定値だけ表示する

Linuxの設定ファイルは、コメント行として#から始まる行が多数記載されている。設定値の意味が記載されており、あれば便利なものではあるが、実際に設定した内容の確認の際には視認性が悪くなるため、邪魔になることも多い。

というわけで、grepでコメント行を消すことを試してみた。

コメント行を消す方法

例として以下のようなテキストファイルを用意してみた。

$ cat test.txt
------------------------------
# comment1

test # comment2


test "####"


 # comment3

  # comment4
   # comment5
------------------------------

コメント行を削除するには以下の通りgrepする。

$ cat test.txt | grep -v '^ *#'
------------------------------

test # comment2

test "####"

------------------------------

さらに空白行も消したい場合は、以下の通りとなる。通常使う場合は、空白行も消した方が視認性がよいのでお勧め。

$ cat test.txt | grep -v -e '^ *#' -e '^$'
------------------------------
test # comment2
test "####"
------------------------------

catを使わず以下の記述でもOK。

$ grep -v '^ *#' test.txt
$ grep -v -e '^ *#' -e '^$' test.txt

エイリアスを作っておく

便利なコマンドなのでエイリアスを登録してすぐに使えるようにしておく。~/.bashrcに以下行を追記すればよい。エイリアスの名前は任意だが、コメント(comment)を取って表示する(cat)ということで、「ccat」としてみた(実際はcatは表示するという意味ではないが)。

alias ccat="grep -v -e '^ *#' -e '^$'"

~/.bashrcの記載方法について補足となるが、UbuntuやRaspbianのようなDebian系のLinuxでは、~/.bashrcを覗くと以下のような記載になっていた。

------------------------------
# Alias definitions.
# You may want to put all your additions into a separate file like
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.

if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi
------------------------------

どうやら「~/.bash_aliases」のファイルを作成して、そこにエイリアスを書け、ということらしい。郷に入っては郷に従えということで、そのように対応した。

$ cat ~/.bash_aliases
------------------------------
alias ccat="grep -v -e '^ *#' -e '^$'"
------------------------------

参考

みんな考えていることは同じだった。

https://www.google.co.jp/search?q=grep+%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88