如何保护自己免受 nginx 僵尸网络请求的侵害?

问题描述 投票:0回答:1

我在 nginx docker 中收到以下请求:

frontend-prod | 206.189.19.19 - - [27/Oct/2024:12:29:42 +0000] "GET /.env HTTP/1.1" 200 600 "-" "Go-http-client/1.1" 
frontend-prod | 206.189.19.19 - - [27/Oct/2024:12:29:43 +0000] "GET /.git/config HTTP/1.1" 200 600 "-" "Go-http-client/1.1"
frontend-prod | 206.189.19.19 - - [27/Oct/2024:12:29:44 +0000] "GET /s/8353e2035313e2331323e2637313/_/;/META-INF/maven/com.atlassian.jira/jira-webapp-dist/pom.properties HTTP/1.1" 200 600 "-" "Go-http-client/1.1" 
frontend-prod | 206.189.19.19 - - [27/Oct/2024:12:29:45 +0000] "GET /config.json HTTP/1.1" 200 600 "-" "Go-http-client/1.1"
frontend-prod | 206.189.19.19 - - [27/Oct/2024:12:29:46 +0000] "GET /telescope/requests HTTP/1.1" 200 600 "-" "Go-http-client/1.1"

有2个问题:

  1. 我没有这些文件,为什么答案是200?
  2. 如果有文件,我如何保护自己免受此类攻击、扫描等?

我的意思是 my_site.conf:

map $http_user_agent $block_user_agent {
    default 0;
    ~*LWP::Simple 1;
    ~*BBBike 1;
    ~*wget 1;
    ~*msnbot 1;
    ~*scrapbot 1;
    ~*(nmap|nikto|wikto|sf|sqlmap|bsqlbf|w3af|acunetix|havij|appscan) 1;
}

map $http_referer $block_referer {
    default 0;
    ~*(babes|forsale|girl|jewelry|love|nudit|organic|poker|porn|sex|teen) 1;
}

server {
    listen 80;
    listen [::]:80;

    server_name MYDOMAIN www.MYDOMAIN;
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    if ($request_method !~ ^(GET|HEAD|POST)$) {
        return 444;
    }
    if ($block_user_agent) {
        return 403;
    }
    if ($block_referer) {
        return 403;
    }
    location ~* ^/cgi-bin/ {
        deny all;
    }

    location / {
        limit_req zone=req_limit burst=5;
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        try_files $uri $uri/ /index.html;
    }

    location /.well-known/acme-challenge/ {
        root /var/www/certbot/;
    }
}

upstream MYDOMAINLAUNCH {
    server mydomainlauncher:6666;
}

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

server {
    listen 80;
    listen [::]:80;

    server_name launcher.MYDOMAIN;
    charset utf-8;

    if ($request_method !~ ^(GET|HEAD|POST)$) {
        return 444;
    }
    if ($block_user_agent) {
        return 403;
    }
    if ($block_referer) {
        return 403;
    }
    location ~* ^/cgi-bin/ {
        deny all;
    }

    root /usr/app/launcher/updates/;

    location / {
        limit_req zone=req_limit burst=5;
    }

    location ~ /\.(?!well-known).* {
        limit_req zone=req_limit burst=5;
        deny all;
    }

    location /api/ {
        limit_req zone=req_limit burst=5;
        proxy_pass http://MYDOMAINLAUNCH;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        error_page 502 = @fallback;
        error_page 504 = @fallback;
    }

    location /webapi/ {
        limit_req zone=req_limit burst=5;
        proxy_pass http://MYDOMAINLAUNCH/webapi/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        error_page 502 = @fallback;
        error_page 504 = @fallback;
    }

    location @fallback {
        return 302 http://MYDOMAIN;
    }
}

这是我的 nginx.conf:

worker_processes 16;

events {
    worker_connections 1024;
}

http {
    include       mime.types; # Connecting the mime file.types
    default_type  application/octet-stream;
    server_tokens off;

    client_body_buffer_size 1K; # Maximum buffer size for storing the client request body
client_header_buffer_size 1k; # Maximum buffer size for storing client request headers
client_max_body_size 1k; # Maximum size of the client request body
    large_client_header_buffers 2 1k; # Number and size of buffers for reading a large client request header

    client_body_timeout 10; # Timeout when reading the client
's request body client_header_timeout 10; # Timeout when reading the client's request header
    keepalive_timeout 5 5; # Timeout, after which the keep-alive connection with the client will not be closed from the server side
    send_timeout 10; # Timeout when sending a response to the client

    limit_conn_zone $binary_remote_addr zone=slimits:5m; # We describe the zone (slimits) in which the session states will be stored. A 1 MB zone can store about 32,000 states, we set its size to 5 MB
    limit_conn slimits 3; # Setting the maximum number of simultaneous connections per session. In fact, this number sets the maximum number of connections from one IP

    limit_req_zone $binary_remote_addr zone=req_limit:10m rate=1r/s;

    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block;";
    add_header Referrer-Policy same-origin;
    add_header Content-Security-Policy "default-src 'self'; img-src 'self' https://i0.wp.com; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';" always;
    add_header Permissions-Policy "geolocation=(self), microphone=(), camera=()"; # Replacing Feature-Policy
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    include /etc/nginx/conf.d/*.conf;  # Enabling all configurations from conf.d
}

这是我的 dockerfile:

###########
# BUILDER #
###########
FROM node:lts-slim AS A builder

# Defining the arguments of the assembly
THE REACT_APP_API_LINK ARGUMENT
THE REACT_APP_API_GETIP ARGUMENT

# Setting environment variables
ENV REACT_APP_API_LINK=$REACT_APP_API_LINK
ENV REACT_APP_API_GETIP=$REACT_APP_API_GETIP

COPY the package file.json with a package lock.json ./
RUN the npm installation && mkdir /react interface && mv ./node_modules ./react interface

WORKDIR /react-
copy interface. .

RUN npm run build

#########
# FINAL #
#########
FROM nginx: latest version

# Copying the build
COPY --from=builder /react-frontend/build /usr/share/nginx/html

# Removing the default configuration
RUN rm /etc/nginx/conf.d/default.conf
# Creating custom Nginx configurations
COPY the nginx.conf /etc/nginx/nginx.conf file
COPY the file my_site.conf /etc/nginx/conf.d/my_site.conf

# Creating a temporary file system for the root directory
RUN mkdir /nginx && \
mv /usr/share/nginx/html/* /nginx/ &&\
rm -rf /usr/share/nginx/html && \
ln -s /nginx /usr/share/nginx/html

# We restrict access to executable files
RUN chmod -R 755 /nginx && \
    find /nginx -type f -exec chmod 644 {} \; && \
    find /nginx -type d -exec chmod 755 {} \;

EXPOSE 80

# Run the script and nginx
CMD ["nginx", "-g", "daemon is disabled";"]

谷歌在这个问题上不起作用:(

security nginx docker-compose deployment
1个回答
0
投票

正如您所说,这实际上是两个问题,应该作为两个单独的问题来提出。我写这篇文章是为了回答你的第一个问题。

我没有这些文件,为什么答案是200?

在您正在使用的服务器的配置中

[try_files][1]

按照指定的顺序检查文件是否存在,并使用第一个找到的文件进行请求处理;处理是在当前上下文中执行的。文件的路径是根据 root 和 alias 指令从 file 参数构造的。可以通过在名称末尾指定斜杠来检查目录是否存在,例如“$uri/”。如果未找到任何文件,则会进行内部重定向到最后一个参数中指定的 uri。

启动一个简单的 docker 容器并将配置设置为

    location / { 
        root   /usr/share/nginx/html; 
        index  index.html index.htm; 
        try_files $uri $uri/ /index.html; 
    }

如果我导航到任何 URI 并且 nginx 无法解析它,它将尝试将其解析为目录,否则它将使用索引页。


127.0.0.1 - - [27/Oct/2024:16:28:17 +0000] "GET /sdf HTTP/1.1" 200 615 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0" "-"
127.0.0.1 - - [27/Oct/2024:16:32:54 +0000] "GET /foo/bar HTTP/1.1" 200 615 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0" "-"
127.0.0.1 - - [27/Oct/2024:16:32:58 +0000] "GET /foo/baz HTTP/1.1" 200 615 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0" "-"
127.0.0.1 - - [27/Oct/2024:16:33:11 +0000] "GET /some/really/long/path/that/doecnt/exist HTTP/1.1" 200 615 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0" "-"

这些都返回 200 成功,因为 try_files 的最后一部分是确实存在的index.html,它是返回的内容。正如您在下面看到的那样,实际路径不存在并不重要,

try_files
指令成功返回索引页面。

您真的需要

try_files
声明吗?

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.