【課題13】 TLSとSNI

[座学]

・SNI(Server_Name_Indication)とは

https://ja.wikipedia.org/wiki/Server_Name_Indication

SNIが働くにはWebサーバ側とブラウザ側両面の対応が必要である。SNIを実装しないブラウザでは警告が表示されることがある。2016年時点でPC・モバイルの主要なブラウザで問題なく利用できる状況である。

名前ベースのバーチャルホストの場合、ブラウザがどのホストを訪問するかを、ハンドシェイク時点でサーバ側には予測できず、HTTPヘッダのホスト名によって複数枚のサーバ証明書を使い分けることができない。

SNIでは、TLSに拡張を加える。TLSのハンドシェイク手続きで、HTTPSクライアントが希望するドメイン名を伝える(この部分は平文となる)[3]。それによってサーバが対応するドメイン名を記した証明書を使うことが可能になる。

SNIは2003年6月、RFC 3546「TLS拡張仕様」に加わった。その後更新され、2014年1月現在SNIの記述のある最新の仕様はRFC 6066 (日本語訳) である。

 

[検証方針]

・自己署名ルート証明書を2つつくる(ルート証明書をブラウザにインストール)

・違うルート秘密鍵に署名されたサーバ証明書を1つずつつくる(計2個)

・nginxに名前ベースバーチャルホストを2つつくる(上記の2つのサーバ証明書をセット)

・名前ベースバーチャルホストがSNIで通信できることをwiresharkで確認

自己署名ルート証明書とサーバ証明書作成

 

[準備]

・下記の自己署名ルート証明書を作成した→ブラウザにインポート

せ7> ll /etc/pki/CA
-rw-r--r--. 1 root root 1086  5月 26 16:04 cacert2.pem
-rw-r--r--. 1 root root 1180  5月 26 16:24 cacert3.pem

・下記のサーバ証明書とTLS秘密鍵を作成した

せ7> ll /etc/pki/tls/certs

-rw-r--r--. 1 root root 4620  5月 26 16:29 gad3.chinko3.crt
-rw-r--r--. 1 root root 4430  5月 26 16:38 gad2.chinko2.crt

せ7> ll /etc/pki/tls/private
-rw-r--r--. 1 root root 1675  5月 26 16:07 gad2.chinko2.key
-rw-r--r--. 1 root root 1679  5月 26 16:25 gad3.chinko3.key

・nginxがSNIに対応していることの確認

せ7> nginx -V | grep SNI
nginx version: nginx/1.12.2
・・・前略・・・
TLS SNI support enabled

・・・後略・・・

・nginxの設定

せ7> cat /etc/nginx/conf.d/virtualhost.conf

server {
    listen       443 default_server;
    ssl                  on;
    server_name  gad2.chinko2;

    ssl_certificate      /etc/pki/tls/certs/gad2.chinko2.crt;
    ssl_certificate_key  /etc/pki/tls/private/gad2.chinko2.key;

    ssl_session_timeout  10m;
    ssl_session_cache   shared:SSL:10m;

    ssl_protocols TLSv1.2;
    ssl_ciphers  HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers   on;

    proxy_cookie_path / "/; secure";

    location / {
        proxy_set_header Host             $host;
        proxy_set_header X-Real-IP        $remote_addr;
        proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-User $remote_user;
        root   /usr/share/nginx/html/gad2.chinko2;
        index  index.html index.htm;
    }
}

server {
    listen       443;
    ssl                  on;
    server_name  gad3.chinko3;

    ssl_certificate      /etc/pki/tls/certs/gad3.chinko3.crt;
    ssl_certificate_key  /etc/pki/tls/private/gad3.chinko3.key;

    ssl_session_timeout  10m;
    ssl_session_cache   shared:SSL:10m;

    ssl_protocols TLSv1.2;
    ssl_ciphers  HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers   on;

    proxy_cookie_path / "/; secure";

    location / {
        proxy_set_header Host             $host;
        proxy_set_header X-Real-IP        $remote_addr;
        proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-User $remote_user;
        root   /usr/share/nginx/html/gad3.chinko3;
        index  index.html index.htm;
    }
}

・静的ページ

せ7> cat /usr/share/nginx/html/gad2.chinko2/index.html
<http>
<head>
<title>test</title>
</head>
<body>
<H1><font color="blue">これはgad2.chinko2だぎゃー</font></H1>
</body>
</http>

せ7> cat /usr/share/nginx/html/gad3.chinko3/index.html
<http>
<head>
<title>test</title>
</head>
<body>
<H1><font color="red">これはgad3.chinko3だぎゃー</font></H1>
</body>
</http>

・nginxサーバ再起動

せ7> systemctl restart nginx

・PCのhostsファイルに書きを追記

192.168.2.7            gad2.chinko2 gad3.chinko3

・動作確認

 

・ブラウザからhttps://gad2.chinko2にアクセスしてパケットをキャプチャしてみる

client helloのSNI extensionってところにサーバ名がいますね。