リモートログインしたユーザの操作ログ（script）を取得する

[tarr1124](http://qiita.com/tarr1124/items/f2c29b8d00f5e29966d3)さんの投稿（以下）を見て、自分でも試行錯誤してみた。

[linuxの作業ログをとるscriptコマンドを起動時からいれる](http://qiita.com/tarr1124/items/f2c29b8d00f5e29966d3)

[tarr1124](http://qiita.com/tarr1124/items/f2c29b8d00f5e29966d3)さんと同じ環境（CentOS）ではありませんが、RHEL6.2で操作ログ（script）が取得できています。

1行目から79行目まではデフォルトで、80行目以降に操作ログ（script）を取得する仕掛けを追記しています。

やりたいことは以下の通り。

**セキュリティ強化の一環で、リモートログイン（sshやtelnet）した全てのユーザの操作ログを取得したい。**
　※ただし、コンソールログインしたユーザの操作ログは取得しない。
　　最近は、コンソールログインする人はあまりいないだうろし、
　　コンソールログインできる人は管理者か有識者ぐらいかなと（勝手に）思っている。

```bash
:/etc/profile
# /etc/profile

# System wide environment and startup programs, for login setup
# Functions and aliases go in /etc/bashrc

# It's NOT a good idea to change this file unless you know what you
# are doing. It's much better to create a custom.sh shell script in
# /etc/profile.d/ to make custom changes to your environment, as this
# will prevent the need for merging in future updates.

pathmunge () {
    case ":${PATH}:" in
        *:"$1":*)
            ;;
        *)
            if [ "$2" = "after" ] ; then
                PATH=$PATH:$1
            else
                PATH=$1:$PATH
            fi
    esac
}


if [ -x /usr/bin/id ]; then
    if [ -z "$EUID" ]; then
        # ksh workaround
        EUID=`id -u`
        UID=`id -ru`
    fi
    USER="`id -un`"
    LOGNAME=$USER
    MAIL="/var/spool/mail/$USER"
fi

# Path manipulation
if [ "$EUID" = "0" ]; then
    pathmunge /sbin
    pathmunge /usr/sbin
    pathmunge /usr/local/sbin
else
    pathmunge /usr/local/sbin after
    pathmunge /usr/sbin after
    pathmunge /sbin after
fi

HOSTNAME=`/bin/hostname 2>/dev/null`
HISTSIZE=1000
if [ "$HISTCONTROL" = "ignorespace" ] ; then
    export HISTCONTROL=ignoreboth
else
    export HISTCONTROL=ignoredups
fi

export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE HISTCONTROL

# By default, we want umask to get set. This sets it for login shell
# Current threshold for system reserved uid/gids is 200
# You could check uidgid reservation validity in
# /usr/share/doc/setup-*/uidgid file
if [ $UID -gt 199 ] && [ "`id -gn`" = "`id -un`" ]; then
    umask 002
else
    umask 022
fi

for i in /etc/profile.d/*.sh ; do
    if [ -r "$i" ]; then
        if [ "${-#*i}" != "$-" ]; then
            . "$i"
        else
            . "$i" >/dev/null 2>&1
        fi
    fi
done

unset i
unset pathmunge

####################
# リモートログインしたユーザの
# 操作ログ（script）を取得する
####################
# 仮想端末（pts）で接続している場合のみ操作ログを取得する。
# ※物理端末（console等）で接続している場合は操作ログを取得しない。
if /usr/bin/tty | /bin/grep pts > /dev/null 2>&1 ; then
	# 自端末名を変数OWNTTYに格納する。
	# ※自端末以外で実行しているコマンドの
	#   影響を受けないようにするため。
	# ttyコマンドを実行すると、
	# "/dev/pst/1"と表示されたりするが、
	# psコマンド上では"pts/1"と表示されるため、
	# "/dev/"という文字列をsedで空に変換する。
	OWNTTY=`/usr/bin/tty | /bin/sed -e 's:/dev/::'`

	# 以下のコマンドから/etc/profileが呼び出された場合、
	# ループしてしまうため操作ログを取得しない。
	# su,sudo,sh
	/bin/ps -C su -C sudo -C sh -f | /bin/grep ${OWNTTY} > /dev/null 2>&1

	# 上記コマンドから/etc/profileが呼び出されていない場合は
	# 操作ログ（script）を取得する。
	if [ $? -eq 1 ]; then
		# 操作ログをscriptコマンドで/var/tmp配下に取得する。
		# なお、通常は/var/log配下にログを取得するのが望ましいが、
		# 一般ユーザの書込権限がないため（rwxr-xr-x）、
		# /var/tmp配下に取得することとする。
		/usr/bin/script -qf /var/tmp/script-`date '+%Y%m%d%H%M%S'`
		# scriptコマンドを実行すると、新規端末が自動起動するため、
		# exitコマンドで端末を停止しておく。
		exit
	fi
fi
```

あれっ？　/etc/profileの冒頭のコメントを見てみると、/etc/bashrcに記載した方が良いみたいですね・・・

あと、取得される操作ログ（/var/tmp/script-YYYYMMDDhhmmss）は、ユーザ自身で書き換え（改竄）や削除ができるので、定期的に別のサーバ（ログ管理サーバ等）に転送するとセキュアですが、やり方が分からないので、教えてエロい人。

[tarr1124](http://qiita.com/tarr1124/items/f2c29b8d00f5e29966d3)さんと同じように、試行錯誤している間は、OSが起動しなくなったり、リモートログインできなくなったりして、rescueモードで復旧させる羽目に陥りました。いい勉強になりました。

その他、取得された操作ログを確認する時は、catコマンドがお勧め。viewコマンドで確認すると、制御文字（^M）が表示されて見づらい。

そもそも、ここまでやるぐらいなら、専用のセキュリティソフトの導入を検討した方がよいかもしれませんね。