こんにちは!ごんです
今回は、ごんが使っているレンタルサーバのエックスサーバーでの独自ドメインとサブドメイン管理方法について紹介したいと思います。
エックスサーバーはroot権限がないレンタルサーバでありながら、とっても多機能でWordPressやEC-CUBEも数クリックで構築できたり、コンピュータに詳しい人はSSH接続を利用して直接サーバ上でコマンドを実行したり、とても自由度が高いレンタルサーバです。
費用も一番安いX10プランで月額1000円程度なので、長年(10年以上?)レンタルサーバを使ってきている人は一度体験してみる事をオススメします!
ごんもずっと企業向けに定評のある某大手レンタルサーバ(月額3000円ほど)を使用していたのですが、エックスサーバーの自由度の高さには驚き、見える世界が一変しました!
そんなエックスサーバーの機能の中で、ごんが気に入っているものの一つが、サブドメインを無制限に使用できる!というものです。
サブドメインとは?
サブドメインを知らない人のために、簡単に解説します。
レンタルサーバを借りてウェブサイトを公開する時に、通常自分で好きなドメイン(独自ドメイン)を取得してサイトを公開します。
ごんの場合は teg-dag.com が取得した独自ドメインになります。
たとえば、企業のコーポレートサイトの場合を考えると、 teg-dag.com という独自ドメインでコーポレートサイトを公開しているけど、それ以外にマーケティング情報を発信したいとか、企業ブログを公開したいとか、本家のサイト以外の関連サービスを運用したいという場合が多数あります。
そんな時に、エックスサーバーだと
マーケティング情報 = marketing.teg-dag.com
ブログ = blog.teg-dag.com
その他サービス情報 = service.teg-dag.com
みたいな感じで、取得した独自ドメイン配下に別ドメインを設定することができるんです。
サブドメインを使うと、別々のサイトを同じ teg-dag.com という企業(ブランド)であるということが分かる状態で公開することができます。
とっても便利ですよね!
独自ドメインディレクトリ内にサブドメインディレクトリが
そんな便利なサブドメイン運用ですが、エックスサーバーの場合一つだけ不満があります。
それは、サーバ内部の話ですが、独自ドメインのディレクトリ内にサブドメインのルートディレクトリができる事です!
それがどういう状態かと言うと、先ほど説明に使ったサブドメインを例にすると以下の図の状態です!
黄色は teg-dag.com のコンテンツで、グリーンはそれぞれのサブドメイン用のディレクトリとコンテンツになります。
この構造は、teg-dag.comのルートディレクトリに入れば、そこからサブドメインのデータにも自由にアクセスできるので、FTPなどを使ってサイトのデータを管理するときには効率的といえます。
ですが、企業サイトのように複数人、場合によっては外部の企業(外注)にアクセス権を設定したい場合には以下のような不都合が発生します。
- ルートディレクトリ(コーポレートサイト)から全てのサブドメインのデータが見えてしまうので、コーポレートサイト編集者にサブドメインのデータを見せたくない場合でも、制限が難しい
- 不要なディレクトリが多数見えてしまうことになり、コーポレートサイトの更新時に間違ってサブドメインのデータを破損してしまう危険性がある
- コーポレートサイトの開発用サブドメインを用意する場合に、公開ディレクトリより上の階層のファイルへの相対パスが開発環境と本番環境で変わってしまう。
- コーポレートサイト内で使用するディレクトリ名がサブドメイン名と重複しないように管理しなければならない。(今回の例だと、js.teg-dag.com というサブドメインは使用できない)
.htaccessの内部転送を使って振り分ける
この問題の解決をするために、Webサーバの内部転送という機能を利用したいと思います!
エックスサーバーはnginxですが、.htaccessが利用できるので独自ドメインのルートディレクトリにある.htaccessを編集します。
(サーバーパネル -> .htaccess編集 -> 目的のドメイン選択)
まずは.htaccessを編集する前に、独自ドメインで使用するコンテンツを入れるためのディレクトリを用意しましょう。
今回は、publicというディレクトリに独自ドメイン用コンテンツを移したいと思います。
以下の図のような状態です。
こうすることで、 ルートディレクトリ直下にはpublic、marketing、blog、serviceのディレクトリのみが並んでいる状態になって、とてもすっきりします!
そして、.htaccessを編集することで独自ドメイン(teg-dag.com)にアクセスすると、public_html/public/index.html が表示されるようにしていきます!
まずは.htaccessに以下の記述を追加します。
※.htaccessを編集する前に、必ず今の状態のバックアップを取っておきましょう!
RewriteEngine On RewriteCond %{REQUEST_URI} !(^/public/) RewriteCond %{HTTP_HOST} !(^marketing\.(.*)$) [NC] RewriteCond %{HTTP_HOST} !(^blog\.(.*)$) [NC] RewriteCond %{HTTP_HOST} !(^service\.(.*)$) [NC] RewriteRule ^(.*)$ public/$1 [QSA,L]
順番に解説します。
1行目
RewriteEngine On
内部転送させる場合のおまじないです。
すでに常時SSL化などで、.htaccess内に記述がある場合は不要です。
2行目
RewriteCond %{REQUEST_URI} !(^/public/)
これは、URLの最後にpublic/がある時は内部転送しないための除外ルールです。
これがないと、無限ループしてサーバエラーになります。
3、4、5行目
RewriteCond %{HTTP_HOST} !(^marketing\.(.*)$) [NC] RewriteCond %{HTTP_HOST} !(^blog\.(.*)$) [NC] RewriteCond %{HTTP_HOST} !(^service\.(.*)$) [NC]
URLのホスト名の冒頭にmarketing. blog. service. がついた時に内部転送をさせないための記述です。
使用するサブドメインの数だけ記述します。
最後の[NC]は大文字・小文字を区別しないという意味です。
6行目
RewriteRule ^(.*)$ public/$1 [QSA,L]
上記のいずれの条件にも当てはまらない場合は独自ドメインへのアクセスとみなして、作成したpublicディレクトリへ転送します。
これで、サブドメイン以外へのアクセスが全てpublicディレクトリに転送されるので、独自ドメインのコンテンツをサブドメインのディレクトリと同階層で管理することができるようになります!
Let’s Encryptで証明書の更新ができるようにする
今やウェブサイトはSSLで暗号化して公開するのが常識となっています。
https〜で始まるURLですね。
ごんのサイトもhttpsで閲覧していただくように設定しています。
エックスサーバーでは無料SSLとしてLet’s EncryptのSSL証明書を使用できるようになっていて、誰でも簡単にウェブサイトのSSL対応が可能になっています。
実は前述の.htaccess編集を行うと、そのままの状態ではLet’s EncryptのSSL証明書の設定と更新ができなくなってしまいます。
それでは使い物にならない!ということで、.htaccessの内部転送除外ルールに以下の1行を追加したいと思います。
RewriteCond %{REQUEST_URI} !(^/.well-known/acme-challenge/)
これは、URLの最後に /.well-known/acme-challenge/ があった場合に内部転送しないというルールです。
Let’s EncryptはSSL証明書の作成・更新を行う時に対象のドメイン直下に .well-known/acme-challenge というディレクトリを作って、その中に作った認証用ファイルにアクセスできるかどうか?の確認をしています。
そして、エックスサーバーで使用する独自ドメインではpublic_html直下に .well-known/acme-challenge ディレクトリが作成されます。
これは、root権限がないレンタルサーバでは設定変更が不可能なんです。
ですので、その回避策として .well-known/acme-challenge へのアクセスがあった場合は、従来のルートディレクトリにそのままアクセスという方法をとっています。
出来上がった.htaccessは以下のようになります。
RewriteEngine On RewriteCond %{REQUEST_URI} !(^/public/) RewriteCond %{REQUEST_URI} !(^/.well-known/acme-challenge/) RewriteCond %{HTTP_HOST} !(^marketing\.(.*)$) [NC] RewriteCond %{HTTP_HOST} !(^blog\.(.*)$) [NC] RewriteCond %{HTTP_HOST} !(^service\.(.*)$) [NC] RewriteRule ^(.*)$ public/$1 [QSA,L]