Nginx Ingress Controller DDOS Protection #1 (feat. locust)

kimchigood·2022년 6월 24일
0

Kubernetes Security

목록 보기
1/1
post-thumbnail

이번 포스팅에서는 Kubernetes상에서 Nginx Ingress Controller 사용 시 DDOS Attack을 방어하는 방법에 대해 알아보겠다.

DDOS Attack?

Distributed Denial of Service의 약자로 공격자가 대량의 트래픽을 특정서버로 보내서 사이트의 기능을 마비시키는 공격이다.

보통 공격은 OSI 7Layer 기준으로 인프라 계층인 L3/4를 공격하거나 어플리케이션 계층인 L6/7 으로 분류될 수 있다.
더 깊이 보면 수 많은 종류의 DDOS 공격유형이 있는데 방식이 날이 갈수록 다양해지고 있다고 한다. 포스팅에서는 어플리케이션 운영자 관점에서 L7 계층의 방어에 대해 다루도록 하겠다.

Nginx Rate Limiting

Nginx에서는 DDOS Attack에 대비하여 몇가지 레퍼런스와 방어 정책을 제공하는데, Kubernetes에서 구동하는 Nginx의 설정방법은 기존 Nginx와는 다르게 대부분 Annotation으로 세팅이 가능하다.

Nginx helm chart value.yaml

controller:
  name: controller
  image:
    ## Keep false as default for now!
    chroot: false
    registry: registry.k8s.io
    image: ingress-nginx/controller
    ## for backwards compatibility consider setting the full image url via the repository value below
    ## use *either* current default registry/image or repository format or installing chart by providing the values.yaml will fail
    ## repository:
    tag: "v1.2.1"
    digest: sha256:5516d103a9c2ecc4f026efbd4b40662ce22dc1f824fb129ed121460aaa5c47f8
    digestChroot: sha256:d301551cf62bc3fb75c69fa56f7aa1d9e87b5079333adaf38afe84d9b7439355
    pullPolicy: IfNotPresent
    # www-data -> uid 101
    runAsUser: 101
    allowPrivilegeEscalation: true

  # -- Use an existing PSP instead of creating one
  existingPsp: ""

  # -- Configures the controller container name
  containerName: controller

  # -- Configures the ports that the nginx-controller listens on
  containerPort:
    http: 80
    https: 443

  # -- Will add custom configuration options to Nginx https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/
  config: {}  <- http-snippet, server-snippet 적용가능
  

Helm chart로 설치하면 value.yaml에 config 설정을 할 수 있는데, 여기서 그냥 Nginx와 같이 http-snippet, server-snippet이 다 먹히긴 하지만, 맘편하게 Kubernetes의 Ingress 리소스에서 Annotation 설정을 하는게 좋다.

1. limit-connections

nginx.ingress.kubernetes.io/limit-connections: 한 개의 IP에서 동시에 연결 가능한 커넥션 수를 제한한다.

Kubernetes Nginx와 그냥(?) Nginx 세팅 방식을 비교해보자

nginx-ingress.yaml (kubernetes)

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/limit-connections: "10"

nginx.conf (그냥 Nginx)

limit_conn_zone $binary_remote_addr zone=addr:10m;
server {
    # ...
    location /store/ {
        limit_conn addr 10;
        # ...
    }
}

Kubernetes Nginx는 딱 한 줄 만 추가하면 된다. 개인적으로 가독성도 더 뛰어나고 복잡하지도 않은 것 같다.


2. limit-rps, limit-rpm

nginx.ingress.kubernetes.io/limit-rps : 클라이언트 IP에서의 초당 요청 건 수 제한 nginx.ingress.kubernetes.io/limit-rpm : 클라이언트 IP에서의 분당 요청 건 수 제한

nginx-ingress.yaml (kubernetes)

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/limit-connections: "10"
    nginx.ingress.kubernetes.io/limit-rps: "2"

**여기서 질문? 왜 초, 분으로 나눠져 있을까? **어차피 계산하면 똑같은거 아닐까? 다음 포스팅에서 설명하겠다.


3. limit-burst-multiplier

nginx.ingress.kubernetes.io/limit-burst-multiplier: 초과된 request에 대해 accept 해주는 값 (default:5)


4. whitelist-source-range:

nginx.ingress.kubernetes.io/whitelist-source-range: IP 수준에서 block/allow를 할 수 있는 방화벽 기능

nginx-ingress.yaml (kubernetes)

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/limit-connections: "10"
    nginx.ingress.kubernetes.io/limit-rps: "2"
    nginx.ingress.kubernetes.io/whitelist-source-range: |
      111.111.111.0/24,22.222.222.22/32

5. Closing Slow Connections

응답 시간을 길게 해서 새로운 connection을 감소시키는 Slowloris라는 공격도 있다. 이것도 client_body_timeout , client_header_timeout 값 설정으로 할 수 있는데, global한 세팅이라 위 helm chart의 value.yaml을 수정해야한다. (default: 60s)

value.yaml

config: 
  client-header-timeout: 60; 
  client-body-timeout: 60;

Nginx와 Nginx Ingress Controller 의 config key 값이 조금 다르니 주의하도록 하자.(-/_ 차이가 있음)
참조 : https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#limit-rate

자, 그럼 이런 DDOS 세팅들이 어떻게 먹힐까? 다음 포스팅에서 테스트 해보겠다.

profile
Shout out to Kubernetes⎈

0개의 댓글