Nginx禁止其他域名访问
今天看到一则来自@kyaky的评论
让我也意识到了这个问题:
如果别人把我的IP地址绑到他的域名上, 那我就是在为别人搭博客了. 我本以为Nginx配置中的server_name
选项可以进行阻挡, 看来不实践真的是不能轻易下结论.
今天就回顾一下这个问题的所在, 及解决方案.
DNS解析场景是这样:
域名 类型 IP
A.com A a.b.c.d
B.com A a.b.c.d
现在我的网站配置的默认服务是A.com.conf
:
server {
listen 80 default;
server_name A.com;
}
当初我为了避免直接拿IP访问站点, 做了IP的过滤:
if ( $host ~* "\d+\.\d+\.\d+\.\d+" ) {
return 403;
}
在这种情况下, 访问A.com
会找到a.b.c.d
这个IP, Nginx解析得知匹配到了A.com.conf
, 于是进入document root目录进行服务.
当访问B.com
时, DNS也会找到a.b.c.d
这个IP, Nginx解析得知没有匹配, 于是也会进入A.com.conf
的document root, 继续提供服务 – 因为是default
.
当时忽略了域名绑定IP的问题, 那么我再加一条if{}
判断, 不符合archean.me
的都返回403, 即可解决这个问题了.
但这样做显然不够优雅, 不仅陡然增加了Nginx配置文件的复杂度, 同时如果有多个域名绑定这台机器, 需要修改的地方就太多了.
所以查阅Nginx官方资料, 果然有相应的解决办法
原来我没有做默认服务default.conf
的配置, A Default "Catch All" Server Block
server {
listen 80 default_server;
server_name _; # This is just an invalid value which will never trigger on a real hostname.
return 403;
}
关键在于server_name _;
, 这是指无效域名, 无论是IP地址, 错误的域名拼写或是未在其他虚拟主机配置中提到的域名, 均会触发return 403;
, 显示页面不存在.
于是略加改进, 去掉其他虚拟主机中的default字段; 把default.conf
中的return 403;
改为重定向到我们期望的默认首页, 即可解决我们的问题.
server {
listen 80 default_server;
server_name _;
rewrite ^ http://archean.me$request_uri?;
}