Splunk Connect for Syslog (SC4S) で快適なSyslog分析ライフ

# はじめに

システムのログを取り込み分析しようとするとき、どうしてもSyslogを取り扱わざるを得ないシーンがでてきます。
特にネットワークデバイスのログなんかはまだまだ現役ですね。

SplunkにSyslogデータを取り込む方法としてすぐ考えられるのは以下です。

<b>1. 直接SplunkにSyslog送信
2. Syslogサーバ（syslog-ngやrsyslog）で一旦ファイル出力してUniversal Forwarderで転送</b>

ところが、これらの方法には難点があります。

<b>1. 直接SplunkにSyslog送信</b>
・Splunk再起動したらその間のSyslogはドロップしてしまう
・受信処理で余計な負荷がかかる
（基本的にはダメ絶対と言われています）
<b>2. Syslogサーバで一旦ファイル出力してUniversal Forwarderで転送</b>
・Syslogサーバなかったら一から立てるのしんどい
・Syslogの種類が増えたら設定が複雑になる
・出力したファイルを定期的に削除しないといけない

また、別の課題としてAdd-onが無かったらフィールド抽出定義も作らないといけないということもあります。

そんな中、[Splunk Connect for Syslog](https://splunkbase.splunk.com/app/4740/)  (略称SC4S) というお悩みを全て解決してくれるツールがあります。

試しにやってみたら超お手軽にSyslog取り込み環境が完成したので手順をメモします。

# SC4Sとは

syslog-ngをベースにしたツールです。
Dockerイメージで提供されており必要なコンポーネントがまとまっているので、すぐに動すことができます。
受信したSyslogについて、対応している製品やCEF、IETFであれば自動的にメタデータ（index、sourcetype、timestamp）を付与し、更にいい感じにパースもしてくれて、Splunkに転送してくれます。

通信は以下図のように受信したSyslogをHEC (HTTPイベントコレクタ) でSplunk Enterprise / Splunk Cloudに送信してくれます。
そのためLBも挟めますので負荷分散できるというメリットもあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1218403/77ebf641-c31b-924b-47b0-84ffad4d298b.png)
https://www.splunk.com/en_us/blog/tips-and-tricks/splunk-connect-for-syslog-turnkey-and-scalable-syslog-gdi.html



# SC4Sのセットアップ手順

それでは[公式ページの手順](https://splunk.github.io/splunk-connect-for-syslog/main/gettingstarted/)を参考にインストール、設定していきます。

以下手順ではCentOS 7、podman 1.6.4で試しています。
他の組み合わせの場合は公式ページを参照ください。


###1. SplunkのHEC準備
設定 > データ入力 > HTTPイベントコレクタ　からSC4S用のHECを作成しトークンをメモしておきます。
indexの指定は不要です。

###2. Splunkのindex作成
[各ソースの説明ページ](https://splunk-connect-for-syslog.readthedocs.io/en/latest/sources/)にデフォルトindexが記載されているので、必要なindexを作成しておきます。または任意のindexに変更できます（後述）。
とりあえず全部作っておきたいという場合は[こちら](https://splunk.github.io/splunk-connect-for-syslog/main/gettingstarted/#create-indexes)に一覧があります。

###3. SC4S用サーバ用意

適当なLinuxサーバを用意します。
サイジングはこちらのページを参照。
https://splunk.github.io/splunk-connect-for-syslog/main/performance/

AWSのm5zn.large（2vCPU、8 GiB RAM、25 Gbps）で以下性能が出たそうです。よほど大量なデータでなければ十分ですね。

> average rate = 24077.33 msg/sec, count=4375116, time=181.711, (average) msg size=800, bandwidth=18810.42 kB/sec

###4. OSの受信バッファサイズ確認

OSの受信バッファサイズをSC4Sのデフォルトの受信バッファサイズである16MBに合わせよとのことです。

```config:/etc/sysctl.conf
net.core.rmem_default = 17039360
net.core.rmem_max = 17039360
```

```bash:適用し、パケットをドロップしていないか確認
sudo sysctl -p
netstat -su | grep "receive errors"
```

###5. IPv4転送を有効化

多くのディストリビューションだとIPv4転送が有効化されていないので有効化。

```bash:設定
sudo sysctl net.ipv4.ip_forward=1
```

```bash:/etc/sysctl.conf
# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1
```

###6. コンテナエンジンインストール
podman、docker、k8sに対応しています。
podmanで進めます。

```bash:podmanインストール
sudo yum -y install podman
```
###7. Volume作成

HEC通信できないときなどのバッファ用Volume作成。

```bash:Volume作成
sudo podman volume create splunk-sc4s-var
```

###8. sc4sサービス定義作成

以下のように`/lib/systemd/system/sc4s.service`を作成（podman用）。
最新情報は公式ページのコンテナのセットアップページを参照

```config:/lib/systemd/system/sc4s.service
[Unit]
Description=SC4S Container
Wants=NetworkManager.service network-online.target
After=NetworkManager.service network-online.target

[Install]
WantedBy=multi-user.target

[Service]
Environment="SC4S_IMAGE=ghcr.io/splunk/splunk-connect-for-syslog/container:1"

# Required mount point for syslog-ng persist data (including disk buffer)
Environment="SC4S_PERSIST_MOUNT=splunk-sc4s-var:/var/lib/syslog-ng"

# Optional mount point for local overrides and configurations; see notes in docs
Environment="SC4S_LOCAL_MOUNT=/opt/sc4s/local:/etc/syslog-ng/conf.d/local:z"

# Optional mount point for local disk archive (EWMM output) files
Environment="SC4S_ARCHIVE_MOUNT=/opt/sc4s/archive:/var/lib/syslog-ng/archive:z"

# Map location of TLS custom TLS
Environment="SC4S_TLS_MOUNT=/opt/sc4s/tls:/etc/syslog-ng/tls:z"

TimeoutStartSec=0

ExecStartPre=/usr/bin/podman pull $SC4S_IMAGE
ExecStartPre=/usr/bin/bash -c "/usr/bin/systemctl set-environment SC4SHOST=$(hostname -s)"

ExecStart=/usr/bin/podman run \
        -e "SC4S_CONTAINER_HOST=${SC4SHOST}" \
        -v "$SC4S_PERSIST_MOUNT" \
        -v "$SC4S_LOCAL_MOUNT" \
        -v "$SC4S_ARCHIVE_MOUNT" \
        -v "$SC4S_TLS_MOUNT" \
        --env-file=/opt/sc4s/env_file \
        --network host \
        --name SC4S \
        --rm $SC4S_IMAGE

Restart=on-abnormal
```

###9. ディレクトリ作成

SC4Sの各種ファイル保存のためのディレクトリを作成。

```bash:ディレクトリ作成
sudo mkdir /opt/sc4s/
sudo mkdir /opt/sc4s/local
sudo mkdir /opt/sc4s/archive
sudo mkdir /opt/sc4s/tls
```

###10. 設定ファイル作成

`/opt/sc4s/env_file`にSC4S用の設定を作成。運用時の設定変更は基本的にこのファイルを編集します。

```config:/opt/sc4s/env_file
SC4S_DEST_SPLUNK_HEC_DEFAULT_URL=https://<Splunkホスト名>:8088
# Splunk Cloudの場合は以下
# SC4S_DEST_SPLUNK_HEC_DEFAULT_URL=https://http-inputs-<Splunkホスト名>:443

SC4S_DEST_SPLUNK_HEC_DEFAULT_TOKEN=<HECトークン>
#Uncomment the following line if using untrusted SSL certificates
#信頼されていないSSL証明書でも無視する場合はコメントを外す
#SC4S_DEST_SPLUNK_HEC_DEFAULT_TLS_VERIFY=no
```

###11. SC4S起動

準備が整ったので起動します。

```bash:起動
sudo systemctl daemon-reload 
sudo systemctl enable sc4s
sudo systemctl start sc4s
```

うまく起動できた場合はSplunkに以下のようなイベントが出力されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1218403/20ac7be5-6883-4474-7e05-1bfbfa480472.png)

```go:確認用SPL
index=* sourcetype=sc4s:events "starting up"
```

イベントが無い場合は、SC4Sのログを見てみましょう。

```bash:SC4Sのログ確認
journalctl -b -u sc4s | tail -100
```

# Syslog取り込んでみるテスト

無事SC4SとSplunkがつながったので、Syslogもどきでテストします。
別のサーバから以下のようにUDP 514ポートにメッセージを投げてみます。

```bash:Syslogもどき
echo "Hello SC4S" > /dev/udp/<SC4SサーバのIPアドレス>/514
```

以下のようなイベントがSplunkで見えたら成功です。
※何も設定していない完全カスタムログなので、そのようなログがたどり着く`sourcetype = sc4s:fallback`で記録されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1218403/16e9aa10-b1d5-c260-45f4-bdcf56447ac9.png)

```go:確認用SPL
index=main sourcetype="sc4s:fallback"
```

Syslog受信、転送がうまくいったことを確認できました。
実際のSyslog取り込み用の設定をしていきましょう。

# 各対応製品用の設定

まずはSC4Sで定義済みの製品です。
https://splunk.github.io/splunk-connect-for-syslog/main/sources/

各ソースのページに対象製品側の設定とSC4Sの設定方法が書かれています。

PaloAltoのNGFWを例にとって見てみましょう。
https://splunk.github.io/splunk-connect-for-syslog/main/sources/PaloaltoNetworks/

<b>・受信用ポート設定</b>
SC4Sの仕様として、ログの種類は受信ポートおよびログフォーマットでソースから識別します。
各ソースのページにOptionsに設定キーが書かれています。
PAの場合は以下です。機器設定にあった方を使います。

> SC4S_LISTEN_PULSE_PALOALTO_PANOS_RFC6587_PORT
SC4S_LISTEN_PALOALTO_PANOS_TCP_PORT

これを`/opt/sc4s/env_file`に追記します。

```config:/opt/sc4s/env_file
SC4S_DEST_SPLUNK_HEC_DEFAULT_URL=https://<Splunkホスト名>:8088
SC4S_DEST_SPLUNK_HEC_DEFAULT_TOKEN=<HECトークン>
#Uncomment the following line if using untrusted SSL certificates
#信頼されていないSSL証明書でも無視する場合はコメントを外す
#SC4S_DEST_SPLUNK_HEC_DEFAULT_TLS_VERIFY=no

SC4S_LISTEN_PALOALTO_PANOS_TCP_PORT=<PAのSyslogポート番号>
```

<b>・index設定</b>
デフォルトのindexは各ソースのページの「Sourcetype and Index Configuration」に記載されています。
例えばトラフィックログは以下です。`netfw`がデフォルト値であることが分かります。

> key	sourcetype	index	notes
> pan_traffic	pan:traffic	netfw	none

設定は以下ファイルに追記します。
/opt/sc4s/local/context/splunk_metadata.csv

indexを`traffic`に変更する場合は以下です。

```config:/opt/sc4s/local/context/splunk_metadata.csv
pan_traffic, index, traffic
```

<b>・設定読み込み</b>
以下コマンドでSC4Sを再起動し設定を再読み込みします。

```bash:SC4S設定再読み込み
sudo systemctl stop sc4s
sudo systemctl daemon-reload 
sudo systemctl enable sc4s
sudo systemctl start sc4s
```

後はSyslogをSC4Sに送信すれば、いい感じにメタデータを付けてログをパースしてSplunkに転送してくれます。
※ログが手元にないので割愛


# CEF (Common Event Format) 用の設定

https://splunk.github.io/splunk-connect-for-syslog/main/sources/CommonEventFormat/

以下のようなCEFイベントの場合。

```config:CEFイベントサンプル
Apr 19 10:29:53 3.3.3.3 CEF:0|Imperva Inc.|SecureSphere|12.0.0|Firewall|SSL Untraceable Connection|Medium|
```

「|」区切りの内、先頭に続く1、2、4番を識別情報として用います。

1: device_vendor (Imperva Inc.)
2: device_product (SecureSphere)
4: device_class (Firewall)

識別キーを「device_vendor_device_product_device_class」とします。
※最後のdevice_classはオプション

上記サンプルの場合のキーは「Imperva Inc._SecureSphere_Firewall」となります。


<b>・受信用ポート設定</b>
CEFの場合は以下です。

> SC4S_LISTEN_CEF_UDP_PORT
SC4S_LISTEN_CEF_TCP_PORT
SC4S_LISTEN_CEF_TLS_PORT

適切なプロトコルについて`/opt/sc4s/env_file`に追記します。
もしCEFのソースが複数ある場合はポート番号をカンマ区切りで増やせます。

```config:/opt/sc4s/env_file
SC4S_LISTEN_CEF_UDP_PORT=<Syslogポート番号>
```

<b>・index、sourcetype設定</b>
任意のindex、sourcetypeを`/opt/sc4s/local/context/splunk_metadata.csv`に追記します。
フォーマットは`識別キー, メタデータ種類, メタデータ値`です。
※indexをSplunkで作っておくことを忘れずに

```config:/opt/sc4s/local/context/splunk_metadata.csv
Imperva Inc._SecureSphere_Firewall, index, cef_index
Imperva Inc._SecureSphere_Firewall, sourcetype, cef_sourcetype
```
<b>・設定読み込み</b>
以下コマンドでSC4Sを再起動し設定を再読み込みします。

```bash:SC4S設定再読み込み
sudo systemctl stop sc4s
sudo systemctl daemon-reload 
sudo systemctl enable sc4s
sudo systemctl start sc4s
```

<b>・テスト</b>
Syslogもどきでテスト。

```bash:Syslogもどき（CEF）
echo "Apr 19 10:29:53 3.3.3.3 CEF:0|Imperva Inc.|SecureSphere|12.0.0|Firewall|SSL Untraceable Connection|Medium|" > /dev/udp/<SC4SサーバIP>/ポート番号
```

メタデータ（timestamp、sourcetype、index）を正しくセットして、テキストもパースしてくれてます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1218403/d74aaec6-3cfa-ebcd-c743-c6f327ff0e6a.png)


# LEEF (Log Extended Event Format) 用の設定

https://splunk.github.io/splunk-connect-for-syslog/main/sources/LogExtendedEventFormat/

CEFと似た感じなので割愛。



# RFC5424（IETF）またはRFC3164（BSD）用の設定

https://splunk.github.io/splunk-connect-for-syslog/main/sources/Simple/

これまでのフォーマットに該当しない、一般的なSyslogフォーマットであるRFC5424（IETF）またはRFC3164（BSD）も取り込めます。
以下はIETFを例に進めます。

```config:IETFイベントサンプル
<17>1 2021-04-19T10:29:53.003Z host5424 app5424 1234 ID100 [exampleSDID@32473 iut="3" eventSource="Application"] test 5424 msg
```

識別キーは「vendor_product」です。
これらの値はイベント中にないため、任意の値を付けます。

例えば「MyCompany_Coolapp」にしたい場合で進めます。


<b>・受信用ポート設定</b>

> SC4S_LISTEN_SIMPLE_VENDOR_PRODUCT_UDP_PORT
SC4S_LISTEN_SIMPLE_VENDOR_PRODUCT_TCP_PORT
SC4S_LISTEN_SIMPLE_VENDOR_PRODUCT_TLS_PORT

適切なプロトコルについて`/opt/sc4s/env_file`に追記します。
VENDOR_PRODUCT部分を大文字で置き換えます。

```config:/opt/sc4s/env_file
SC4S_LISTEN_SIMPLE_MYCOMPANY_COOLAPP_UDP_PORT=<Syslogポート番号>
```

<b>・index、sourcetype設定</b>
`/opt/sc4s/local/context/splunk_metadata.csv`に追記します。
vendor_productのように小文字にします。

```config:/opt/sc4s/local/context/splunk_metadata.csv
mycompany_coolapp, index, ietf_index
mycompany_coolapp, sourcetype, ietf_sourcetype
```
<b>・設定読み込み</b>
以下コマンドでSC4Sを再起動し設定を再読み込みします。

```bash:SC4S設定再読み込み
sudo systemctl stop sc4s
sudo systemctl daemon-reload 
sudo systemctl enable sc4s
sudo systemctl start sc4s
```

<b>・テスト</b>
Syslogもどきでテスト。

```bash:Syslogもどき（IETF）
echo "<17>1 2021-04-19T10:29:53.003Z host5424 app5424 1234 ID100 [exampleSDID@32473 iut=\"3\" eventSource=\"Application\"] test 5424 msg"  > /dev/udp/<SC4SサーバIP>/ポート番号
```

メタデータ（timestamp、sourcetype、index）を正しくセットして、テキストもパースしてくれてます。
ダミーイベントが悪いのか最後のメッセージは抽出してくれなかったので、ここが必要な場合はフィールド抽出ルールを作る必要があるかも？
その場合でもメッセージの前に[meta sequenceId="n"]を付け加えてくれているので抽出は簡単ですね。
※正規表現例：`\[meta sequenceId=\"[0-9]+\"\] (?<msg>.+)$`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1218403/87282353-58c0-fc3e-f868-1c02cdf0d985.png)



# おわりに

Splunk Connect for SyslogでSyslogも友達！

# リファレンス
公式ページ
https://splunk.github.io/splunk-connect-for-syslog/main/

Splunk Blog（公式ページに書かれていない、SyslogやSC4Sの周辺情報も豊富）
https://www.splunk.com/en_us/blog/tips-and-tricks/splunk-connect-for-syslog-turnkey-and-scalable-syslog-gdi.html