솔루션/Nginx

Nginx로 DDoS공격 방어하기 with 웹 방화벽 구축하기

bluebamus 2024. 3. 24.

 - 최신 Nginx plus에는 유료 모듈이 있다. 하지만 무료 Nginx를 사용하는 사용자는 설정값을 업데이트 하고 Fail2ban를 설치해 DDoS를 막거나 nginx의 modsecurity 모듈로 웹 방화벽을 설치할 수 있다.

 

 - 이번 포스트에서는 다음 순서의 글을 작성하고자 한다.

   1) Nginx에서 요청 속도, 수를 제한하고 이상 연결과 ip를 관리하는 방법을 정리한다.

   2) Fail2ban를 설치한다.

   3) modsecurity를 설치한다. 조사한 자료를 정리한다.

 

 - 모든 코드는 내가 관리하고 있는 관련한 github에 반영하여 테스트를 진행한다.

   - docker-compose 기반 테스트 중에 발생한 이슈는 이 글에 같이 정리하도록 한다.

   - 저장소 :

      - https://github.com/devspoons/devspoon-web

      - https://github.com/devspoons/devspoon-startup-web

 

 1. Nginx 설정으로 DDoS 방어하기

   1) 요청 속도 제한

      - 로그인 페이지에 액세스 하는 실제 사용자는 2초마다 한 번만 요청할 수 있도록 제한

      - 단일 클라이언트 IP 주소가 2초마다(분당 30건 요청) 로그인을 시도하도록 Nginx 구성

         - limit_req_zone 지시문은 지정된 키(이 경우 클라이언트 IP 주소)에 대한 요청 상태를 저장하기 위해 one이라는 공유 메모리 Zone을 구성한다($binary_remote_addr).

         - /login.html의 location 블록에 있는 limit_req 지시문은 공유 메모리 Zone을 참조한다.

limit_req_zone $binary_remote_addr zone=one:10m rate=30r/m;

server {
    # ...
    location /login.html {
        limit_req zone=one;
    # ...
    }
}

 

http {
	limit_req_zone $binary_remote_addr zone=mylimit:10m rate=3r/s;
    ...
}

 

      1. 단일 클라이언트 ip 주소가 모든 페이지에 대해 1초에 3건의 요청을 시도하도록 설정하는 방법 

         - nginx.conf 파일에 아래 설정을 업데이트 한다.

         - limit_req_zone : request 비율 제한 설정을 위해 작성

         - $binary_remote_addr : 클라이언트 ip 주소에 대한 정보

         - zone=one:10m : 

            - 클라이언트 ip에 대한 request 상태를 저장하기 위한 메모리 영역 확보

            - 메모리 영역의 이름을 ddos_req로 설정한 것 (사용자 마음대로 변경 가능)

            - 10m는 10mb의 메모리 영역을 할당하겠다는 것

         - rate=30r/m : 

            - 클라이언트 ip에 대한 request를 1초(s)에 최대 30개(30r)받을 수 있다는 것

            - s는 분 단위인 m으로도 설정 가능

            - ex) 10r/s -> 1초에 최대 10개

            - ex) 30r/m -> 2초에 최대 1개 (60초에 최대 30개)

server {
    ...
    location / {
        limit_req zone=mylimit burst=5 nodelay;
        ...
    }
}

 

         2. domain별 conf 파일에 아래 설정을 업데이트 한다.

            - limit_req : limit_req_zone에서 설정했던 정보를 적용하겠다는 뜻이다.

            - zone=mylimit: 이 위치에서 사용할 제한 영역이다.

            - burst=5: 초과 허용량을 설정한다. 이 설정은 초과 요청이 즉시 거부되지 않고 대기열에 들어간 다음 지정된 요청 비율에 따라 처리될 수 있음을 의미한다.

               - 예를 들어, burst=5는 클라이언트가 초당 최대 3건의 요청을 할 수 있지만, 짧은 시간 동안 최대 5건까지 요청이 축적될 수 있음을 의미한다.

            - nodelay: 설정 시, 초과 요청들은 지정된 비율에 따라 대기열에 들어가지 않고 즉시 처리된다. burst 값 이내의 요청은 추가 지연 없이 처리된다.

 

         3. limit_req_status 설정하기.

            - deny 하게되면 status code 기본값은 503이지만, 다음과 같이 limit_req_status 설정을 통해 status code를 지정해줄 수 있다.

limit_req_zone $binary_remote_addr zone=ddos_req:10m rate=5r/s;
limit_req_status 404; 

server {
    # ...
    location /login {
        limit_req zone=ddos_req;
    # ...
    }
}

 

   2) 요청 수 제한

      - location /pen/ {} 이렇게 정의하면 test.com/pen/ 이하의 모든 페이지를 의미한다.

      - location / {} 이렇게 정의하면 test.com 이하 모든 페이지를 의미한다.

 

      - 단일 클라이언트 IP 주소가 연결할 수 있는 연결 수를 제한하는 방법

         - 예) 웹사이트의 /store 영역에 대해 10개 이하의 연결만 열도록 제한

            - limit_conn_zone 지시문은 지정된 키(이 예에서는 앞의 예에서와 같이 클라이언트 IP 주소인 $binary_remote_addr)에 대한 요청을 저장하기 위해 addr이라는 공유 메모리 Zone을 구성한다.

            - store에 대한 location 블록의 limit_conn 지시문은 공유 메모리 Zone을 참조하고 각 클라이언트 IP 주소에서 최대 10개의 연결을 설정한다.

limit_conn_zone $binary_remote_addr zone=addr:10m;

server {
    # ...
    location /store/ {
        limit_conn addr 10;
        # ...
    }
}


      - 각 클라이언트 IP 주소가 웹사이트의 모든 페이지에 대해 동시에 10개 이하의 연결만 열도록 설정하는 방법

         - nginx.conf 파일에 limit_conn_zone 설정

            - $binary_remote_addr: 클라이언트 IP 주소를 나타내며, 이를 기준으로 연결 수를 제한한다.

            - zone=addr_limit:10m: addr_limit은 메모리 존의 이름이며, 10m은 10MB의 메모리를 할당하여 대략 16만 개의 IP 주소를 저장할 수 있음을 나타낸다.

http {
    limit_conn_zone $binary_remote_addr zone=addr_limit:10m;
}

 

         - domain별 conf 파일에 아래 설정을 업데이트 한다.

            - limit_conn addr_limit 10;은 addr_limit 존에 정의된 각 IP 주소당 최대 동시 연결 수를 10개로 제한한다.

server {
    listen 80;
    server_name example.com;

    location / {
        limit_conn addr_limit 10;
    }
}

 

   3) Slow Connection 종료

      - 데이터 쓰는 빈도가 너무 낮은 연결을 연결 해제할 수 있는데, 이는 연결을 가능한 한 오래 열어두려는 시도일 수 있다. 하나의 서버가 유지할 수 있는 연결 I/O는 제한이 있기 때문에 서버가 새 연결을 수락하는 기능이 저하되거나 불가능할 수 있다.

         - Slowloris가 이러한 유형의 공격의 한 예이다.

         - 관련 문서 : https://nginxstore.com/docs/nginx/ngx_http_core_module/#client_body_timeout-time

 

      - client_body_timeout 지시문은 클라이언트 본문의 쓰기 사이에 NGINX가 대기하는 시간을 제어한다.

      - client_header_timeout 지시문은 클라이언트 헤더의 쓰기 사이에 NGINX가 대기하는 시간을 제어한다.

      - 두 설정의 기본값은 60초이다.

 

      - 클라이언트에서 헤더 또는 본문 쓰기 사이에 12초 이상 대기하지 않는 구성 예시이다.

server {
	client_body_timeout 12;
	client_header_timeout 12;
}

 

 

   4) IP 주소 거부(deny) 목록 설정

      - 공격에 사용되는 클라이언트 IP 주소를 식별/수집할 수 있는 경우, location 내 deny 지시문을 사용해 식별된 주소를 deny 목록에 추가하여 nginx가 해당 연결 또는 요청을 수락하지 않도록 설정할 수 있다.

 

      - 단일 IP 주소 차단 방법

server {
    location / {
        deny 192.168.1.1;
        allow all;
    }
}

 

      - 125.125.125.1 ~ 125.125.125.16 주소 범위에서 공격이 발생하는 경우

location / {
    deny 125.125.125.0/28;
    allow all;
}

   

   5) IP 주소 허용(allow) 목록 설정

      - 하나 이상의 특정 클라이언트 IP 주소 집합 또는 범위에서만 서버의 접근을 허용하는 경우 allow와 deny를 함께 사용하여 해당 주소만 서버에 접근할 수 있도록 제어할 수 있다.

      - 이 설정에서 모든 것을 거부하는 지시문 deny는 allow에서 지정한 범위에 속하지 않는 모든 클라이언트 IP 주소를 차단한다.

location / {
    allow 192.168.1.0/24;
    deny all;
    # ...
}

 

   6) 캐싱으로 서버의 트래픽 급증을 원활하게 처리하는 방법

      - 관련 문서 : https://nginxstore.com/docs/nginx/ngx_http_proxy_module/#proxy_cache_key-string

 

      - proxy_cache_use_stale :

         - 오래된 캐시 객체의 업데이트를 가져와야 할 경우나 원본 서버가 응답하지 않거나 오류가 발생하였을 경우, 업데이트 요청을 한 번만 보내고 Backend 서버에서 업데이트를 받는 데 걸리는 시간 동안 요청하는 클라이언트에게 캐시된 데이터를를 계속 제공하도록 nginx에 지시한다. 특정 파일에 대한 반복적인 요청이 공격의 일부인 경우 Backend 서버에 대한 요청 횟수를 크게 줄일 수 있다.

         - 주요 옵션 :

            - updating: 다른 요청에 의해 캐시가 현재 업데이트 중일 때, 기존의 캐시된 버전을 사용한다.

            - error: 원본 서버로부터 오류 응답(예: 500, 502, 503, 504 상태 코드)을 받았을 때 캐시된 버전을 사용한다.

            - timeout: 원본 서버로부터 응답을 받는 데 설정된 시간을 초과했을 때 캐시된 버전을 사용한다.

            - invalid_header: 원본 서버로부터 유효하지 않은 헤더를 받았을 때 캐시된 버전을 사용한다.

            - http_500, http_502, http_503, http_504: 특정 HTTP 오류 코드에 대해 캐시된 버전을 사용한다.

http {
    proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;

    server {
        location / {
            proxy_pass http://localhost:8000;
            proxy_cache my_cache;
            proxy_cache_valid 200 1d;
            proxy_cache_use_stale error timeout updating invalid_header http_500 http_502 http_503 http_504;
        }
    }
}

 

         - 동작 설명 :

            1. /data/nginx/cache에 캐시를 저장한다.

            2. my_cache라는 이름의 캐시 영역을 정의하고, 최대 크기를 10GB로 설정한다.

            3. 원본 서버로부터 200 OK 응답을 받은 콘텐츠를 1일 동안 캐시한다.

            4. 원본 서버가 오류를 반환하거나 응답 시간이 초과되었을 때, 또는 캐시가 업데이트 중이거나 유효하지 않은 헤더를 받았을 때, 캐시된 콘텐츠를 사용한다.

 

      - proxy_cache_key :

         - 캐시된 콘텐츠를 식별하는 데 사용되는 키를 설정한다. 이 키는 요청을 고유하게 식별하여 적절한 캐시된 응답을 찾거나 저장하는 데 사용된다.

         - 기본키 :

            1. $scheme: 요청이 사용하는 프로토콜 (예: http, https).

            2. $proxy_host: 프록시 요청을 받는 서버의 호스트 이름.

            3. $request_uri: 전체 요청 URI (쿼리 문자열 포함).

http {
    proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;

    server {
        location / {
            proxy_pass http://localhost:8000;
            proxy_cache my_cache;
            proxy_cache_key "$scheme$request_method$host$request_uri";
        }
    }
}

 

         - 이 설정은 $scheme, $request_method, $host, $request_uri를 조합하여 캐시 키를 생성합니다. 이렇게 하면 동일한 URI에 대한 GET 및 POST 요청 등이 서로 다른 캐시 항목으로 관리된다.

 

      - $query_string 변수에 대한 설명 :

         - $query_string 또는 $args 변수는 URL의 쿼리 문자열 부분을 포함한다.

         - 쿼리 문자열을 캐시 키의 일부로 사용할 때는 주의가 필요하다. 동일한 페이지나 리소스에 대해 쿼리 매개변수만 다른 수많은 요청이 있을 경우, 이를 모두 별도로 캐싱하게 되면 과도한 캐시 사용으로 이어질 수 있다.

 

         - 잘못된 사용 예시 : 

location / {
    proxy_pass http://localhost:8000;
    proxy_cache my_cache;
    proxy_cache_key "$scheme$request_method$host$request_uri$query_string";
}

 

         - 값에 $query_string 변수가 포함되어 있으면 임의의 쿼리 문자열을 전송하는 공격으로 인해 오히려 과도한 캐싱이 발생할 수 있다. 특별한 이유가 없는 한 $query_string 변수를 키에 포함하지 않는 것이 좋다.

         - 이 설정에서는 $query_string을 캐시 키에 포함시킨다. 만약 /search?query=nginx와 /search?query=nginx&sort=date 같은 요청이 있다면, 이 두 요청은 쿼리 매개변수가 다르기 때문에 별도의 캐시 항목으로 저장된다. 이는 필요 이상으로 많은 캐시 항목을 생성할 수 있으므로, 쿼리 매개변수가 결과에 큰 영향을 미치지 않는 경우에는 쿼리 문자열을 캐시 키에서 제외하는 것이 좋다.

 

         - 적절한 $query_string 사용 예시 :

http {
    proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;

    server {
        location / {
            proxy_pass http://localhost:8000;
            set $cache_bypass 1;

            # 쿼리 매개변수 "nocache"가 있으면 캐시를 우회
            if ($arg_nocache) {
                set $cache_bypass 0;
            }

            proxy_cache my_cache;
            proxy_cache_bypass $cache_bypass;
            proxy_cache_key "$scheme$request_method$host$request_uri";
        }
    }
}

 

         - 이 설정에서는 $arg_nocache 변수를 사용하여 "nocache" 쿼리 매개변수의 존재 여부를 확인한다. 만약 요청 URL이 http://example.com/page?nocache=true와 같이 "nocache" 매개변수를 포함하고 있다면, 이 요청은 캐시를 우회하고 직접 백엔드 서버로 전달된다. 이 방법을 통해 특정 요청에 대해 캐시를 제어할 수 있다.

 

   7) 여러 조건의 요청을 차단하는 방법

      - 여러 종류의 요청을 차단하도록 nginx의 설정을 구성할 수 있다.

         - 타겟팅된 것으로 보이는 특정 url에 대한 접근

         - User-Agent 헤더가 정상적인 클라이언트 트래픽에 해당하지 않는 값으로, 비정상적인 트래픽으로 판단되는 요청

         - Referer 헤더가 공격과 관련이 있는 값으로 설정되어 있다 판단되는 요청

         - 이 외 다른 헤더에 공격과 관련될 수 있는 설정 값이 있다고 판단되는 요청

 

      - 예시) DDoS 공격이 /foo.php 주소를 공격 대상으로 삼고 있다면, 해당 페이지에 대한 모든 접근을 차단하도록 설정할 수 있다.

location /foo.php {
    deny all;
}

 

      - 예시) DDoS 공격이라 판단되는 헤더의 User-Agent 값이 foo 혹은 bar인 것을 확인하게 되면 해당 요청의 접근을 제한할 수 있다.

location / {
    if ($http_user_agent ~* foo|bar) {
        return 403;
    }
    # ...
}

 

   - reference : 

https://www.nginx.com/blog/rate-limiting-nginx/

 

NGINX Rate Limiting

Protect your applications from excessive traffic, including DDoS attacks, by controlling the requests they receive with NGINX rate limiting.

www.nginx.com

https://nginxstore.com/blog/nginx/nginx-%EB%B0%8F-nginx-plus%EB%A1%9C-ddos-%EA%B3%B5%EA%B2%A9-%EC%99%84%ED%99%94%ED%95%98%EA%B8%B0/

 

NGINX 및 NGINX Plus로 DDoS 공격 완화하기

NGINX와 NGINX Plus는 DDoS 방어 솔루션의 중요한 부분으로 사용할 수 있으며, NGINX Plus는 DDoS 공격으로부터 보호하고 공격 발생 시점을 식별하는 데 도움이 되는 추가 기능을 제공합니다.

nginxstore.com

https://velog.io/@damiano1027/Nginx-DoS-DDoS-%EA%B3%B5%EA%B2%A9-%EB%B0%A9%EC%96%B4-%EC%84%A4%EC%A0%95

 

[Nginx] DoS, DDoS 공격 방어 설정

며칠 전에 Nginx에서 DoS, DDoS 관련 설정을 공부해보고 설정한 바 있는데, 이에 대해 간단히 포스팅 해보고자 한다.공부하며 작성한 내용이기 때문에 오류가 있을 수 있습니다.악의적으로 서버에 re

velog.io

https://moonseoklee.tistory.com/entry/nginx%EB%A1%9C-%EC%95%85%EC%9D%98%EC%A0%81%EC%9D%B8-%EB%B0%98%EB%B3%B5-%EC%9A%94%EC%B2%AD-%EB%B0%A9%EC%A7%80%ED%95%98%EA%B8%B0

 

nginx로 악의적인 반복 요청 방지하기

웹 서비스 하나를 개발하였는데 백엔드 서버는 Django 와 gunicorn, nginx 를 같이 사용하고 있고 별도의 프론트엔드 서버와 통신하고 있다. 이제 서버 방어체계를 구축해야 한다. DDos 방어까지는 아니

moonseoklee.tistory.com

https://tech.goorm.io/ddos-%EC%96%B4%EB%94%94%EA%B9%8C%EC%A7%80-%EB%B0%A9%EC%96%B4%ED%95%B4%EB%B4%A4%EB%8B%88/

 

DDoS 어디까지 방어해봤니? - 구름 기술 블로그

서비스 제공사가 제일 두려운 것이 <그림 1>, <그림 2>와 같은 서비스 장애 알림이다. 나 또한 이러한 알림 메시지가 오지 않기를 늘 바라고 있다. 놀란 가슴을 진정시키고 서비스 장애의 원인부터

tech.goorm.io

https://nginxstore.com/nginx-modsecurity-waf/

 

NGINX ModSecurity WAF

NGINX ModSecurity WAF NGINX에서 지원하는 NGINX ModSecurity WAF 동적 모듈을 사용하여 SQLi, XSS, CSRF, LFI 및 RFI와 같은 Layer 7 공격으로부터 보호합니다. NGINX ModSecurity Web Application Firewall(WAF)은 ModSecurity 3.0을 기

nginxstore.com

https://sronsemiro.tistory.com/8

 

Nginx에 ModSecurity 웹방화벽 설치

* Ubuntu 18.04.4 LTS / Nginx 1.19.0 버전에서 테스트 했습니다. * Ubuntu에 Nginx가 설치되어있다고 가정합니다. 필요 라이브러리 설치 apt-get install autotools-dev automake libtool m4 pkgconf libcurl4-openssl-dev libxml2 libxml

sronsemiro.tistory.com

https://hoing.io/archives/9487

 

Nginx ModSecurity 설치 및 설정 - Nginx 웹 방화벽

 

hoing.io

 

 2. Fail2ban를 설치하여 DDoS 방어를 더 효율적으로 하기

   - 본문 실습 참고 : https://tech.goorm.io/ddos-%EC%96%B4%EB%94%94%EA%B9%8C%EC%A7%80-%EB%B0%A9%EC%96%B4%ED%95%B4%EB%B4%A4%EB%8B%88/

 

   - Fail2Ban은 서버의 로그 파일을 모니터링하여 비정상적인 접근 시도나 악의적인 행위를 감지하고, 이를 기반으로 IP 주소를 일정 시간 동안 차단하는 소프트웨어이다.

 

      1) Fail2Ban은 서버의 다양한 로그 파일을 지속적으로 검사한다. 이를 통해 비정상적인 로그인 시도, 취약점 탐색 시도 등 악의적인 징후를 감지할 수 있다.

 

      2) 감지된 비정상적인 행위가 설정된 임계값을 초과하면, Fail2Ban은 해당 IP 주소를 방화벽 규칙에 추가하여 일정 시간 동안 서버 접근을 차단한다. 이는 주로 iptables 또는 firewalld와 같은 방화벽 도구를 사용하여 구현된다.

 

      3) Fail2Ban은 다양한 서비스(예: SSH, Apache, Nginx 등)에 대한 사전 정의된 필터와 액션을 포함하고 있으며, 사용자는 이를 자유롭게 수정하거나 새로운 필터와 액션을 추가하여 사용할 수 있다. 이를 통해 서버의 보안 요구사항에 맞게 Fail2Ban을 맞춤 설정할 수 있다.

 

      4) Fail2Ban은 IP 차단 외에도 알림 이메일 전송과 같은 다양한 추가 동작을 설정할 수 있어, 보안 관리자가 비정상적인 접근 시도를 신속하게 인지하고 대응할 수 있도록 돕는다.

 

   1) Fail2Ban 설치하기

      1) nginx가 설치 되어 있다고 가정한다.

      2) DDoS 공격을 탐지하기 위해 Nginx에 설정을 한다.

# /etc/nginx/sites-enabled/default 
# 모든 도메인에 공통적으로 적용하려면 nginx.conf에 정의하면 된다.
# 각각의 도메인별로 설정하려면 해당 도메인의 conf 파일에 정의하면 된다.

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

...

location / {
	...
    limit_req zone=ddos_limit burst=10 nodelay;
    real_ip_header    X-Forwarded-For;
    set_real_ip_from 0.0.0.0/0;
}

 

         1.요청 속도 제한 설정 :

            - limit_req: 요청 속도를 제한하는 지시어이다.
            - zone=ddos_limit: ddos_limit이라는 이름의 속도 제한 구역을 사용한다.
            - burst=10: 초과 요청을 허용하는 버스트 크기를 10으로 설정한다. 이는 초과 요청이 일정 수준까지는 버퍼링되어 처리될 수 있음을 의미한다.
            - nodelay: 초과 요청이 즉시 처리되도록 설정한다. 즉, 요청이 버스트 한도 내에 있으면 대기 시간 없이 즉시 처리된다. 

 

         2. 실제 IP 주소 식별 설정 :

            - real_ip_header X-Forwarded-For :
               - real_ip_header: 클라이언트의 실제 IP 주소를 식별하기 위해 사용되는 헤더이다.
               - X-Forwarded-For: 프록시 서버를 통해 전달된 요청의 원래 IP 주소를 식별하는 데 사용되는 표준 헤더이다. 

            - set_real_ip_from 0.0.0.0/0 :

               - set_real_ip_from: 실제 IP 주소를 식별할 수 있는 트래픽의 출처 IP 범위를 지정한다.
               - 0.0.0.0/0: 모든 IP 주소에서 오는 트래픽을 실제 클라이언트 IP로 간주한다. 이 설정은 보안상 주의가 필요하며, 실제 환경에서는 신뢰할 수 있는 IP 범위로 제한하는 것이 좋다.

 

      3) Fail2ban 설치하기

sudo apt install -y fail2ban

      

         - 보통은 설치 완료 후 Fail2ban이 바로 실행되지만, docker나 특정 클라우드의 환경에서 Fail2ban의 기본 설정에 의해 바라보고 있는 sshd 데몬의 로그를 확인할 수 없는 경우가 발생하거나 다른 문제들로 service의 시작이 안되는 경우가 발생할 수 있다.

 

         - 관련한 설정이 많이 있지만, DDoS 방어와 관련한 핵심적인 설정만 간단히 설정해 보도록 한다.

         - apt로 설치한 fail2ban-server의 버전은 Fail2Ban v0.11.1이다.

         - 참고한 문서에서는 /etc/fail2ban/jail.d/jail.local를 참고하라고 되어 있지만, 실재로 찾아본 파일의 경로와 이름은 다음과 같다.

            - /etc/fail2ban/fail2ban.conf

         - 파일을 열고 설정의 일부분을 변경/추가 한다.

[nginx-limit-req]
enabled = true                       # 설정 on/off
filter = nginx-limit-req             # 사용할 필터 이름
findtime = 60                        # 모니터링 시간 (60초)
maxretry = 10                        # 60초 동안 10번 이벤트 발생 시 차단
bantime = 10800                      # 차단 시간 (3시간)
port = http, https                   # 차단 대상 포트
protocol=tcp                         # 차단 대상의 프로토콜
banaction = iptables-multiport       # 차단 방식 선택 ( iptables 이용 )
action_with_ban = %(banaction)s[name=%(__name__)s, bantime="%(bantime)s", port="%(port)s", protocol="%(protocol)s"]
action = %(action_with_ban)s    # 차단 액션 등록
logpath = /var/log/nginx/*error.log  # 모니터링할 로그 파일 경로

 

         - fail2ban이 동작하는데 문제가 되었던 sshd 데몬을 바라보는 문제를 해결한다.

            - /etc/fail2ban/jail.d/defaults-debian.conf

# /etc/fail2ban/jail.d/defaults-debian.conf

[sshd]
enabled = false

 

         - 동작 시나리오 :

            1. 악성 사용자가 DDoS 공격을 시도하면 Nginx가 특정 IP에 대해 서버가 응답하기 전에, Nginx 설정 파일에서 설정한 대기열 10개를 넘어서면 요청한 IP와 limit_req log를 error log에 남긴다.

            2. Fail2ban은 nginx의 error log을 실시간으로 모니터링한다.

            3. 1분 동안 해당 로그가 10번 이상 발생해 임계치에 도달하면 서버 방화벽(iptables)을 이용해 해당 IP의 TCP 80, 443번 포트를 차단한다.

            4. DDoS 공격이 Nginx로 도달하지 못하게 막아 불필요한 부하로 서비스가 멈추는 것을 방지한다.

 

         - fail2ban 시작하기

service fail2ban start

 

      4) 스트레스 테스트 siege로 DDoS 설정 테스트하기

         - siege 설치하기

service fail2ban start

         

         - siege 실행하기

siege -b -c 100 localhost -v

 

            - '-b'  옵션 : 벤치마크 모드로 실행하라는 옵션이다. 이 모드에서는 사용자 시뮬레이션 대신 최대한 빠르게 요청을 보낸다.

            - '-c 100' 옵션 : 동시에 100개의 연결(클라이언트)를 생성하여 서버에 요청을 보내라는 의미이다.

            - localhost : 테스트 대상 서버의 주소이다. 여기서는 로컬 컴퓨터에 설치된 서버를 대상으로 한다.

            - '-v' : 실행 과정에서 발생하는 세부 정보를 출력하라는 옵션이다. 요청과 응답에 대한 정보를 보여준다.

 

         - siege 로그 및 테스트 중단 :

            - 연결이 거부되면 테스트는 중단된다.

 

         - Nginx 에러 로그 확인 :

            - ddos_limit 문자와 함께 웹 서버가 해당 요청에 더 이상 응답하지 않는 것을 확인할 수 있다.

tail -f /var/log/nginx/error.log

 

   - reference : 

https://fail2ban.readthedocs.io/en/latest/#

 

Welcome to Fail2Ban’s developers documentation! — Fail2Ban 0.9.0.dev documentation

 

fail2ban.readthedocs.io

https://www.digitalocean.com/community/tutorials/how-to-protect-an-nginx-server-with-fail2ban-on-ubuntu-20-04

 

How To Protect an Nginx Server with Fail2Ban on Ubuntu 20.04 | DigitalOcean

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

www.digitalocean.com

https://scalastic.io/en/ufw-fail2ban-nginx/

 

Turn Your Nginx Server into a Fortress with Fail2ban and UFW

The ultimate guide to securing your Nginx server on Ubuntu with Fail2ban and UFW. Practical tips for an infallible defense.

scalastic.io

https://nginxstore.com/blog/nginx/fail2ban-%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC-nginx-%EB%8F%99%EC%A0%81-ip-%EC%B0%A8%EB%8B%A8/

 

fail2ban 사용하여 NGINX 동적 IP 차단

이 블로그 게시물에서는 수상한 활동을 감지하고, 사전에 구성된 하나 이상의 작업을 수행합니다. 일반적으로 fail2ban 은 로그인 실패 시도를 모니터링하고, 그러한 시도를 한 Dynamic IP 주소를 일

nginxstore.com

https://forum.openmediavault.org/index.php?thread/49480-nginx-proxy-manager-with-fail2ban-guide/

 

NGINX Proxy Manager with fail2ban guide - openmediavault

OMV nginx-proxy-manager (referred to as NPM from here on) and fail2ban tutorial This tutorial will assume that you know how to port forward in your router and that you have a DNS service configured to route incoming internet traffic to your internet…

forum.openmediavault.org

 

 3. modsecurity 설치로 웹 방화벽 구축하기

   - nginx-plus(유료 버전)를 이용하면 쉽게 설치할 수 있는 방법이 제공된다.

   - 하지만 nginx에 설치를 하려는 경우, 제대로 된 설정 방법과 테스트 방법이 준구 난방이다.

   - 같이 설치를 하는 modsecurity-crs의 경우, github의 문서는 수년 전 이후 다른 저장소로 변경된 것으로 보인다.

   - 테스트는 성공적으로 완료 했으나, 테스트 및 동작의 신뢰성을 확신할 수 없기에 참고한 사이트만 정리한다.

 

   - 참고로 아래 문서들에는 설정 파일들이 서로 각기 다르다. find를 이용해 파일명을 찾아 사용해야 한다.

   - 설정 파일에는 더 이상 사용되지 않는 설정값이 있고, nginx 패키지를 설치했는데 apache에 대한 log 경로가 있다. 이러한 부분들을 검증하기 위해 nginx -t를 사용해 설정 값들에 대해 이동 및 변경 후 검증해야 한다.

 

https://seomj74.tistory.com/354

 

Nginx ModSecurity 및 CRS 적용하기

ModSecurity 표준 오픈 소스 웹 애플리케이션 방화벽(WAF) 엔진 Apache HTTP Server용 모듈로 설계되었지만 다양한 플랫폼에서 HTTP 요청 및 응답 필터링 기능을 제공하도록 발전했다. 상세 설정 사항은 owas

seomj74.tistory.com

https://github.com/owasp-modsecurity/ModSecurity/wiki/Reference-Manual-%28v3.x%29

 

Reference Manual (v3.x)

ModSecurity is an open source, cross platform web application firewall (WAF) engine for Apache, IIS and Nginx that is developed by Trustwave's SpiderLabs. It has a robust event-based programmin...

github.com

https://dyoerr9030.tistory.com/entry/Modsecurity%EB%9E%80

 

[Modsecurity] Modsecurity란?

Modsecurity에 대해 공부하기 전에 먼저 웹 방화벽에 대해서 알아야 한다. 웹 방화벽 웹 방화벽(Web Application Firewall, WAF)이란, 일반적인 네트워크 방화벽(Firewall)과는 달리 웹 애플리케이션 보안에 특

dyoerr9030.tistory.com

https://github.com/phusion/nginx-modsecurity-ubuntu

 

GitHub - phusion/nginx-modsecurity-ubuntu: Ubuntu package for modsecurity-nginx

Ubuntu package for modsecurity-nginx. Contribute to phusion/nginx-modsecurity-ubuntu development by creating an account on GitHub.

github.com

https://redundant4u.com/post/cloud-security

 

학부생이 바라본 클라우드 보안 | 설명탕

설명탕은 공유하고 싶은 컴퓨터 관련 글 또는 영상을 요약하여 전달하거나, 소개하고 싶은 저의 경험을 여러분들한테 전달합니다.

redundant4u.com

https://awjunaid.com/nginx/how-to-secure-nginx-with-modsecurity/

 

How to Secure Nginx with ModSecurity | Abdul Wahab Junaid

Securing Nginx with ModSecurity involves adding a Web Application Firewall (WAF) to protect your web server and applications from various web-based

awjunaid.com

https://access.redhat.com/documentation/ko-kr/red_hat_enterprise_linux/8/html/deploying_different_types_of_servers/assembly_securing-web-applications-on-a-web-server-using-modsecurity_setting-apache-http-server

 

1.11. ModSecurity를 사용하여 웹 서버에서 웹 애플리케이션 보안 Red Hat Enterprise Linux 8 | Red Hat Customer

Access Red Hat’s knowledge, guidance, and support through your subscription.

access.redhat.com

https://modsecurity.digitalwave.hu/

 

Digitalwave ModSecurity Repository

 

modsecurity.digitalwave.hu

https://github.com/coreruleset/coreruleset

 

GitHub - coreruleset/coreruleset: OWASP CRS (Official Repository)

OWASP CRS (Official Repository). Contribute to coreruleset/coreruleset development by creating an account on GitHub.

github.com

 

댓글