Zenn
🤖

駆け出しエンジニアが会社で一番CIDRについて詳しくなるんだぞっていうハナシ

2025/03/10に公開

はじめに

みなさんこんにちは!新卒として入社してもうすぐ1年が経とうとしているエンジニアのマツケンです!
今回は駆け出しエンジニアが「CIDR」について勉強したことをみなさんに共有します!
「CIDRって聞いたことあるけどなんか分からないんだよな・・・」
「IPアドレス周りの知識不安なんだよな・・・」
このような人たち(自分も含めて)がこの記事を読むことで、すこしでも概要や必要性を理解していただけるきっかけになったら嬉しいです!それでは始めます!

CIDRとは

CIDR(サイダー) って聞いたことあるけど、よくわからない……という方、多いですよね?
CIDRは Classless Inter-Domain Routing(クラスレス インタードメイン ルーティング) の略で、ざっくり言うと「IPアドレスを効率よく使うためのルール」です。

昔は「クラスA、B、C」という決められた区分でIPアドレスが割り振られていました。でもこの方法だと、使われないIPアドレスがたくさん出てしまう問題がありました。

そこで登場したのがCIDRです! CIDRを使うと、必要な分だけIPアドレスを割り当てられる ので、無駄が少なくなります。

CIDRの表記方法って?

CIDRのアドレス表記はこんな感じです。
192.168.1.0/24
「/24」って何? と思いますよね。僕も最初に見た時はそうでした。これはIPアドレスの先頭24ビットがネットワークを表している という意味です。

  • 192.168.1.0/24 → 192.168.1.0 〜 192.168.1.255 の範囲(256個)

  • 192.168.1.0/25 → 192.168.1.0 〜 192.168.1.127 の範囲(128個)

  • 192.168.1.0/26 → 192.168.1.0 〜 192.168.1.63 の範囲(64個)
    こんな感じで、スラッシュの後ろの数字が大きくなるほど、使えるIPの数が減っていきます。

寄り道:CIDR以外の表記方法だとどうなる?

他の表記方法があるのか気になってAIに聞いてみました!
CIDR以外にも、IPアドレスの範囲を表記する方法はいくつかあります。

  1. サブネットマスク表記
    CIDRの「/」の代わりにサブネットマスクを使う方法です。主にレガシーなシステムやネットワーク機器で使用され、直感的に理解しやすいです。
    サブネットマスク表記: 192.168.1.0 255.255.255.0

  2. ワイルドカードマスク表記
    CiscoのACL(アクセスコントロールリスト)などで使われる表記方法で、特定の範囲を指定しやすいのが特徴です。
    ワイルドカードマスク表記: 192.168.1.0 0.0.0.255

  3. IPアドレス範囲表記
    CIDRではなく、明示的に開始IPと終了IPを指定する方法です。人間には分かりやすいですが、システムでの処理には不向きです。
    IP範囲表記: 192.168.1.0 - 192.168.1.255

  4. ネットワークとブロードキャストアドレスの組み合わせ
    ネットワークアドレスとブロードキャストアドレスを指定することで、範囲を示すこともできます。IPの利用可能範囲を把握する際に便利です。
    ネットワークアドレス: 192.168.1.0
    ブロードキャストアドレス: 192.168.1.255

CIDR表記は一見わかりづらいですがほかの表記法と比べるとかなりスマートに感じます!

アプリケーション層でCIDR形式を使ってIP制限するには?

chatGPTとgithub codespacesでブロックされる様子を確認したいと思います!

cidr-access-control-app/
│── public/
│   ├── index.php        # エントリーポイント
│   ├── welcome.php      # OK時の画面
│   ├── denied.php       # NG時の画面
│   ├── assets/
│       ├── style.css    # CSSファイル
│       ├── blocked.png  # NG時に表示する画像
│── src/
│   ├── config.php       # 設定ファイル(DB接続)
│   ├── check_ip.php     # IPチェック処理
│── database/
│   ├── schema.sql       # テーブル作成用SQL
│── .env.example         # 環境変数設定ファイルのサンプル
│── docker-compose.yml   # MySQL環境構築用(必要なら)
│── README.md            # プロジェクトの説明
<?php
require_once 'config.php';

// クライアントのIPアドレスを取得
$client_ip = $_SERVER['REMOTE_ADDR'] ?? 'UNKNOWN';

// CIDRの範囲内かチェックする関数
function ip_in_range($ip, $cidr) {
   [$subnet, $mask] = explode('/', $cidr);
   $ip_binary = ip2long($ip);
   $subnet_binary = ip2long($subnet);
   $mask_binary = ~((1 << (32 - $mask)) - 1);

   return ($ip_binary & $mask_binary) === ($subnet_binary & $mask_binary);
}

// データベースから許可されたCIDR一覧を取得
try {
   $stmt = $pdo->query("SELECT cidr FROM allowed_ips");
   $allowed_cidrs = $stmt->fetchAll(PDO::FETCH_COLUMN);

   // IPが許可リストに含まれているかチェック
   $allowed = false;
   foreach ($allowed_cidrs as $cidr) {
       if (ip_in_range($client_ip, $cidr)) {
           $allowed = true;
           break;
       }
   }

   // 許可 or 拒否の結果を表示(デバッグ用)
   if ($allowed) {
       echo "<p>✅ 許可されました!</p>";
       header("Location: /welcome.php");
   } else {
       echo "<p>❌ アクセス拒否!</p>";
       header("Location: /denied.php");
   }
   exit();
} catch (PDOException $e) {
   die("❌ データベースエラー: " . $e->getMessage());
}
?>

ポイント:CIDRのIP判定ロジック (ip_in_range)

CIDRを活用して、特定のIPアドレスが範囲内にあるかどうかを確認するための関数である ip_in_range を見てみましょう。

ip_in_range の仕組み

 // CIDRの範囲内かチェックする関数
function ip_in_range($ip, $cidr) {
    [$subnet, $mask] = explode('/', $cidr);
    $ip_binary = ip2long($ip);
    $subnet_binary = ip2long($subnet);
    $mask_binary = ~((1 << (32 - $mask)) - 1);

    return ($ip_binary & $mask_binary) === ($subnet_binary & $mask_binary);
}

1. CIDRの分割

例として 192.168.1.0/24 がある場合、/24 は「ネットワーク部分が上位24ビット」という意味です。
ここでは「ネットワークアドレス = 192.168.1.0」「プレフィックス長 = 24」に分割します。

2. IPアドレスの数値化

IPアドレスは通常「192.168.1.100」のようにドット区切りで書かれますが、ビット演算を行うには数値に変換する必要があります。
PHPの ip2long() 関数を使うと、IPアドレス(文字列)から32ビット整数へ簡単に変換できます。

  • 例: 192.168.1.1003232235876
  • 例: 192.168.1.03232235776

3. ビットマスクの作成

CIDRのプレフィックス長(例:24)に応じて、上位24ビットを 1、残りの8ビットを 0 としたマスクを作成します。

  • 例: /24
    → 先頭24ビットが 1、残り8ビットが 0
    11111111111111111111111100000000
    255.255.255.0
    → 32ビット整数で表すと 4294967040
    このマスクを使うと、IPアドレスの上位24ビット(ネットワーク部分)だけを取り出すことができます。

4. ビットマスクを使った範囲内チェック

変換したIPアドレスとネットワークアドレスに、同じマスクを適用して結果が一致すれば「同じネットワーク」に属していると判定できます。

  • ビット演算の例:
    • 192.168.1.100 & 255.255.255.0192.168.1.0
    • 192.168.1.0 & 255.255.255.0192.168.1.0
      両方とも 192.168.1.0 になったので、192.168.1.100192.168.1.0/24 の範囲に含まれるとわかります。
      このように、ビットマスクを適用することで ホスト部分を無視し、ネットワーク部分だけを比較 し、範囲内かどうかを判断できるのです。

画面で見てみよう


これを押すと

こう!許可されるだけで何もできない素晴らしいサイトです。
もしも弾かれると・・・

きゃーーーーーーーー無事に弾かれましたね。これでいつでも意図しないIPからのアクセスをブロックできるマツケンになりました!!

おまけ話:そもそもアプリでIP制限するのは適切?

アプリでIP制限することはできますが、ウェブサーバーやロードバランサー(LB)などのミドルウェアでブロックする方が効率が良いです。
なぜなら、アプリでIP制限を行うと 無駄なリクエストがアプリケーションレイヤーまで到達してしまい、サーバーの負荷が増えるためです。
例えば、NginxやApache のようなウェブサーバーや、AWSのALB(Application Load Balancer)などのロードバランサーでIP制限を設定すれば、アプリケーションにリクエストが届く前にアクセスを制限できるためより効率的です。

まとめ

  • CIDRはIPアドレスを効率的に管理するためのルール!
  • 「/」の後ろの数字でネットワークの範囲が決まる
  • アプリでCIDRを使ったIP制限も可能(PHPで実装例あり)
  • でも、IP制限はサーバー側でやるのがベター!
    CIDRを知っておくと、ネットワークの知識がグッと深まります。ぜひ、試してみてください!

終わりに(感想)

最後まで読んでいただきありがとうございました!
今回IPアドレスやCIDRに関して勉強してみて、6月からエンジニアとして働き始めてありがたいことにたくさんのコードは書かせていただいたものの、自分はまだまだネットワークやセキュリティ周りの知識が疎いことを再認識しました。
いつの間にか3月になりもう来月は先輩になるのか?!と自分でも驚いていますができることには自信を持ち、できないことは一緒に学んでいくスタンスで頑張ろうと思います!
ありがとうございました!マツケンでした!

参考資料

NE株式会社の開発ブログ

Discussion

ログインするとコメントできます