2017年10月20日金曜日

LinuxでCIFS共有フォルダをマウントする

小ネタ。

Linuxでは通常NFSなどでネットワークファイル共有を実現するが、WindowsではCIFSが標準的に使われている。最近のLinuxはCIFSでも簡単にマウントできるようになっているので、その方法記載する。

コマンド

マウントコマンドは以下の通り。

mount -t cifs -o username=<ユーザー名> //<CIFS接続先>/<共有名> <マウントポイント>

試しにログインユーザーは"user"とし、QNAPのNAS(IPアドレス:192.168.33.13)のPublic領域をマウントしてみる。

# mount -t cifs -o username=user //192.168.33.13/Public /mnt
------------------------------
Password for user@//192.168.33.13/Public:  ******** ←パスワードを入力
------------------------------

マウント状況を確認してみると、いろいろなオプションがデフォルトで付与されている模様。

# mount
------------------------------
//192.168.33.13/Public on /mnt type cifs (rw,relatime,vers=1.0,cache=strict,username=user,domain=T3013QNAP,uid=0,noforceuid,gid=0,noforcegid,addr=192.168.33.13,file_mode=0755,dir_mode=0755,nounix,serverino,mapposix,rsize=61440,wsize=65536,echo_interval=60,actimeo=1)
------------------------------

アンマウントする場合は以下の通り。

# umount /mnt

参考

・CIFS を使用して Red Hat Enterprise Linux システムに Windows 共有をマウントする
https://access.redhat.com/ja/node/1447443

2017年10月6日金曜日

Amazonで売ってる最安値のUSB温度計「TEMPer」をRaspberry Piで試してみた

AmazonでUSB温度計を検索すると、最安値で出てくる以下のような商品がある。



いろんな商品名で販売されているが、中身はTEMPerという製品のようだ。今回、このTEMPerを試すことができる機会があったので、実際に温度計測を実施してみることにした。


Amazonで売っているこれらの製品には、Windows用の温度計測ツールは用意されているようだが、Linux用は用意されていない。しかし、GitHubには様々な計測用のスクリプトが存在しているようなので、そちらを利用することにする。

当初はESXiのUSBポートに刺してパススルーして、Linuxから使うことを想定していたが、このUSB温度計はパススルーできない仕様のようで、うまく仮想マシンに認識させることができなかった。そこで、Raspberry PiのUSBポートにTEMPerを接続して、温度計測を実施してみることにした。

TEMPerを接続する

とりあえず、TEMPerをRaspberry PiのUSBポートに刺してみる。

lsusbで確認すると、下線部のデバイスが増えていることが確認できる。これがTEMPerとなる。

$ lsusb
------------------------------
Bus 001 Device 004: ID 0c45:7401 Microdia
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
------------------------------

スクリプトをインストールする

今回利用するスクリプトはこちら。

・GitHub - padelt/temper-python
https://github.com/padelt/temper-python

まずは、git cloneでスクリプトを入手する。

$ git clone https://github.com/padelt/temper-python.git
------------------------------
Cloning into 'temper-python'...
remote: Counting objects: 603, done.
remote: Total 603 (delta 0), reused 0 (delta 0), pack-reused 603
Receiving objects: 100% (603/603), 138.40 KiB | 263.00 KiB/s, done.
Resolving deltas: 100% (364/364), done.
Checking connectivity... done.
------------------------------

入手したファイルは以下の通り。setup.pyがインストールするためのPythonスクリプトとなる。

$ cd temper-python/
$ ls -l
------------------------------
-rw-r--r-- 1 pi pi  1232  9月 23 15:44 CHANGELOG.md
-rw-r--r-- 1 pi pi  5443  9月 23 15:44 DEVELOPMENT.md
-rw-r--r-- 1 pi pi 32612  9月 23 15:44 LICENSE.md
-rw-r--r-- 1 pi pi    18  9月 23 15:44 MANIFEST.in
-rw-r--r-- 1 pi pi 14903  9月 23 15:44 README.md
drwxr-xr-x 2 pi pi  4096  9月 23 15:44 etc
-rw-r--r-- 1 pi pi   886  9月 23 15:44 setup.py
drwxr-xr-x 2 pi pi  4096  9月 23 15:44 temperusb
------------------------------

前提となるライブラリをインストールする。なお、snmpdは外部からSNMPを使って温度取得するために必要となるもので、スクリプトのみで温度を取得するだけであればインストール不要となる。

$ sudo apt-get install python-usb python-setuptools snmpd
------------------------------
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
python-setuptools はすでに最新版です。
python-setuptools は手動でインストールしたと設定されました。
以下の追加パッケージがインストールされます:
  libperl5.20 libsensors4 libsnmp-base libsnmp30 perl perl-base perl-modules
提案パッケージ:
  lm-sensors snmp-mibs-downloader perl-doc libterm-readline-gnu-perl
  libterm-readline-perl-perl libb-lint-perl libcpanplus-dist-build-perl
  libcpanplus-perl libfile-checktree-perl libobject-accessor-perl snmptrapd
以下のパッケージが新たにインストールされます:
  libperl5.20 libsensors4 libsnmp-base libsnmp30 python-usb snmpd
以下のパッケージはアップグレードされます:
  perl perl-base perl-modules
アップグレード: 3 個、新規インストール: 6 個、削除: 0 個、保留: 7 個。
9,416 kB 中 5,709 kB のアーカイブを取得する必要があります。
この操作後に追加で 6,785 kB のディスク容量が消費されます。
続行しますか? [Y/n] y

~(以下略)~
------------------------------

次に、setup.pyを実行してスクリプトをインストールするのだが、以下の通りエラーで失敗してしまった。

$ sudo python setup.py install
------------------------------
Traceback (most recent call last):
  File "setup.py", line 10, in <module>
    long_description=open('README.md', encoding='utf-8').read(),
TypeError: 'encoding' is an invalid keyword argument for this function
pi@t3015rasp:~/temper-python $ file -i README.md
README.md: text/plain; charset=utf-8
------------------------------

どうやら、pythonのバージョンの問題のように思われる。Raspbianでは、PythonコマンドはPython2.7のシンボリックリンクになっているので、Python3コマンド(Python3.4コマンドのシンボリックリンク)で試してみると、問題なくインストールに成功した。

$ sudo python3 setup.py install
------------------------------
running install
Checking .pth file support in /usr/local/lib/python3.4/dist-packages/
/usr/bin/python3 -E -c pass
TEST PASSED: /usr/local/lib/python3.4/dist-packages/ appears to support .pth files
running bdist_egg
running egg_info
creating temperusb.egg-info
writing requirements to temperusb.egg-info/requires.txt
writing temperusb.egg-info/PKG-INFO
writing dependency_links to temperusb.egg-info/dependency_links.txt
writing entry points to temperusb.egg-info/entry_points.txt
writing top-level names to temperusb.egg-info/top_level.txt
writing manifest file 'temperusb.egg-info/SOURCES.txt'
reading manifest file 'temperusb.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file 'temperusb.egg-info/SOURCES.txt'
installing library code to build/bdist.linux-armv7l/egg
running install_lib
running build_py
creating build
creating build/lib
creating build/lib/temperusb
copying temperusb/cli.py -> build/lib/temperusb
copying temperusb/snmp.py -> build/lib/temperusb
copying temperusb/__init__.py -> build/lib/temperusb
copying temperusb/temper.py -> build/lib/temperusb
creating build/bdist.linux-armv7l
creating build/bdist.linux-armv7l/egg
creating build/bdist.linux-armv7l/egg/temperusb
copying build/lib/temperusb/cli.py -> build/bdist.linux-armv7l/egg/temperusb
copying build/lib/temperusb/snmp.py -> build/bdist.linux-armv7l/egg/temperusb
copying build/lib/temperusb/__init__.py -> build/bdist.linux-armv7l/egg/temperusb
copying build/lib/temperusb/temper.py -> build/bdist.linux-armv7l/egg/temperusb
byte-compiling build/bdist.linux-armv7l/egg/temperusb/cli.py to cli.cpython-34.pyc
byte-compiling build/bdist.linux-armv7l/egg/temperusb/snmp.py to snmp.cpython-34.pyc
byte-compiling build/bdist.linux-armv7l/egg/temperusb/__init__.py to __init__.cpython-34.pyc
byte-compiling build/bdist.linux-armv7l/egg/temperusb/temper.py to temper.cpython-34.pyc
creating build/bdist.linux-armv7l/egg/EGG-INFO
copying temperusb.egg-info/PKG-INFO -> build/bdist.linux-armv7l/egg/EGG-INFO
copying temperusb.egg-info/SOURCES.txt -> build/bdist.linux-armv7l/egg/EGG-INFO
copying temperusb.egg-info/dependency_links.txt -> build/bdist.linux-armv7l/egg/EGG-INFO
copying temperusb.egg-info/entry_points.txt -> build/bdist.linux-armv7l/egg/EGG-INFO
copying temperusb.egg-info/requires.txt -> build/bdist.linux-armv7l/egg/EGG-INFO
copying temperusb.egg-info/top_level.txt -> build/bdist.linux-armv7l/egg/EGG-INFO
zip_safe flag not set; analyzing archive contents...
creating dist
creating 'dist/temperusb-1.5.3-py3.4.egg' and adding 'build/bdist.linux-armv7l/egg' to it
removing 'build/bdist.linux-armv7l/egg' (and everything under it)
Processing temperusb-1.5.3-py3.4.egg
Copying temperusb-1.5.3-py3.4.egg to /usr/local/lib/python3.4/dist-packages
Adding temperusb 1.5.3 to easy-install.pth file
Installing temper-poll script to /usr/local/bin
Installing temper-snmp script to /usr/local/bin

Installed /usr/local/lib/python3.4/dist-packages/temperusb-1.5.3-py3.4.egg
Processing dependencies for temperusb==1.5.3
Searching for pyusb>=1.0.0rc1
Reading https://pypi.python.org/simple/pyusb/
Best match: PyUSB 1.0.0
Downloading https://pypi.python.org/packages/8a/19/66fb48a4905e472f5dfeda3a1bafac369fbf6d6fc5cf55b780864962652d/PyUSB-1.0.0.tar.gz#md5=c8a571bfdba778555156af3facaea6fc
Processing PyUSB-1.0.0.tar.gz
Writing /tmp/easy_install-f2wopxqc/pyusb-1.0.0/setup.cfg
Running pyusb-1.0.0/setup.py -q bdist_egg --dist-dir /tmp/easy_install-f2wopxqc/pyusb-1.0.0/egg-dist-tmp-3sda3exd
zip_safe flag not set; analyzing archive contents...
Adding pyusb 1.0.0 to easy-install.pth file

Installed /usr/local/lib/python3.4/dist-packages/pyusb-1.0.0-py3.4.egg
Finished processing dependencies for temperusb==1.5.3
------------------------------

温度を計測してみる

それでは、温度取得コマンドを叩いてみる。が、失敗。

$ temper-poll
------------------------------
Traceback (most recent call last):
  File "/usr/local/lib/python3.4/dist-packages/temperusb-1.5.3-py3.4.egg/temperusb/temper.py", line 95, in __init__
  File "/usr/local/lib/python3.4/dist-packages/temperusb-1.5.3-py3.4.egg/temperusb/temper.py", line 164, in lookup_sensor_count
  File "/usr/local/lib/python3.4/dist-packages/pyusb-1.0.0-py3.4.egg/usb/core.py", line 841, in product
  File "/usr/local/lib/python3.4/dist-packages/pyusb-1.0.0-py3.4.egg/usb/util.py", line 314, in get_string
ValueError: The device has no langid

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/bin/temper-poll", line 9, in <module>
    load_entry_point('temperusb==1.5.3', 'console_scripts', 'temper-poll')()
  File "/usr/local/lib/python3.4/dist-packages/temperusb-1.5.3-py3.4.egg/temperusb/cli.py", line 38, in main
  File "/usr/local/lib/python3.4/dist-packages/temperusb-1.5.3-py3.4.egg/temperusb/temper.py", line 420, in __init__
  File "/usr/local/lib/python3.4/dist-packages/temperusb-1.5.3-py3.4.egg/temperusb/temper.py", line 419, in <listcomp>
  File "/usr/local/lib/python3.4/dist-packages/temperusb-1.5.3-py3.4.egg/temperusb/temper.py", line 97, in __init__
AttributeError: 'ValueError' object has no attribute 'message'
------------------------------

原因はsudoを忘れたことによるものだった。sudoを付けて実行すると、0.5秒ほど間があって温度取得に成功した。

$ sudo temper-poll
------------------------------
Found 1 devices
Device #0: 38.4°C 101.2°F
------------------------------

温度計測の精度について

自宅のRaspberry Piでは、DHT11というセンサーを利用した温度計測も実施している。
※詳細は以下記事を参照

・Raspberry Pi + DHT11 + Zabbixによる温度・湿度監視
https://tech-mmmm.blogspot.jp/2017/08/raspberry-pi-dht11-zabbix.html

TEMPerの計測温度が38.4℃の時のDHT11の温度は32℃となっており、TEMPerの方が計測温度がかなり高い。

これは、Raspberry Pi本体の温度がTEMPer本体に伝わり熱くなってしまうことが原因で、温度が高く計測されてしまっているようだ。したがって、Raspberry Pi本体の熱を伝わらないようにするために、USB延長ケーブルなどで接続する必要がありそうだ。

実際にUSB延長ケーブルでTEMPerを接続すると、以下の通りほぼ同じ温度での計測ができることが確認できた。

・DHT11:33℃
・TEMPer:32.6℃

2017年9月29日金曜日

QNAPで"Not all files/folders and their attributes are copied!"のバックアップ警告を解消する

自宅のQNAPでは、USBの外付けハードディスクにバックアップを取得するよう構成している。当初は問題なくバックアップ取得に成功していたが、ある日から以下のような警告が表示されるようになった。

------------------------------
[Hybrid Backup Sync(External Drive)] (Sync) Job Public-->backup-1 finished with warning. Not all files/folders and their attributes are copied!
------------------------------


詳細なバックアップログを取得し確認すると、以下のようなメッセージが表示されていた。

------------------------------
[2017/09/26 03:09:50] # WARNING: Skip the "USBDisk1/backup/.streams/19/3C/00FC000000000000C2000C0200000000/:Zone.Identifier:$DATA" file which has an unsupported filename!
[2017/09/26 03:09:51] # WARNING: Skip the "USBDisk1/backup/.streams/D1/E7/00FC0000000000008E0C760100000000/:Zone.Identifier:$DATA" file which has an unsupported filename!
[2017/09/26 03:09:51] # WARNING: Skip the "USBDisk1/backup/.streams/D1/E7/00FC0000000000008D0C760100000000/:Zone.Identifier:$DATA" file which has an unsupported filename!
[2017/09/26 03:09:51] # WARNING: Skip the "USBDisk1/backup/.streams/D1/E7/00FC0000000000008C0C760100000000/:Zone.Identifier:$DATA" file which has an unsupported filename!
[2017/09/26 03:09:51] # WARNING: Skip the "USBDisk1/backup/.streams/D1/E7/00FC0000000000008B0C760100000000/:Zone.Identifier:$DATA" file which has an unsupported filename!

~(中略)~

[2017/09/26 03:09:54] The synchronization is finished.
[2017/09/26 03:09:54] Sync statistic: Total number of the folders: 5534. Total number of the files: 190407. Total updated size: 29.85 MB. Average updating speed: 51.92 (KB/sec). Time elapsed: 9 minutes 48 seconds
[2017/09/26 03:09:54] Not all files/folders and their attributes are synchronized!
[2017/09/26 03:09:54] 187 file(s) and 0 folder(s) are skipped because of their unsupported filename (or unsupported file size), and 46 symbolic link(s) is skipped because symbolic link is not supported.

[2017/09/26 03:09:54] Job finished with warning. (Not all files/folders and their attributes are copied!)
------------------------------

/.streamsフォルダ配下のファイル名がサポートされていないことが原因のようだ。おそらく$か:の記号が使えないのだろう。

このファイルが何に使用されているものかはよくわかっていないが、特に必要ではないファイルであるため、バックアップ対象から除外することで警告を表示させないようにした。

環境

今回の環境情報は以下の通り。

・QNAP TS-231P
・QTS 4.3.3.0299 (2017/09/01)

対応手順

「Hybrid Backup Sync」→「External Backup」の画面を開き、警告メッセージを出力するバックアップジョブを選択し、「編集」ボタンを押下する。


「同期化ジョブプロパティ」の画面が開くので、「フィルター」タブを開き以下設定を行う。なお、この設定は/.streamsフォルダだけではなく、ドットから始まるファイル名はすべてバックアップ対象から除外されるので、影響がある場合は注意。

・「ファイルタイプを除外する」をチェック
・「その他」をチェック
・入力欄に「/.*」


「OK」を選択すると、何やら長文で確認画面が表示される。すぐにバックアップを再取得するなら「はい」、スケジュール通りに取得する場合は「いいえ」を選べばよい。


しばらく待つと、以下の通り正常に完了する。もし警告がある場合は、ステータス欄に「詳細についてはログを確認してください」というメッセージが表示される。


念のためバックアップログを確認したところ、特に警告メッセージもなくバックアップジョブが終了していることが確認できた。

------------------------------
[2017/09/26 18:18:13] The synchronization is finished.
[2017/09/26 18:18:13] Sync statistic: Total number of the folders: 5128. Total number of the files: 157453. Total updated size: 88.75 MB. Average updating speed: 566.96 (KB/sec). Time elapsed: 2 minutes 40 seconds
[2017/09/26 18:18:13] Job finished.
------------------------------

参考

・Hyride Backup Sync - Beta create hidden folder

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
------------------------------

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