Edited at

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

More than 1 year has passed since last update.

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

参考: Splunkマニュアル(英語)

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サーバでも証明書を発行できますか?

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

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


証明書取得

certbotで取得。

参考にしたページ → AWS EC2にLet's Encryptを導入してみた

$ # 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


証明書をSplunkにインストール

まずは証明書配置用のディレクトリを $SPLUNK_HOME/etc/auth 配下に作成

$ 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]スタンザで証明書のパスを設定するわけですが、前のステップでインストールしたサーバー証明書を書くだけではダメでした。

$ 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再起動

再起動してオシマイ

$ /opt/splunk/bin/splunk restart


テスト

HECヘルスチェック用エンドポイント /services/collector/health/1.0 にHTTPSでGETリクエストしてみる。

Screen Shot 2018-02-16 8.57.38 PM_mosaic.png

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


おわりに

ここまで書いておきながら、実はKinesis FirehoseはLet's Encryptを認証できないようです。

エラー出ました。

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

2018/02/23追記

Kinesis Firehoseを使ってSplunkでAWSユーザーアクティビティを可視化してみた 記事を書きました。