事始め

会社ではL7プロキシの運用・開発をしている。 複数のEP(ドメイン)を持っている。 複数のドメインをひとつのL7プロキシ(単一のIP)でさばいている。 さて、これはいったいどの様に実現しているのか?というのが今回の議題。 IPアドレスはDNSによって単一のドメインと紐づけられる。と自分は認識していたが、これが誤りだった。 そして、自分は、会社に入るまでホストヘッダーという概念を全く分かっていなかった。 HTTPにはホストヘッダーというものがあり、これによって単一IP上に複数のドメインを保持することができるようになる。 そして、ポイントはやはり、HTTPはL7レイヤーであり、IPはL3レイヤーであるというところに落ち着くと思う。

前提

DNSでのIPアドレスとドメインの紐づけは一対一ではなく、一対多であった。ここがすごく大事なところでした。 そして、自分はホストヘッダーについて理解していなかった。

nginxを使ってバーチャルサーバを立てる

chatgptから

単一の物理サーバー上で複数のウェブサイトやアプリケーションをホストするために使用される機能です。それぞれのバーチャルサーバーは、異なるドメイン名やサブドメインに対応して、個別に設定されたリソース(例えばウェブページやアプリケーションのファイル、SSL証明書、ログファイルなど)にアクセスを提供します。 Nginxでは、これらのバーチャルサーバーを「サーバーブロック」として設定ファイルに記述します。以下は、Nginxでのバーチャルサーバー設定の基本的な例です:

server {
    listen 80;
    server_name example.com www.example.com;

    location / {
        root /var/www/example.com/html;
        index index.html index.htm;
    }

    error_page 404 /404.html;
    location = /404.html {
        root /var/www/example.com/html;
    }

    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /var/www/example.com/html;
    }
}

ホストヘッダーの役割

chatgptより

HTTPのホストヘッダーは、HTTPリクエストを送信する際に非常に重要な役割を果たします。このヘッダーは、クライアントがリクエストを送信する際に、どのホスト(ドメイン名またはIPアドレス)とポートに対してリクエストが意図されているかを指定するために使用されます。特に、一つのサーバーが複数のドメインをホスティングしている場合(仮想ホスティング)、ホストヘッダーがないとサーバーはリクエストがどのウェブサイトに対してなのか判断できません。 HTTP/1.1ではホストヘッダーは必須とされています。これは、HTTP/1.0と異なり、サーバーが複数のドメインをホストしている状況が一般的になったためです。リクエストにホストヘッダーが含まれていない場合、サーバーは400 Bad Requestのエラーを返すことが多いです。

DNSのAレコード

複数のサブドメインが同じサーバーのリソースを指す場合、それら全てに同じIPアドレスを割り当てることが一般的です。

例えば、次のように設定することができます:

www.example.com → 192.0.2.1 mail.example.com → 192.0.2.1 ftp.example.com → 192.0.2.1 これらのサブドメイン全てに同じAレコードのIPアドレス(192.0.2.1)を指定することで、一つのサーバーが異なるサービス(ウェブ、メール、FTPなど)を提供することができます。これは特に、ホスティングサービスが複数のウェブサイトを単一の物理サーバーで管理する場合などに便利です。また、メンテナンスやアップグレードが必要な場合にも、一箇所で変更を行うだけで済むため効率的です。

実際に、複数のサブドメインのAレコードに単一のIPを指定して、バーチャルホストで複数サービスを運用する方法

自分が使っているサービスで説明します。

  1. ムームードメインでAレコードでipとドメインの紐づけをマッピングする
  2. nginxでバーチャルホストを立てる
  3. (ssl通信したいのであれば) lets encryptでssl/TLS証明書を発行する。

以上。マジでこれだけです。これで複数のドメインを単一のnginxサーバ上で運用することができます。

さらなるステップアップ

自分が今考えている最強のシナリオが、フロントエンドプロキシだけをインターネット上でレンタルし、オリジンは自分で管理するというもの。 これができるようになるとサーバ代金がかなり節約できると思っている。 で、オリジンがポート解放できないルータだとすると、これは結構面倒くさいですがフロントエンドプロキシ内にVPNサーバを立てて、フロントエンドプロキシとローカルネットワーク内のVPNクライアントをつなぐ必要がある(site2site routing)。これに関しては別の記事があるのでそちらを参照してくれ。とにかく、今回の収穫は、一つのフロントエンドプロキシを持っておけば、いろいろなサービス(ドメイン)を展開できるというものだった。最高だ。

さらなるさらなるステップアップ

正直、nginxの性能は限界が来ている。master process - worker process というソフトウェアのアーキテクチャ事態に限界があるといわれている。素晴らしいソフトであることには間違いない。が、限界が来ている、ということである。 そこで、L7プロキシを自作したいよね、というはなし。Pingoraを使って。まあ、これはまたいつかの機会に。