オレオレ認証局(CA)を作ってオレオレ証明書を発行

開発環境

意外と理解できていないSSLの仕組み


前回記事

vagrantでweb開発用LAMP + phpMyAdmin環境を構築

ここでローカルマシンにウェブ開発のためのLAMP環境を構築したわけですが、昨今の状況を鑑みると、テストサーバー・ローカルサーバー・本番サーバー問わず全てのウェブ環境をhttps化しておくことは必須です。
その中でも開発環境においては極力予算をかけずに、ようはタダでsslを使いたいわけです。

そこで出てくるのが「オレオレ証明書」つまり自己発行した証明書で認証を通すというやり方です。

それで、いろいろとググりながらこの問題をクリアしていくわけですが、その過程で、かなり頭が混乱します。
考えずにやり方だけ真似ると出来るかもしれませんが、やってることの意味を理解しようとすると、はたと気づくわけです。

「ワシ、SSLのこと全く分かっとらんわ」

ということで、SSLについて基礎的なお勉強を少しでもやってからこの記事に取り組むとより良いと思います。

いろいろありますが、動画時代ちゅうことで、簡単な動画を二つほど紹介しておきます。

オレオレ証明書の発行についてググって見つかる記事はいろいろありますが、大きく分けて2通りの考え方に分かれます。

一つは「認証局から作る」方法、もう一つは認証局は作らない方法。

ここでは「認証局から作る」やり方を実践します。

その方が全体的な仕組みの理解が深まりますし、実益で言えば複数のドメインに対して証明書を次々と発行していくことが出来るので有利です。

今回の作業の進め方


今回は基本的には以下の記事を参照しながら進めます。他にもかなりの数の記事などを参照しましたが、最も分かりやすかったのがこちらです。

参考サイト:オレだよオレオレ認証局で証明書つくる

上記の記事の通りにやってできたら、今回のこの記事は必要ありません(爆)

ただ、環境や時期等によって躓く場合も多々ありますので、補足として今回記事を参考にしていただければよろしいかと。


参考までに私の環境

  • VirtualBox6.0 + Vagrant2.2.5
  • OS : CentOS 7.2
  • Web Server: Apache 2.4.6(mod_ssl必須ですよ)
  • OpenSSL 1.0.2

基本的には参考サイトの通りに進めます。この記事ではOpenSSLの各種証明書等のパスをデフォルトの通りにやってくれているので、失敗しにくいと思われます。

他にも参考に出来る記事は山ほどありますが、

  • 最近のChromeやFF等ブラウザ側のバージョンアップでhttpsまわりの仕様が結構変わってるようで、極力新しい記事を参考にすべし。
  • 証明書を作るだけの記事と認証局(CA)まで作る記事とを混同しないこと
  • 知識に不安がある場合はホストマシンのOS(win/mac/Linux)やウェブサーバー(apache/nginx/iis)も合っている記事の方を探した方がよさげ

このあたりに気をつけて複数の記事を参考にしたらよいと思います。

では、始めます。

オレオレ認証局(CA)の開設

認証局(CA)とは Certification Authority の略。つまり、ウェブサーバーへの証明書に署名できるエラい人。えっへん。
認証局から作っておくと、いろいろなウェブサーバーに対して証明書を発行できるわけです。なので、複数のドメインを運用する場合にはここからやった方がいいのです。

OpenSSLの設定編集

まずは、OpenSSLの設定を確認しつつ、必要に応じて書き換えていきます。

$ sudo vi /etc/pki/tls/openssl.cnf

# 75行目の項目でハッシュ方式をsha256に変更
default_md = sha256

# 107行目の[req]セクション内もハッシュ方式を変更
default_md = sha256

# [req_distinguished_name]項目で毎度入れる内容の初期値を入れておく
countryName_default = JP #日本
stateOrProvinceName_default = Tokyo #都道府県
localityName_default = Chiyoda-ku #市区町村
0.organizationName_default = OREORE.INC #組織名

[ usr_cert ]
このセクションに以下の行を追記

subjectAltName = @alt_names

認証局 = CA の秘密鍵を生成

$ openssl genrsa -aes256 -out /etc/pki/CA/private/cakey.pem 2048

Generating RSA private key, 2048 bit long modulus
...............................................+++
..................................................................
..........................................................+++
e is 65537 (0x10001)
Enter pass phrase for /etc/pki/CA/private/cakey.pem:  # <= 鍵のパスフレーズを設定
Verifying - Enter pass phrase for /etc/pki/CA/private/cakey.pem: # <= 再度パスフレーズを入力

証明書発行要求 CSRファイル作成 (cacert.csr)

秘密鍵から生成された公開鍵が本物の証であることのファイルを発行してもらうCSRファイル。

先ほど生成したcakey.pem という鍵を使ってcacert.csrという発行要求を作るよ!!ということ。

$ openssl req -new -key /etc/pki/CA/private/cakey.pem -out /etc/pki/CA/cacert.csr

Enter pass phrase for /etc/pki/CA/private/cakey.pem: # <= CAの鍵パスフレーズ
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
 -----
Country Name (2 letter code) [JP]: # <= 何も入力しないでEnter
State or Province Name (full name) [Tokyo]: # <= 何も入力しないでEnter
Locality Name (eg, city) [Chiyoda-ku]: # <= 何も入力しないでEnter
Organization Name (eg, company) [OREORE.INC]: # <= 何も入力しないでEnter
Organizational Unit Name (eg, section) []: # <= 何も入力しないでEnter
Common Name (eg, your name or your servers hostname) []: Oreore.local #  <=オレオレ認証局用に好きな名前
Email Address []: # <= 何も入力しないでEnter

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []: # <= 何も入力しないでEnter
An optional company name []: # <= 何も入力しないでEnter

ここの「Common Name」は親玉の名前。あとで出てくるサーバー証明書のCommon Nameにはドメインを指定するが、こちらはそうではなく、好きな名前をつけてよい。


オレオレ証明書発行

自分自身の鍵を自分自身で署名する。これが俗に言うオレオレ証明書。

$ openssl x509 -days 3650 -in /etc/pki/CA/cacert.csr -req -signkey /etc/pki/CA/private/cakey.pem -out /etc/pki/CA/cacert.pem

Signature ok
subject=/C=JP/ST=Tokyo/L=Chiyoda-ku/O=OREORE.INC/CN=Oreore.local CA
Getting Private key
Enter pass phrase for /etc/pki/CA/private/cakey.pem: # <=さっき入れた認証局の鍵パスフレーズ

認証局運用に必要なファイルの生成

以下の二つのファイル index.txt と serial(拡張子なし)を作って置かないとダメダメ!

$ touch /etc/pki/CA/index.txt
$ echo 00 > /etc/pki/CA/serial

これで認証局側の作業は完了!!


鍵作成からオレオレ認証局でのサーバー証明書発行

Apacheなどで使用したいサーバーの証明書を発行してもらうための作業


秘密鍵作成

$ openssl genrsa -aes256 -out /etc/pki/tls/private/privkey.pem 2048

発行要求CSRファイル作成(domain_name.csr)

domain_name の部分は発行したいサイトのドメイン毎に任意に指定すれば良いのだが、今回はもうこのままでやるww

$ openssl req -new -key /etc/pki/tls/private/privkey.pem -out /etc/pki/tls/certs/domain_name.csr

Enter pass phrase for /etc/pki/tls/private/privkey.pem:  # <= 鍵パスフレーズ
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
 -----
Country Name (2 letter code) [JP]: # <= 何も入力しないでEnter
State or Province Name (full name) [Tokyo]: # <= 何も入力しないでEnter
Locality Name (eg, city) [Shibuya]: # <= 何も入力しないでEnter
Organization Name (eg, company) [OREORE.INC]: # <= 何も入力しないでEnter
Organizational Unit Name (eg, section) []: # <= 何も入力しないでEnter
Common Name (eg, your name or your servers hostname) []: *.vagrant.test # <=証明書を発行したいドメイン
Email Address []: # <= 何も入力しないでEnter

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []: # <= 何も入力しないでEnter
An optional company name []: # <= 何も入力しないでEnter

ここでのCommon Nameは重要。

証明書を利用したいサイトのドメインを入れる。

  • www.vagrant.test の証明書を発行したいのなら www.vagrant.test
  • マルチドメインで www.vagrant.test とか hoge.vagrant.test とか fuga.vagrant.testとかいろいろ使ううよ〜という場合は *.vagrant.test と指定する。
  • hoge.fuga.vagrant.testとかになる場合は *.fuga.vagrant.test としてやらなければならない。

サーバー証明書発行(domain_name.crt.pem)

Subject Alternative Name の設定

証明書発行の前に追加設定ファイルを作成

  1. san.ext(ファイル名はなんでも可)
  2. このファイルに subjectAltName=DNS:hogehoge.com を追記(マルチドメインの場合はカンマ区切り)
  3. opensslコマンドに -extfile san.ext を追加して証明書発行を実行
# ファイル作成と書き込みは一気にやろう
$ echo "subjectAltName=DNS:vagrant.test,DNS:*.vagrant.test" > /etc/pki/CA/san.ext
 
$ openssl ca -in /etc/pki/tls/certs/domain_name.csr -out /etc/pki/tls/certs/domain_name.crt.pem -days 825 -extfile /etc/pki/CA/san.ext
Using configuration from /etc/pki/tls/openssl.cnf
Enter pass phrase for /etc/pki/CA/private/cakey.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 0 (0x0)
        Validity
            Not Before: Feb 15 10:49:34 2020 GMT
            Not After : May 20 10:49:34 2022 GMT
        Subject:
            countryName               = JP
            stateOrProvinceName       = Tokyo
            organizationName          = OREORE.INC
            commonName                = *.vagrant.test
        X509v3 extensions:
            X509v3 Subject Alternative Name: 
                DNS:vagrant.test, DNS:*.vagrant.test
Certificate is to be certified until May 20 10:49:34 2022 GMT (825 days)
Sign the certificate? [y/n]:y
 
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

自己署名openssl x509ではなく、認証局openssl caとして署名する!!


Chromeに証明書を読み込ませる

ブラウザ側に持たせる証明書は /etc/pki/CA/cacert.pem

共有フォルダ経由でホストマシンに取り込み、OSやブラウザに登録し、「常に信頼」としておく。

# 共有フォルダからPCに取り込む場合
cp /etc/pki/CA/cacert.pem /var/www/html/cacert.pem
# PC側で保存したらこれは削除しておく

ウェブサーバー起動時にパスフレーズを求めらる問題を回避

$ openssl rsa -in /etc/pki/tls/private/privkey.pem -out /etc/pki/tls/private/privkey-nopass.pem

# パスフレーズを聞かれるので、鍵を作成したときに入力したパスフレーズを入れる。

これらを使用したいデーモンに読み込ませるようにすれば使える。

例えばApacheで使いたいなら最低限の設定は以下の通り。

※ /etc/httpd/conf/httpd.conf に書き込んでも良いが、外部に置きたい私。

/etc/httpd/conf.d/vhost.conf(無ければ作れ) に以下を記述

$ vi /etc/httpd/conf.d/vhost.conf

<VirtualHost *:443>
    ServerName vagrant.test
    SSLEngine On
    SSLCertificateFile /etc/pki/tls/certs/domain_name.crt.pem
    SSLCertificateKeyFile /etc/pki/tls/private/privkey-nopass.pem
</VirtualHost>

今回はここまで!!

2021/03/19開発環境CentOS,https,ssl,Vagrant

Posted by 大将