備忘録とかいろいろ

駆け出しのインフラエンジニアです。自分用のメモです

SSLサーバ証明書についてのまとめ

仕事でSSLサーバ証明書の作成、更新などを行うことがあるが、
仕組みや機能について漠然としか理解できていないので、まとめてみる。
後半は、自己認証局を立て、証明書を発行する手順と、自己署名証明書の作成手順についての記録。

SSLサーバ証明書の概要

SSLサーバ証明書とは

SSLサーバ証明書とはWebサーバの身分証明書のようなものでCA(Certificate Authority)と呼ばれる認証局が発行する。
誰でもCAになって証明書を発行できるため、必ずしも安全とは限らない。
このため、有力な商用CAが厳格な身元確認などの審査を要する「EV SSL証明書」の発行を行っており、
ブラウザ上の表示も通常とは区別されるようになっている。

SSLサーバ証明書の機能

SSLサーバ証明書は、以下の2つの機能により、インターネット上での情報のやり取りを安全なものにしてくれる。
 ・WebブラウザとWebサーバ間(もしくはサーバ同士)でSSL暗号化通信を行う機能
 ・通信先のサーバの運用組織が実在することを証明する機能

SSLサーバ証明書の種類

大きく分けて以下の3種類の証明書がある。
どちらもSSLによる暗号化は行われるが、証明書の信頼性が異なる。

種類 発行の仕組み
クイック認証SSL
ドメイン認証)
whoisデータベースに登録されている情報をもとに審査が行われる。対象ドメインの所有は証明されるが、組織や個人の実在は証明されない。
組織認証SSL
(組織実在認証)
whoisデータベースでの照会に加え、第三者データベース(帝国データバンクやDUNS)に組織情報の照会を行い、法的に実在している組織であるかを確認する。その後、登録されている代表電話番号に電話を行い、実在確認を経て証明書が発行される
EV SSL
(Extended Validation)
発行申請時に、申請者の印鑑証明書や登記簿謄本などの提出をする。次に、whoisデータベースでの照会に加え、第三者データベース(帝国データバンクやDUNS)に組織情報の照会を行い、物理的に実在している組織であるかを確認する。電話による実在確認を経て証明書が発行される


さらに、以下ような機能がついた証明書もある。

名称 機能
ワイルドカード 1枚の証明書でサブドメインを証明できる。例えば、「*.example.jp」というワイルドカード証明書は「www.example.jp」や「mail.example.jp」といったサブドメインに対しても正当な証明書として使用できる。ただし「*」は必ず1文字以上で置き換える必要があるため、「https://example.jp/」では利用できない。
マルチドメイン 1枚の証明書で複数のドメインを証明できる。通常、サーバのFQDNを「CN(Common Name)」というフィールドに格納するが、このCNは1つしか設定できない。これとは別に「SAN(Subject Alternative Names)」という拡張領域フィールドに別のドメイン名を複数格納することで、複数のドメイン名の証明をすることができる
サイトシール(SSLシール) 証明書によって証明されているドメイン名や有効期限などをWebサイトに表示する機能のこと。クリックすると証明内容を表示する画像が表示される。


一般的なSSLサーバ証明書発行の流れ

SSLサーバ証明書が発行されるまでには一般的に以下のような流れになる
1.Webサーバで秘密鍵を生成
2.秘密鍵を使用してCSRを生成
3.認証局CSRと本人証明データを提出
4.認証局による審査(証明書の種類によって審査項目は異なる)
5.SSLサーバ証明書の発行

SSLサーバ証明書の中身

証明書には以下のような項目が記載されている。
1.Webサーバの情報(識別名)
  ・Country(国コード)
  ・State(都道府県名)
  ・Locality(市区町村名)
  ・Organizational Name(組織名)
  ・Organizational Unit(部署名)
  ・Common Name(コモンネーム)
2.Webサーバの公開鍵
3.証明書発行局名
4.証明書発行局の電子署名
5.有効期間
6.証明書の基本情報
  ・証明書のバージョン(X.509 Ver.3など)
  ・証明書の通し番号
  ・電子署名に使われている暗号化方式


自己認証局での証明書の発行

本来であれば信頼のあるCAで認証してもらうが、今回は自分でCAを構築してみる。
そして構築したCAで作成したCSRに署名を行い、サーバ証明書を作成する

CAの構築

CAの構築にはopenssl付属のCA.shを使用する
CAは/usr/local/ssl/CAに構築する

予めCAの構築ディレクトリを作成しておく

$ sudo mkdir -p /usr/local/ssl/CA


CA.shをCAの作成場所にコピー

$ locate CA.sh
/usr/lib/ssl/misc/CA.sh
$ sudo cp /usr/lib/ssl/misc/CA.sh /usr/local/ssl/CA/


CA.shを修正する

$ sudo vi /usr/local/ssl/CA/CA.sh
CATOP=/usr/local/ssl/CA


同様にopenssl.cnfも修正する

$ sudo vi /etc/ssl/openssl.cnf
[ CA_default ]
#dir        = ./demoCA      # Where everything is kept
dir     = /usr/local/ssl/CA     # Where everything is kept


CA構築の準備ができたのでスクリプトを実行する

$ sudo ./CA.sh -newca
Enter PEM pass phrase: ←パスフレーズを入力
Verifying - Enter PEM pass phrase: ←パスフレーズを再入力
-----
Country Name (2 letter code) [AU]: ←国名
State or Province Name (full name) [Some-State]: ←都道府県名
Locality Name (eg, city) []: ←市区町村名
Organization Name (eg, company) [Internet Widgits Pty Ltd]: ←組織名
Organizational Unit Name (eg, section) []: ←部署名
Common Name (e.g. server FQDN or YOUR name) []: ←サーバのホスト名
Email Address []: ←連絡先メールアドレス

A challenge password []: ←ENTER
An optional company name []: ←ENTER

これでCAの構築は完了。
/usr/local/ssl/CA以下にcacert.pem(認証局の証明書)と
/usr/local/CA/private以下にcakey.pem(認証局秘密鍵)が作成されている。

作成した証明書は以下のコマンドで内容の確認ができる

openssl x509 -in /usr/local/ssl/CA/cacert.pem -text


サーバの秘密鍵を作成する

サーバの秘密鍵は/usr/local/ssl/SERVERに作成する

ディレクトリの作成、パーミッションの変更

$ sudo mkdir /usr/local/ssl/SERVER
$ sudo chmod 600 /usr/local/ssl/SERVER


サーバの秘密鍵の作成

$ sudo openssl genrsa -des3 -out /usr/local/ssl/SERVER/server.key 1024
Enter pass phrase for /usr/local/ssl/SERVER/server.key: ←パスフレーズを入力
Verifying - Enter pass phrase for /usr/local/ssl/SERVER/server.key: ←パスフレーズを再入力


apacheで利用すると、起動時にパスワードを要求されるのでパフレーズを解除しておく

$ sudo openssl rsa -in ./SERVER/server.key -out ./SERVER/server_nopass.key
Enter pass phrase for ./SERVER/server.key:
writing RSA key


鍵の中身を確認するには以下のコマンドを使う

$ sudo openssl rsa -in ./SERVER/server.key -text


CSR(署名要求書)を作成する

同一ホストの自己認証局を利用する場合、CA構築時とまったく同じ内容を入力する必要がある

$ sudo openssl req -new -days 365 -key ./SERVER/server.key -out ./SERVER/csr.pem
Enter pass phrase for ./SERVER/server.key: ←サーバの秘密鍵のパスフレーズ入力
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:

A challenge password []:
An optional company name []:


CSRの中身を確認するには以下のコマンドを使う

$ sudo openssl req -in ../SERVER/csr.pem -text


サーバ証明書の作成

CAでCSRに署名をする

$ cd /usr/local/ssl/CA/
$ sudo openssl ca -in ../SERVER/csr.pem -keyfile ./private/cakey.pem -cert ./cacert.pem -out ../SERVER/cert.pem
Enter pass phrase for ./private/cakey.pem:
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y


サーバ証明書Apacheへ設定

まず、Apacheでmod_sslが有効になっているか確認する。

$ sudo apachectl -M | grep ssl

何も返ってこないので有効になっていない

mod_sslを有効にする

$ sudo a2enmod ssl
$ sudo service apache2 restart
$ sudo apachectl -M | grep ssl
   ssl_module (shared)


次にサーバ証明書秘密鍵を設置する

$ sudo mkdir /etc/apache2/ssl
$ sudo mv /usr/local/ssl/SERVER/cert.pem /etc/apache2/ssl/
$ sudo mv /usr/local/ssl/SERVER/server_nopass.key /etc/apache2/ssl/
$ sudo chmod 400 /etc/apache2/ssl/server_nopass.key


サイトの設定

$ sudo vi /etc/apache2/sites-available/default-ssl
   SSLCertificateFile    /etc/apache2/ssl/cert.pem
   SSLCertificateKeyFile /etc/apache2/ssl/server_nopass.key


サイトを有効にし、再起動

$ sudo a2ensite default-ssl
$ sudo service apache2 restart

ブラウザでhttps://(サーバのIPアドレス、またはサーバ名)/ にアクセスする。
ただし、自己認証局を利用して署名したサーバ証明書を利用しているため警告が表示される


自己署名証明書の作成

CAで署名せず、自己署名した証明書を作成することもできる
秘密鍵CSRを作成した後、以下のコマンドを実行する

$ sudo openssl x509 -days 3650 -in ./SERVER/csr.pem  -req -signkey ./SERVER/server.key -out ./SERVER/server.cert


ワイルドカード自己署名証明書の作成

ワールドカード自己署名証明書を作成するには、
CSR作成時のCNフィールドに「*.example.jp」のように入力する

Common Name (eg, your name or your server's hostname) []:*.example.jp

後の手順は他と同じ。


名前ベースのバーチャルホストでSSLを使用するには

以前は、名前ベースのバーチャルホストでは、複数のサーバ証明書を使用することはできなかった。
バーチャルホストで複数のサーバ証明書を使うには、IPベースのバーチャルホストにするか、ワイルドカードもしくはマルチドメイン証明書を使用する必要があった。

しかし現在では、SNI(Server Name Indication)という、SSLプロトコルに対する拡張機能をサポートするサーバとブラウザ間の通信であれば、名前ベースのバーチャルホストでもSSLが使えるようになった。


SNIを使用できる条件としては以下の通り。

  • Apacheのバージョンは2.2.12以降
  • OpenSSLのバージョンは0.9.8f以降でTLS拡張オプションを指定した状態でビルド
  • Apacheは上記のOpenSSLでビルド
  • ブラウザがSNI対応


設定として特別なことは不要で、HTTPの名前ベースのバーチャルホストと同じように設定すればよい。

Listen 443
NameVirtualHost *:443
SSLStrictSNIVHostCheck off
<VirtualHost *:443>
DocumentRoot /var/www/example1/
ServerName www.example1.jp
...
SSLEngine on
SSLCertificateFile    /etc/apache2/ssl/example1.pem
SSLCertificateKeyFile /etc/apache2/ssl/server_nopass.key
...

</VirtualHost>
<VirtualHost *:443>
DocumentRoot /srv/www/example2/
ServerName www.example2.jp
...
SSLEngine on
SSLCertificateFile    /etc/apache2/ssl/example2.pem
SSLCertificateKeyFile /etc/apache2/ssl/server_nopass.key
...
</VirtualHost>

「SSLStrictSNIVHostheck Off」はSNI未対応のブラウザからアクセスした際の挙動を制御する設定。
「Off」の場合は、デフォルトのバーチャルホストへリダイレクトされる。
「On」の場合は、サイトへのアクセス自体が拒否される。