ApacheをSSL/TLSサーバ(HTTPSサーバ)として設定する方法を説明します。
SSL/TLSの機能を使用することで、なりすましや改竄の検知、通信の暗号化が行えるようになります。

前提条件

  • 作業は、root権限を持つユーザで実施します。
  • OSおよびApacheは、以下のバージョンで検証しています。
# cat /etc/redhat-release 
CentOS Linux release 8.2.2004 (Core) 
# uname -r
4.18.0-193.el8.x86_64
# httpd -v
Server version: Apache/2.4.37 (centos)
Server built:   Sep 15 2020 15:41:16

パッケージインストール

ApacheをSSL/TLSサーバとして動作させるためのモジュールであるmod_sslをインストールします。

# dnf install -y mod_ssl
(略)
完了しました!

サーバ証明書の作成

SSL/TSLサーバ機能を使用するためには、サーバ証明書が必要です。

秘密鍵の作成

2048bitのSRA秘密鍵を作成します。
-outで指定している秘密鍵のファイル名は、<FQDN>.keyにすると分かりやすいです。

# openssl genrsa -out www.example.com.key 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
(略)

CSRの作成

前述の秘密鍵から作成される公開鍵、および公開鍵のハッシュ値を組み合わせて、CSR(証明書署名要求)を作成します。
-keyには、前述の工程で作成した秘密鍵のファイルを指定します。
-outで指定しているCSRのファイル名は、<FQDN>.csrにすると分かりやすいです。

1行目のコマンドを実行した後は、ディスティングイッシュネーム情報の入力が促されるので、以下表の通り入力します。

項目名 入力値
Country Name JP
State or Province Name 都道府県
Locality Name 市区町村
Organization Name 組織名
Organizational Unit Name 部署名
Common Name 外部から名前解決可能なFQDN
Email Address 空欄
A challenge password 空欄
An optional company name 空欄
# openssl req -new -key www.example.com.key -out www.example.com.csr
(略)
Country Name (2 letter code) [XX]:JP
State or Province Name (full name) []:Tokyo
Locality Name (eg, city) [Default City]:Chuo-ku
Organization Name (eg, company) [Default Company Ltd]:Example Corp
Organizational Unit Name (eg, section) []:Information Systems Department
Common Name (eg, your name or your server's hostname) []:www.example.com
Email Address []:

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

パブリック認証局からサーバ証明書を購入する場合、作成したCSRを認証局へ送付し、サーバ証明書を発行してもらいます。

サーバ証明書の作成(自己証明書の場合のみ実施)

本作業は、自己証明書(通称オレオレ証明書)を作成する場合のみ実施します。パブリック認証局からサーバ証明書を購入する場合は飛ばしてください。

秘密鍵とCSRを使用して、サーバ証明書を作成します。本来ならばCA(認証局)が行う作業ですが、自己証明書の場合は自分で作業を行います。以下の例では、有効期限を3650日(10年)にしています。

# openssl x509 \
 -days 3650 \
 -req -signkey www.example.com.key \
 -in www.example.com.csr \
 -out www.example.com.crt

Signature ok
subject=C = JP, ST = Tokyo, L = Chuo-ku, O = Example Corp, OU = Information Systems Department, CN = www.example.com
Getting Private key

作成した証明書は、以下のコマンドで内容をテキスト出力できます。

# openssl x509 -noout -text -in www.example.com.crt

(略)
        Validity
            Not Before: Dec 15 15:02:42 2020 GMT
            Not After : Dec 13 15:02:42 2030 GMT
        Subject: C = JP, ST = Tokyo, L = Chuo-ku, O = Example Corp, OU = Systems Department, CN = www.example.com
(略)

作成したファイルの配置

秘密鍵とサーバ証明書のファイルを、それぞれ以下のディレクトリに移動します

# mv www.example.com.key /etc/pki/tls/private/
# mv www.example.com.crt /etc/pki/tls/certs/

なお、SELinuxが有効である場合、別のディレクトリで作成した証明書ファイルを配置すると不適切なラベルが付与され、Apacheが秘密鍵と証明書のファイルを読み込めなくなります。
その場合は、restoreconコマンドで正しいラベルを付与し直す必要があります。

# ls -Z /etc/pki/tls/private/www.example.com.key 
unconfined_u:object_r:user_home_t:s0 /etc/pki/tls/private/www.example.com.key
# restorecon /etc/pki/tls/private/www.example.com.key
# ls -Z /etc/pki/tls/private/www.example.com.key
unconfined_u:object_r:cert_t:s0 /etc/pki/tls/private/www.example.com.key

# ls -Z /etc/pki/tls/certs/www.example.com.crt 
unconfined_u:object_r:user_home_t:s0 /etc/pki/tls/certs/www.example.com.crt
# restorecon /etc/pki/tls/certs/www.example.com.crt 
# ls -Z /etc/pki/tls/certs/www.example.com.crt 
unconfined_u:object_r:cert_t:s0 /etc/pki/tls/certs/www.example.com.crt

Apache設定ファイル(ssl.conf)の編集

mod_sslをインストールすることで、SSL/TLS設定用のファイルが作成されます。
viなどのテキストエディタで、以下のファイルを開きます。

# vi /etc/httpd/conf.d/ssl.conf

ドキュメントルート、ホスト名の設定

mod_sslインストール直後のデフォルト設定では、バーチャルホストが使用されています。
Apacheの基本設定(/etc/httpd/conf/httpd.conf)で指定しているドキュメントルート(DocumentRoot)、およびホスト名(ServerName)と異なるパラメータを使用する場合は、以下のコメントアウト行をそれぞれ編集します。

複数のWebサイトをホスティングする場合は、NameVirtualHost *:443で名前ベースのバーチャルホストを有効化し、Webサイトの数だけ<VirtualHost>ディレクティブを作成します。
1つのWebサイトのみホスティングする場合は、NameVirtualHost *:443は不要です。

NameVirtualHost *:443

<VirtualHost *:443>

# General setup for the virtual host, inherited from global configuration
#DocumentRoot "/var/www/html"
#ServerName www.example.com:443
(略)
</VirtualHost>

暗号化プロトコルの設定

2020年12月現在、SSLおよびTLS1.0, TLS1.1は非推奨となっています。TLS1.2, TLS1.3のみ有効とします。

#SSLProtocol all -SSLv3
↓
SSLProtocol TLSv1.2 +TLSv1.3

参考:
TLS暗号設定ガイドライン~安全なウェブサイトのために(暗号設定対策編)~

サーバ証明書配置先の設定

サーバ証明書のパスを指定します。

SSLCertificateFile /etc/pki/tls/certs/localhost.crt
↓
SSLCertificateFile /etc/pki/tls/certs/www.example.com.crt

サーバ証明書秘密鍵配置先の設定

サーバ証明書の作成に使用した秘密鍵のパスを指定します。

SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
↓
SSLCertificateKeyFile /etc/pki/tls/private/www.example.com.key

中間証明書配置先の設定

パブリック認証局からサーバ証明書を購入した場合、中間CA証明書が必要な場合があります。その場合は、/etc/pki/tls/certs/の配下に中間CA証明書を配置し、SSLCertificateChainFileでパスを指定します。ca-chain.crtは、認証局から提供されたファイルの名前に変更してください。

新たに中間CA証明書を追加しない場合は、本パラメータはコメントアウトされたままで構いません。

#SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt
↓
SSLCertificateChainFile /etc/pki/tls/certs/ca-chain.crt

ルート証明書配置先の設定

パブリック認証局からサーバ証明書を購入する場合、ルート証明書が必要な場合があります。その場合は、/etc/pki/tls/certs/の配下にルート証明書を配置し、SSLCACertificateFileでパスを指定します。root.crtは、認証局から提供されたファイルの名前に変更してください。

新たにルート証明書を追加しない場合は、本パラメータはコメントアウトされたままで構いません。

#SSLCACertificateFile /etc/pki/tls/certs/ca-bundle.crt
↓
SSLCACertificateFile /etc/pki/tls/certs/root.crt

ログ出力設定

エラーログ、アクセスログの出力先、出力対象のログレベルを指定します。
ログ出力先のlogsディレクトリは、/var/log/httpdに対するシンボリックリンクとなります。

アクセスログは後述のカスタム書式を使用するので、TransferLogから始まる行をコメントアウトします。

ErrorLog logs/ssl_error_log
# TransferLog logs/ssl_access_log
LogLevel warn

デフォルト設定のCustomLogは、簡易な出力内容となっているため、コメントアウトします。
アクセスログの出力設定として、/logs/ssl_access_logを出力先としたCustomLogを新たに設定します。
conf/httpd.confにデフォルトで用意されているcombinedログフォーマットを参考に、ログフォーマットを指定します。HTTP通信向けのcombinedログフォーマットに加え、以下の情報を追加します。

  • %{SSL_PROTOCOL}x (暗号化プロトコル)
  • %{SSL_CIPHER}x (暗号スイート)
  • %D (リクエスト処理時間(マイクロ秒))
# CustomLog logs/ssl_request_log \
#           "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"

CustomLog logs/ssl_access_log \
          "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{SSL_PROTOCOL}x\" \"%{SSL_CIPHER}x\" %D"

常時SSL/TLS化設定

HSTS(HTTP Strict Transport Security)を有効化することで、次回アクセスからHTTPSで通信を行うようクライアントのWebブラウザに指示を出すことができます。

ファイルの末尾に、Headerディレクティブを追記して、HTTPレスポンスヘッダにStrict-Transport-Securityを付与します。
以下の例では、1年間の有効期間(max-age=31536000)と、サブドメインにも適用する(includeSubDomains)パラメータを指定しています。

併せて、TCP/80用のバーチャルホスト(<VirtualHost *:80>)を追加し、HTTPで接続された通信を常時HTTPSにリダイレクトするようにします。

Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"

<VirtualHost *:80>
ServerAlias *
RewriteEngine On
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [redirect=301]
</VirtualHost>

設定の反映

設定ファイルの文法に問題がないか確認します。
文法が正しければ、Syntax OKが表示されます。

# apachectl configtest
Syntax OK

httpdサービスを再起動して設定を反映します。

# systemctl restart httpd.service

httpdサービスが起動状態であることを確認します。
Active:の列にactive (running)が表示されていれば、サービスは起動中です。

# systemctl status --no-pager httpd.service
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
   Active: active (running) since Wed 2020-12-16 22:13:41 JST; 1min 36s ago
(略)

動作確認

opensslコマンドで、SSL/TLS通信の動作確認を行います。
確認対象サーバのFQDNを名前解決できる状態で接続を行います。以下の例では、サーバのFQDNはwww.example.comとしています。

# openssl s_client -connect www.example.com:443 < /dev/null
(略)
Server certificate
-----BEGIN CERTIFICATE-----
(略)
-----END CERTIFICATE-----
subject=C = JP, ST = Tokyo, L = Chuo-ku, O = Example Corp, OU = Systems Department, CN = www.example.com
(略)
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 2048 bit
(略)
DONE

以下、問題ないことを確認します。

  • Server certificatesubjectにサーバ証明書の情報が表示されていること
  • 暗号化プロトコルと暗号スイートが表示されること(実行例ではそれぞれTLSv1.3, TLS_AES_256_GCM_SHA384)
  • 秘密鍵のビット数が表示されること(実行例では2048bit)

参考情報

インストールパッケージの一覧

mod_sslのインストールに必要なパッケージは以下の通りです。
オフライン環境のサーバにインストールを行う場合は、パッケージリポジトリから該当ファイルを取得して、作業対象のサーバに転送してください。

# dnf install mod_ssl
(略)
===================================================================================================
 パッケージ    Arch         バージョン                                       リポジトリー    サイズ
===================================================================================================
インストール中:
 mod_ssl       x86_64       1:2.4.37-21.module_el8.2.0+494+1df74eae          AppStream       132 k
依存関係のインストール中:
 sscg          x86_64       2.3.3-14.el8                                     AppStream        49 k

トランザクションの概要
===================================================================================================
インストール  2 パッケージ

ダウンロードサイズの合計: 181 k
インストール済みのサイズ: 360 k
(略)

参考文献

2.3.1. Apache HTTP サーバー の設定
TLS暗号設定ガイドライン~安全なウェブサイトのために(暗号設定対策編)~