繁体   English   中英

在反向代理下仅允许 Nginx 上的单个特定 IP 地址

[英]Allow only a single specific IP address on Nginx under reverse proxy

我有一个在本地主机上运行的 api。 为了允许外部访问特定域路径下的 API,我设置了一个反向代理。 这部分工作正常。 现在我正在尝试过滤访问并只允许一个 IP 连接到 API,换句话说,拒绝除特定 IP 之外的所有 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;

我认为将该控制置于 Web 服务器级别并不是一个好主意。

授予访问权限是更具防火墙性的任务。

但是在某些情况下,当您想在不重新启动或配置某些内容的情况下动态授予对已注册主机的访问权限时 - 最好在应用程序级别创建保护方法。


现在我可以推荐以下之一:

1) 将防火墙放在 app 或 nginx 前面。 你可以使用ufw

2)将访问控制置于应用程序级别。 如果是 nodejs 应用程序编写中间件:

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();
};

app.js

const express = require('express');
const app = express();

const ipFirewall = require('middlewares/allowByIp');
app.use(ipFirewall);

...

app.listen(3000);


我已经检查了您的 nginx 示例,它按预期工作。

所以我怀疑nginx得到了不同的ip。 检查/var/log/nginx/access.log以获取当源部分请求目标时您的 nginx 获得的真实 IP 地址。

但是,如果你想在内部限制访问,告诉服务器在对foo.com请求中使用环回接口,然后在/etc/hosts文件中添加这样的行:

127.0.0.1   foo.com www.foo.com

它会告诉您的服务器不要请求 DNS 服务器来解析该主机名,这将提供全局 ip 并导致来自外部的请求。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM