현재 포스트는 예쁜 블로그 테마 Haon Blog 로 이전되었습니다. 지금보다 훨씬 예쁜 뷰에서 가독성 있는 글을 읽을 수 있습니다 🙂
두가지 공격방식 모두 공격 대상 서버에다 Request 를 많이 날려서, 리소스를 소진시켜 서버가 마비되도록 하는 공격 기법입니다. 다만 차이점이 약간 존재합니다.
DoS 는 직접 공격대상 서버를 공격하는 것으로, 한대의 PC 만으로 요청을 여러번 날려서 리소스를 소진시키도록 만드는 것입니다.
DDos(Distributed Denial of Service) 는 반면 해커카 감염시킨 여러 좀비 PC 들을 활용해서 여러대로 공격시키는 방법입니다. 떄문에 감염된 PC 들은 자신도 모르는 사이에 악성코드들에 감염되고 해커의 공격에 악용되는 셈입니다.
본격적인 설명전에, 잠깐 Nginx 와 스프링부트 애플리케이션 환경을 어떻게 구축했는지를 잠깐 짚고 넘어가봅시다.
upstream backend{
server 111.11.111.111:8080;
}
server{
listen 80;
location / {
proxy_pass http://backend;
}
location /admin {
proxy_pass http://backend;
auth_basic "접근제한!";
auth_basic_user_file /etc/nginx/.htpasswd;
}
}
이렇게 악의적인 공격으로 서버에 매우빠른 속도로 요청을 넣으면 서버가 다운될 수 있습니다. 이럴때는 시간당 Request 개수를 제한하고, 해당 제한 개수를 초과하게 되면 해당 Request 는 거절하는 설정을 해주면 됩니다.
아래와 같이 코드를 리팩토링을 해봤습니다. 이에 대해 분석해봅시다.
upstream backend{
server 111.11.111.111:8080;
}
limit_req_zone $binary_remote_addr zone=ddos_req:10m rate=5r/s; // 변경 라인
server{
listen 80;
location / {
proxy_pass http://backend;
limit_req zone=ddos_req; // 변경 라인
}
location /admin {
proxy_pass http://backend;
auth_basic "접근제한!";
auth_basic_user_file /etc/nginx/.htpasswd;
}
}
1-1. $binary_remote_addr
1-2.zone=ddos_req:10m
1-3. rate=5r/s
2-1.limit_req
2-2.zone=ddos_req
이렇게 설명을 모두 마치면 Nginx 서버에 대한 모든 URL 의 요청에 대해서는 하나의 클라이언트 IP의 Request에 대해 1초에 최대 5개까지만 수용할 수 있게 됩니다.
또한 나머지 Request 는 모두 거절하는것이죠.
앞선 limit_req_zone 설정에서 허용된 요청수 범위를 벗어나게 되면, 기본적으로 503 status code 값을 리턴합니다.
그런데 아래처럼 limit_req_status 설정을 하면 리턴될 status code 값을 지정할 수 있습니다.
upstream backend{
server 111.11.111.111:8080;
}
limit_req_zone $binary_remote_addr zone=ddos_req:10m rate=5r/s;
limit_req_status 404; // 404 상태코드를 리턴하도록 지정
server{
listen 80;
location / {
proxy_pass http://backend;
limit_req zone=ddos_req;
}
location /admin {
proxy_pass http://backend;
auth_basic "접근제한!";
auth_basic_user_file /etc/nginx/.htpasswd;
}
}
burst 라는것을 활용하면 초과된 요청들을 조금 더 허용할 수 있습니다.
아래와 같이 burst 를 추가해주면, 초과된 Request 에 대해 최대 5개까지를 버킷에 임시로 담아두고, 앞선 Request 들에 대한 처리가 끝난 후 차례대로 처리하도록 하는 설정입니다.
limit_req zone=ddos_req brust=5;
이를 적용한 전체 코드는 아래와 같습니다.
upstream backend{
server 111.11.111.111:8080;
}
limit_req_zone $binary_remote_addr zone=ddos_req:10m rate=5r/s;
limit_req_status 404;
server{
listen 80;
location / {
proxy_pass http://backend;
limit_req zone=ddos_req brust=5; // 버킷에 최대 5개까지 임시저장
}
location /admin {
proxy_pass http://backend;
auth_basic "접근제한!";
auth_basic_user_file /etc/nginx/.htpasswd;
}
}
하나의 클라이언트가 여러 Request 를 동시에 넣게되면 서버에 부하줄 수 있습니다. 이를위해 동시에 들어오는 Request 개수를 제한할 수도 있습니다.
upstream backend{
server 111.11.111.111:8080;
}
limit_req_zone $binary_remote_addr zone=ddos_req:10m rate=5r/s;
limit_req_status 404;
server{
listen 80;
location / {
proxy_pass http://backend;
limit_req zone=ddos_req 10; // 한 클라이언트에 대해 최대 10개의 요청을 동시에 처리가능
}
location /admin {
proxy_pass http://backend;
auth_basic "접근제한!";
auth_basic_user_file /etc/nginx/.htpasswd;
}
}
한 클라이언트가 보낸 요청을 동시에 최대 10까지만 처리할 수 있도록 지정해준것입니다. 만약 50개의 요청을 동시에 보내면 10개는 처리되고, 나머지 40개느 거절되는 것이겠죠?
특정 ip들에 대해 아예 request를 못하게 제한할 수도 있습니다.
location / {
deny 333.333.333.3;
deny 444.444.444.4;
deny 555.555.555.5;
...
지금까지 DDos, Dos 공격으로 인해 발생하는 동시성 Request 들로 인해 Nginx 서버에서 발생하는 부하를 어떻게 처리할 수 있을지에 대해 다루었습니다. 더 자세한 내용은 Mitigating DDoS Attacks with NGINX and NGINX Plus 도큐먼트를 참고해주세요!
Nginx Docs
[Nginx] DoS, DDoS 공격 방어 설정
DDoS vs DoS 차이점 및 디도스 공격의 유형 및 특징 알아보기 (1)
.