今回の検証環境
- 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 接続を受信するのとは違うポートでリクエストを行えるようにする。
実際にリクエストを行ってみる。
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 通信のポート番号が用いられる
らしいことがわかった。