AWS上にHTTPSアクセス可能なSplunk環境を作成する

AWS上でブラウザ->LBまでがHTTPS、LBからEC2インスタンスがHTTPの構成となるような環境を作っていく。

# 前提条件

* Splunk Enterpriseのバージョン: 8.1.2
* Nginxのバージョン: 1.21
* EC2インスタンスのOS: RHEL 7.7
* SELinuxを無効化すること
* AWSマネージドコンソールの言語: `English(US)`

# AWS S3の準備

* AWSのマネージドコンソールにログインし、**Amazon S3**ダッシュボードを開きます。
* **Create bucket**ボタンをクリックします。
* **Bucket name**に任意のバケット名を入力します。
* **AWS Region**をEC2インスタンスを作成するリージョンと同じにします。
* **Default encryption**を`Enable`にします。
* **Encryption key type**を`AWS Key Management Service key (SSE-KMS)`にします。
    * APIのコールがSSE-KMSの上限を超える可能性がある場合は`Amazon S3 key (SSE-S3)`を利用します。
* **AWS KMS key**を`AWS managed key (aws/s3)`にします。
* **Create bucket**をクリックします。

# IAMポリシーの準備

* **Identity and Access Management (IAM)**ダッシュボードを開きます。
* 左ペインのメニューから**Policies**を選択します。
* **Create Policy**をクリックします。
* **JSON**タブを開きます。
* 以下の内容をテキストエリアに書き込みます。

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": "kms:*",
            "Resource": "arn:aws:kms:{Region}:{AccountID}:key/{KMS ID}"
        },
        {
            "Sid": "VisualEditor2",
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::{BucketName}/*"
        }
    ]
}
```

* **Next: Tags**をクリックします。（タグが必要な場合は設定します。）
* **Next: Review**をクリックします。
* **Name**にポリシー名を入力します。これは必須項目です。
* **Create Policy**をクリックします。

# IAMロールの準備

* **Identity and Access Management (IAM)**ダッシュボードを開きます。
* 左ペインのメニューから**Roles**を選択します。
* **Create role**をクリックします。
* **Choose a use case**から`EC2`を選択します。
* **Next: Permissions**をクリックします。
* **Atatach permissions policies**で上記の手順で作成したIAMポリシーをアタッチします。
* **Next: Tags**をクリックします。
* **Next: Review**をクリックします。
* **Role name**を入力します。
* **Create role**をクリックします。

# EC2インスタンスの準備

詳細な手順は割愛しますが、上記の手順で作成したロールをアタッチしてください。
今回の構成としては、1つのVPCにpublicなサブネットとprivateなサブネットを用意しており、このEC2インスタンスはprivateなサブネットに構築します。
後ほどロードバランサーをpublicなサブネットに紐づけて作成し、リクエストをこのインスタンスに流すように設定します。
また、自身の作業環境からSSHアクセスできるようにセキュリティグループを設定してください。

# Splunk Enterpriseのインストールと設定

今回は`/app/splunk`にSplunk Enterpriseをインストールします。

* [公式のインストール手順](https://docs.splunk.com/Documentation/Splunk/8.1.2/Installation/InstallonLinux)に従って、Splunk Enterpriseをインストールし、Splunkが起動することを確かめます。
* 以下のようなディレクトリとファイルを用意します。コンフィグをアプリとして管理することで運用管理しやすくなります。

```
$ cd /app/splunk/etc/apps/
$ mkdir -p standalone_config/local
$ mkdir -p standalone_config/metadata
$ touch standalone_config/local/app.conf
$ touch standalone_config/local/indexes.conf
$ touch standalone_config/metadata/default.meta
```

* `standalone_config/local/app.conf`を以下のように編集します。

```conf
[install]
state = enabled

[package]
check_for_updates = false

[ui]
is_visible = false
is_manageable = false
```

* `standalone_config/local/indexes.conf`を以下のように編集します。

```conf
[default]
remotePath = volume:remote_store/$_index_name

[volume:remote_store]
storageType = remote

path = s3://{s3BucketName}

remote.s3.encryption = sse-kms
remote.s3.kms.key_id = {kmsId}
```

* `standalone_config/metadata/default.meta`を以下のように編集します。

```
[]
access = read : [ * ], write : [ admin ]
export = system
```

* Splunkを再起動します。`/app/splunk/bin/splunk restart`
* Splunkのモニターコンソール等で正常にSmartStore機能が働いているか確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6624/5cad63a1-cc97-1c0f-3e82-583db74efdee.png)

# Nginxのインストールと設定

* [こちらの手順](http://nginx.org/en/linux_packages.html#stable)を参考にNginxをyumでインストールします。
* `/etc/nginx/conf.d/default.conf`を以下のように編集します。

```nginx
server {
        listen 80 default_server;
        listen [::]:80 default_server;
        server_name {dnsName};
        # plunkのファイルアップロードによる取り込み対応
        client_max_body_size 1024M;
		
        # SplunkのリダイレクトURLのプロトコルがhttpになることへの対応
        if ($http_x_forwarded_proto != https) {
                return 301 https://$host$request_uri;
        }

        location / {
                proxy_pass http://127.0.0.1:8000;
        }

}
```

* Nginxを起動します。 `$ sudo systemctl start nginx`

今回の構成はブラウザからLBまでがHTTPS、LBからEC2へのアクセスがHTTPとなる構成をとっています。
SplunkがHTTPモードで動作しているため、ログイン後のリダイレクトURLがHTTPになってしまいます。
常にHTTPSでアクセスさせたいため、LBからHTTPによるアクセスが来たら強制的にHTTPSでアクセスさせるように対応しています。


# ACMの準備

* **Certificate Manager**ダッシュボードを開きます。
* **Request a certificate**をクリックします。
* `Request a public certificate`が選択されていることを確認し、**Request a certificate**をクリックします。
* **Domain name**を入力します。ここでは`*.example.com`を例とします。
* **Next**をクリックします。
* Route53でドメイン取得したことを前提としているので、`DNS validation`が選択されていることを確認し、`Next`をクリックします。
* **Review**をクリックします。
* **Confirm and request**をクリックします。
* **Domain**の情報を開いて**Create record in Route53**をクリックします。
* **Create**をクリックします。
* **Continue**をクリックします。

# AWS CLBの準備

* **EC2**ダッシュボードを開きます。
* 左ペインのメニューから**Load Balancers**を選択します。
* **Create Load Balancer**を選択します。
* **Classic Load Balancer**の**Create**をクリックします。
* **Load Balancer name**を入力します。
* **Create LB Inside**をEC2が存在するVPCにします。
* **Listener Configuration**で80番ポートと443番ポートをEC2インスタンスに流すように設定します。
    * Load Balancer Protocol:80, Load Balancer Port:80, Instance Protocol:HTTP, Instance Port:80
    * Load Balancer Protocol:443, Load Balancer Port:443, Instance Protocol:HTTP, Instance Port:443
* **Select Subnets**で上記で選択したVPCのパブリックなサブネットを選択します。
* **Next Assign Security Group**をクリックします。
* インターネットからのアクセスおよび、作成したEC2インスタンスへのアクセス(HTTP/HTTPS)が許可されたセキュリティグループを選択します。
* **Next: Configure Security Settings**をクリックします。
* **Certificate type**を`Choose a certificate from ACM (recommended)`にします。
* **Certificate**をACMの手順で作成した証明書を選択します。
* **Next: Configure Health Check**をクリックします。
* **Ping Protocol**を`TCP`にします。
* **Ping Port**を`80`にします。
* **Next: Add EC2 Instance**をクリックします。
* 対象のEC2インスタンスをチェックします。
* **Next: Add Tags**を選択します。
* **Review and Create**をクリックします。
* **Create**をクリックします。

# Route53

既に必要なドメインが取得されている前提です。

* **Route53**ダッシュボードを開きます。
* 左ペインのメニューから**Hosted zones**を選択します。
* 対象のドメインを一覧から選択します。
* **Create record**をクリックします。
* `Simple routing`を選択します。
* **Next**をクリックします。
* **Define simple record**をクリックします。
* **Record name**を入力します。
* **Value/Route traffic to**を`Alias to Application and Classic Load Balancer`とし、リージョンをEC2インスタンスが存在しているリージョンにします。
* **Choose load balancer**を作成したロードバランサーに設定します。
* **Define simple record**をクリックします。
* **Create records**をクリックします。