AWS Ubuntu 18 で fluentd (td-agent) を使って CloudWatch Logs へログを送ってみる

Ubuntu版の記事があまり見当たらなかったので、なるべく分かり易く纏めてチュートリアル風にしてみました。
※AWSのUIはコロコロ変わるみたいなので、参考までに。(2019/10/12）

# チュートリアル
このチュートリアルでは、Ubuntuサーバーの認証ログ（/var/log/auth.log）をCloudWatchへ送って、AWSコンソール上でSSHのログイン・ログアウトを監視してみます。

- AWSでEC2サーバー（Ubuntu）を立てる
- アクセスキーID、シークレットアクセスキーを取得する
- EC2サーバー（Ubuntu）にtd-agentを設定する
- ログ送信テスト


# AWSでEC2サーバー（Ubuntu）を立てる
まずはEC2にUbuntuサーバーを立てて起動している事を前提としています。
このチュートリアルでは、「Ubuntu Server 18.04 LTS (HVM), SSD Volume Type」(t2.micro) を使用します。
どのリージョンでも良いですが、東京リージョンはレスポンス早くて快適です。

![00_EC2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280104/8f5b156e-4688-804a-137b-f3cae34d73a9.png)
※EC2設定は[コチラの記事](https://qiita.com/hf7777hi/items/08b25fba65f0d214aee3)が分かり易いと思います。この記事は「Amazon Linux 2」で書かれているので、ここを「Ubuntu Server 18.04」に読み替えて下さい。


# アクセスキーID、シークレットアクセスキーを取得する
td-agentを使ってサーバーからAWSへログを送信するには、アクセスキーIDとシークレットアクセスキーが必要です。アクセスキーIDとシークレットアクセスキーは、AWSコンソールでユーザーを作成する事で取得出来ます。

## ユーザーの追加

[セキュリティ、ID、およびコンプライアンス] > [IAM] をクリックします。
![00_AIM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280104/67370ec3-8d66-826b-1eee-49d4d24608a8.png)


[ユーザ] > [ユーザーを追加] をクリックします。
![01_user.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280104/24261592-e292-4bc4-2cf2-9e4a16ec183b.png)


[ユーザーを追加] 画面で、ユーザー詳細の設定を行い、[次のステップ:アクセス制限] をクリックします。
- ユーザー名　td-agent-user
- アクセスの種類　`プログラムによるアクセス` にチェックを入れる
![02_user_add_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280104/65104026-40a9-4f49-01e3-92de2465c1ae.png)


アクセス許可の設定画面では、[既存のポリシーを直接アタッチ]をクリックし、ポリシーのフィルタに「CloudWatchLogsFullAccess」と入力して、検索結果に表示されたら左端のチェックをＯＮにして[次のステップ:タグ]をクリックします。
- アタッチするポリシー名 CloudWatchLogsFullAccess
![02_user_add_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280104/d34aa51d-8c6e-1152-995c-0bf121962c7f.png)
　※この権限があれば、CloudWatchにログ送信する事が出来ます（もっと機能を限定してもいいかもです）。

後は、次の[ユーザータグの追加]で[次のステップ:確認]をクリックし、最後の[確認]画面で[ユーザーの作成]をクリックすれば完成です。
![02_user_add_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280104/fa2d3067-3c5a-d964-0945-9b49425d2212.png)
表示されるアクセスキーIDとシークレットアクセスキーを忘れずメモしておきましょう。
これでAWS側は準備が整いました。



# EC2サーバー（Ubuntu）にtd-agentを設定する
EC2サーバー（Ubuntu）側の設定を行う為、サーバーに初期アカウント（Ubuntu）で接続します。

```
ssh -i .ssh/pri-key.pem ubuntu@ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com
```

## td-agentパッケージをインストール

ここではUbuntu 18 (Bionic)用のパッケージをインストールします。

```
curl -L https://toolbelt.treasuredata.com/sh/install-ubuntu-bionic-td-agent3.sh | sh
```
※他のバージョンをインストールする場合は、以下のサイトから探してください。
[Install by DEB Package (Debian/Ubuntu)](https://docs.fluentd.org/installation/install-by-deb#step-1-install-from-apt-repository)

インストール直後はサービス起動するので、一旦停止させておきます。

```
sudo systemctl stop td-agent
```

## プラグインfluent-plugin-cloudwatch-logsのインストール
次に、td-agentからAWSのCloudWatchにログを送信する為のプラグインをインストールします（※こちらはsudoを使います）。
インストール用のツール（fluent-gem）は、td-agentインストール時に用意されているものを使います（gemのインストールは不要です）。

```
sudo /opt/td-agent/embedded/bin/fluent-gem install fluent-plugin-cloudwatch-logs
```


## AWS環境変数の設定

/etc/default/td-agentファイルを編集して、リージョン（東京：ap-northeast-1）、アクセスキーID、シークレットアクセスキーを設定して下さい。サービス再起動時に有効になります。

```console:/etc/default/td-agent
# This file is sourced by /bin/sh from /etc/init.d/td-agent
# Options to pass to td-agent
TD_AGENT_OPTIONS=""
AWS_REGION="ap-northeast-1"　←リージョンを合わせる
AWS_ACCESS_KEY_ID="xxxxxxxxxxxxxxxxxxxx"　←書き換える
AWS_SECRET_ACCESS_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"　←書き換える
```
※ちなみに、/etc/init.d/td-agentは今回の方法では不要なので書き換えは行いません。


## td-agent.conf設定

/etc/td-agent/td-agent.confを編集し、ログ送信設定を行います。ここでは、認証ログ（/var/log/auth.log）を指定しています。

```conf:/etc/td-agent/td-agent.conf
<source>
  @type tail
  path /var/log/auth.log
  pos_file /tmp/auth.log.pos
  tag syslog.auth.log
  format none
</source>

<match syslog.**>
  @type cloudwatch_logs
  log_group_name logstest
  log_stream_name targetserver/var/log/auth.log
  auto_create_stream true
</match>
```
　※デフォルトのtd-agent.confは全て消して、上記に置き換えてください。

設定パラメータについて：
`<source>`
- `@type tail` 監視対象ログファイルに新たなログが追記された分を送信対象とする
- `path /var/log/auth.log` 送信対象ファイル（今回はUbuntu標準で出力されている認証ログを指定） 
- `pos_file` pathの読み込み位置を記録するファイル
- `tag syslog.auth.log` ここで設定したtagは `<match>` で検知されます
- `format none` fluentdの標準的なフォーマットでログを調整する（noneでも何もしない訳では無い）

`<match syslog.**>` 
- `@type cloudwatch_logs` プラグインfluent-plugin-cloudwatch-logsでログを送信
- `log_group_name logstest` CloudWatchのロググループ名を指定
- `log_stream_name targetserver/var/log/auth.log` CloudWatchのログストリーム名を指定
- `auto_create_stream true` ロググループ・ログストリームを自動的に作成する
※設定については[github](https://github.com/fluent-plugins-nursery/fluent-plugin-cloudwatch-logs/blob/master/README.md)に詳しく書かれています。


## td-agentユーザーをadmグループに所属させる
**（※本セクションはvar/log/auth.logをCloudWatchに送る為に必要な設定です。それ以外のログ送信では恐らく不要です。）**

このチュートリアルでは/var/log/auth.logのログをCloudWatchに送りますが、auth.logファイルは所有者でも所有グループでもない"その他のアカウント"からの読み込みは禁止されています。

```
$ ls -la /var/log
　　：
-rw-r-----   1 syslog    adm   212987 Oct 12 07:46 auth.log
　　：
　　※認証ファイル（auth.log）は、admグループに所属しています。
```

td-agentサービスは、td-agentをインストールした際に自動生成されたユーザー（td-agent）で実行されるので、
ここでは対策として、ユーザーtd-agentをグループadmに所属させる事でファイルを読み込める様に設定します。

```
sudo gpasswd -a td-agent adm
```

設定が出来たか確認します。

```
$ cat /etc/group | grep adm
adm:x:4:syslog,ubuntu,td-agent
　　：
```
admグループにtd-agentが加わった事が確認出来ました。これでauth.logにアクセス出来る様になります。


## td-agentサービス再起動
準備が整いました。サービスを再起動して設定を読み直します。

```
sudo systemctl start td-agent
```

各種設定がうまく行けば、td-agentサービスに下記の様なログが確認出来る筈です。

```
$ tail -f /var/log/td-agent.log
2019-10-12 08:24:51 +0000 [info]: gem 'fluent-plugin-s3' version '1.1.11'
2019-10-12 08:24:51 +0000 [info]: gem 'fluent-plugin-td' version '1.0.0'
2019-10-12 08:24:51 +0000 [info]: gem 'fluent-plugin-td-monitoring' version '0.2.4'
2019-10-12 08:24:51 +0000 [info]: gem 'fluent-plugin-webhdfs' version '1.2.4'
2019-10-12 08:24:51 +0000 [info]: gem 'fluentd' version '1.7.0'
2019-10-12 08:24:51 +0000 [info]: adding match pattern="syslog.**" type="cloudwatch_logs"
2019-10-12 08:24:51 +0000 [info]: adding source type="tail"
2019-10-12 08:24:51 +0000 [info]: #0 starting fluentd worker pid=20217 ppid=20210 worker=0
2019-10-12 08:24:51 +0000 [info]: #0 following tail of /var/log/auth.log
2019-10-12 08:24:51 +0000 [info]: #0 fluentd worker is now running worker=0
```
うまく行かない場合は、もう一度設定を見直して見て下さい。



# ログ送信テスト
まずは準備として、AWSコンソールからCloudWatchを確認しましょう。


## CloudWatch確認
まだログ送信していない筈なので、CloudWatchには何も表示されていないと思います。確認してみましょう。

[管理とガバナンス]から、[CloudWatch]を選択して下さい。
![03_cw_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280104/634cc02a-a489-182a-d6f1-63c13d5f5b8e.png)

[ログ]をクリックしてみましょう。まだ何もログをキャッチしていない為、ロググループが存在していません。
![03_cw_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280104/f487a64f-986a-4fc4-9d39-0b0f7eeb726d.png)

## ログ送信
ではログ送信を行いましょう。認証ログ（auth.log）は、sshログインでも出力されるので、この方法で試します。

もう一つのシェルを開き、EC2サーバーに接続します。

```
ssh -i .ssh/pri-key.pem ubuntu@ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com
```
ログインにすれば、認証ログ（auth.log）がCloudWatchに送信された筈です。


## CloudWatch再確認
では再びCloudWatchを確認しましょう。
AWSコンソール上でログが確認できる迄、10秒～30秒ほど時間が掛かる場合があるので注意して下さい。
![03_cw_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280104/bde2d012-c620-b0c8-c9e5-e00529db8173.png)
ロググループに「logtest」が現れました！
「logtest」をクリックすると、ログストリーム「targetserver/var/log/auth.log」が表示されました。
![03_cw_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280104/6d842a94-a532-dfb7-d570-7368a67db0a5.png)

ログストリーム「targetserver/var/log/auth.log」をクリックすると、auth.logの内容をCloudWatchLogsで確認する事が出来ました。
![03_cw_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280104/7c270be5-36c9-cdaa-fed4-bed3dbfdf7a4.png)

念のためサーバー側でauth.logを確認してみましょう。

```
$ tail -f /var/log/auth.log
　　：
Oct 12 09:10:24 ip-172-31-39-76 sudo: pam_unix(sudo:session): session closed for user root
Oct 12 09:10:33 ip-172-31-39-76 sudo:   ubuntu : TTY=pts/1 ; PWD=/etc/default ; USER=root ; COMMAND=/bin/systemctl start td-agent
Oct 12 09:10:33 ip-172-31-39-76 sudo: pam_unix(sudo:session): session opened for user root by ubuntu(uid=0)
Oct 12 09:10:34 ip-172-31-39-76 sudo: pam_unix(sudo:session): session closed for user root
Oct 12 09:11:48 ip-172-31-39-76 sshd[20376]: Accepted publickey for ubuntu from 124.209.150.139 port 64980 ssh2: RSA SHA256:43Gtsdhxbp1l6H6AQMY2BmOVuva1TO3ex4zIZBDQW40
Oct 12 09:11:48 ip-172-31-39-76 sshd[20376]: pam_unix(sshd:session): session opened for user ubuntu by (uid=0)
Oct 12 09:11:48 ip-172-31-39-76 systemd-logind[843]: New session 49 of user ubuntu.
Oct 12 09:12:28 ip-172-31-39-76 sshd[20495]: Invalid user usuario from 49.83.149.194 port 40281
Oct 12 09:12:30 ip-172-31-39-76 sshd[20495]: error: maximum authentication attempts exceeded for invalid user usuario from 49.83.149.194 port 40281 ssh2 [preauth]
Oct 12 09:12:30 ip-172-31-39-76 sshd[20495]: Disconnecting invalid user usuario 49.83.149.194 port 40281: Too many authentication failures [preauth]
Oct 12 09:17:01 ip-172-31-39-76 CRON[20505]: pam_unix(cron:session): session opened for user root by (uid=0)
Oct 12 09:17:01 ip-172-31-39-76 CRON[20505]: pam_unix(cron:session): session closed for user root
```
同じログがCloudWathLogsにアップロードされている事が確認出来ました。


## CloudWatchの使い道
一度CloudWatchに上げてしまえば、AWS上でアラート設定したり、Eメールでアラートを受け取ったり、溜まりすぎたログを自動的にS3に移動させたり（Lambda）と、様々な機能が簡単に使える様になって便利です。


# 最後に
もし不明点等あれば、なるべく分かり易く修正したいと思います。よろしくお願いします。