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?

nginx のバーチャルホストとポート番号 ~server_name にポート番号はつけるな~

Posted at

今回の検証環境

  • Amazon EC2 t2.micro
  • Ubuntu Server 24.04 LTS (HVM), SSD Volume Type (ami-075686beab831bb7f)
  • nginx/1.24.0 (Ubuntu)

server_name にポート番号をつけると効かない

server_name を用いると、バーチャルサーバーの名前を指定し、リクエストの処理方法を Host ヘッダーの内容に応じて変えることができる。

Host ヘッダーの内容には、ポート番号が含まれる場合がある。(example.com:8080 など)
なので、server_name もポート番号を含めて指定したほうが良さそうに思える。
早速やってみよう。

server {
	listen 8080;
	server_name 127.0.0.1:8080;
	return 200 "using ip address\n";
}

server {
	listen 8080;
	server_name localhost:8080;
	return 200 "using host name\n";
}

curl を用いてリクエストを送ってみる。

YUKI.N> curl -v http://127.0.0.1:8080/
*   Trying 127.0.0.1:8080...
* Connected to 127.0.0.1 (127.0.0.1) port 8080
> GET / HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/8.5.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.24.0 (Ubuntu)
< Date: Sat, 26 Apr 2025 23:53:02 GMT
< Content-Type: application/octet-stream
< Content-Length: 17
< Connection: keep-alive
<
using ip address
* Connection #0 to host 127.0.0.1 left intact
YUKI.N> curl -v http://localhost:8080/
* Host localhost:8080 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
*   Trying [::1]:8080...
* connect to ::1 port 8080 from ::1 port 50870 failed: Connection refused
*   Trying 127.0.0.1:8080...
* Connected to localhost (127.0.0.1) port 8080
> GET / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/8.5.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.24.0 (Ubuntu)
< Date: Sat, 26 Apr 2025 23:53:16 GMT
< Content-Type: application/octet-stream
< Content-Length: 17
< Connection: keep-alive
<
using ip address
* Connection #0 to host localhost left intact

http://127.0.0.1:8080/ にアクセスした場合も http://localhost:8080/ にアクセスした場合も、両方とも http://127.0.0.1:8080/ 用のメッセージ using ip address が出力されており、server_name の指定が意図通りに反映されていないことがわかる。

server_name にポート番号をつけないと効く

server_name にポート番号込みのホストを指定してもなぜか上手く反映されないようなので、server_name からポート番号を外してみる。

server {
	listen 8080;
	server_name 127.0.0.1;
	return 200 "using ip address\n";
}

server {
	listen 8080;
	server_name localhost;
	return 200 "using host name\n";
}

同様にリクエストを送ってみる。

YUKI.N> curl -v http://127.0.0.1:8080/
*   Trying 127.0.0.1:8080...
* Connected to 127.0.0.1 (127.0.0.1) port 8080
> GET / HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/8.5.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.24.0 (Ubuntu)
< Date: Sun, 27 Apr 2025 00:04:53 GMT
< Content-Type: application/octet-stream
< Content-Length: 17
< Connection: keep-alive
<
using ip address
* Connection #0 to host 127.0.0.1 left intact
YUKI.N> curl -v http://localhost:8080/
* Host localhost:8080 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
*   Trying [::1]:8080...
* connect to ::1 port 8080 from ::1 port 48512 failed: Connection refused
*   Trying 127.0.0.1:8080...
* Connected to localhost (127.0.0.1) port 8080
> GET / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/8.5.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.24.0 (Ubuntu)
< Date: Sun, 27 Apr 2025 00:04:55 GMT
< Content-Type: application/octet-stream
< Content-Length: 16
< Connection: keep-alive
<
using host name
* Connection #0 to host localhost left intact

http://127.0.0.1:8080/ にアクセスした際は using ip address が、http://localhost:8080/ にアクセスした際は using host name が出力され、server_name の指定が意図通りに反映されていることがわかる。

Host のポートではなく TCP のポートで判定される

まず、2種類のポートでアクセスを受け付け、それぞれ別のレスポンスを返すように設定する。

server {
	listen 8080;
	listen 11111;
	server_name "";
	return 200 "using default";
}

server {
	listen 8080;
	server_name 127.0.0.1;
	return 200 "using ip address on port 8080\n";
}

server {
	listen 8080;
	server_name localhost;
	return 200 "using host name on port 8080\n";
}

server {
	listen 11111;
	server_name 127.0.0.1;
	return 200 "using ip address on port 11111\n";
}

server {
	listen 11111;
	server_name localhost;
	return 200 "using host name on port 11111\n";
}

SSHの機能でポート転送を行い、nginx が TCP 接続を受信するのとは違うポートでリクエストを行えるようにする。

ローカルのポート11111をリモートのポート8080に、ローカルのポート22222をリモートのポート11111に転送する

実際にリクエストを行ってみる。

YUKI.N>curl -v http://127.0.0.1:11111/
*   Trying 127.0.0.1:11111...
* Connected to 127.0.0.1 (127.0.0.1) port 11111
* using HTTP/1.x
> GET / HTTP/1.1
> Host: 127.0.0.1:11111
> User-Agent: curl/8.11.1
> Accept: */*
>
* Request completely sent off
< HTTP/1.1 200 OK
< Server: nginx/1.24.0 (Ubuntu)
< Date: Sun, 27 Apr 2025 00:18:24 GMT
< Content-Type: application/octet-stream
< Content-Length: 30
< Connection: keep-alive
<
using ip address on port 8080
* Connection #0 to host 127.0.0.1 left intact
YUKI.N>curl -v http://127.0.0.1:22222/
*   Trying 127.0.0.1:22222...
* Connected to 127.0.0.1 (127.0.0.1) port 22222
* using HTTP/1.x
> GET / HTTP/1.1
> Host: 127.0.0.1:22222
> User-Agent: curl/8.11.1
> Accept: */*
>
* Request completely sent off
< HTTP/1.1 200 OK
< Server: nginx/1.24.0 (Ubuntu)
< Date: Sun, 27 Apr 2025 00:18:31 GMT
< Content-Type: application/octet-stream
< Content-Length: 31
< Connection: keep-alive
<
using ip address on port 11111
* Connection #0 to host 127.0.0.1 left intact

結果は、Host で指定したポート番号は無視され、実際に TCP 通信を行っているポート番号で判定されるようであった。

まとめ

nginx 1.24.0 のバーチャルホストでは

  • server_name としてポート番号込みのホストを指定すると、認識されない
  • Host ヘッダで指定したポート番号と実際の TCP 通信のポート番号が異なる場合は、TCP 通信のポート番号が用いられる

らしいことがわかった。

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?