[javascript] Express.js에서의 DOS/DDOS 공격 방어 방법

Distributed Denial of Service (DDoS) 및 Denial of Service (DoS) 공격은 애플리케이션에 대한 서비스 거부를 일으키기 위해 다수의 요청을 악의적으로 보내는 공격 유형입니다. Express.js는 Node.js 위에서 작동하는 빠르고 유연한 웹 프레임워크이지만, 악의적인 공격으로부터 보호받아야 합니다.

이 글에서는 Express.js 애플리케이션을 보호하기 위한 몇 가지 기본적인 방어 방법을 소개하겠습니다.

1. Rate Limiting (요청 제한)

Rate limiting은 애플리케이션에 대한 요청 속도를 제한하는 방법입니다. 이를 통해 한 사용자나 IP 주소가 너무 많은 요청을 보내는 것을 방지할 수 있습니다. Express.js에서는 express-rate-limit 미들웨어를 사용하여 Rate Limiting을 구현할 수 있습니다.

const rateLimit = require("express-rate-limit");

const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15분 동안
  max: 100, // 최대 100개의 요청만 허용
});

app.use(limiter);

위의 코드는 15분 동안 최대 100개의 요청만 허용하는 Rate Limiting을 구현한 예시입니다. 필요에 따라 windowMsmax 값을 조정하여 요청 제한을 조절할 수 있습니다.

2. CAPTCHA (외부 인증)

CAPTCHA는 자동화된 스크립트나 봇에 의해 생성된 요청을 차단하기 위한 대표적인 방법입니다. 사람인지를 구별하기 위해 화면에 이미지나 문제를 제시하고, 사용자가 올바른 응답을 제출해야만 요청이 처리되도록 합니다. Express.js에서는 express-recaptcha와 같은 외부 CAPTCHA 서비스와 함께 사용할 수 있습니다.

const Recaptcha = require("express-recaptcha").RecaptchaV3;

const recaptcha = new Recaptcha(
  "SITE_KEY", // 사이트 키
  "SECRET_KEY", // 비밀 키
  { callback: "cb" /* 콜백 함수 이름 */ }
);

app.post("/login", recaptcha.middleware.verify, (req, res) => {
  if (req.recaptcha.error) {
    res.status(403).send("인증 실패");
  } else {
    // 인증 성공
    // 로그인 처리 등...
  }
});

위의 코드는 CAPTCHA 인증을 위해 express-recaptcha 모듈을 사용하는 예시입니다. SITE_KEYSECRET_KEY를 자신의 CAPTCHA 서비스 키로 변경해야 합니다.

3. 웹 방화벽

웹 방화벽은 Express.js 애플리케이션 바로 앞에 배치되어 악성 요청을 필터링하고 차단하는 역할을 합니다. 웹 방화벽에는 다양한 종류와 기능이 있으며, 대표적인 예로 Cloudflare나 AWS WAF가 있습니다. 웹 방화벽은 기존의 DDOS 공격에 대한 보호뿐만 아니라 다양한 보안 기능을 제공합니다.

4. 서버 부하 분산

Express.js 애플리케이션을 여러 대의 서버 인스턴스에 배포하여 부하를 분산하는 것은 공격에 대한 내구성을 향상시키는 좋은 방법입니다. 이를 위해 로드 밸런싱을 구성하고, 여러 인스턴스 간의 트래픽을 균등하게 분배해주는 도구를 사용할 수 있습니다. 예를 들면, Nginx의 upstream 모듈을 사용하여 로드 밸런싱을 설정할 수 있습니다.

http {
  upstream backend {
    server backend1.example.com;
    server backend2.example.com;
    server backend3.example.com;
  }

  server {
    listen 80;
    location / {
      proxy_pass http://backend;
    }
  }
}

위의 Nginx 설정은 / 경로의 요청을 backend1.example.com, backend2.example.com, backend3.example.com 서버로 균등하게 분배합니다. 이렇게 서버 부하를 분산하면 단일 서버에 대한 공격에도 대응할 수 있습니다.

위에서 소개한 방법들을 조합하여 Express.js 애플리케이션을 가능한 공격으로부터 보호할 수 있습니다. 하지만 보안은 지속적으로 검토되고 업데이트되어야 하므로, 최신 보안 업데이트를 적용하고 보안 관련 뉴스와 정보를 주시하는 것이 중요합니다.

참고 문서