使用 Nginx 阻止未发送至我的域的连接

Del*_*Del 6 nginx django elastic-beanstalk

我正在 AWS elastic beanstalk 上运行 django 应用程序,并且收到尝试扫描漏洞的机器人发送的垃圾邮件。它会导致大量错误,例如:

(其中 xx.xxx.xx.xx 是我的 ec2 实例的 IP 地址。)

DisallowedHost at //www/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php
Invalid HTTP_HOST header: 'xx.xxx.xx.xx'. You may need to add 'xx.xxx.xxx.xx' to ALLOWED_HOSTS.
Run Code Online (Sandbox Code Playgroud)

我的合法用户只能使用域名访问该网站。我一直在尝试找出如何修改我的 nginx 配置以阻止所有未寻址到 *.mydomain.com 或 mydomain.com 的连接。

我根据需要动态添加和删除子域,因此我为子域使用通配符。

AWS Elastic beanstalk 为我生成以下默认配置文件:

/etc/nginx/nginx.conf

#Elastic Beanstalk Nginx Configuration File

user                    nginx;
error_log               /var/log/nginx/error.log warn;
pid                     /var/run/nginx.pid;
worker_processes        auto;
worker_rlimit_nofile    32788;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    include       conf.d/*.conf;

    map $http_upgrade $connection_upgrade {
        default     "upgrade";
    }

    server {
        listen        80 default_server;
        access_log    /var/log/nginx/access.log main;

        client_header_timeout 60;
        client_body_timeout   60;
        keepalive_timeout     60;
        gzip                  off;
        gzip_comp_level       4;
        gzip_types text/plain text/css application/json application/javascript $

        # Include the Elastic Beanstalk generated locations
        include conf.d/elasticbeanstalk/*.conf;
    }
}

Run Code Online (Sandbox Code Playgroud)

然后我用这个文件扩展它:

.platform\nginx\conf.d\elasticbeanstalk\00_application.conf

location / {
    set $redirect 0;
    if ($http_x_forwarded_proto != "https") {
        set $redirect 1;
    }
    if ($redirect = 1) {
        return 301 https://$host$request_uri;
    }   

    proxy_pass        http://127.0.0.1:8000;
    proxy_http_version  1.1;

    proxy_set_header    Connection         $connection_upgrade;
    proxy_set_header    Upgrade            $http_upgrade;
    proxy_set_header    Host               $host;
    proxy_set_header    X-Real-IP          $remote_addr;
    proxy_set_header    X-Forwarded-For    $proxy_add_x_forwarded_for;
    
    gzip on;
    gzip_comp_level 4;
    gzip_types text/html text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
    client_max_body_size 2000M;
}

location = /health-check.html {
    set $redirect 0;
    if ($http_x_forwarded_proto != "https") {
        set $redirect 1;
    }
    if ($http_user_agent ~* "ELB-HealthChecker") {
        set $redirect 0;
        return 204;
    }
    if ($redirect = 1) {
        return 301 https://$host$request_uri;
    }   

    proxy_pass        http://127.0.0.1:8000;
    proxy_http_version  1.1;

    proxy_set_header    Connection         $connection_upgrade;
    proxy_set_header    Upgrade            $http_upgrade;
    proxy_set_header    Host               $host;
    proxy_set_header    X-Real-IP          $remote_addr;
    proxy_set_header    X-Forwarded-For    $proxy_add_x_forwarded_for;
Run Code Online (Sandbox Code Playgroud)

该覆盖文件的目的是让 nginx 将 http 重定向到 https 并响应 ELB 健康检查。

我对 nginx 或 elastic beanstalk 不太熟悉,但从研究这个问题时我可以收集到的是,我需要让我的默认服务器连接返回 444,然后有一个单独的服务器块,其中 server_name 设置为我的域。

这是处理此问题的正确方法吗?它是否适用于通配符子域?

谢谢

Ter*_*nen 10

看来您唯一的虚拟主机是具有default_server属性的虚拟主机。这意味着如果没有找到匹配的虚拟主机,则使用该块来服务请求。

为了妥善处理您的案件,您需要:

  1. serverdefault_server指令中的块listen。该块应该只有return 404;or return 444;。您可能也想在这个区块中关闭access_log
  2. server块与server_name example.com *.example.com;. 该虚拟主机应包含您的实际应用程序。

请注意,这是当一个人完全控制 nginx 配置时的配置方式。我不知道 Elastic Beanstalk 是否有一些功能可以以这种方式自动生成配置文件。