nginx 如何禁止 IP 访问,只允许域名访问?
方法一:
# 限制IP访问,只允许域名访问, 方法一;
server {
listen 80 default_server;
server_name _;
location / {
return 403;
}
}
server {
listen 80;
server_name www.server_name1.com;
location / {
echo "通过域名访问, $host, $remote_addr";
}
}
# 本地 hosts 文件中配置映射关系
192.168.135.129 www.server_name1.com
192.168.135.129 www.server_name2.com
原理:
直接通过IP地址访问和通过域名访问,请求到达 nginx 时其实都是 IP 地址访问的(域名访问时会做域名解析成IP地址),不同的是直接通过IP地址访问时请求头中 HOST 字段是IP地址,而通过域名访问时请求头中 HOST 字段是域名。
直接通过IP地址访问时两个 server 块都能匹配上,但是第一个 server 块中 listen 指令使用了 default_server 参数,所以在两个都匹配的情况下,nginx 最终匹配了默认的。
通过域名访问时其实两个 server 块也都能匹配上,但是 nginx 根据它的匹配规则选择了 server_name 指令匹配的那个块,此时不会看 default_server 参数。
default_server 参数是在最终都可以匹配的情况下去选择这个默认的 server 块。
方法二:
# 限制IP访问,只允许域名访问, 方法二;
server {
listen 80;
server_name www.server_name1.com;
if ($host != 'www.server_name1.com') {
return 403;
}
location / {
echo "通过域名访问,方法二, $host, $remote_addr";
}
}
# 本地 hosts 文件中配置映射关系
192.168.135.129 www.server_name1.com
192.168.135.129 www.server_name2.com
原理:
直接通过IP地址访问和通过域名访问,请求到达 nginx 时其实都是 IP 地址访问的(域名访问时会做域名解析成IP地址),不同的是直接通过IP地址访问时请求头中 HOST 字段是IP地址,而通过域名访问时请求头中 HOST 字段是域名。
直接通过IP地址访问时匹配上 server 块了,由于有 $host != 'www.server_name1.com' 判断最终返回 403。
通过域名访问时匹配上 server 块了,因为访问域名是 http://www.server_name1.com,所以最终返回正常。