BIG-IPでSNI（Server Name Indication）対応

##　はじめに
SNI(Server Name Indication)とは、SSL接続の開始時（SSLのハンドシェイクより前）に接続先のホスト名（FQDN）をクライアントがサーバへ送る仕組みです。これによってSSL接続の確立前にサーバが接続先のホスト名を知ることができます。

サーバからすると、ホスト名を確認してからSSLハンドシェイクの応答をすることになるので、要求されたホスト名にあったSSL証明書を利用したSSL接続を行えるようになります。

一つのグローバルIPアドレスでFQDNの異なる複数のサイトを運営しているとき、それぞれのサイト毎にSSL対応するために、SNIを用います。

以下では、BIG-IPのVirtual ServerをSNI対応する際の方法について記載します。

## 設定の流れ
BIG-IPで複数のSSL証明書をSNIで利用するには、簡単には以下のような流れになります。

![Untitled.png](https://qiita-image-store.s3.amazonaws.com/0/157891/6e51946b-f23b-0575-93a0-7c7cc44f960d.png)


## 設定手順（GUI）

### SSL証明書と秘密鍵のインポート
まず、SNIに利用したいサーバ証明書と秘密鍵をBIG-IPへインポートします。GUIでは**System→File Management→SSL Certificate List** という箇所になります。

![BIG-IP_SNI_SS1.png](https://qiita-image-store.s3.amazonaws.com/0/157891/e0e4a252-5b47-83fb-cc31-487d46602bec.png)

ここでちょっと重要なのが、「Fallback用」の証明書と秘密鍵というもので、これは「どの証明書にもマッチしないSSL接続」に対して応答するための証明書です。FallBack用の証明書と秘密鍵もあらかじめ用意する必要があります。

### Client SSL Profileの作成
次に、各証明書ごとにClient SSL Profileを作成します。各Client SSL Profileでは、Certificate, Key,そしてServerNameの設定が必要です。

ここの設定と（Client SSL Profileは設定項目が多く、１つのスクリーンショットで収まらないので分割します。）
![BIG-IP_SNI_SS2.png](https://qiita-image-store.s3.amazonaws.com/0/157891/eab8acfb-5bed-0796-7962-86b9bde8f4f9.png)

こっちの設定です。
![BIG-IP_SNI_SS3.png](https://qiita-image-store.s3.amazonaws.com/0/157891/a0d89265-3c55-bf70-adb2-6e75490d08bc.png)

ただし、Fallback用証明書と紐づけるClient SSL Profileだけは、ServerNameを入力せず、代わりに「Default SSL Profile for SNI」を有効にします。

こんな感じに。
![BIG-IP_SNI_SS4.png](https://qiita-image-store.s3.amazonaws.com/0/157891/9c14ad3a-ccef-2edc-be44-7f108331822b.png)

### Virtual ServerへのClient SSL Profileの適用
最後に、SSL接続を待ち受けるVirtual Serverに、作成した複数のClient SSL Profileを適用すればOKです。

Virtual Server設定の、該当部分です。
![BIG-IP_SNI_SS5.png](https://qiita-image-store.s3.amazonaws.com/0/157891/a582c953-f944-e331-71b5-dfc83bc5077c.png)

## 補足：CLIでの設定について
CLIで設定する場合は、以下のようになります。

### SSL証明書や秘密鍵のインポート
SSL証明書や秘密鍵のファイルを、BIG-IP内の任意のディレクトリ（/shared/tmpなど）へアップロードし、コマンドでファイルをBIG-IPのコンフィグ内に登録します。登録の際、指定のディレクトリへファイルはコピーされるので、アップロードしたファイルは削除して構いません。

ここでは証明書ファイルを「/shared/tmp/test.crt」、秘密鍵ファイルを「/shared/tmp/test.key」として、それをBIG-IPに「test-cert.crt」、「test-cert.key」という名前で登録する方法を記載します。
(こうすると、GUI上では証明書と秘密鍵をまとめて「test-cert」と表示します） 

```text:
# tmsh
(tmos)# 
(tmos)# create sys file ssl-cert test-cert.crt source-path file:///shared/tmp/test.crt
Copying file "file:///shared/tmp/test.crt" ...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
101  1216  101  1216    0     0  3710k      0 --:--:-- --:--:-- --:--:--     0
(tmos)# 
(tmos)# create sys file ssl-key test-cert.key source-path file:///shared/tmp/test.key
Copying file "file:///shared/tmp/test.key" ...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1704  100  1704    0     0  4982k      0 --:--:-- --:--:-- --:--:--     0
```

### Client SSL Profileの作成
Client SSL Profileを作成し、証明書と秘密鍵を紐付け、Server Nameを設定する方法です。３段階に分けていますが、一行でまとめて設定することも可能です。

```text:
# tmsh
(tmos)# 
(tmos)# create ltm profile client-ssl test.example.co.jp 
(tmos)# modify ltm profile client-ssl test.example.co.jp { cert-key-chain replace-all-with  { test-cert { cert test-cert.crt key test-cert.key } } }
(tmos)# modify ltm profile client-ssl test.example.co.jp server-name "test.example.co.jp" 
```

### Virtual ServerへのClient SSL Profileの適用
ここでは、すでにVirtual Server"vs_example.co.jp_https"が存在していて、そこにClient SSL Profileを追加する方法を記載します。

```text:
# tmsh
(tmos)# modify ltm virtual vs_example.co.jp_https profiles add { test.example.co.jp { context clientside } } 
```

## 参考情報
 - [Wikipedia（日本語):Server Name Indication](https://ja.wikipedia.org/wiki/Server_Name_Indication)
 - [Askf5 K13452: Configuring a virtual server to serve multiple HTTPS sites using the TLS Server Name Indication feature](https://support.f5.com/csp/article/K13452)