LoginSignup
19
21

More than 3 years have passed since last update.

openssl オレオレ認証局で証明書発行

Last updated at Posted at 2020-04-23

openssl でオレオレ認証局で証明書を発行する

ubuntuバージョン

$ cat /etc/os-release | grep PRETTY_NAME
PRETTY_NAME="Ubuntu 18.04.4 LTS"

openssl バージョン

$ openssl version  
OpenSSL 1.1.1  11 Sep 2018

概要

2020/05/31
ちょー簡単に証明書を発行してくれる mkcert という開発環境用の証明書発行ツールが存在しています。

https://github.com/FiloSottile/mkcert

何らかの理由でLetsEncryptなど無料の証明書が使えない場合とにかく開発環境でSSLを使いたい。
ルート認証局を作成し、ルートCA証明書(ルート認証局の証明書)とサーバ証明書を発行する。
ルートCA証明書は、クライアントのブラウザにインポートする。
サーバ証明書は、Webサーバにインポートする。
ルート認証局から発行したルートCA証明書とサーバ証明書を使用することでクライアント(ブラウザ)とサーバ(WEBサーバ)でSSL通信ができる。

シェルを作った。けど mkcert の方を使った方がいいと思う。
https://github.com/yutakachi/createCertificates

ルート認証局(オレオレ認証局)を作成する

ルート証明局用のディレクトリを作成する

$ cd ~
$ mkdir -p ./rootCA/private
$ mkdir -p ./rootCA/newcerts
$ mkdir -p ./rootCA/testDomain.jp
$ mkdir -p ./rootCA/testDomain.jp/certs
$ mkdir -p ./rootCA/testDomain.jp/private

秘密鍵を作る

$ openssl genrsa -aes256 -out ./rootCA/private/cakey.pem 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
...................+++++
..........................................................+++++
e is 65537 (0x010001)
Enter pass phrase for ./rootCA/private/cakey.pem:任意のパスフレーズ
Verifying - Enter pass phrase for ./rootCA/private/cakey.pem:確認用のパスフレーズ

CSRを作る

秘密鍵に対する公開鍵を作るための情報を作成する
(Can't load /home/a_user/.rnd into RNG のエラーがでたら。。後述)

$ openssl req -new -key ./rootCA/private/cakey.pem -subj "/C=JP/ST=Tokyo/L=edogawa/O=testCompany/OU=software/CN=my_rootCA/" -out ./rootCA/cacert.csr
Enter pass phrase for ./rootCA/private/cakey.pem:秘密鍵のパスフレーズ

-subj オプションの補足
-subj無しの場合、対話形式で入力を求められる
/C Country Name(2 letter code)
/ST State or Province Name (full name)
/L Locality Name(eg, company)
/O Organization Name (eg, company)
/OU Organization Unit Name (eg, section)
/CN Common Name (eg, your name or your server's hostname)
※ /CN はサーバ証明書の作成時にはドメイン名を指定する必要がある。
https://ドメイン名/xxx 一致しないとSSLのエラーとなる。

以下、注意すべきオプション。
/O Organization (認証局の組織名) 会社名とか。。 例) testCompany
ルートCA証明書をブラウザにインポートした後、確認するのでわかりやすい名前がいい。

/CN Common Name (コモンネーム) ルート認証局の名前 例) my_rootCA
ルートCA証明書用なのでmy_rootCA としているが、サーバ証明書を作成(後述)する際は、ドメイン名にする。

Can't load /home/a_user/.rnd into RNG のエラーがでたら。。
Can't load /home/a_user/.rnd into RNG
140491206660544:error:2406F079:random number generator:RAND_load_file:Cannot open file:../crypto/rand/randfile.c:88:Filename=/home/a_user/.rnd

以下の対応をする。

$ sudo vim /etc/ssl/openssl.cnf

コメントアウトする
RANDFILE              = $ENV::HOME/.rnd
↓
# RANDFILE              = $ENV::HOME/.rnd

ルートCA証明書(自己証明書)認証局自信が自分を証明する

自己署名(openssl x509)することで証明する。

$ openssl x509 -days 825 -in ./rootCA/cacert.csr -req -signkey ./rootCA/private/cakey.pem -out ./rootCA/cacert.pem
Signature ok
subject=C = JP, ST = Tokyo, L = edogawa, O = testCompany, OU = software, CN = my_rootCA
Getting Private key
Enter pass phrase for ./rootCA/private/cakey.pem:秘密鍵のパスフレーズ

補足 -days 有効期限の最長(上限)で 825日。

認証局に必要なファイル

証明書発行を記録していくファイルを作成する

$ touch ./rootCA/index.txt
$ touch ./rootCA/index.txt.attr
$ echo 00 > ./rootCA/serial

ここまででルート証明局は完了。

ブラウザにルートCA証明書をインポート

ルートCA証明書(./rootCA/cacert.pem)をインポートすることで、my_rootCAで発行されたサーバ証明書は有効なものになる。

Chrome
ブラウザ右上点3つ > 設定 > 左メニューのプライバシーとセキュリティ > もっと見る > 証明書の管理 > インポート
windows 信用さえた認証期間タブ
Linux 認証局タブ
org-testCompany で一覧に登録されていることを確認する。
org-は接頭語 testCompanyは、opensslの/Oオプションで設定した Organization name

Firefox
ブラウザの右上三本線 > 設定 > プライバシーとセキュリティ > 証明書(一番下)> 証明書を表示 > 認証局証明書 > インポート
testCompany で一覧に登録されていることを確認する

Webサーバ用証明書作成

ルート認証局からWebサーバで使用する鍵や証明書を発行する

openssl.cnf を修正する

$ sudo cp /etc/ssl/openssl.cnf /etc/ssl/openssl.cnf.org
$ sudo vim /etc/ssl/openssl.cnf 

[CA_default]
dir = ./rootCA

[usr_cert]
subjectAltName = @alt_names

SANs拡張を使用する (subjectAltName = Subject Alternative Names)

subjectAltNameを設定しないとブラウザで不正な証明書と認識されてしまう。
サーバ証明書に登録するドメインをtestDomain.jpとする。
今回はサブドメインにも対応できるように設定する。
san.ext を作成する。san.extは証明書を発行する際のオプション-extfileで読み込む

vim ./rootCA/san.ext
subjectAltName=DNS:*.testDomain.jp, DNS:testDomain.jp

秘密鍵を作成

openssl genrsa -aes256 -out ./rootCA/testDomain.jp/private/privkey.pem 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
...............................+++++
.+++++
e is 65537 (0x010001)
Enter pass phrase for ./rootCA/testDomain.jp/private/privkey.pem:任意のパスフレーズ
Verifying - Enter pass phrase for ./rootCA/testDomain.jp/private/privkey.pem:確認用パスフレーズ

CSR作成

$ openssl req -new -key ./rootCA/testDomain.jp/private/privkey.pem -subj "/C=JP/ST=Tokyo/L=edogawa/O=testCompany/OU=software/CN=testDomain.jp/" -out ./rootCA/testDomain.jp/certs/testDomain.csr
Enter pass phrase for ./rootCA/testDomain.jp/private/privkey.pem:秘密鍵のパスフレーズを入力

証明書発行

ルート(オレオレ)認証局(openssl ca)で署名する。

$ openssl ca -keyfile ./rootCA/private/cakey.pem -cert ./rootCA/cacert.pem -in ./rootCA/testDomain.jp/certs/testDomain.csr -out ./rootCA/testDomain.jp/certs/testDomain.crt.pem -days 825 -outdir ./rootCA/newcerts -extfile ./rootCA/san.ext

Using configuration from /usr/lib/ssl/openssl.cnf
Enter pass phrase for ./rootCA/private/cakey.pem: cakey.pemの秘密鍵のパスフレーズを入力
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 0 (0x0)
        Validity
            Not Before: Apr 15 07:51:59 2020 GMT
            Not After : Jul 19 07:51:59 2022 GMT
        Subject:
            countryName               = JP
            stateOrProvinceName       = Tokyo
            organizationName          = testCompany
            organizationalUnitName    = software
            commonName                = testDomain.jp
        X509v3 extensions:
            X509v3 Subject Alternative Name: 
                DNS:*.testDomain.jp, DNS:testDomain.jp
Certificate is to be certified until Jul 19 07:51:59 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

ここまででサーバ証明書の作成、発行は完了

Webサーバへの適用

Apacheの場合

Apache2.4

apache ssl 設定ファイルを編集

vim /etc/apache2/sites-available/default-ssl.conf
<IfModule mod_ssl.c>
    <VirtualHost _default_:443>
        # ServerAdmin webmaster@localhost

        DocumentRoot /home/a_user/testDomain.jp
        ServerName gitproject
        ErrorLog ${APACHE_LOG_DIR}/error-ssl.log
        CustomLog ${APACHE_LOG_DIR}/access-ssl.log combined

        SSLEngine on

        SSLCertificateFile "/home/a_user/rootCA/testDomain.jp/certs/testDomain.crt.pem"
        SSLCertificateKeyFile "/home/a_user/rootCA/testDomain.jp/private/privkey.pem"

        <FilesMatch "\.(cgi|shtml|phtml|php)$">
                SSLOptions +StdEnvVars
        </FilesMatch>
        <Directory /usr/lib/cgi-bin>
                SSLOptions +StdEnvVars
        </Directory>

    </VirtualHost>
</IfModule>

ssl の有効化

$ sudo a2enmod ssl
Considering dependency setenvif for ssl:
Module setenvif already enabled
Considering dependency mime for ssl:
Module mime already enabled
Considering dependency socache_shmcb for ssl:
Enabling module socache_shmcb.
Enabling module ssl.
See /usr/share/doc/apache2/README.Debian.gz on how to configure SSL and create self-signed certificates.
To activate the new configuration, you need to run:
  systemctl restart apache2

$ sudo systemctl restart apache2
Enter passphrase for SSL/TLS keys for testDomain.jp:443 (RSA): *********
サーバ証明書を作成した際の秘密鍵のパスフレーズを入力する  ↑

サーバ秘密鍵のパスフレーズを確認したい場合

$ openssl rsa -in ./rootCA/testDomain.jp/private/privkey.pem 
Enter pass phrase for ./rootCA/testDomain.jp/private/privkey.pem:確認するパスフレーズをいれる
パスフレーズが正しければ以下のように表示される。間違っている場合、エラーとなる。
※パスフレーズが設定されていない場合は、Enter pass phrase は表示されない。
writing RSA key
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA1lD1H2Z8HIZihM/VGqCkAXNLuTCxJvGX7jduajypN+t6gAYB
RX+pWNPjkVE1G69k0RlplxF+951x1+54QZ9CuYQNbKuamfEQg5VKnn8jyhZgWfPn
QoPnQiMdUwurlBsjUE24XusdU24aXXXXXXXXXXXXXXXXXXXXX
省略。。。
-----END RSA PRIVATE KEY-----

nginxの場合

/etc/nginx/nginx.conf は直接いじらない。
sslの鍵のパスフレーズを記載したファイルを用意しておく必要がある。
Apacheの場合は、起動時に入力を求められるが、nginxの場合はエラーになる。

Job for nginx.service failed because the control process exited with error code.
See "systemctl status nginx.service" and "journalctl -xe" for details.

パスフレーズを記載した任意のファイルを用意する。ここでは pwf とした。

vim /home/a_user/rootCA/testDomain.jp/pwf
記述内容は、SSLのパスフレーズを記述する
password01

default.conf の ssl_password_file に設定する

sudo vim /etc/nginx/conf.d/default.conf

server {
  listen 80;
  listen 443 ssl;
  ssl on;
  ssl_certificate /home/a_user/rootCA/testDomain.jp/certs/testDomain.crt.pem;
  ssl_password_file /home/a_user/rootCA/testDomain.jp/pwf;
  ssl_certificate_key /home/a_user/rootCA/testDomain.jp/private/privkey.pem;
  server_name testDomain.jp;
  access_log /home/a_user/testDomain/log/testDomain.access.log;
  location / {
    root /home/a_user/testDomain;
    index index.html;
  }
}

https 接続確認

ブラウザで確認

https://testDomain.jp/index.html

curlで確認

$ curl --cacert /home/a_user/rootCA/cacert.pem https://testDomain.jp/index.html

以上。

19
21
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
21