在使用 Nginx 作为反向代理或 Web 服务器时,通常会配置多个 server
块来监听同一个端口(例如 443),并根据 server_name
区分不同的服务。例如:
1 | server { |
在这种情况下,Nginx 会根据请求的 Host
头将流量路由到对应的 server
块。然而,如果直接通过 IP:443
访问(例如 https://<IP>:443
),Nginx 无法通过 server_name
区分请求,因此默认会使用第一个匹配的 server
块。
本文将探讨如何通过 IP:443
访问 Nginx 中的多个服务,并确保请求能够正确路由到对应的 URI。
问题分析
当通过 IP:443
访问时,Nginx 无法获取 Host
头信息(因为请求中没有域名),因此无法根据 server_name
区分请求。此时,Nginx 会使用默认的 server
块(通常是配置文件中第一个定义的 server
块)。
为了确保通过 IP:443
访问时能够正确路由到不同的服务,我们需要采取以下方法之一:
方法 1:为 IP 访问添加默认的 server
块
在 Nginx 配置中添加一个默认的 server
块,专门处理通过 IP 访问的请求,并根据 URI 路径路由到不同的后端服务。
示例配置:
1 | # 默认处理 IP 访问的 server 块 |
说明:
- 第一个
server
块使用server_name _;
捕获所有未匹配的请求(包括通过 IP 访问的请求)。 - 通过
location
块根据 URI 路径(如/mall/
或/api/
)将请求路由到不同的后端服务。
客户端访问示例:
1 | curl https://<IP>:443/mall/ |
方法 2:使用 Host
头手动指定域名
如果无法修改 Nginx 配置,可以通过在客户端请求中手动指定 Host
头来模拟域名访问。
示例:
1 | curl -H "Host: mall.example.com" https://<IP>:443 |
说明:
- 客户端在请求中手动添加
Host
头,Nginx 会根据Host
头的值选择对应的server
块。 - 即使通过 IP 访问,也能正确路由请求。
方法 3:修改本地 Hosts 文件
通过修改客户端的 hosts
文件,将域名解析到服务器的 IP 地址。这样,客户端可以通过域名访问,而 Nginx 会根据 server_name
正确路由请求。
步骤:
- 打开客户端的
hosts
文件:- Windows:
C:\Windows\System32\drivers\etc\hosts
- Linux/Mac:
/etc/hosts
- Windows:
- 添加以下内容:
1
2<IP> mall.example.com
<IP> api.example.com - 保存文件并刷新 DNS 缓存:
- Windows: 运行
ipconfig /flushdns
。 - Linux/Mac: 运行
sudo systemd-resolve --flush-caches
或sudo dscacheutil -flushcache
。
- Windows: 运行
- 现在可以通过域名访问:
1
2curl https://mall.example.com
curl https://api.example.com
方法 4:使用 curl
的 --resolve
参数
如果不想修改 hosts
文件,可以使用 curl
的 --resolve
参数手动指定域名解析的 IP 地址。
示例:
1 | curl --resolve mall.example.com:443:<IP> https://mall.example.com |
说明:
--resolve
参数会强制将域名解析为指定的 IP 地址。- Nginx 会根据
Host
头正确路由请求。