この記事は、ニフクラブログで2022-09-05に公開された記事を移転したものです。
こんにちは、CRE部 技術支援チームです。
サーバー、ネットワーク、ストレージなどのシステムを構成するコンポーネントの安定運用に、ログ管理は大変重要です。ログファイルには、システムの状態を知るための多量の情報が記されていますが、常にログの内容を監視している方はあまりいないと思います。とりあえずログを蓄積しておいて、後で何かがあった際に追跡できるよう、管理されている方も多いのではないでしょうか。
また、ログを細かく管理しようとすると、例えばサーバーの台数分、個別にログを参照しなければならず、運用コストが増大します。蓄積されたログを効果的に活用するためには、ログを集約、可視化し、統合監視できるシステムがあると便利であり、運用コストを下げることができます。
当ブログ記事では過去に、fluentdとオブジェクトストレージを使用したログ収集や、telegraf+influxdb+chronografでログを可視化してみるといった、ログ管理に関するtipsをご紹介してきました。
今回も「ログの可視化」に焦点を当て、オープンソースのElasticsearch・Logstash・Kibanaを使用し、収集したログの参照やグラフ化を行ってみたいと思います。この3つのツールはELKスタックとして知られ、それぞれを組み合わせることにより、ログの収集、統合管理、そして可視化を実現可能です。
本記事では、Apache HTTP Serverのアクセスログを対象に検証していきます。
構成イメージ
前提条件
本記事は、以下の前提知識がある方を想定しています。
- ニフクラの基本的なコントロールパネルの操作、サービスを利用に関する知識
- Linuxの基本的な操作、設定に関する知識
利用リソース
east-13にサーバーを3台作成し、プライベートLANで接続します。
リソース | 数量 |
---|---|
仮想サーバー (OS:Rocky Linux 8.5) | 3 |
ロードバランサー | 1 |
プライベートLAN | 1 |
環境構築
1. プライベートLANの作成
ログの転送経路として、プライベートLANを作成します。
本検証ではプライベートLANに付与するIPアドレス帯を「192.168.1.0/24」としています。
作成方法の詳細は以下をご参照ください。
クラウドヘルプ(プライベートLAN:作成)
2. 仮想サーバーの作成
各サーバーのホスト名と役割は以下の通りです。
ホスト名 | 役割 | アプリケーション | プライベートIP |
---|---|---|---|
logserver | ログ監視サーバー(アクティビティログ取得・ログ集積) | Elasticsearch, Logstash, Kibana | 192.168.1.100 |
web01 | ログ収集対象Webサーバー(アクセスログ出力・転送) | Logstash, Apache HTTP Server | 192.168.1.1 |
web02 | ログ収集対象Webサーバー(アクセスログ出力・転送) | Logstash, Apache HTTP Server | 192.168.1.2 |
今回はRocky Linuxを使用しているため、SSHキーの作成が必須となります。 また、本検証ではサーバーに適用するファイアウォールには以下の通信を許可するよう設定しています。
ファイアウォール設定:logserver(ログ監視サーバー)
INルール
プロトコル | ポート | 接続元 | 用途 |
---|---|---|---|
TCP | 22 | 作業端末のグローバルIPアドレス | SSH接続 |
TCP | 5601 | 作業端末のグローバルIPアドレス | Kibana接続 |
TCP | any | 192.168.1.0/24 | サーバー間接続 |
ファイアウォール設定:web01/web02(ログ収集対象Webサーバー)
INルール
プロトコル | ポート | 接続元 | 用途 |
---|---|---|---|
TCP | 22 | 作業端末のグローバルIPアドレス | SSH接続 |
TCP | any | 192.168.1.0/24 | サーバー間接続 |
作成方法の詳細は以下をご参照ください。
クラウドヘルプ(SSHキー)
クラウドヘルプ(サーバーの作成)
クラウドヘルプ(ファイアウォールグループの新規作成)
3. Webサーバーの準備
Apache HTTP Serverのアクセスログを可視化するため、ログ出力用のWebサーバーを用意します。 本検証ではweb01/web02(ログ収集対象Webサーバー)にてApache HTTP Serverを起動し、テスト用のhtmlファイルを配置しています。
ここでは設定項目や設定値は省略します。
4. ソフトウエアの準備
使用するソフトウエアのインストールとセットアップを行います。
リポジトリの設定 (作業対象:全台)
公開署名キーをインストールします。
# rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch
リポジトリ情報を登録します。 (今回のバージョンは、 7.xで検証しています)
# vi /etc/yum.repos.d/elasticsearch.repo
- 以下のパラメータを設定します。
[elasticsearch] 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=0 autorefresh=1 type=rpm-md
Elasticsearchのインストール(作業対象:logserver)
Elasticsearch をインストールします。
# dnf -y install --enablerepo=elasticsearch elasticsearch
Logstash から転送されるログを受け付けられるようにネットワーク設定を変更します。
# vi /etc/elasticsearch/elasticsearch.yml
- 以下のパラメータを設定します。
-- 省略 -- network.host: 0.0.0.0 http.port: 9200 transport.host: localhost transport.tcp.port: 9300
サービスを起動します。
# systemctl start elasticsearch.service
サービスの自動起動を設定します。
# systemctl enable elasticsearch.service
サービスが起動していることを確認します。
# systemctl status elasticsearch.service
- 出力結果が「active (running)」となっていることを確認します。
アクセスできるか確認します。
# curl http://localhost:9200/
- 応答があることを確認します。
Kibanaのインストール(作業対象:logserver)
Kibana をインストールします。
# dnf -y install --enablerepo=elasticsearch kibana
設定ファイルを変更します。
# vi /etc/kibana/kibana.yml
- 以下のパラメータを設定します。
-- 省略 -- # To allow connections from remote users, set this parameter to a non-loopback address. server.host: “0.0.0.0“
サービスを起動します。
# systemctl start kibana.service
サービスの自動起動を設定します。
# systemctl enable kibana.service
サービスが起動していることを確認します。
# systemctl status kibana.service
- 出力結果が「active (running)」となっていることを確認します。
Logstashのインストール(作業対象:web01/web02)
Logstash をインストールします。
# dnf -y install --enablerepo=elasticsearch logstash
ログの取得、整形、出力の設定をします。
# vi /etc/logstash/conf.d/sample.conf
- 以下のパラメータを設定します。(本手順では /var/log/httpd/access_log からログを収集します。)
input { file { path => ["/var/log/httpd/access_log"] sincedb_path => "/dev/null" start_position => "beginning" } } filter { } output { elasticsearch { hosts => "<192.168.1.100>" //logserverのIPアドレス } }
システムログを取得できるように systemd の ユーザー情報を変更します。
# vi /etc/systemd/system/logstash.service
- 以下のパラメータを設定します。
-- 省略 -- #User=logstash //コメントアウト #Group=logstash //コメントアウト User=root Group=root
サービスを起動します。
# systemctl start logstash.service
サービスの自動起動を設定します。
# systemctl enable logstash.service
サービスが起動していることを確認します。
# systemctl status logstash.service
- 出力結果が「active (running)」となっていることを確認します。
5. ロードバランサーの準備
ロードバランサーを作成し、今回作成したログ収集対象サーバーweb01/web02を負荷分散対象にします。
作成方法の詳細は以下をご参照ください。
クラウドヘルプ(ロードバランサーの作成)
ログを可視化してみる
Kibanaにアクセスする
テスト端末から、Web ブラウザで Kibana のホームページにアクセスします。
http://<ログ可視化サーバーのIPアドレス>:5601/
- KibanaのTOP画面が表示されます。
インデックスパターンを構成する
左サイドメニューの [Discover] を選択し、[Create index pattern] を押下します。(Elasticsearch のインデックスを識別するためのインデックスパターンを構成します。)
[Index pattern name] に "Logstash-YYYY.MM.DD-000001" と入力し、 次へ進みます。(入力する値は表示される候補を利用してください。)
[Time field] から [@timestamp] を選択し、[Create index pattern] を押下します。
インデックスパターンのフィールドが一覧表示されることを確認します。
Webアクセスでログを記録する
Webサーバーを構築したばかりなので、まだアクセスログがありません。 Webサーバーにログを蓄積させるため、テスト端末からロードバランサーの公開IPに向けてアクセスします。 今回はApacheBenchにてトラフィックを印加しています。ここではテスト端末のオペレーションは省略します。
ログ表示を確認する
左サイドメニュー [Discover] をクリックして取得した時系列のログを確認します。(ログ可視化サーバー と 監視対象Webサーバー1,2のログが混在した状態で表示されます。)
監視対象Webサーバー1,2のアクセスログが取り込まれていることは確認できましたが、情報量が少ないです。
もう少し情報を取り込めるよう、設定を変更していきます。
ログ表示内容のカスタマイズ
監視対象Webサーバー1,2の設定変更
Apache HTTP Serverのログフォーマット変更
web01,02のアクセスログフォーマットを変更します。現状アクセスログに記録されているIPはロードバランサーのIPとなっており、 本来のアクセス元を記録できていません。今回は以下のように、X-Forwarded-For ヘッダを記録するよう、設定変更します。
# vi /etc/httpd/conf/httpd.conf
X-Forwarded-For を LogFormat 部分に挿入します。
-- 省略 -- <IfModule log_config_module> -- 省略 -- LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
- 設定変更後、httpdサービスを再起動しておきます。
Logstashの設定変更
次に、web01,02のLogstashにおいて、フィルターを設定変更します。今回、grok,geoip各フィルターを追加してみます。
# vi /etc/logstash/conf.d/sample.conf
-- 省略 -- filter { grok { match => { "message" => "%{COMBINEDAPACHELOG}" } //Apache の Combined形式をパターンとしてフィールドに抜き出す } geoip { source => "clientip" //clientipフィールドを geoip の解析対象とする } date { match => [ "timestamp", "dd/MMM/yyyy:HH:mm::ss Z"] //@timestamp の値を書き換える locale => "en" target => "@timestamp" } }
- 設定変更後、Logstashサービスを再起動しておきます。
再度ログ表示を確認する
テスト端末からロードバランサーの公開IPに向けてアクセスし、ログを記録させます。
本来のアクセス元のIPが clientip として記録されています。また、先ほど追加したgeoipの情報が付加されていることが確認できます。
ログ可視化までの準備は以上で終了です。
いろいろなログ可視化方法例
ここからはKibanaを利用し、アクセスログを可視化する例について、みていきたいと思います。
多様な検索方式
ログの検索についても、Discoverのメニューから確認できます。
- 左サイドメニューの [Discover] を選択。
Search欄では、各フィールド属性を指定して、指定した値を含むログを検索できます。 また、対象となる日時の検索も可能です。
web01サーバーの過去3時間のログを絞り込んでみます。
絞り込み条件に合致するログが表示されました。絞り込む条件は、指定フィールドを自在に組み合わせることができますので、詳細なログ抽出が可能です。 1台1台、サーバーにログインしてログを確認するよりも、このようなツールを使って横断的に、かつ詳細に検索ができることは、大変便利ですね。
geoip情報を活用したマップ表示
先ほど、Logstashの設定で geoip のフィルター条件を追加しました。Kibanaではマップ表示機能がありますので、アクセス元のIPをベースにマップ上での可視化を行ってみます。
- 左サイドメニューの [Maps] を選択
初期状態では地図が表示されるだけなので、[Add layer] を押下して、読み込ませるデータを指定します。
今回は [Documents] を選択してみます。
[Index pattern] より、今回作成したインデックスパターン名を選択します。
[Add layer] を押下します。
geoip によって、アクセス元のIPを位置判定した結果が表示されました。(今回 geoip のテスト用に、テスト端末のアクセス元を変更しています。) 他に Heatmap という機能もあり、意図しない利用者からのWebアクセスやサイバー攻撃を受けた際などには、どこからどれくらいのボリュームのアクセスがあるか、またはあったかを 把握できます。
ログ可視化とわかりやすいインターフェース
これまでご紹介してきたようなログ表示画面、マップ、グラフ表示などは、全てダッシュボードに登録ができ、各情報を一度に確認可能です。
知りたい情報をダッシュボードに並べ、必要に応じて情報を深堀することができますので、日常の情報収集やトラブルシューティングに役立ちそうです。
まとめ
今回は、Elasticsearch・Logstash・Kibana を使って、Webサーバーのログの可視化について検証しました。
どうやって解析対象ログを取り込むか、取り込んだあとの処理をどうするかなどの、ログフォーマットやフィルタリング周りの知識は若干必要とはなりますが、とりあえず動かしてみるレベルであれば、特に難しい所なく、実装することができました。
システムを運用されている方で、何らかの理由でログを可視化をしたい、すぐに実装しなければいけなくなったというケースが今後生じるかもしれませんが、ニフクラであれば本検証の手順を参考にすることで、「必要な時に」「すぐ」「簡単に」ログサーバーを構築いただけます! ※ちなみに、本検証の作業実績として、ログサーバー作成~Kibanaを使えるようになるまで10分以内に完了しています。
利用したツールはオープンソースなので、お財布にも優しく、導入にかかる時間や作業難易度に対するパフォーマンスはとても高いと感じました。
ここまで読んでいただきありがとうございました!
注意事項
- 本記事については検証結果の1つとなります。実際に検討される場合は、事前にそれぞれの要件を確認の上、実装してください。
- 本記事ではOS上の操作についても記載していますが、ニフクラではOS以上はご利用者様の責任範囲となりますのでご留意ください。
- 本記事での各ソフトウェアの設定パラメータはテスト用となります。実際に構築される場合は、サイトのSSL化や、アクセスを許可するネットワークの限定など、要件に応じたセキュリティ設定を検討してください。
- 本記事で記載した各サービス/ニフクラの機能等は、2022年8月時点の情報です。利用時には各サービス/ニフクラの機能の最新情報をご確認いただきご利用ください。