我有一个在本地主机上运行的api。为了允许在特定域路径下从外部访问API,我设置了反向代理。这部分工作正常。现在,我正在尝试过滤访问权限,并仅允许单个IP连接到API,换句话说,拒绝所有IP的连接(特定连接除外)。
使用下面的配置,所有IP被成功阻止,但是它也阻止了我要允许的一个IP。我已经研究并尝试了多种修复程序,但我怀疑我需要在反向代理下获取real_IP,但仍无法使其适合我的特定情况。感谢所有帮助。这是我在站点内可用的nginx配置文件的代码:
server {
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name foo.com www.foo.com;
location / {
allow XX.XX.XX.XX;
#allow 127.0.0.1;
deny all;
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
listen [::]:443 ssl; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/foo.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/foo.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
XX.XX.XX.XX是我要允许的IP,它实际上是服务器的实际IP。但我认为这没有什么不同。我还尝试在“ location / {}”范围内添加以下内容,但没有运气:
set_real_ip_from XX.XX.XX.XX;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
答案 0 :(得分:1)
我认为将控件置于Web服务器级别不是一个好主意。
授予访问权限是防火墙任务。
但是在某些情况下,当您希望动态地赋予已注册的主机访问权限而无需重新启动或配置某些内容时-最好在应用程序级别上设置保护方法。
目前,我可以推荐以下之一:
1)将防火墙放在应用程序或nginx的前面。您可以使用ufw
2)将访问控制置于应用程序级别。如果是nodejs应用,请编写中间件:
Button
:
onClick
或:
middlewares/allowByIp.js
在'use strict';
cons db = require('../database'); // mongoose models abstraction
const AllowedHosts = db.model('AllowedHost');
module.exports = async (req, res, next) => {
const isAllowed = await AllowedHosts.findOne({ip: req.ip});
if (!isAllowed) {
res.status(403).send('Forbidden');
}
next();
};
中:
'use strict';
cons allowedHosts = [... ip listing ...]; // take care of graceful restarting of Your app when You'll modify this array
module.exports = async (req, res, next) => {
const isAllowed = allowedHosts.includes(req.ip);
if (!isAllowed) {
res.status(403).send('Forbidden');
}
next();
};
我已经检查了您的nginx示例,该示例可以正常工作。
所以我怀疑nginx获得了不同的IP。检查app.js
以获得当源部件向目的地请求时您的nginx获取的真实IP地址。
但是,如果您想在内部限制访问,则告诉服务器在对const express = require('express');
const app = express();
const ipFirewall = require('middlewares/allowByIp');
app.use(ipFirewall);
...
app.listen(3000);
的请求中使用环回接口,然后在/var/log/nginx/access.log
文件中添加以下行:
foo.com
它将告诉您的服务器不要请求DNS服务器解析该主机名,该主机名将提供全局ip和外部请求的结果。