Nginx 中的 $host 是一个重要的内置变量,用于处理和管理 HTTP 请求中的主机名信息。以下是对 $host 变量的详细解释:
$host 的来源
Host头部:$host通常从客户端请求的Host头部中提取。这个头部是 HTTP/1.1 规范中必需的,用于指定请求目标的主机名和可选的端口号。- 默认回退:如果请求中没有
Host头部,Nginx 会使用请求匹配的服务器块中的server_name作为$host的值。如果也没有匹配的server_name,则使用请求的 IP 地址。 server_name 详解参考
使用场景
-
虚拟主机:
- Nginx 通过
$host来区分不同的虚拟主机。它可以用于根据请求的域名选择不同的服务器块。
server { listen 80; server_name example.com; location / { proxy_pass http://backend; proxy_set_header Host $host; } } - Nginx 通过
-
反向代理:
- 在反向代理配置中,
$host常用于将客户端请求的原始主机名传递给后端服务器。
location / { proxy_pass http://backend; proxy_set_header Host $host; } - 在反向代理配置中,
-
日志记录:
$host可以用于记录日志文件,帮助分析请求是针对哪个主机名的。
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$host"'; access_log /var/log/nginx/access.log main; -
重定向和重写:
- 在重定向和重写规则中,
$host可以用于动态构建 URL。
if ($host = 'old.example.com') { return 301 http://new.example.com$request_uri; } - 在重定向和重写规则中,
特性
- 大小写不敏感:根据 HTTP 规范,主机名是不区分大小写的,因此
$host的值也是大小写不敏感的。 - 默认值:如果
Host头部缺失,Nginx 会使用匹配的server_name或请求的 IP 作为默认值。 - 处理端口:
$host不包含端口号,即使Host头部中包含端口号,$host变量也只会提取主机名部分。
安全性
- 主机头攻击:由于
Host头部可以被客户端伪造,使用$host时需小心,特别是在生成重定向 URL 时。确保对$host进行适当的验证和清理,以防止主机头攻击。
通过正确使用 $host,你可以确保 Nginx 配置的灵活性和安全性,特别是在处理多域名和反向代理场景时。