Nginx でサブドメインによるアクセスをサブ・ディレクトリに転送させたい。
つまり、Nginx で http://xxx.sample.com/
を https://sample.com/xxx/
に転送させたるために "xxx
" の部分、ドメインの一部(サブドメイン部分)を変数に入れたいのです。
🐒 2018/08/06 追記:2018/03/02 に Let's Encrypt がワイルドカード(*
の使用)に対応しました。本記事の「サブドメインのアクセスを別ドメインのディレクトリ下に転送する」のではなく、ワイルドに SSL を使いたい場合は、他の Qiita 記事を参照ください。
TL; DR (今北産業)
-
正規表現でサブドメインを変数にキャプチャして使いまわす。
$subhostにサブドメインをキャプチャする例server_name ~^(?<subhost>.+)\.sample\.com$;
-
Nginx の
http
アクセスをhttps
に変更しながらサブディレクトリに転送http://xxx.sample.com/
→https://sample.com/xxx/
/etc/nginx/conf.d/_http.conf## default HTTP server { listen 80; server_name ~^(?<subhost>.+)\.sample\.com$; return 301 https://sample.com/$subhost$request_uri; }
-
Nginx の
https
アクセスでサブディレクトリに転送https://xxx.sample.com/
→https://sample.com/xxx/
/etc/nginx/conf.d/_ssl.conf## default SSL server { listen 443 ssl; server_name ~^(?<subhost>.+)\.sample\.com$; return 301 https://sample.com/$subhost$request_uri; }
TS; DR (nginx
のドメイン変数とコマケーこと)
「*.sample.com」のサブドメインをディレクトリ下に転送する
NS の DNS 設定で CNAME 設定を以下のように設定すると全てを1つのサーバーに向けることができます。
-
* CNAME @
,@ A xxx.xxx.xxx.xxx
つまり「kyoto.sample.com
, yokohama.sample.com
, ...
, ?????.sample.com
」は同じサーバーで処理できます。サブドメインの Catch All
的な設定です。
今まで、PHP 側で URL を解析して分岐処理をしていたのですが、全てのサブ・ドメインで Let'sEnctypt を使って SSL 対応することにしました。しかし、不特定多数のサブドメインごとに SSL 認証を取得するのが面倒大変になったため、以下のように転送させることにしました。
http://yokohama.sample.com/?hoge=huga
→ https://sample.com/yokohama/?hoge=huga
Nginx の設定ファイル(conf ファイル)で使える環境変数に $host
があるのですが、これを使うと以下のよう転送されてしまいます。
悪い設定
## default HTTP
server {
listen 80;
server_name default_server;
return 301 https://example.com/$host$request_uri;
}
悪い転送結果
http://hoge.sample.com/
→ https://sample.com/hoge.sample.com/
当然と言えば当然なのですが、ホスト情報全体が渡されてしまうので、サブドメインだけが欲しいんです。
正しい転送方法
StackOverflow に聞いたところ、「正規表現使えばよくね?」って事でした。Oh...。
## default SSL
server {
listen 443 ssl;
server_name ~^(?<subhost>.+)\.sample\.com$;
return 301 https://sample.com/$subhost$request_uri;
}
そこは Apache と同じ概念なのね。Nginx 慣れていないので基本的な事を忘れてました。
「読んだのに、読んだつもりで、読んでない 英語の公式ドキュメント」ですな。Nginx って Apache と比べて意外に日本語訳って整っていないのね。
参考文献
- Nginx variable for subdomain? @ Stack Overflow
https://stackoverflow.com/questions/45318758/nginx-variable-for-subdomain - Server names | Regular expressions names @ Nginx.org
http://nginx.org/en/docs/http/server_names.html#regex_names