我目前正在我的nginx.conf中执行此操作:
allow 1.2.3.4;
deny;
我真正想做的是:
allow my.domain.name;
deny;
即,我希望nginx在请求时对my.domain.name执行A记录查找,如果它与请求来自的IP匹配,则允许它。但是,我没有看到任何内置机制。在开始编写自定义内容之前,有人有本地方法吗?
答案 0 :(得分:18)
ngx_http_rdns_module可以满足您的需求:http://wiki.nginx.org/HttpRdnsModule(https://github.com/flant/nginx-http-rdns)
此模块允许对传入连接进行反向DNS(rDNS)查找,并通过允许/拒绝规则提供对传入主机名的简单访问控制(类似于HttpAccessModule允许/拒绝指令;支持正则表达式)。模块使用标准解析器指令定义的DNS服务器。
location / {
resolver 127.0.0.1;
rdns_deny badone\.example\.com;
if ($http_user_agent ~* FooAgent) {
rdns on;
}
if ($rdns_hostname ~* (foo\.example\.com)) {
set $myvar foo;
}
#...
}
答案 1 :(得分:5)
nginx的正式发布中没有这样的功能。因为它可能会大大降低性能。
第三方模块http://wiki.nginx.org/3rdPartyModules也不包含此功能。
答案 2 :(得分:0)
此答案是一种替代方案,可以让域解析超出nginx,但目标完全相同,可以解析nginx配置中包含的ip。
1)创建文件allowed-domain.list
,其中包含您要授予访问权限的域:
jean-paul.mydomain.com
rufus.mydomain.com
robert.mydomain.com
2)创建一个bash脚本domain-resolver.sh
来为您执行查找:
#!/usr/bin/env bash
filename="$1"
while read -r line
do
ddns_record="$line"
if [[ ! -z $ddns_record ]]; then
resolved_ip=`getent ahosts $line | awk '{ print $1 ; exit }'`
if [[ ! -z $resolved_ip ]]; then
echo "allow $resolved_ip;# from $ddns_record"
fi
fi
done < "$filename"
3)对此脚本chmod +x domain-resolver.sh
4)添加一个cron作业,该作业将生成有效的nginx配置并重新启动nginx:
#!/usr/bin/env bash
/pathtoscript/domain-resolver.sh /pathtodomainlist/allowed-domain.list > /pathtooutputdir/allowed-ips-from-domains.conf
service nginx reload > /dev/null 2>&1
这可以是一项@daily
的工作,也可以使其每小时,每分钟,每秒钟运行一次……
5)更新您的nginx配置,以将此输出考虑在内:
include /pathtooutputdir/allowed-ips-from-domains.conf;
deny all;
您可以通过添加ip格式检查来改进此功能,如果不希望使用ipv6,可以将所有内容归为一个文件...
答案 3 :(得分:0)
你可以使用lua脚本。 您需要安装 nginx-mod-http-lua 和 lua-nginx-dns 模块。 nginx lua 脚本示例将是:
location /test/ {
access_by_lua_block {
local resolver = require "nginx.dns.resolver";
local r, err = resolver:new {
nameservers = { "8.8.8.8", "1.1.1.1" },
retrans = 5, -- timeout retransmits
timeout = 500, -- 500msec
no_random = true, -- always start from the first name server
};
if not r then
ngx.log(ngx.ERR, "failed to instantiate the DNS resolver: " .. err)
return
end
local answers, err, tries = r:query("my.domain.name", nil, {});
if not answers then
ngx.log(ngx.ERR, "failed to query the DNS server: " .. err)
return
end
if answers.errcode then
ngx.log(ngx.ERR, "server returned error code: " .. answers.errcode .. ": " .. answers.errstr)
return;
end
for i, ans in ipairs(answers) do
if ans.address == ngx.var.remote_addr then
return
end
end
ngx.log(ngx.ERR, "Not allow IP : " .. ngx.var.remote_addr);
ngx.exit(ngx.HTTP_FORBIDDEN);
}
}