SplunkをLet's EncryptでHTTPS化してみた

Amazon Kinesis Firehoseを使ってCloudTrailやVPC FlowをSplunkに食わせてみようとふと思い立ってセットアップを開始したはいいものの、どうやら商用証明書を使ったSSL通信が要件らしい。

[参考： Splunkマニュアル（英語）](http://docs.splunk.com/Documentation/AddOns/released/Firehose/Hardwareandsoftwarerequirements#SSL_requirements)

Firehoseを使うと、CloudWatch Logs、CloudWatch Events、IoTといったデータストリームをSplunkのHTTP Event Collectorに向けてPOSTできるらしい。
（詳しくはまた別の記事書きます）

ということで、とりあえず検証環境ということで、Let's Encryptを使ってSplunkでHTTPS通信できるようにしてみた。

# なぜLet's Encrypt？
タダだから。

# Let's Encryptで証明書取得
ざっくりの手順書いていきます。

## 証明書取得用のNginxを準備
なぜNginix？ SplunkインスタンスからLet's Encryptにリクエストできないの？

どうやらcertbotを使ってLet's Encrypt証明書を取得する場合、ドメイン認証として80番ポートに通信するらしい。

[ポート80を開放していないWebサーバでも証明書を発行できますか？
](https://letsencrypt.jp/faq/#Port443)

でもSplunkでは権限の都合上Webポートを80に設定することはできない。rootユーザーでSplunk動かせば80番ポートにバインドできるのかな？でもそれは危険だからやめた方がいいかな。

だからEC2にNginxのインスタンスを作成して、Splunk用サブドメインのDNSレコードをNginxインスタンスにふり向ける（これ大事）

## 証明書取得
certbotで取得。
参考にしたページ → [AWS EC2にLet's Encryptを導入してみた
](https://qiita.com/MashMorgan/items/56498f276c54406b1928)

```bash
$ # certbotインストール
$ sudo curl https://dl.eff.org/certbot-auto -o /usr/bin/certbot-auto
$ sudo chmod 755 /usr/bin/certbot-auto
$ 
$ # 証明書取得
$ sudo certbot-auto certonly --webroot -w /var/www/html -d xxxxxx.example.com --email admin@example.com --no-bootstrap
```

07/28/2020 追記

上記方法でやると `WARNING: couldn't find Python 2.7+ to check for updates.` というエラーが出ます。
certbotインストールは [公式](https://certbot.eff.org/lets-encrypt/ubuntubionic-nginx) を参考にインストールして、証明書取得のコマンドは以下で

```
sudo certbot certonly --webroot -w /var/www/html -d xxxxxx.example.com --email admin@example.com --no-bootstrap
```


## 証明書をSplunkにインストール
まずは証明書配置用のディレクトリを `$SPLUNK_HOME/etc/auth` 配下に作成

```bash
$ mkdir $SPLUNK_HOME/etc/auth/mycerts
```

`web.conf` で証明書のパスを設定

```$SPLUNK_HOME/etc/system/local/web.conf
[settings]
enableSplunkWebSSL = 1
serverCert = $SPLUNK_HOME/etc/auth/mycerts/cert.pem
privKeyPath = etc/auth/mycerts/privkey.pem
```

## HTTP Event CollectorでHTTPS通信を有効化
これはハマりました。1週間悶々とハマりました。
`inputs.conf` の[http]スタンザで証明書のパスを設定するわけですが、前のステップでインストールしたサーバー証明書を書くだけではダメでした。

```bash
$ curl -k https://xxxxxxx.com:8088/services/collector/event -H "Authorization: Splunk XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" -d '{"event": "hello world"}' -v
Trying xx.xxx.xxx.xxx...
Connected to xxxxxxx.com (xx.xxx.xxx.xxx) port 8088 (#0)
Operation timed out after 0 milliseconds with 0 out of 0 bytes received
Closing connection 0
curl: (28) Operation timed out after 0 milliseconds with 0 out of 0 bytes received
```

↑ アウツ・・・！ 圧倒的タイムアウツっ・・・・・・！！！

Cipher指定してみたりと色々試したっ・・・！ がっ・・・ダメっ・・・・・・！！！

…結論から言うと、指定する証明書に秘密鍵と中間証明書を書いてやる必要があるのです。
ということで、Let's Encryptからゲットした` fullchain.pem` から `server.pem` という名前でコピーして編集して秘密鍵を挿入。

```$SPLUNK_HOME/etc/auth/mycerts/server.pem
-----BEGIN CERTIFICATE-----
（サーバー証明書）
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
（秘密鍵）
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
（中間証明書）
-----END CERTIFICATE-----
```

そしてそれを `inputs.conf` で指定する。

```$SPLUNK_HOME/etc/apps/splunk_httpinput/local/inputs.conf
[http]
disabled = 0
serverCert = $SPLUNK_HOME/etc/auth/mycerts/server.pem
```

## Splunk再起動
再起動してオシマイ

```bash
$ /opt/splunk/bin/splunk restart
```

## テスト
HECヘルスチェック用エンドポイント `/services/collector/health/1.0` にHTTPSでGETリクエストしてみる。
![Screen Shot 2018-02-16 8.57.38 PM_mosaic.png](https://qiita-image-store.s3.amazonaws.com/0/174837/90ea49ed-8d13-2d23-5124-764f9156b752.png)

ステータスコード200とともに **HEC is healthy** というメッセージが返ってきたのでこれでおk

## おわりに
ここまで書いておきながら、実はKinesis FirehoseはLet's Encryptを認証できないようです。
エラー出ました。

Amazon Kinesis Firehoseの対処法とSplunkへのデータ送信は次回の記事で。

2018/02/23追記
[Kinesis Firehoseを使ってSplunkでAWSユーザーアクティビティを可視化してみた](https://qiita.com/kikeyama/items/bb609cb90269019962cb) 記事を書きました。