ご留意事項
本記事は私の実装事例(検証事例)を共有し、同様の構築を実施される方の効率化を目的としております。私の所属組織ならびにCortex Data Lakeを提供するPalo Alto Networks社が推奨する構成や手順ではありません。
本情報は2021年12月時点のサービス仕様を元にしております。
手順や情報に不備等あれば是非コメントください。
本記事でご紹介するもの
Cortex Data LakeのSyslog転送機能を利用し、ログをS3へ保管するための構成例を示します。
基盤構成
- TrafficログとThreatログで別ファイルとしてS3に保存する
- Cortex Data LakeのSyslog転送を設定し、EC2のrsyslogでログを受信・ファイルへ出力する
- ログファイルをtd-agent(fluentd)で読み込み、S3 Plugin経由でS3へ保管する
- S3に保管したログファイルの分析を行いたい場合はAthena等を利用する(本手順の範囲外)
作業手順
1. サーバ証明書取得
- Cortex Data LakeのSyslog転送機能はTSLの暗号化が必要なため、syslogサーバで利用するサーバ証明書を取得します。
- 今回は手軽に実装することを目的とし、Let's Encryptで発行された証明書を使います。
- 利用できるサーバ証明書には以下の制約があります。
- 暗号化で利用するSyslogサーバのサーバ証明書はOCSPの証明書の有効チェックができる証明書である必要があります。(オレオレ証明書ではダメ)
- Cortex Data Lake側で信頼する証明書のリストは公開されています。ただ、証明書チェーンをインポートすることは可能であり、上記の信頼する認証局の証明書である必要はありません。
2. 独自ドメイン取得とRoute53への登録
こちらの記事などを参考に、独自ドメインの取得とRoute53の登録を行います。
今回はAレコードに登録するIPアドレスを固定化したいため、Elastic IPを利用します。
3. EC2インスタンスとS3バケットの作成
ログを保管するためのS3バケットを作成します
パブリックサブネットにEC2を構築します。
- VPC/サブネット/ルートテーブル等の構成要件
- 一般的なパブリックサブネット構築手順にない独自の構成要件は以下です。
- インターネットからの80, 443ポートの許可 (サーバ証明書取得のため)
- インターネットからの6514ポートの許可 (Syslog転送のため)
- 一般的なパブリックサブネット構築手順にない独自の構成要件は以下です。
Syslog転送のポートは任意のportに設定可能です。
rsyslog.confの設定とCortex Data Lake側のLog Forwarding設定のポート設定を変更してください。
- EC2インスタンス
- AMI: Amazon Linux 2
- インスタンスタイプ: t4g.large
- セキュリティグループ: 80, 443, 6514を許可 (用途等はVPCの設定を参照)、ssh等も必要に応じて許可
- ロール: ログを保管するS3バケットへの書き込み権限を設定
インスタンスタイプはt2, t3でも問題ありません。x86_64を利用したい場合はt4g以外を利用してください。
また、サイジングもsmall、mediumでも問題無いと思われますが、ログローテーション時など負荷がかかった状態でもログ受信処理が遅れることを避けるためlargeとしています。
構築したEC2に1-2の手順でAレコードに登録したElastic IPをアタッチします。
4. 証明書の取得
- こちらの手順を参照し、「Certbot をインストールして実行する」までの作業を実施します。完了すると以下のファイルが作成されます。
[root@ip-172-31-47-127 ~]# ll /etc/letsencrypt/live/xxx.com/
total 4
lrwxrwxrwx 1 root root 43 Nov 30 06:39 cert.pem -> ../../archive/xxx.com/cert1.pem
lrwxrwxrwx 1 root root 44 Nov 30 06:39 chain.pem -> ../../archive/xxx.com/chain1.pem
lrwxrwxrwx 1 root root 48 Nov 30 06:39 fullchain.pem -> ../../archive/xxx.com/fullchain1.pem
lrwxrwxrwx 1 root root 46 Nov 30 06:39 privkey.pem -> ../../archive/xxx.com/privkey1.pem
-rw-r--r-- 1 root root 692 Nov 30 06:39 README
証明書の有効期限は90日のため、期限切れまでに自動更新するように構成することをお勧めします。
5. rsyslogの設定
rsyslogの設定はrsyslogでのTLS(SSL)によるセキュアな送受信(暗号化のみ)を参照しました。
(rsyslogのTLS実装が分かりやすく解説されていて、記事で非常に参考になりました)
rsyslog用のkeyファイルフォルダを作成し、cert.pem chain.pem privekey.pemをコピーします。
$ sudo mkdir /etc/rsyslog.d/tls/
$ sudo cp /etc/letsencrypt/live/xxx.com/cert.pem /etc/rsyslog.d/tls/
$ sudo cp /etc/letsencrypt/live/xxx.com/chain.pem /etc/rsyslog.d/tls/
$ sudo cp /etc/letsencrypt/live/xxx.com/privkey.pem /etc/rsyslog.d/tls/
フォルダを新規に作成せず直接参照した方が証明書更新等を考慮すると合理的ですが、pemファイルもrsyslogの設定ファイルの一部として管理することを目的としています。
/etc/letsencrypt/live/xxx.com/chain.pemがCortex Data Lake設定時に必要になるため、手元のPC等にDLします。
rsyslog.confを編集し、MODULEの項目に以下のエントリを追加します。
module(
load="imtcp"
StreamDriver.Name="gtls"
StreamDriver.Mode="1"
StreamDriver.Authmode="anon"
)
input(type="imtcp" port="6514")
global(
DefaultNetstreamDriver="gtls"
DefaultNetstreamDriverCAFile="/etc/rsyslog.d/tls/chain.pem"
DefaultNetstreamDriverCertFile="/etc/rsyslog.d/tls/cert.pem"
DefaultNetstreamDriverKeyFile="/etc/rsyslog.d/tls/privkey.pem"
)
同じrsyslog.confを編集し、Cortex Data Lakeから受信するログを記録するログファイルを指定します。(デフォルト設定だと/var/log/messages
に出力されます)
RULESの項目を以下のように修正します。
-
/var/log/messages
のロギング対象からlocal0, local2を除外する(;local0.none;local1.none
を追加) - local0のファシリティを全て任意のログファイル(今回の例は
/var/log/traffic.log
と/var/log/threat.log
)に記録する設定を追加
#### RULES ####
(略)
# Log anything (except mail) of level info or higher.
# Don't log private authentication messages!
*.info;mail.none;authpriv.none;cron.none;local0.none;local1.none /var/log/messages
(略)
# Cortex Data Lake Log Fowarding
local0.* /var/log/traffic.log
local1.* /var/log/threat.log
ログのファシリティにはデフォルト(log_user)以外に「local0~local7」を設定可能です。
Cortex Data Lakeの転送設定ごとにファシリティを設定できます。
rsyslogを再起動し、エラーメッセージが出力されていないことを確認します。
$ sudo systemctl restart rsyslog
$ sudo systemctl status rsyslog
6. Cortex Data LakeのLog Forwarding転送設定
Cortex Data Lakeにログインし、左側ペインからLog Forwadingをクリックします。
「Syslog」の項目の右側の + ボタン(Display 20 Profilesの右)をクリックします。
設定に以下を入力します。
- Name: 任意 (Traffic-logなど)
- SYSLOG SERVER: サーバ証明書を取得したFQDN名
- PORT: 任意(今回はデフォルト6514を利用)
- FACILITY: LOG_LOCAL0 注)デフォルトから変更します
Let's Encryptを利用している場合は中間証明書をアップロードする必要があるため、手元PC等にDLした/etc/letsencrypt/live/xxx.com/chain.pem
ファイルを「+ UPload」ボタンから追加します。
Test Connectionのボタンが有効化します。クリックしてSuccessが出力されることを確認します。(うまくいかない場合はSyslogサーバ側の設定やVPCのルートテーブル等を見直してください)
Nextをクリックするとログ形式や取得対象ログを設定する画面が開きます。
FILTERSの項目の + Add をクリックして任意のログタイプを選択します。今回はTrafficログを取得対象として設定しました。
SAVEボタンが有効化するので、クリックします。
これでログ転送設定のエントリが設定されますが、画面上のステータスはしばらくPROVISONINGと表示され、Syslogサーバへの転送もすぐには始まりません。設定してから5分前後でログが転送されるので、しばらく待ちます。
設定直後(おそらくPROVISIONING中)にログエントリの追加・変更・削除などを追加で実施するとCortex Data Lake側の状態が異常となる場合があります。ステータスが正常になったのを確認してから作業を行なうことお勧めします。
設定後、過去72時間分のログがまとめて転送されます。
初期設定時も含め、Cortex Data Lakeからはログを一行一行転送するわけではなく、まとめてblukで転送する仕様と推測されます。大量のログが出力される場合でも、Syslogサーバ側に大きな処理能力は不要です。(vCPUが2コア程度でも問題ありませんでした)
FILTERSの項目には複数のログタイプの設定や、クエリによって絞り込んだログの転送を行うなどの設定が可能です。
ログの転送要件に合わせて定義ください。
今回はThreatログを別のログファイルで保管したいので、再度 + ボタンをクリックしてエントリを追加します。
最初の画面の設定は先ほどと同じですが、FACILITYだけ変更します。
- FACILITY: LOG_LOCAL1 注)Trafficログとログファイルを分けたいのでLOCAL 1とします
次の画面のFILTERSの + Add ボタンからThreatログを選択します。
ログ転送が開始されるまでしばらく待ちます。
7. td-agent(fluentd)設定
td-agentを利用し、rsyslogで任意のログファイルに出力されたログを読み込み、S3バケットに保管します。
以下のコマンドでtd-agentをインストールします。
$ curl -L https://toolbelt.treasuredata.com/sh/install-amazon2-td-agent4.sh | sh
td-agentの起動ユーザをroot変更します。
/usr/lib/systemd/system/td-agent.service
のUser, Groupをtd-agentからrootへ変更します。
(略)
[Service]
User=root
Group=root
....
rsyslogで出力されるログがデフォルト設定の場合rootユーザにしか読み取り権限がないため、td-agentの起動ユーザをrootに変更しています。
rsyslogの設定でログファイルの権限を変更した方が正しいアプローチかもしれません。
デフォルトのtd-agent設定ファイルをリネームします。
$ sudo mv /etc/td-agent/td-agent.conf
/etc/td-agent/td-agent.conf
を以下の内容に変更します。
<バケット名> <リージョン名> は作成したS3バケットの情報を設定してください。
<source>
@type tail
format none
path /var/log/traffic.log
pos_file /var/log/traffic.log.pos
tag traffic.log
</source>
<match traffic.log>
@type s3
format single_value
s3_bucket <バケット名>
region <リージョン名>
path traffic-log/%Y/%m/%d/
<buffer>
@type file
path /var/log/td-agent/traffic-buffer
timekey 3600
chunk_limit_size 10g
</buffer>
</match>
<source>
@type tail
format none
path /var/log/threat.log
pos_file /var/log/threat.log.pos
tag threat.log
</source>
<match threat.log>
@type s3
format single_value
s3_bucket <バケット名>
region <リージョン名>
path threat-log/%Y/%m/%d/
<buffer>
@type file
path /var/log/td-agent/threat-buffer
timekey 3600
chunk_limit_size 10g
</buffer>
</match>
rsyslog.confの設定で指定したログファイルを読み込み、元のcsvファイル形式のままgzip圧縮してS3バケットへ保存します。ログはS3バケットに/ログ種別/年/月/日のパスで分類されます。ログファイルは1時間1ファイルとするためtimekeyを3600とし、chunk_limit_sizeを十分に大きい値(今回は10g)としています。バッファ容量を大きく設定するため、バッファタイプにファイルを設定しています。
td-agentの起動ユーザ変更の読み込みとtd-agentの再起動を行います。
ステータスとログファイルを参照してエラーがないことを確認します。
$ sudo systemctl daemon-reload
$ sudo systemctl restart td-agent
$ sudo systemctl status td-agent
$ sudo less /var/log/td-agent/td-agent.log
ログファイル読み込みの権限エラーが出力されている場合、/usr/lib/systemd/system/td-agent.serviceの設定を確認してください。
1時間ほど待つとS3バケットにログが保存されるはずです。
すぐに確認したい場合はtd-agent.conf
のtimekey
の値を小さくすることで確認できます。
参考情報