目录
前言
一、server_name是什么
server_name就是访问部署了nginx那台服务器的域名、ip、localhost。(一个机器可以有多个域名,server_name可以配置不同的域名)
nginx里面的server模块可以配置相同的端口,然后这里会根据不同的域名,跳转到不同的server模块中
二、匹配优先级
server_name与host匹配优先级如下:
1、完全匹配
2、通配符在前的,如*.test.com
3、在后的,如www.test.*
4、正则匹配,如~^\.www\.test\.com$
如果都不匹配
1、优先选择listen配置项后有default或default_server的
2、找到匹配listen端口的第一个server块
三、总结
server name 为虚拟服务器的识别路径。因此不同的域名会通过请求头中的HOST字段,匹配到特定的server块,转发到对应的应用服务器中去。
问题现象
先贴一段默认的server配置
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
可以观察发现,默认配置文件下有且仅有该一个server配置,并且其下默认的server_name为localhost。但是实际上我们仍然可以通过ip:80去访问nginx index页面。
其原因在于nginx 的 default_server 指令可以定义默认的 server 出处理一些没有成功匹配 server_name 的请求,如果没有显式声明 default server 则第一个 server 会被隐式的设为 default server,那么当其没有匹配到对应的server_name时,就会走default_server下的路由转发规则。
其踩坑点在于,但我们新开一个nginx,针对一域名,通过其做一些简单的路由转发,这种场景通常是一些转发用的网关模块。 习惯会在默认的server配置里面配置规则,这个时候虽然server配置的server_name是localhost,其实是因为其作为default_server而被匹配到的。但是,随着业务的扩展,部分路由转发需求会打到这个nginx上来,这时候有可能是不同的域名。这就会导致一个问题,因为当default_server没有配置时,默认选取的第一个server作为default_server,如果配置新的server处于首个server位置的话,默认匹配到default_server,那么,相当于原来通过default_server匹配的规则的这部分请求会重新匹配到另一部分规则。
解决方法
一种方法是通过显式的定义一个default_server,一般在生产环境中,我们需要拒绝通过ip进来的请求,通常是一些攻击或者漏洞扫描,所以需要对这部分请求返回404,通常配置在server的最上方。具体配置如下:
server {
listen 80 default_server;
server_name _;
return 404;
}
然后我们的所有server都需要一对一配置相应的域名,并且新的配置加于文件尾部,形成一种合规性操作。