読者です 読者をやめる 読者になる 読者になる

hiroshi akutsuの日記

主にプログラミング関係のこと

samba【centOS6.5で構築した共有にて、クライアントのNetBIOS名をログに記録する】

sambaで共有を構築されているオフィスは結構多いと思います。

共有マシンにlinuxなりunixをいれてsamba入れてportあけて共有をつなげるまでは割と簡単にできますが、
「このファイルのコピー作ったの誰だ!」
とか
「このフォルダが削除か移動されてるらしく、見つからないんですが……」

どうしてもこういった問題は100人ぐらいで使っていると頻発します。

共有管理している人のせいにされるのも癪なので、犯人特定できりゃいいって話ではないですが、犯人……じゃないや、作業した人が特定できるように、ログをきちんと吐き出すように設定したメモを残します。

今回logをとっていく上で問題になったのは次の点---

(1)smb.confのlog levelの設定は管理が大変。
複数行にまたがるのでgrepしたときに探しにくいのではないか。
またlog level = 2では削除したかどうかがよくわからない。
かといってlog level = 3では量が甚大になる。
単純に、いつ、誰が、どのディレクトリで、どのファイルを、どうしたか、のみわかればいい。

(2)デフォルトの設定ではユーザーの情報がIPアドレスしか取れなかった。
DHCPIPアドレスを割り振っているのでIPからその時のユーザーを特定するのが困難。
NetBIOS名が取れればいい。

(3)ログの出力先が1ファイルだと量が大きくなるので、ログファイルを分割する設定が月ごとに1ファイルになるようにしたい。

早速見ていきます。
環境は以下のとおりです。

OS:centOS6.5
samba: 3.6.9-168.el6_5
数多のクライアントマシン:Windows7

まず(1)について。
sambavfsのfull-auditを使いました。
sambaに搭載された機能で、目的のlogを吐き出すのに相当役立ちました。sambaの処理は全て記録できるそうです。

最終的にこんなログが吐き出されるようになります。

May  2 12:01:34 smbshare smbd[11552]: pc0217-pc|192.168.0.80|sharename|pwrite|ok|共有/チームA/管理/プロジェクト/test.xlsx

※参考 → http://www.samba.org/samba/docs/man/manpages-3/vfs_full_audit.8.html

smb.conf共有のユーザー定義のセクションに以下の赤字の箇所を追記します。
smb.confはデフォルトで
/etc/samba/smb.conf
にあります。

[sharename]
        comment = file share
        browseable = yes
        writable = yes
        guest ok = yes
        guest only = yes
        path = /home/sharedir
        vfs objects = full_audit
        full_audit:facility = local1
        full_audit:prefix = %m|%I|%S
        full_audit:failure = connect disconnect mkdir rmdir pwrite rename unlink
        full_audit:success = connect disconnect mkdir rmdir pwrite rename unlink

vfs objects = full_audit
はこれからfull_auditを使いますという宣言的なもの?です。

full_audit:facility = local1
はrsyslog.confのファシリティにlocal1を追加します(後述)。
これを記述することで、sambaのsharenameセクションのログのみのログファイルや日ごとのログファイルを収めたディレクトリを作ることができるようになります。
逆にこれをしないと、ログは/var/log/messagesに吐き出されますが他のシステムログと混ざってしまうので、よろしくありません。


full_audit:prefix = %m|%I|%S
ですが、

%m : NetBIOS名(簡単に言うとwindowsクライアントのPC名)
%I(大文字のアイ) : IPアドレス
%S : セクション名(この場合sharename)

をそれぞれ|で区切るという意味になります。
※参考 → http://www.samba.org/samba/docs/man/manpages-3/smb.conf.5.html#FULL_AUDIT:PREFIX

上のログの

May  2 12:01:34 smbshare smbd[11552]: pc0217-pc|192.168.0.80|sharename|pwrite|ok|共有/チームA/管理/プロジェクト/test.xlsx

の赤字部分にあたります。これがプレフィックスというわけですね。

full_audit:failure = connect disconnect mkdir rmdir pwrite rename unlink
こちらは操作が失敗したとき、どのアクションのログを出力するかという設定になります。
見てのとおり、アクション名をスペース区切りで記述していきます。
http://www.samba.org/samba/docs/man/manpages-3/vfs_full_audit.8.html
に記載のあるアクションが記述できるようですが、多すぎると管理が大変になるので必要最低限でいいと思います。

connect : 接続
disconnect: 遮断
mkdir : フォルダ作成
rmdir : フォルダ削除
pwrite : ファイル作成
rename : ファイル名変更
unlink : ファイル削除

いろいろありますが、samba開発者はfailure(失敗)のログをもとにバグを見つけたりするのでとても大事な情報ですが、sambaのユーザーは、あまり意識する必要がないとおもいます。

それよりは、私のような管理をする立場の人間は、成功した情報(つまり実際にsambaサーバのファイルやフォルダを操作した情報)の方が欲しいのです。それで下記の設定をするのです。
full_audit:success = connect disconnect mkdir rmdir pwrite rename unlink
これが大事です。どの操作のログを取得するか指定しています。failureと同様の記載方法です。

下記が今回のブログの設定をすると出力されるログの例です。

May  2 12:01:34 smbshare smbd[11552]: pc0217-pc|192.168.0.80|sharename|pwrite|ok|共有/チームA/管理/プロジェクト/test.xlsx

の赤字部分が操作記録になります。
つまり「pc0217-pcというnetbios名を持つパソコンから、test.xlsxが共有に作成された」とわかります。

さて、こちらで/etc/samba/smb.confを上書き保存するとすぐにログの情報が/var/log/messagesに書き出されると思います。


ただし、私の環境ではこのままではユーザー(クライアント)のNetBIOS名が取得できませんでした。
%mの値がIPアドレスになってしまいました。

sambaの公式サイトには

%m

the NetBIOS name of the client machine (very useful).

This parameter is not available when Samba listens on port 445, as clients no longer send this information. If you use this macro in an include statement on a domain that has a Samba domain controller be sure to set in the [global] section smb ports = 139. This will cause Samba to not listen on port 445 and will permit include functionality to function as it did with Samba 2.x.

となっていました。
つまり要約すると、NetBIOS名は非常に有効なんだけど、445ポートを使っているとだめで、その場合はグローバルセクションに
smb ports = 139
と書いてください、ということでした。

なのでグローバルセクションに以下追記しました。

[global]
……(中略)
smb ports = 139

smbとnmbを再起動したら、見事NetBIOSが取得できました。
これで(2)がクリアです。


次に(3)ログの切り分けについて。
デフォルトではrsyslogというシステムログ出力のプログラムにログが渡されます。
ここで、rsyslogはsambaとは別のシステムなので、smb.confでfull_auditの設定はできても、ログの吐き出し先を指定することはできません。
ログの吐き出し先は/etc/rsyslog.confにて記述します。

今のままだと
/var/log/messages
に設定したログが吐き出されると思いますが、messagesはsamba以外のログも吐き出されるので、sambaのログを切り分けます。
/var/log/sharename-log/2014-05.log
に吐き出したいと思います。

あらかじめ、以下のコマンドを実行しログ置き場のディレクトリを作成してください。
#mkdir /var/log/sharename-log


ファイル名の05のところは月ごとに新しいファイルを新規作成するようにします。

/etc/rsyslog.conf

を編集します。
# ### begin forwarding rule ###
の上に以下を追記

$template sharetmpl, "/var/log/sharename-log/%$year%-%$month%.log"
local1.*                                                ?sharetmpl

これでlocal1というファシリティのログはsharetmplというテンプレートに記述された位置に保存されるようになります。
/etc/samba/smb.confで
full_audit:facility = local1
と記述しましたがこのlocal1が上のファシリティ名にあたります。
※local1は勝手な名前は付けられませんが、local0~local7まで未使用のものならどれでも使えます。

local1.*の.*はログのレベルをあらわしています。*はワイルドカードです。
つまりすべてのlocal1のログレベルにおいて、/var/log/sharename-log/%$year%-%$month%.logに保存する
という意味になります。
ログレベルについてはあまり調べられていないのと、smb.confで特に設定しなかったので割愛します。

これで
#/etc/init.d/rsyslog restart
を実行して、問題なくrsyslogが再起動できれば完了です。