レンタルサーバーだと管理画面でcertbot
を使って自動で組めたり、
AWS
、GCP
、Azure
などのクラウドサービスを利用するとGUIで操作するだけだったりしますが、
オンプレミスの場合はコマンドラインの操作が必要。
今どきオンプレミスの時代じゃないかもしれませんが、
勉強目的ということで初心者向けに記事です。
条件
- CentOS 7
- Apache2.4
- mod_ssl
- 予めSSL証明書、秘密鍵、中間証明書が取得できていること
注意すべきこと
SSL証明書と秘密鍵、CSRなどのチェックサムを利用して秘密鍵と証明書とCSRのセットの整合性が担保された状態で作業にあたることを推奨します。
これらが間違っている場合や証明書、鍵ファイル自体が間違ったものである場合、
httpd -t
などのシンタックスチェックでは引っかからず、
再起動などを行うとWebサーバーがエラー停止します。
当然ですが、httpdが停止するとホスティングされている全てのWebサイトに影響が出るため注意を払うべきです。
尚、本稿は前提として以下のいずれかの条件を満たしている必要があります。
-
sudo
を利用する場合そのユーザーがwheel
グループに入っている(Ubuntuの場合はsudo
グループ) -
sudo
にてhttpd
vim/vi
service
systemctl
などが利用可能 -
su
などでroot
ログイン可能
SSL化する方法
1つのサーバーでVirtualHost
などを利用して多数のWebサイトをホスティングしているケースについて書いています。
SSL証明書(.crt)、秘密鍵(.key)、中間証明書(.crt)の配置
仮にexample.comに対してSSLの化を行うとします。
証明書、鍵、中間証明書を所定のディレクトリに配置します。
まずsftp
, rsync
などでサーバー内に転送する(FileZilla等クライアントアプリでも可)。
$ rsync -avh [source_directory] user@host:[destination_directory]
ホスティングサイトのドキュメントルートに秘密鍵などをコピーするのはやめましょう。
ここでは~/ssl/example.com
とすると
$ mkdir -p ~/ssl/example.com
以下の通りになるようにファイルを配置
~/ssl/example.com/example.com.crt
~/ssl/example.com/example.com.key
~/ssl/example.com/cert-chain.crt
SSL鍵を置くべきディレクトリに
ローカルから転送してきたSSL証明書をコピー
(ここでは/etc/httpd/conf/ssl
に配置するものとします)
$ cp -r ~/ssl/example.com /etc/httpd/conf/ssl
このままだと所有者と所有グループがroot
以外になっているはずなので
$ chown -R root:root /etc/httpd/conf/ssl/example.com
で所有者:グループをroot
に変更。
権限が適切でない場合はこのタイミングで読み取り専用に変更。
$ chmod -R 744 /etc/httpd/conf/ssl/example.com
ここまでで下記のようなパスに配置されているはずです。
# ファイルを置くディレクトリ
/etc/httpd/conf/ssl/example.com/example.com.crt
/etc/httpd/conf/ssl/example.com/example.com.key
/etc/httpd/conf/ssl/example.com/cert-chain.crt
バーチャルホストのconf編集
SSL未導入で新規にSSL化する場合はVirtualHostで80番ポートのみListenされている状態だと思います。
例えば以下のようになっているはずです。
<VirtualHost *:80>
ServerName www.example.com
ServerAlias example.com
ServerAdmin info@example.com
ErrorLog /var/www/vhosts/example.com/logs/error_log
CustomLog /var/www/vhosts/example.com/logs/access_log combined
DirectoryIndex index.html index.php
AddDefaultCharset UTF-8
DocumentRoot /var/www/vhosts/example.com/httpdocs
<Directory "/var/www/vhosts/example.com/httpdocs">
Options -Indexes +FollowSymLinks
AllowOverride ALL
Require all granted
</Directory>
</VirtualHost>
#ここに443番のポートをListenする設定とSSLの情報を追加
この状態で以下を追加
(設定内容については割愛)
<VirtualHost *:443>
ServerName example.com
ServerAlias www.example.com
ServerAdmin info@example.com
ErrorLog /var/www/vhosts/example.com/logs/error_ssl_access_logs
CustomLog /var/www/vhosts/example.com/logs/access_ssl_log combined
DocumentRoot /var/www/vhosts/example.com/httpdocs
<Directory /var/www/vhosts/example.com/httpdocs>
Options -Indexes +FollowSymLinks
AllowOverride ALL
Require all granted
</Directory>
SSLEngine on
SSLProtocol All -SSLv2 -SSLv3 -TLSv1
SSLHonorCipherOrder ON
SSLCipherSuite EECDH+HIGH:EDH+HIGH:HIGH:MEDIUM:+3DES:!ADH:!RC4:!MD5:!aNULL:!eNULL:!SSLv2:!LOW:!EXP:!PSK:!SRP:!DSS:!KRB5
SSLCertificateFile /etc/httpd/conf/ssl/example.com/example.com.crt
SSLCertificateKeyFile /etc/httpd/conf/ssl/example.com/example.com.key
SSLCertificateChainFile /etc/httpd/conf/ssl/example.com/cert-chain.crt
</VirtualHost>
できたファイルは以下のようになります。
<VirtualHost *:80>
ServerName www.example.com
ServerAlias example.com
ServerAdmin info@example.com
ErrorLog /var/www/vhosts/example.com/logs/error_log
CustomLog /var/www/vhosts/example.com/logs/access_log combined
DirectoryIndex index.html index.php
AddDefaultCharset UTF-8
DocumentRoot /var/www/vhosts/example.com/httpdocs
<Directory "/var/www/vhosts/example.com/httpdocs">
AllowOverride ALL
Require all granted
</Directory>
</VirtualHost>
<VirtualHost *:443>
ServerName example.com
ServerAlias www.example.com
ServerAdmin info@example.com
ErrorLog /var/www/vhosts/example.com/logs/error_ssl_access_logs
CustomLog /var/www/vhosts/example.com/logs/access_ssl_log combined
DocumentRoot /var/www/vhosts/example.com/httpdocs
<Directory /var/www/vhosts/example.com/httpdocs>
Options -Indexes +FollowSymLinks
AllowOverride ALL
Order allow,deny
Allow from all
</Directory>
SSLEngine on
SSLProtocol All -SSLv2 -SSLv3 -TLSv1
SSLHonorCipherOrder ON
SSLCipherSuite EECDH+HIGH:EDH+HIGH:HIGH:MEDIUM:+3DES:!ADH:!RC4:!MD5:!aNULL:!eNULL:!SSLv2:!LOW:!EXP:!PSK:!SRP:!DSS:!KRB5
SSLCertificateFile /etc/httpd/conf/ssl/example.com/example.com.crt
SSLCertificateKeyFile /etc/httpd/conf/ssl/example.com/example.com.key
SSLCertificateChainFile /etc/httpd/conf/ssl/example.com/cert-chain.crt
</VirtualHost>
シンタックスチェック
$ httpd -t
Syntax OK
となれば設定ファイルの文法ミスは無い。
SSL証明書ファイル、鍵ファイルなどが間違っている場合でも文法がOKであればOKと出ます。
鍵ファイルと証明書ファイルのチェックサムを強く推奨。
これまでの動作にミスが無いことを祈りながら
以下のコマンドでApacheを再起動
$ systemctl restart httpd
.htaccessを使ってリダイレクト
SSL未導入の場合はhttp://からhttps://
へのリダイレクトは適用されていないはずなので追加
RewriteEngine on
# httpをhttpsにリダイレクト
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
お好みで
# www無しをwwwありにリダイレクト
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/ [R=301,L]
その後ブラウザで確認する。
証明書適用を確認
$ openssl s_client -connect example.com:443
などで確認する。
まとめ
今どきオンプレミス構築なんていうものは流行らないかもしれませんが
そういう構成でずっとやってきているところも結構あると思うし、何よりクラウドサービス内部で何が行われてるを理解する点で勉強目的にはちょうど良いように思います。
Let's Encryptのcertbot
を使うと全て自動でいい感じにやってくれるので、
証明書をわざわざ課金して取得するのはあまり無いかもしれません(企業認証型SSLなどは別ですが)。