sftp コマンドのロギング
sftp を使用したファイルサーバーへのデータ保存は、一般的かつ安全な方法になりました。以前は、chroot された環境でユーザーアクティビティーをログに記録しようとしても、そのためのファイルがないため問題が発生していました。この問題は、RHEL 6 でファイル記述子の受け渡しを使用することで最終的に解決され、RHEL 7 では特権を持つモニターを使用することでこの機能が実現されました。その詳細をここで説明します。
chroot を使用しないロギング
単一ファイル
基本的に、chroot を使用しない場合はデフォルトの設定を使用できますが、/etc/ssh/sshd_config
の Subsystem sftp
行にコマンドライン引数を追加して、sftp-server
からのロギングを許可する必要があります。
Subsystem sftp /usr/libexec/openssh/sftp-server -l VERBOSE
sshd
を再起動し、sftp セッションを実行すると、次の行が /var/log/messages
に表示されます。
Mar 9 09:39:07 localhost sftp-server[1829]: received client version 3
Mar 9 09:39:07 localhost sftp-server[1829]: realpath "."
Mar 9 09:39:09 localhost sftp-server[1829]: lstat name "/root"
特定のファイル
別のファイルにログを記録する必要がある場合は、/etc/ssh/sshd_config
の log_facility
オプションを使用するなどして、その別のファイルに直接メッセージを送信するように rsyslog
を設定する必要があります。
Subsystem sftp /usr/libexec/openssh/sftp-server -l VERBOSE -f LOCAL3
/etc/rsyslog.conf
では次のようになります。
local3.* /var/log/sftp.log
sshd
と rsyslog
を再起動すると、/var/log/sftp.log
に次のログが記録されます。
Mar 9 09:49:02 localhost sftp-server[1947]: received client version 3
Mar 9 09:49:02 localhost sftp-server[1947]: realpath "."
Mar 9 09:49:04 localhost sftp-server[1947]: lstat name "/root"
- 特定の 1 つの sftp トランザクションのみをログに記録する場合は、
/etc/rsyslog.conf
ファイルを編集して次の行を追加します。
..snip..
local3.* /var/log/sftp.log
&~
*.info;mail.none;authpriv.none;cron.none /var/log/messages
..snip..
その後、rsyslog サービスを再起動します。
これで、メッセージは /var/log/sftp.log
に記録されるようになりました。ただし、'&~' があるため、/var/log/sftp.log
のみに制限されます。
chroot へのロギング
chroot を使用する場合、基本的に 2 つの方法が考えられます。1 つはサポートファイルを使用しない chroot で、特権を持つモニターを介したロギングが必要です。これは、多数のユーザーが存在し、chroot ごとに個別の /dev/log
ソケットを用意できない場合に役立ちます。もう 1 つは、/dev/log
ソケットを設定する方法で、sshd
によりモニターを介したロギングよりも優先して適用されます。ただし、どちらの場合も、chroot には該当するファイルがないため、上記のように実行可能パスではなく internal-sftp
サブシステムを使用する必要があります。
RHEL 6 (RHEL 6.7 以降)
モニター経由
openssh
のベースリリースには、/dev/log
に利用可能な設定済みのソケットがない場合に chroot された環境からログを記録する機能がありません。chroot を有効にするには、次のように /etc/ssh/sshd_config
を変更する必要があります。
Subsystem sftp internal-sftp -l VERBOSE
Match Group sftponly
ChrootDirectory /chroots/%u
sshd
を再起動し、sftponly
グループのユーザーを使用して sftp セッションを実行すると、/var/log/secure
に以下の行が表示されます (sftp-server
ではなく特権を持つモニターがファイル記述子を所有するため、プロセス名は sftp-server
ではなく sshd
になる点に注意してください)。
Mar 9 10:04:35 localhost sshd[2159]: received client version 3
Mar 9 10:04:35 localhost sshd[2159]: realpath "."
Mar 9 10:04:36 localhost sshd[2159]: lstat name "/"
このユースケースでは、log_facility
オプションは新しく開かれたログ記述子に対してのみ適用されるため、別のファイルにログを記録することはできません。このユースケースでは、sftp-server
によってスキップされます。
chroot のソケット経由
chroot の /dev/log
ソケットを介してログを記録する場合は、前述した方法で /etc/ssh/sshd_config
をセットアップしますが、/etc/rsyslog.d/sftp.conf
で rsyslog
設定を指定すると、必要なソケットが自動的に作成されます。以下は、rsyslog v7 (rsyslog7
パッケージ) の例です。
input(type="imuxsock" HostName="user" Socket="/chroots/user/dev/log" CreatePath="on")
if $fromhost == 'user' then /var/log/sftp.log
& stop
sshd
と rsyslog
を再起動すると、/var/log/sftp.log
に次のログエントリーが記録されます。
Mar 9 10:53:39 user internal-sftp[2475]: received client version 3
Mar 9 10:53:39 user internal-sftp[2475]: realpath "."
Mar 9 10:53:40 user internal-sftp[2475]: lstat name "/"
このセットアップでは多くの設定が必要ですが、クリーンな結果を得ることができます。ここで重要なのは、このソケットにアクセスできるように rsyslog
の SELinux ルールを、/chroots/user/
ディレクトリーにアクセスできるように sshd
の SELinux ルール (internal-sftp
) を、そしてソケットディレクトリー /chroots/user/dev/
(デフォルトは 0700 で、所有者は root) の SELinux および Linux ACL をセットアップすることです。
chroot のソケット経由、log facility によるフィルタリング
/etc/ssh/sshd_config
で log_facility
を再度使用しても、同じ結果を得ることができます。
Subsystem sftp internal-sftp -l VERBOSE -f LOCAL3
Match Group sftponly
ChrootDirectory /chroots/%u
/etc/rsyslog.conf
では次のようになります。
input(type="imuxsock" Socket="/chroots/user/dev/log" CreatePath="on")
local3.* /var/log/sftp.log
ログは /var/log/sftp.log
に保存されます。
Mar 9 12:28:46 rhel6 internal-sftp[4008]: received client version 3
Mar 9 12:28:46 rhel6 internal-sftp[4008]: realpath "."
Mar 9 12:28:47 rhel6 internal-sftp[4008]: lstat name "/"
RHEL 7 (RHEL 7.1 以降)
モニター経由
このバージョンの openssh
ベースリリースはさらに新しく、特権を持つモニターを介してログを記録する機能を提供しています。使用方法はシンプルで、前述の例のように internal-sftp
と chroot を設定するだけで使用できます。
Subsystem sftp internal-sftp -l VERBOSE
Match Group sftponly
ChrootDirectory /chroots/%u
この場合も、結果は /var/log/secure
に表示されます。
Mar 9 11:24:04 rhel7 sshd[20327]: received client version 3 [postauth]
Mar 9 11:24:04 rhel7 sshd[20327]: realpath "." [postauth]
Mar 9 11:24:05 rhel7 sshd[20327]: opendir "/" [postauth]
chroot のソケット経由
ログを別のファイルに記録する場合は、同じ sshd
設定を使用できますが、/etc/rsyslog.conf
を調整する必要があります。
input(type="imuxsock" HostName="user" Socket="/chroots/user/dev/log" CreatePath="on")
if $fromhost == 'user' then /var/log/sftp.log
& stop
sshd
と rsyslog
を再起動すると、sftp メッセージが /var/log/sftp.log
に記録されます (rsyslog
の bug #1184402 により、現在は /var/log/messages
)。
Mar 9 13:04:49 rhel7 internal-sftp[12699]: received client version 3
Mar 9 13:04:49 rhel7 internal-sftp[12699]: realpath "."
Mar 9 13:04:50 rhel7 internal-sftp[12699]: opendir "/"
chroot のソケット経由、log facility によるフィルタリング
前述のケースと同様に、/etc/ssh/sshd_config
で log_facility
を使用することもできます。
Subsystem sftp internal-sftp -l VERBOSE -f LOCAL3
Match Group sftponly
ChrootDirectory /chroots/%u
また、chroot にソケットが必要です。ない場合、sftp-server
のファシリティーは変更できません。これは /etc/rsyslog.conf
で行います。
input(type="imuxsock" Socket="/chroots/user/dev/log" CreatePath="on")
local3.* /var/log/sftp.log
SELinux 設定を行い、rsyslog
がソケットを作成してログがそれを使用できる場合、ログは /var/log/sftp.log
に記録されます。
Mar 12 09:40:06 rhel7 internal-sftp[2472]: received client version 3
Mar 12 09:40:06 rhel7 internal-sftp[2472]: realpath "."
Mar 12 09:40:07 rhel7 internal-sftp[2472]: opendir "/"
Chroot コメント
- chroot ディレクトリー構造のアクセス権に関する最小限の設定は、次の方法で定義できます (この場合のユーザー
user
はsftponly
グループのメンバーです)。
drwxr-xr-x. 3 root root 17 Jan 20 16:17 /chroots/
drwxr-xr-x. 4 root sftponly 27 Mar 11 17:55 /chroots/user/
drwxr-xr-x. 2 user sftponly 6 Mar 9 11:05 /chroots/user/home
drwxr-xr-x. 2 root root 16 Mar 12 09:39 /chroots/user/dev
srw-rw-rw-. 1 root root 0 Mar 12 09:39 /chroots/user/dev/log
- ユーザーが sftp アクセスのみを持つようにするには、上記の
Subsystem sftp
オプションと同じ引数を指定してForceCommand external-sftp
を使用することが推奨されます。 - RHEL 7 には、親ディレクトリーが欠落している場合にソケット作成が妨げられるバグが
rsyslog
にあります (ユーザーの chroot にdev
ディレクトリーを作成する必要があります)。(bug #1184410) - RHEL 7 では、たとえば別のディレクトリーへのフィルタリングに使用されるホスト名パラメーターの変更を妨げるバグが
rsyslog
にあります。(bug #1184402) - SELinux 設定がない RHEL 6 では、sftp chroot 内のディレクトリーを一覧表示することが SELinux によって禁止されているため、ユーザーはこれを実行できません。
- SELinux 設定がない RHEL 7 では、
rsyslog
は chroot にソケットを作成できません。
Comments