Elasticsearchの最新版は7.xであることに、どういうわけか前回の記事を公開してから気づいたので、大慌てで書き直しをした。やっぱり本家のインストールガイドをきちんと読まないといけないよな、ということで改めてFlutentdでsyslogを集めてKibana7で閲覧する環境を整えてみる。
全体の構成はこんな感じだ。
受信サーバのインストール
受信サーバはCPU2コア、4GBメモリ、20GBディスクのサーバを用意した。どれぐらいのスペックが適切なのかよくわからなかったので、適当に準備してみたというのが正直なところだ。これにCentOS7.xを新規に入れて、最新状態にupdateしたところから始める。
Elasticsearch7のインストール
最初にyumのrepoファイルを作成する。手動で作成することになるので、コピペ用にバッチ風のテキストを用意しておこう。
cat <<EOL >/etc/yum.repos.d/elasticsearch.repo [elasticsearch-7.x] name=Elasticsearch repository for 7.x packages baseurl=https://artifacts.elastic.co/packages/7.x/yum gpgcheck=1 gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch enabled=1 autorefresh=1 type=rpm-md EOL
こうしておいて、PGP Keyをインポートし、yum installする。
rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch yum install java-1.8.0-openjdk elasticsearch
続いて設定ファイルを書く。まず /etc/elasticsearch/elasticsearch.yml だ。
cluster.name: クラスタ名 node.name: ノード名 network.host: 0.0.0.0 transport.host: localhost transport.tcp.port: 9300 xpack.security.enabled: true discovery.type: single-node
Elasticsearch7ではx-packは標準装備なので、xpack.security.enabled を true にするだけで認証機能を利用できる。それから本稿ではマルチノードにしていないので discovery.type を single-node に設定している。この行がないと、xpackをONにしたときにElasticsearchが起動しなくなってしまうので必ず追記する。
もうひとつ設定ファイル /etc/elasticsearch/jvm.options を確認する。サーバのメモリ容量に応じて、下記の部分を調整する。
-Xms2g -Xmx2g # メモリの半分を指定
設定ファイルができたら、Elasticsearchを起動する。
systemctl enable elasticsearch systemctl start elasticsearch
次にElasticsearchの予約ユーザのパスワードを設定する。Elasticsearch7には6つの予約ユーザがあって、それぞれ任意のパスワードが設定できるが、一つずつ設定するのは面倒なので、autoモードでランダムパスワードを割り当て、利用するものだけ自分の都合のよいパスワードに付け替えるか、Kibanaログイン用のスーパーユーザーを自分の名前で新規作成することをオススメする。まずはランダムパスワードをつけてみよう。
[root@syslog ~]# /usr/share/elasticsearch/bin/elasticsearch-setup-passwords auto Initiating the setup of passwords for reserved users elastic,apm_system,kibana,logstash_system,beats_system,remote_monitoring_user. The passwords will be randomly generated and printed to the console. Please confirm that you would like to continue [y/N]y Changed password for user apm_system PASSWORD apm_system = 9TZRzFnyN2QB4DdQgh9T Changed password for user kibana PASSWORD kibana = hwgZNrnNNgeBiwgN7NMh Changed password for user logstash_system PASSWORD logstash_system = GPw6PmAaaZWUhAF3gsTT Changed password for user beats_system PASSWORD beats_system = iYAQeHHhR6mvEvpTrPxe Changed password for user remote_monitoring_user PASSWORD remote_monitoring_user = mpPNvGxUxENw5mGQPUNM Changed password for user elastic PASSWORD elastic = 5hmeFXwZ3w8N4TxVusVe
表示されたパスワードは忘れないようにメモしておく。
Kibana7のインストール
続いてKibana7をインストールする。こちらもyumで簡単にインストールできる。
yum install kibana
Kibana7の設定ファイルは /etc/kibana/kibana.yml だ。インストール直後は、デフォルト値を示すコメントばかりなので、ファイルの末尾に以下のように記述するとよい。
server.host: "0.0.0.0" elasticsearch.username: "elastic" elasticsearch.password: "xxxxxxxxxxxxxxxxxxxx" logging.quiet: true
3行目のパスワードは、先ほど割り当てたelasticのパスワードを指定しておく。4行目のオプションは、エラー以外の余計なログを抑制するもので、ぜひとも指定しておくことをオススメする。
次にファイアウォールを設定する。Kibanaにアクセスするだけなら、5601ポートを開ければよい。
firewall-cmd --permanent --add-port=5601/tcp firewall-cmd --reload
最後にKibanaを起動する。
systemctl enable kibana systemctl start kibana
これでKibanaにアクセス可能になった。http://受信サーバのIPアドレス:5601 にアクセスして確かめてみよう。次のように表示されれば成功だ。
ユーザ名にelastic、パスワードに割り当て済みのパスワードを指定してログインすると、このような画面になる。
無事にログインできたら、最初にやるべきはログイン用のユーザを作ることだ。下図の通り、左のサイドメニューのManagement(ギアアイコン)から始めて、Security/Users を選択し、Create new user ボタンを押す。
するとユーザ作成のダイアログが表示されるので、諸情報を入力してボタンを押せばよい。ログインしやすい名前とパスワードを設定し、ロールはSuperuserにしておく。Kibanaの普段使いにはそちらを利用すればよい。
Fluentdのインストール(受信サーバ)
さて、続いてFluentdのインストールだ。Fluentdのインストールは次のone linerで行う。
curl -L https://toolbelt.treasuredata.com/sh/install-redhat-td-agent3.sh | sh
次にElasticsearch用のプラグインを追加する。
td-agent-gem install fluent-plugin-elasticsearch
Fluentdは24224ポートを使ってアクセスするので、これを開けておく。単純にアクセスを開放してしまうと色々心配なので、監視対象にするサーバのIPアドレスを指定して開けるようにする。
firewall-cmd --permanent --new-zone=fluentd firewall-cmd --permanent --zone=fluentd --set-target=ACCEPT firewall-cmd --permanent --zone=fluentd --add-port=24224/tcp firewall-cmd --permanent --zone=fluentd --add-source=送信サーバIP1 firewall-cmd --permanent --zone=fluentd --add-source=送信サーバIP2 firewall-cmd --reload
次にFluentdの設定ファイルを用意する。/etc/td-agent/td-agent.conf だが、インストールするとデフォルトのファイルがすでにあるので、以下のように追記する。途中にelasticのパスワードがあるので、上記で設定したものをコピペする。
<source> @type syslog port 5140 tag fluentd.syslog format syslog </source> <match fluentd.**> @type copy <store> @type elasticsearch logstash_format true include_timestamp true port 9200 user elastic password elasticのパスワード buffer_type file buffer_path /var/log/td-agent/buffer/fluentd.back </store> </match>
この設定ファイルは2つのディレクティブから成る。sourceはポート5140からsyslogメッセージを受信して解析することを指示する部分、matchは内外から受信するFluentdのメッセージをElasticsearchへ突っ込む設定だ。できたらFluentdを起動する。
systemctl enable td-agent systemctl start td-agent
さてsyslogメッセージだが、 Fluentdがログを送信する方法はいくつかある。たとえばログファイルを直接パースして送信することもできる(実際は/var/log/messagesのファイル権限の都合でうまくいかない)。だがsyslogを扱うなら本家のドキュメントが示す手段を使うのがよさそうだ。概要はこんな感じだ。
- rsyslogに設定を加えて、local port 5140にsyslogを送るようにする
- Fluentdでそれを捕まえて受信サーバへ送る
2のFluentdで捕まえるほうは、すでにtd-agent.confに記述済みなので、1のrsyslogの設定を行う。/etc/rsyslog.conf の末尾に、次の1行を追加する。
*.* @127.0.0.1:5140
設定はお好みに合わせて変えていただきたい。もし /var/log/messages と同程度でよいと思うなら、次のようにするとよい。
*.info;mail.none;authpriv.none;cron.none @127.0.0.1:5140
設定できたら、rsyslogを再起動する。
systemctl restart rsyslog
これで、まずは受信サーバ自身のログが溜まりはじめるはずだ。
送信サーバの設定
送信サーバでは、既存の設定にFluentdを追加する形になる。つまりrsyslogにログを出力する設定を施し、Fluentdで送信するわけだ。
まずFluentdをインストールする。受信サーバと同じone linerで行う。
curl -L https://toolbelt.treasuredata.com/sh/install-redhat-td-agent3.sh | sh
次にFluentdの設定ファイルを書く。送信サーバの /etc/td-agent/td-agent.conf はこのようにする。
<source> @type syslog port 5140 tag fluentd.syslog format syslog </source> <match fluentd.**> @type forward <server> host 受信サーバのホスト名またはIPアドレス port 24224 </server> </match>
hostのところに、先ほど作成した受信サーバのホスト名またはIPアドレスを指定する。設定ファイルができたら起動する。
systemctl enable td-agent systemctl start td-agent
最後にrsyslogを設定する。/etc/rsyslog.conf は
*.* @127.0.0.1:5140
または
*.info;mail.none;authpriv.none;cron.none @127.0.0.1:5140
としておき、再起動して設定を有効化する。
systemctl restart rsyslog
Kibanaのセットアップ
設定が完了したら、改めてKibanaにアクセスしてみよう。サイドメニューのManagementを選択し、Kibana/Index Patternsをクリックする。するとCreate index pattern という画面になる。
ここで、Elasticsearchに溜まったデータから、インデックスを頼りにどのデータを閲覧するかを選択できる。本稿の通りに設定していれば、Fluentdで収集したログには「logstash-日付」というインデックスが付与されていて、すでにログが集まってきていると思う。もしインデックスが見つからないというメッセージが表示されていたら、対象サーバがsyslogを出力していないか、設定のどこかに間違いがあるかのいずれかだ。syslogに明示的にログを出力したいなら次のようにする。
logger 'fluentd test'
数分待っても変化がなければ、/var/log/elasticsearch 以下のログを確認するとか、/var/log/td-agent/td-agent.log をチェックして、エラーがないかを見てほしい。
順調にログが収集できていれば、上記のようにlogstash-なんとか、というインデックスが見えているので、全部にマッチするパターンすなわち「logstash-*」を入力し、Next stepボタンを押す。
次の画面では時刻を示すフィールドを指定する。Kibana7ではユーザが指定する必要があるので、ドロップボックスから @timestamp を選び、Create index pattern ボタンを押す。これで完了だ。
この画面になれば準備完了だ。いよいよデータを閲覧できる。今度はサイドメニューの一番上にあるDiscover(コンパスアイコン)を選択する。
これで準備完了だ。
Kibanaの使い方
Discover画面では、時系列にイベントの数をカウントしたグラフとその内容の一覧を表示する。スケールは右上部の「Last 15 minutes」などと表示されているところで調整できるし、グラフをクリックすることで拡大することもできる。下記の画面は、8台のサーバからsyslogを集めたデータの例だ。
ざっと見ると、10分あたり平均して50イベント前後記録されているのが分かる。ピーク時には200に到達している時間帯もある。このように多数のデータを、ただ時系列に眺めていては埒が明かない。そこで種別ごとに分類したり、特に多いメッセージを抽出したりして、調べていく手順を示そう。
syslogの場合、頼りになるのはidentというフィールドだ。これは単刀直入に言えばメッセージを出力したデーモンの名前に相当する。左側のサブメニューをクリックするとidentの部分が詳細化され、トップ5リストがヒストグラム化される。
ここでルーペアイコンをクリックすることで、特定フィールドを抽出したり、除外することができる。 たとえばsshdの+アイコンをクリックしてみよう。するとsshdの出力だけが抽出され、こんなグラフになる。
これは実は、12時間に渡って記録された22番ポートへスキャンしにきた不埒者のログだ。8台分のサーバの合計なのと、セッションのすべての記録なので単純に人数を示しているわけではないことに留意してもらいたいが、結構な頻度であることが分かる。これらのスキャンは fail2ban でブラックリスト送りにしているので実害はないが、対策が必要なのはわかっていただけると思う。
KibanaをHTTPS化する
【2019年12月2日修正】/etc/letsencrypt/live
をソースにするように改定した。
さてKibanaにアクセスすると、HTTPなので「保護されていない通信」と出る。実にうざったいのでLet’s Encryptを利用してHTTPS化したい。もしサーバにホスト名を割り当てられる方なら、次のような手順で実施できる。
まずサーバにcertbotをインストールする。
yum install certbot
firewall-cmdでHTTPをあけておく。
firewall-cmd --permanent --add-service=http firewall-cmd --reload
次にstandaloneモードでLet’s Encryptから証明書をもらう。
certbot --standalone certonly
certbotの使い方は説明しないが、メールアドレスや登録したいFQDNを聞かれるのできちんと答える。最後までうまくいけば、正しく証明書ファイルが作成される。/etc/letsencrypt/live/登録したFQDN
、というディレクトリにファイルが格納されているはずだ。
次がトリックなのだが、Kibanaはこのディレクトリを直接読めない。root権限で保護されてしまっているからだ。仕方がないのでこれをコピーする。適切な場所を選んで、次のようなバッチを設置する。たとえば /usr/local/bin/kibana-letsencrypt などとしておこう。
#!/bin/sh FQDN=登録したFQDN LETSENCRYPT_DIR=/etc/letsencrypt/live KIBANA_DIR=/etc/kibana/ssl mkdir -p $KIBANA_DIR cp $LETSENCRYPT_DIR/$FQDN/*.pem $KIBANA_DIR/$FQDN cd $KIBANA_DIR/$FQDN chmod 640 $KIBANA_DIR/$FQDN/* chown -R root:kibana $KIBANA_DIR
このバッチを実行して、ファイルが適切な場所に適切なパーミッションでコピーされていることを確認する。
[root@syslog3 ~]# ll /etc/kibana/ssl/xxxxxxxxxxxxxxxxxxx/ total 16 -rw-r----- 1 root kibana 1948 Jun 18 16:38 cert.pem -rw-r----- 1 root kibana 1647 Jun 18 16:38 chain.pem -rw-r----- 1 root kibana 3595 Jun 18 16:38 fullchain.pem -rw-r----- 1 root kibana 1704 Jun 18 16:38 privkey.pem
次に /etc/kibana/kibana.yml を編集する。次の3行を追加する。
server.ssl.enabled: true server.ssl.certificate: /etc/kibana/ssl/登録したFQDN/fullchain.pem server.ssl.key: /etc/kibana/ssl/登録したFQDN/privkey.pem
最後にKibanaをリスタートする。
systemctl restart kibana
これで、https://サーバ名:5601 という名前でアクセスすることができるようになった。
なお Let’s Encrypt の証明書は3ヶ月ごとに更新が必要なので、cronを設定しておく。たとえば /etc/cron.d/cert-renew のようなバッチを用意する。これは毎週月曜日の9時30分に期限をチェックして、更新があればファイルのコピーも行ってくれる。
MAILTO= 30 9 * * mon root /usr/bin/certbot renew --standalone --post-hook "/usr/loal/bin/kibana-letsencrypt && systemctl restart kibana" | logger -t certbot-renew -p local0.info