0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

オンプレミスのサーバーでバーチャルホストしながらSSL対応する

Posted at

レンタルサーバーだと管理画面でcertbotを使って自動で組めたり、
AWSGCPAzureなどのクラウドサービスを利用すると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などは別ですが)。

0
0
0

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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?