フリーキーズ | 独学プログラミング

DoS/DDoS攻撃とは?レート制限で守るWebセキュリティ入門

リンドくん

リンドくん

先生、ニュースで「DDoS攻撃でサービスが停止」って聞いたんですけど、これって何なんですか?

たなべ

たなべ

DDoS攻撃は、Webサービスを使えなくする代表的な攻撃手法なんだ。
今日は、この攻撃がどういうものか、そしてどうやって防ぐかを学んでいこう。

Webサービスを運営していると、必ず直面するのがサービス妨害攻撃への対策です。
特に近年では、DoS/DDoS攻撃による大規模なサービス停止が頻繁にニュースになっています。

この記事では、DoS/DDoS攻撃とは何か、そしてレート制限による防御方法について、プログラミング初心者の方でも理解できるよう、基礎から丁寧に解説していきます。

プログラミング学習でお悩みの方へ

HackATAは、エンジニアを目指す方のためのプログラミング学習コーチングサービスです。 経験豊富な現役エンジニアがあなたの学習をサポートします。

✓ 質問し放題

✓ β版公開中(2025年内の特別割引)

HackATAの詳細を見る

DoS攻撃とDDoS攻撃の基本を理解しよう

リンドくん

リンドくん

DoSとDDoSって似た名前ですけど、違うものなんですか?

たなべ

たなべ

DoSは1台のコンピュータから、DDoSは大量のコンピュータから攻撃する違いがあるよ。
DDoSの方がはるかに防ぐのが難しいんだ。

DoS攻撃とは

DoS(Denial of Service)攻撃とは、サービス妨害攻撃のことです。
攻撃者が意図的に大量のリクエストをサーバに送りつけることで、正規のユーザーがサービスを利用できなくする攻撃手法です。

具体的には以下のような影響が発生します。

  • サーバの処理能力を超える負荷をかけてサービスを停止させる
  • ネットワーク帯域を使い切ることで通信不能にする
  • サーバのメモリやCPUリソースを枯渇させる

たとえば、普段100人のユーザーが利用するサービスに対して、攻撃者が一人で1万件のリクエストを送り続けたとします。すると、サーバは攻撃者のリクエスト処理に追われ、正規のユーザーからのアクセスに応答できなくなってしまうのです。

DDoS攻撃の恐ろしさ

DDoS(Distributed Denial of Service)攻撃は、DoS攻撃をさらに強力にしたものです。
「Distributed(分散)」という言葉が示す通り、複数のコンピュータから同時に攻撃を仕掛ける手法です。

DDoS攻撃の特徴は以下の通りです。

  • 数千〜数万台のコンピュータから同時攻撃
  • ボットネット(乗っ取られたコンピュータ群)を使用することが多い
  • 攻撃元の特定が極めて困難
  • 攻撃規模が巨大で防御が非常に難しい

DDoS攻撃では、攻撃者は事前にマルウェアなどで多数のコンピュータを乗っ取り、それらを遠隔操作して一斉に攻撃を行います。正規のユーザーと攻撃者を区別するのが難しいため、防御が複雑になるのです。

被害事例

過去には以下のような大規模なDDoS攻撃が発生しています。

  • 金融機関へのDDoS攻撃 → オンラインバンキングサービスが数時間停止
  • ECサイトへの攻撃 → セール期間中に攻撃され、大きな機会損失
  • ゲームサーバへの攻撃 → オンラインゲームが遊べなくなり、ユーザー離れが発生

これらの攻撃による損害は、数百万円から数億円規模に及ぶこともあり、企業にとって深刻な脅威となっています。

レート制限の基本概念と実装の重要性

リンドくん

リンドくん

じゃあ、こうした攻撃からサービスを守るにはどうすればいいんですか?

たなべ

たなべ

そこで登場するのがレート制限(Rate Limiting)なんだ。
簡単に言うと、一定時間内にアクセスできる回数を制限する仕組みだよ。

レート制限とは

レート制限とは、特定のユーザーやIPアドレスからのリクエスト数を制限する防御手法です。
これにより、以下のような効果が得られます。

  • 異常に多いリクエストを自動的にブロックできる
  • サーバリソースの保護が可能になる
  • 正規ユーザーへのサービス提供を維持できる

たとえば、「1分間に100回まで」というレート制限を設定すれば、それを超えるリクエストは自動的に拒否されます。正規のユーザーが1分間に100回もアクセスすることはまずないため、異常なアクセスだけを効果的にブロックできるわけです。

レート制限の種類

レート制限には、いくつかの実装方法があります。

IPアドレスベース

  • 最も基本的な方法
  • 同一IPアドレスからのリクエスト数を制限
  • ただし、プロキシやVPNを使われると回避される可能性がある

ユーザーアカウントベース

  • ログイン後のユーザーごとに制限
  • より正確な制限が可能
  • APIトークンなどと組み合わせて使用されることが多い

エンドポイントベース

  • APIの各エンドポイントごとに異なる制限を設定
  • 負荷の高い処理には厳しい制限を適用できる

レート制限の実装パターン

代表的な実装パターンとしては以下があります。

固定ウィンドウ方式

  • 1分ごとなど、固定された時間枠でカウントをリセット
  • シンプルだが、時間枠の境界で一時的に2倍のリクエストを受ける可能性がある

スライディングウィンドウ方式

  • 直近N秒間のリクエスト数を常に追跡
  • より正確だが、実装がやや複雑

トークンバケット方式

  • 一定速度でトークンが補充され、リクエストごとにトークンを消費
  • バーストトラフィックにも柔軟に対応できる

これらの中から、サービスの特性に応じて適切な方式を選択することが重要です。

レート制限の実装方法

リンドくん

リンドくん

実際にどうやってコードで実装するんですか?難しそうですね...

たなべ

たなべ

心配しないで!実は、便利なライブラリやツールがたくさんあるから、意外と簡単に実装できるんだよ。
具体的な例を見てみよう。

Express.jsでのレート制限実装

Node.jsのWebフレームワークであるExpress.jsでは、express-rate-limitというライブラリを使うことで簡単にレート制限を実装できます。

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

const app = express();

// レート制限の設定
const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15分間
  max: 100, // 最大100リクエスト
  message: 'リクエストが多すぎます。しばらく待ってから再度お試しください。',
  standardHeaders: true, // RateLimit-* ヘッダーを返す
  legacyHeaders: false, // X-RateLimit-* ヘッダーは使用しない
});

// すべてのリクエストに適用
app.use(limiter);

// 特定のエンドポイントにのみ適用する例
const apiLimiter = rateLimit({
  windowMs: 1 * 60 * 1000, // 1分間
  max: 5, // 最大5リクエスト
});

app.use('/api/', apiLimiter);

app.get('/api/data', (req, res) => {
  res.json({ message: 'データを取得しました' });
});

app.listen(3000, () => {
  console.log('サーバーが起動しました');
});

このコードでは、15分間に100回までという全体的な制限と、APIエンドポイントには1分間に5回までという厳しい制限を設定しています。

Nginxでのレート制限

Webサーバとして広く使われているNginxでも、レート制限を設定できます。

# リクエスト数を記録するゾーンを定義
limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;

server {
    listen 80;
    server_name example.com;

    # レート制限の適用
    location / {
        limit_req zone=general burst=20 nodelay;
        proxy_pass http://backend;
    }

    # APIエンドポイントにはより厳しい制限
    location /api/ {
        limit_req_zone $binary_remote_addr zone=api:10m rate=2r/s;
        limit_req zone=api burst=5;
        proxy_pass http://backend;
    }
}

この設定では、1秒あたり10リクエストを基本レートとし、最大20リクエストまでのバーストを許可しています。APIエンドポイントにはさらに厳しい1秒あたり2リクエストの制限を設けています。

Redisを使った分散環境でのレート制限

複数のサーバで運用している場合、Redisを使うことで、サーバ間で共通のレート制限を実装できます。

const redis = require('redis');
const { RateLimiterRedis } = require('rate-limiter-flexible');

const redisClient = redis.createClient({
  host: 'localhost',
  port: 6379,
});

const rateLimiter = new RateLimiterRedis({
  storeClient: redisClient,
  keyPrefix: 'rate_limit',
  points: 10, // 10ポイント
  duration: 1, // 1秒あたり
});

// ミドルウェアとして使用
app.use(async (req, res, next) => {
  try {
    await rateLimiter.consume(req.ip);
    next();
  } catch (error) {
    res.status(429).send('リクエストが多すぎます');
  }
});

このように、Redisを使用することで、複数のサーバインスタンス間で一貫したレート制限を実現できます。

レート制限以外の防御策と組み合わせ

リンドくん

リンドくん

レート制限だけで完璧に防げるんですか?

たなべ

たなべ

いい質問だね!実は、レート制限だけでは不十分なんだ。
複数の防御策を組み合わせることで、より強固なセキュリティを実現できるよ。

CAPTCHAの活用

CAPTCHAは、人間とボットを区別するための仕組みです。
疑わしいアクセスに対してCAPTCHAを表示することで、自動化された攻撃を防ぐことができます。

reCAPTCHAを使った実装例は以下のようになります。

const axios = require('axios');

async function verifyCaptcha(token) {
  const secretKey = 'YOUR_SECRET_KEY';
  const response = await axios.post(
    `https://www.google.com/recaptcha/api/siteverify`,
    null,
    {
      params: {
        secret: secretKey,
        response: token,
      },
    }
  );
  
  return response.data.success;
}

app.post('/api/submit', async (req, res) => {
  const { captchaToken, data } = req.body;
  
  // CAPTCHAの検証
  const isHuman = await verifyCaptcha(captchaToken);
  
  if (!isHuman) {
    return res.status(400).json({ error: 'CAPTCHA検証に失敗しました' });
  }
  
  // 正常な処理を続行
  res.json({ success: true });
});

IPアドレスのブロックリスト管理

既知の攻撃元IPアドレスをブロックリストに登録し、アクセスを拒否する方法も有効です。

const blocklist = new Set([
  '192.168.1.100',
  '10.0.0.50',
  // 攻撃元IPアドレスを追加
]);

app.use((req, res, next) => {
  const clientIP = req.ip;
  
  if (blocklist.has(clientIP)) {
    return res.status(403).send('アクセスが拒否されました');
  }
  
  next();
});

CDNとWAFの利用

CDN(Content Delivery Network)WAF(Web Application Firewall)を組み合わせることで、より高度な防御が可能になります。

主要なCDN/WAFサービスには以下があります。

  • Cloudflare → 無料プランでも基本的なDDoS対策が利用可能
  • AWS CloudFront + AWS WAF → AWSの強力なインフラを活用
  • Akamai → エンタープライズ向けの高度な防御機能

これらのサービスは、以下のような機能を提供します。

  • 大規模なDDoS攻撃の吸収
  • 地理的分散によるトラフィック分散
  • 自動的な脅威検出とブロック
  • リアルタイムの攻撃分析

監視とアラートの設定

攻撃を早期に検出するため、監視体制を整えることも重要です。

const prometheus = require('prom-client');

// リクエスト数のカウンター
const requestCounter = new prometheus.Counter({
  name: 'http_requests_total',
  help: 'Total number of HTTP requests',
  labelNames: ['method', 'path', 'status'],
});

app.use((req, res, next) => {
  res.on('finish', () => {
    requestCounter.inc({
      method: req.method,
      path: req.path,
      status: res.statusCode,
    });
  });
  next();
});

// 異常なトラフィックを検出
setInterval(() => {
  const metrics = prometheus.register.metrics();
  // メトリクスを解析して異常を検出
  // 必要に応じてアラートを送信
}, 60000); // 1分ごとにチェック

このように、複数の防御策を組み合わせる多層防御が、DoS/DDoS攻撃に対する最も効果的なアプローチです。

まとめ

リンドくん

リンドくん

なるほど!レート制限って、思ったより簡単に実装できるんですね。

たなべ

たなべ

そうだね!でも、セキュリティは一度設定したら終わりではないんだ。
常に最新の脅威を学び、対策をアップデートし続けることが大切だよ。

この記事では、DoS/DDoS攻撃の基本からレート制限の実装まで、Webセキュリティの重要な基礎知識を解説してきました。

重要なポイントをおさらいしましょう。

  • DoS/DDoS攻撃は大量のリクエストでサービスを停止させる攻撃である
  • レート制限は一定時間内のリクエスト数を制限する基本的な防御手法
  • Express.jsやNginxで簡単に実装できる
  • レート制限だけでなく、CAPTCHA、WAF、CDNなどを組み合わせることが重要

セキュリティ対策は、サービスの信頼性を保つために欠かせません。
特に、ユーザーの個人情報を扱うサービスや、ビジネスに直結するサービスでは、適切な防御策を講じることが必須です。

今回学んだレート制限の実装は、セキュリティ対策の第一歩です。まずは自分のプロジェクトに基本的なレート制限を導入してみて、実際の動作を確認してみてください。

また、セキュリティは常に進化する分野です。
新しい攻撃手法が日々生まれていますので、定期的に最新の情報をキャッチアップし、対策をアップデートしていくことが重要です。

この記事をシェア

関連するコンテンツ