CentOS8のApacheで自己署名証明書を使いSSL化する方法

投稿者: | 2020-05-18

前回はApacheのソースインストールの方法について説明しました。今回はソースインストールしたApacheに自己署名を行い、「https://~」でWebサーバに接続を行う方法について説明します。

前提条件

今回は、Apacheをソースインストールしている前提で実施するため、Apacheのインストールがまだ終わっていない人は以下のページでApacheのソースインストールを行ってください。

・CentOS8にApache2.4.43をソースインストールする方法

https://www.kdkwakaba.com/archives/735

SSL/TLSとは

SSL(Secure Sockets Layer)とTLS(Transport Layer Security)はインターネット上のデータ通信を暗号化して送信する仕組みです。

Webサーバとの通信を行うHTTP通信はデータを平文で送信しているため、悪意を持ったユーザーから通信内容を見られてしまいます。ECサイトやWebサービス等、個人情報をやり取りするサイトでデータが見えてしまうと、個人情報を盗まれたりデータを改ざんされる等、個人情報を悪用される恐れがあります。

こうしたHTTPの平文でデータを送信する仕組みに対し、データを暗号化して悪意を持ったユーザーから見えないようにするのがSSLやTLSです。SSLやTLSでデータを暗号化することで、悪意を持ったユーザーから個人情報を盗まれたり悪用されるリスクを回避することができます。

ブラウザの通信が暗号化されているかどうかを判断するには、ブラウザのURL部分に鍵のマークがついているかどうかで判断できます。

最初の画像は暗号化していないサイトです。URL部分に「!」が表示されます。

次に、暗号化されているサイトです。URL部分に鍵のマークが表示されます。

SSL/TLSの仕組みについて

Webサーバへ通信を行うデータの暗号化を設定する前に、どのようにしてデータを暗号化して通信をしているかについて説明します。

SSLやTLSは公開鍵認証を使いデータを暗号化します。公開鍵認証とは、データの送信者が公に公開している公開鍵でデータを暗号化し、データの受信者が秘密鍵でデータを復号する仕組みです。

ユーザーがWebサーバにSSL通信でアクセスすると、Webサーバは公開鍵のデータが入ったサーバ証明書をユーザーに送付します。ユーザーはサーバ証明書から公開鍵を確認し、共通鍵の元データを作成してWebサーバの公開鍵で暗号化をします。暗号化後、共通鍵の元データからWebサーバと通信を行うための共通鍵を作成し、暗号化した元データを送信します。

Webサーバは暗号化した共通鍵の元データを秘密鍵で復号します。お互いが共通鍵の内容を知ったところで、ユーザーは共通鍵で暗号化したデータをWebサーバに送信しSSL通信を開始します。

以下の画像はSSL通信の一連の流れの図となります。

自己署名証明書とは

自己署名証明書とは、自分自身で作成した認証局でサーバの署名要求に署名し作成されたサーバ証明書のことです。オレオレ証明書とも言われます。信頼のある認証局から署名を行っていない証明書ため、暗号化はされているけど信頼性はないという証明書になります。

自己署名証明書が使われるケースとしては、主に以下の内容があります。

  • 社内のみで使用するツール、サイト(外部には一切公開しないもの)
  • SSL化の検証
  • SSL化の手順の勉強

外部に公開するWebサイト等では信頼のある認証局で署名した証明書を使いますが、自己署名証明書も業務等で使用するケースもあるため覚えておきましょう。

自己署名証明書の作成・設定

それでは、自己署名証明書の作成と設定について説明していきます。今回使用する環境は以下の通りです。

OSCentOS 8
環境VirtualBoxの仮想マシン
ドメインwww.example.com

今回使用するwww.example.comは既にネット上で使用されているため、仮想マシンのwww.example.comにアクセスするために、hostsファイルを編集します。

Windows端末であれば「C:\Windows\System32\drivers\etc」配下にhostsファイルがあるため、管理者権限でテキストエディタを開いた後、hostsファイルを開き編集します。今回のIPアドレスは、仮想マシンのIPアドレスが192.168.56.116という想定で記述していますが、実際に設定する際はご自身のWebサーバのIPアドレスを記述してください。

■hosts

# 仮想マシンのhttps://www.example.comにアクセスさせる
192.168.56.116          www.example.com

※参考
hostsファイルは社内システムや社内サイト等へ明示的にアクセスしたい場合に使われます。実務でもクライアント端末のhostsを設定することがあるため覚えておきましょう。

初めにプライベート認証局を作成します。CentOS8ではOpenSSLの設定ファイルで指定されたCAフォルダが存在しないため、フォルダおよびファイルを作成します。

・認証局用のファイル、フォルダを作成
# mkdir -p /etc/pki/CA/certs
# mkdir /etc/pki/CA/private
# touch /etc/pki/CA/index.txt
# touch /etc/pki/CA/serial && echo 00 > /etc/pki/CA/serial

ファイル・フォルダの作成後、OpenSSLの設定ファイルを編集します。alt_namesセクションのみ新規追加となります。

# vi /etc/pki/tls/openssl.cnf

■openssl.cnf
--------------------------------------------------
[ CA_default ]

#new_certs_dir  = $dir/newcerts
new_certs_dir   = $dir/certs

#certificate    = $dir/cacert.pem
certificate     = $dir/certs/ca.crt

#private_key    = $dir/private/cakey.pem
private_key     = $dir/private/ca.key

[ req ]

#req_extensions = v3_req # The extensions to add to a certificate request 
req_extensions = v3_req # The extensions to add to a certificate request

[ usr_cert ]
# subjectAltName=email:copy
subjectAltName = @alt_names

[ v3_req ]
subjectAltName = @alt_names

[ alt_names ]
DNS.1 = www.example.com
DNS.2 = *.example.com
--------------------------------------------------

OpenSSLの設定ファイルを編集後、認証局の秘密鍵および証明書を作成します。認証局の各種情報については設定例として記述します。

・認証局の秘密鍵および証明書を同時に作成
# openssl req -new -x509 -sha256 -days 3650 -newkey rsa:4096 -out /etc/pki/CA/certs/ca.crt -keyout /etc/pki/CA/private/ca.key 

・秘密鍵のパスワードを聞かれるため、パスワードを設定する
writing new private key to '/etc/pki/CA/private/ca.key'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:

・認証局の各種情報を設定する
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) [XX]:JP       # 国の名前
State or Province Name (full name) []:Tokyo      # 州の名前、日本だと都道府県あたり
Locality Name (eg, city) [Default City]:Shinjuku-ku      # 都市の名前
Organization Name (eg, company) [Default Company Ltd]:Example Co.    # 会社名
Organizational Unit Name (eg, section) []:Example Department    # 会社の部署名
Common Name (eg, your name or your server's hostname) []:www.example.com  # ドメイン名やサーバのホスト名
Email Address []:root@example.com    # 認証局のメールアドレス

認証局作成後、秘密鍵のパスワードを削除します。パスワードを聞かれるため先程設定したパスワードを入力します。

・認証局の秘密鍵のパスワードを削除
# openssl rsa -in /etc/pki/CA/private/ca.key -out /etc/pki/CA/private/ca.key 
Enter pass phrase for /etc/pki/CA/private/ca.key:
writing RSA key

認証局の作成後、サーバの秘密鍵および署名要求ファイルを作成します。サーバの各種情報は認証局と同じサーバのため同じ内容を入力します。チャレンジパスワードとオプションの会社名は空欄で設定します。

・認証局用のファイル、フォルダを作成
# openssl req -new -sha256 -days 3650 -newkey rsa:4096 -out /etc/pki/tls/server.csr -keyout /etc/pki/tls/private/server.key 

・秘密鍵のパスワードを聞かれるため、パスワードを設定する
writing new private key to '/etc/pki/tls/private/server.key'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:

・サーバの各種情報を設定する
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) [XX]:JP       # 国の名前
State or Province Name (full name) []:Tokyo      # 州の名前、日本だと都道府県あたり
Locality Name (eg, city) [Default City]:Shinjuku-ku      # 都市の名前
Organization Name (eg, company) [Default Company Ltd]:Example Co.    # 会社名
Organizational Unit Name (eg, section) []:Example Department    # 会社の部署名
Common Name (eg, your name or your server's hostname) []:www.example.com  # ドメイン名やサーバのホスト名
Email Address []:root@example.com    # サーバ管理者のメールアドレス

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

サーバの秘密鍵作成後、秘密鍵のパスワードを削除します。パスワードを聞かれるため先程設定したパスワードを入力します。

・サーバの秘密鍵のパスワードを削除
# openssl rsa -in /etc/pki/tls/private/server.key -out /etc/pki/tls/private/server.key 
Enter pass phrase for /etc/pki/tls/private/server.key:
writing RSA key

署名要求ファイル作成後、認証局の秘密鍵で署名を行いサーバ証明書を作成します。署名確認およびコミットの確認があるため、両方ともyを入力します。

・認証局をの秘密鍵で署名を行いサーバ証明書を作成
# openssl ca -days 3650 -keyfile /etc/pki/CA/private/ca.key -cert /etc/pki/CA/certs/ca.crt -in /etc/pki/tls/server.csr -out /etc/pki/tls/certs/server.crt 

Using configuration from /etc/pki/tls/openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 0 (0x0)
        Validity
            Not Before: May 17 11:34:42 2020 GMT
            Not After : May 15 11:34:42 2030 GMT
        Subject:
            countryName               = JP
            stateOrProvinceName       = Tokyo
            organizationName          = Example Co.
            organizationalUnitName    = Example Department
            commonName                = www.example.com
            emailAddress              = root@example.com
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Comment:
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier:
                FE:90:4A:D4:FD:47:79:14:A4:F0:CF:88:EF:53:43:F6:A3:4F:92:C0
            X509v3 Authority Key Identifier:
                keyid:87:14:9E:0E:25:DC:04:5C:17:DD:D8:60:7D:B0:86:47:68:F3:C6:24 

            X509v3 Subject Alternative Name:
                DNS:www.example.com, DNS:*.example.com
Certificate is to be certified until May 15 11:34:42 2030 GMT (3650 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.cnfの設定を間違えている場合、opensslコマンドでラーとなります。もしエラーが表示された場合は、コマンドのパスやopenssl.cnfの設定を再度確認しましょう。

サーバ証明書の作成後、Apacheの設定ファイルにSSLの設定を行います。

・Apacheの設定ファイルを編集する
# vi /usr/local/apache2/conf/httpd.conf

■httpd.conf
--------------------------------------------------
# HTTPSの443ポートを待ち受ける
Listen 443

# mod_sslを読み込む
#LoadModule ssl_module modules/mod_ssl.so
LoadModule ssl_module modules/mod_ssl.so

# VirtualHostにSSLの有効化、サーバの秘密鍵、証明書等を設定
<virtualhost *:443="">
    SSLEngine on
    SSLCertificateFile /etc/pki/tls/certs/server.crt
    SSLCertificateKeyFile /etc/pki/tls/private/server.key
    DocumentRoot "/usr/local/apache2/htdocs"
    ServerName www.example.com
</virtualhost>
--------------------------------------------------

Apacheの設定後、HTTPSを使用するため、firewallの443番ポートを開放する必要があります。今回はfirewallでhttpsサービスを許可します。

・firewallでhttpsを許可する
# firewall-cmd --add-service=https --zone=public --permanent
# firewall-cmd --reload

firewall設定後、Apacheを再起動します。

・Apacheを再起動する
# systemctl restart httpd

Apache再起動後、Google Chrome等のChromium系ブラウザで自己署名証明書を有効とするため、認証局の証明書(今回はca.crt)をSCP等のツールでサーバからダウンロードします。

認証局の証明書をダウンロード後、Google Chromeを起動し証明書をインポートします。手順につきましては、以下のリンクを参考にしてください。

・Google Chromeへ証明書ファイルをインポートするには

https://jp.globalsign.com/support/faq/558.html

「信頼された証明機関」にwww.example.comの証明書が表示されたらインポート完了です。

動作確認

ブラウザを開き、「https://www.example.com」と入力してURLの横に鍵のマークが表示されれば成功です。もしGoogle Chrome等のChromium系ブラウザで上手く行かない場合は、一度ブラウザを再起動しURLを入力してください。