Linux のログイン・ログオフ履歴を Cloudwatch Logs に送信する


# サマリ
Linux のログイン/ログオフの履歴(だけ)を Cloudwatch Logs に送りたかった。
rsyslog から sshd のログだけ抽出して Cloudwatch Logs Agent で送った。できた。

# 要件
Linux へのログイン・ログオフの履歴を Cloudwatch Logs に保存する必要があり、Cloudwatch Logs Agent をインストールして `/var/log/secure` を Cloudwatch Logs に送信する。
ただし、トラフィック量の都合で `secure` 全て送るのはよろしくないのでいい感じに絞ったものを送信したい。

SSH ログイン時に出力されるログには2種類あり、

1. sshd プロセスが出力する rsyslog
    - /var/log/secure
2. login プロセス出力するログ達（バイナリ形式）
    - /var/log/wtmp （ログイン成功ログ）
        - last コマンドで表示、新しいものが上で並ぶ
    - /var/log/btmp （ログイン失敗ログ）
        - lastb コマンドで表示、新しいものが上で並ぶ

送信するにはテキストである必要があるため、

1. rsyslog からうまいこと sshd プロセスのログだけを別ファイルにする
    - rsyslog で出力されたログをCloudwatch Logs Agent で送信する
2. last/lastbコマンドを実行し、結果をログファイルに出力するシェルスクリプトを作成する。その際、時系列降順に直す必要がある。
    - cronで定期的に実行し、ログをCloudwatch Logs Agent で送信する

の2パターン考えられるが、楽そうな前者を試す。

# 設定手順

## 環境
- Red Hat Enterprise Linux 7.4 (HVM)
- awscli-cwlogs 1.4.4

## SSHログの抽出
適当な EC2 インスタンスを起動。

要件としては、rsyslog の secure ログ `/var/log/secure` の `| grep 'sshd'`したような結果が出力できればよさそう。そのほかの secure ログはいらない。

```bash:console
$ sudo cat /var/log/secure | grep 'sshd'
略
Jan 23 19:41:46 HOSTNAME sshd[5106]: Server listening on 0.0.0.0 port 22.
Jan 23 19:41:46 HOSTNAME sshd[5106]: Server listening on :: port 22.
Jan 23 20:40:54 HOSTNAME sshd[1976]: pam_unix(sshd:session): session closed for user ec2-user
Jan 23 20:47:46 HOSTNAME sshd[4914]: Accepted publickey for ec2-user from 10.0.0.2 port 61646 ssh2: RSA SHA256:xxx
Jan 23 20:47:46 HOSTNAME sshd[4914]: pam_unix(sshd:session): session opened for user ec2-user by (uid=0)
Jan 23 20:49:12 HOSTNAME sshd[4914]: pam_unix(sshd:session): session closed for user ec2-user
```

rsysgにはプロパティベース フィルタというものがあり、 `:property, [!]compare-operation, "value"`
で `programname` でフィルタがかけられる。これを利用すれば特定のプロセスのログだけ別ファイルに出力することが可能。
なので rsyslog の設定をしていく。`secure_sshd` という新しいログファイルに sshd プロセスのログだけを出力する設定を追記。

```bash:/etc/rsyslog.conf
# sshd ログを別ファイルにも出力
:programname, isequal, "sshd" /var/log/secure_sshd
```

```bash:console
sudo service rsyslog restart
```

ログイン・ログオフしてから良い感じにログが出ていること確認できた。

```bash:console
$ sudo cat /var/log/secure_sshd
Jan 24 03:08:55 HOSTNAME sshd[9308]: Accepted publickey for ec2-user from 10.0.0.3 port 60196 ssh2: RSA SHA256:xxx
Jan 24 03:08:55 HOSTNAME sshd[9308]: pam_unix(sshd:session): session opened for user ec2-user by (uid=0)
Jan 24 03:09:14 HOSTNAME sshd[9308]: pam_unix(sshd:session): session closed for user ec2-user
```



## Cloudwatch Agent 側設定
EC2インスタンスに CloudwatchLogs 用のポリシーをアタッチ。

```json:Send2Cloudwatch
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents",
        "logs:DescribeLogStreams"
    ],
      "Resource": [
        "arn:aws:logs:*:*:*"
    ]
  }
 ]
}
```

パッケージ更新、awslogsインストール

```bash:console
sudo yum update -y
# ubuntu,centos,redhat はこう
curl https://s3.amazonaws.com/aws-cloudwatch/downloads/latest/awslogs-agent-setup.py -O
sudo python ./awslogs-agent-setup.py --region us-east-1
# Amazon Linux ならこっち
# sudo yum install awslogs
```


バージョン確認

```bash:console
$ /var/awslogs/bin/awslogs-version.sh
略
/etc/cron.d/awslogs_log_rotate version:
# Version: 1.4.3
CloudWatch Logs Plugin Version:
You are using pip version 6.1.1, however version 9.0.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
---
Metadata-Version: 1.1
Name: awscli-cwlogs
Version: 1.4.4
Summary: AWSCLI CloudWatch Logs plugin
Home-page: http://aws.amazon.com/cli/
Author: Amazon
Author-email: UNKNOWN
License: Amazon Software License
Location: /var/awslogs/lib/python2.7/site-packages
Requires: awscli, six, python-dateutil
AWS CLI Version
```

ログファイル送信設定、先ほどの `secure_sshd` を指定する
※Amazon Linux(rpm版) の場合はリソース配置先が `/etc/awslogs/` 配下になる

```bash:/etc/awslogs.conf
# 元のmessageログ送信は今回使わないのでコメントアウト
# [/var/log/messages]
# datetime_format = %b %d %H:%M:%S
# file = /var/log/messages
# buffer_duration = 5000
# log_stream_name = {instance_id}
# initial_position = start_of_file
# log_group_name = /var/log/messages

# 普通にsecureログ送るならこう
# [/var/log/secure]
# datetime_format = %b %d %H:%M:%S
# file = /var/log/secure
# buffer_duration = 5000
# log_stream_name = {instance_id}
# initial_position = start_of_file
# log_group_name = /var/log/secure

[/var/log/secure_sshd]
datetime_format = %b %d %H:%M:%S
file = /var/log/secure_sshd
buffer_duration = 5000
log_stream_name = {instance_id}
initial_position = start_of_file
log_group_name = /var/log/secure_sshd
```

必要に応じてプロキシ設定

```bash:/var/awslogs/etc/proxy.conf
HTTP_PROXY=proxyserver:8080
HTTPS_PROXY=proxyserver:8080
NO_PROXY=
```

リージョンも必要に応じて変更する

```bash:/var/awslogs/etc/awscli.conf
[plugins]
cwlogs = cwlogs
[default]
region = us-east-1
```

サービス再起動＆起動設定

```bash:console
sudo service awslogs start
sudo chkconfig awslogs on
```

Logs への送信ログ確認するなら

```bash:console
sudo tail /var/log/awslogs.log
```

## 動きました
![image.png](https://qiita-image-store.s3.amazonaws.com/0/130874/8998e31a-3d13-5872-f1ac-eca63fd41f92.png)

# 参考
[CloudWatch Logs エージェントのリファレンス - Amazon CloudWatch ログ](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/AgentReference.html)
[クイックスタート: 実行中の EC2 Linux インスタンスに CloudWatch Logs エージェントをインストールして設定する - Amazon CloudWatch ログ](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/QuickStartEC2Instance.html)
[Linux環境設定/sshによる不正アクセスを確認する - Linuxと過ごす](http://linux.just4fun.biz/?Linux%E7%92%B0%E5%A2%83%E8%A8%AD%E5%AE%9A/ssh%E3%81%AB%E3%82%88%E3%82%8B%E4%B8%8D%E6%AD%A3%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%82%92%E7%A2%BA%E8%AA%8D%E3%81%99%E3%82%8B)
[Rsyslog - Wikinote](http://hagio.org/wiki/index.php/Rsyslog)
[システム管理の基礎 syslogdの設定をマスターしよう：Linux管理者への道（3） - ＠IT](http://www.atmarkit.co.jp/ait/articles/0209/07/news002.html)
[必読！ログファイルとディレクトリ | Think IT（シンクイット）](https://thinkit.co.jp/article/711/1?page=0%2C1)