众所周知,浏览器发送到后台请求header中携带的host是可能被修改的,为了防止这件事情发生,就很有必要给后台设置host请求白名单了,本次将介绍nginx如何配置,以及结合confd和etcd实现动态配置。
1. http/https请求的host参数
http/https请求的请求头header部分会携带Host参数,一般默认位访问地址url的服务地址,如下图所示,但是这个host参数是很容易被篡改的,如使用post请求工具 postman 、apipost、postwoman等,所以很有必要针对Host篡改的问题做拦截。
2.nginx如何过滤掉被篡改的Host请求
其实配置很简单,只要在nginx的配置文件配置好host白名单,然后再配置好判断,不在白名单内的host禁止访问就好了,配置如下
# host 白名单
map $http_host $nms_white_host {
default "";
111.121.13.14 1;
111.121.13.15 1;
}
# ... 其他配置省略
server {
if ($nms_white_host = "") {
return 403;
}
}
解释下,$http_host
是nginx的内置参数,值为http
请求的header
中的Host
参数,$nms_white_host
是自定义变量,代表 $http_host
与 map中参数进行匹配后的值,如果匹配到 111.121.13.14
或 111.121.13.15
, 那么 $nms_white_host
的值是1,如果没有匹配的Host值,则 $nms_white_host
的值为空字符串;结合下面的if判断,即可实现不在白名单内的Host禁止访问的功能。
3. 结合confd + nginx 实现动态启用白名单,动态配置白名单列表
confd的使用介绍参考之前的博客:confd 0.20.0 监听etcd动态更新nginx配置文件
下面代码是实现方案:
首先获取通过 etcd 的key值 /whitelist
赋给 自定义变量 $whitelist
,如果etcd没有配置/whitelist
的值,则$whitelist
是空值,那么就不会走白名单过滤,也就是没有开启白名单校验。
如果开启了则会根据etcd配置的值 /whitelist
动态配置nginx,实现动态配置nginx的Host过滤白名单功能。
{{ $whitelist := getv "/whitelist" "" }}
{{ if ne $whitelist "" }}
map $http_host $nms_white_host {
default "";
{{ $whitelist }}
}
{{ end }}
# ... 其他配置省略
server {
{{ if ne $whitelist "" }}
if ($nms_white_host = "") {
return 403;
}
{{ end }}
}