Nginx 限制域名

21
请查找以下设置,该设置位于我站点域名 (mysite.lk) 下的 /etc/nginx/sites-enabled 文件中。
server {  
   listen   80;
   server_name mysite.lk www.mysite.lk;

   location / {  
        proxy_set_header   X-Forwarded-For $remote_addr;
        proxy_set_header   Host $http_host;
        proxy_pass "http://127.0.0.1:8080";
   }

} 
应用程序正在8080端口上运行,并且我正在将所有80流量重定向到8080。 我的网站仅使用mysite.lk和www.mysite.lk域名。
因此,我想限制/阻止所有其他域(除了mysite.lk和www.mysite.lk)访问这个服务器IP。我需要做什么更改来实现这一点?
我尝试了很多方法,如为什么nginx响应任何域名?中给出的答案,但在nginx启动时会遇到错误。
请帮帮我! 谢谢。
更新
找到答案。 在给定配置之前,在配置顶部应该需要一个捕获所有服务器块,如下所示。 代码块应该像这样。
server {
    return 403;
}

server {
    listen   80;
    server_name mysite.lk www.mysite.lk;
    location / {
        proxy_set_header   X-Forwarded-For $remote_addr;
        proxy_set_header   Host $http_host;
        proxy_pass "http://127.0.0.1:8080";
   }

}

1
你需要一个全能型服务器。你链接的答案展示了解决方案。如果你在实现中遇到错误 - 你需要修复它们。从/etc/nginx/nginx.conf文件开始。你的系统中是否已经定义了其他server块 - 使用nginx -T来查看完整的情况。 - Richard Smith
非常感谢!这是服务器块中的错误。在给定的块之前添加“server {return 403;}”的catch-all块会限制所有其他域名。 - Amila Iddamalgoda
它可以使用端口80,但无法使用443端口。有任何想法为什么? - Kornikopic
是的,它可以使用端口80工作,但无法使用443端口,为什么? - ShivaGaire
@Kornikopic,你找到了任何解决方法吗? - ShivaGaire
5个回答

23

Nginx中定义的第一个服务器被视为default_server,因此只需将其添加为默认服务器并返回412(前提条件失败)或任何最适合您要求的其他状态码,将有助于让后续的服务器遵守server_name

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;
    return 412;
} 

server {
    listen   80;
    server_name mysite.lk www.mysite.lk;
    location / {
        proxy_set_header   X-Forwarded-For $remote_addr;
        proxy_set_header   Host $http_host;
        proxy_pass "http://127.0.0.1:8080";
   }
}

1
你在return 412后面漏了一个分号,除此之外,对我来说运行得很好。 - Juan Fuentes

13

以上所有答案都是正确的,但如果另一个域尝试通过端口443(https/SSL)访问您的主机,则它们都无法工作。

要阻止访问https请求,只需在您的主机的https服务器配置中添加一个if块即可。

server {

    server_name www.xyz.com xyz.com;

    location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to displaying a 404.
        try_files $uri $uri/ =404;
    }


    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot

    if ($host = "www.specificdomainyouwanttoblock.com") {
        return 404;
    }

    if ($host = "specificdomainyouwanttoblock.com") {
        return 404;
    }

    # or you can simply add:

    if ($host != "yourdomain.com") {
        return 404;
    }

}

如果要考虑主机检查子域名,您需要使用正则表达式。例如 $host !~* "\.domain\.com$"(以 .domain.com 结尾)。 - Berel Levy

0

如果没有server_name,那么创建一个服务器指令怎么样?就像这样:

server {
    listen 80 default_server;

    location / {
        deny all;
    }
}

编辑 请阅读http://nginx.org/en/docs/http/request_processing.html 简而言之,当涉及到server_names或locations时,nginx总是寻找最佳匹配,如果找不到,则使用默认服务器。


我也看了一下。我想拒绝除了mysite.lk和www.mysite.lk之外的所有域名。并且流量也必须重定向到8080端口。 - Amila Iddamalgoda
是的,我明白了。在你的配置旁边的这段配置将会准确地实现这一点。 - avpav
找到了!请在问题部分查找更新后的答案。同时感谢快速的支持。 - Amila Iddamalgoda

0
我有一个带有防火墙的播放器脚本,它会阻止不在我的白名单上的网站,但事实证明,如果我启用了防火墙,在我的Android应用程序中视频将停止工作。您知道如何修改我的防火墙以使用Android应用程序包名称来将我的应用程序添加到白名单中,并能够在我的应用程序中使用防火墙播放视频,因为我必须禁用它才能播放我的应用程序中的视频。
/**
 * Disable access baseed on referer
 */
if (Data::Get("accs_restriction") == "enable") {
    $domains = explode(",", Data::Get("allowed_domains"));
    $referer = parse_url($_SERVER["HTTP_REFERER"], PHP_URL_HOST);
    if (empty($referer) || !in_array($referer, $domains)) {
        header('HTTP/1.0 403 Forbidden');
        require TEMPLATES . "pages/access_denied.php";
        exit;
    }
}

0
我在网站的虚拟主机文件中实现了以下几行代码:
if ($http_referer ~* (example\.com)) {
    return 403;
}

对我来说,这很有效。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接