CIDR(サイダー)とは、IPアドレスの後ろに「/24」のようにネットワーク部のビット数を書いて、ネットワークの範囲を表す記法です。 「/24 なら 256 個、ホストに使えるのは 254 個」という対応さえ手元にあれば、サブネットの計算はほとんど暗算で終わります。この記事は、その対応表を /0 から /32 まで一枚にまとめたうえで、2進数での手計算の手順、Python 標準ライブラリ ipaddress だけで動くコピペ用スクリプト(実行結果つき)、AWS VPC を AZ×用途に分ける設計例、IPv6 の簡易表、ipcalc / sipcalc コマンドの実行結果まで載せています。

早見表には、AWS の VPC サブネットで実際に割り当てられる数(各サブネットで 5 個が予約されるため、アドレス数から 5 を引いた値)も入れました。表を眺めて終わりではなく、「10.0.0.0/16 をどう切るか」「2つの CIDR が重なっていないか」まで、この記事の中で答えが出ます。

CIDR・サブネットマスクの早見表(/0〜/32)

「使えるホスト数」はアドレス数から先頭(ネットワークアドレス)と末尾(ブロードキャスト)の 2 個を引いた数、「AWS VPC で使える数」はアドレス数から 5 個を引いた数です。 AWS の VPC とサブネットは /16〜/28 の範囲でのみ作れるので、それ以外は「-」にしています(公式ドキュメント「Subnet CIDR blocks」「VPC CIDR blocks」で確認)。

プレフィックス サブネットマスク ワイルドカード アドレス数 使えるホスト数 AWS VPC で使える数 用途の目安
/0 0.0.0.0 255.255.255.255 4,294,967,296 4,294,967,294 - デフォルトルート(0.0.0.0/0 = すべて)
/1 128.0.0.0 127.255.255.255 2,147,483,648 2,147,483,646 - 経路集約
/2 192.0.0.0 63.255.255.255 1,073,741,824 1,073,741,822 - 経路集約
/3 224.0.0.0 31.255.255.255 536,870,912 536,870,910 - 経路集約
/4 240.0.0.0 15.255.255.255 268,435,456 268,435,454 - マルチキャスト範囲(224.0.0.0/4)
/5 248.0.0.0 7.255.255.255 134,217,728 134,217,726 - 経路集約
/6 252.0.0.0 3.255.255.255 67,108,864 67,108,862 - 経路集約
/7 254.0.0.0 1.255.255.255 33,554,432 33,554,430 - 経路集約
/8 255.0.0.0 0.255.255.255 16,777,216 16,777,214 - 10.0.0.0/8(プライベート全体)、旧クラス A
/9 255.128.0.0 0.127.255.255 8,388,608 8,388,606 - 大規模なアドレス計画
/10 255.192.0.0 0.63.255.255 4,194,304 4,194,302 - 100.64.0.0/10(キャリアグレード NAT)
/11 255.224.0.0 0.31.255.255 2,097,152 2,097,150 - 大規模なアドレス計画
/12 255.240.0.0 0.15.255.255 1,048,576 1,048,574 - 172.16.0.0/12(プライベート)
/13 255.248.0.0 0.7.255.255 524,288 524,286 - 拠点・リージョン単位の割り当て
/14 255.252.0.0 0.3.255.255 262,144 262,142 - 拠点・リージョン単位の割り当て
/15 255.254.0.0 0.1.255.255 131,072 131,070 - 拠点・リージョン単位の割り当て
/16 255.255.0.0 0.0.255.255 65,536 65,534 65,531 VPC 1 つの最大サイズ、192.168.0.0/16、旧クラス B
/17 255.255.128.0 0.0.127.255 32,768 32,766 32,763 VPC を 2 分割
/18 255.255.192.0 0.0.63.255 16,384 16,382 16,379 VPC を 4 分割
/19 255.255.224.0 0.0.31.255 8,192 8,190 8,187 VPC を 8 分割
/20 255.255.240.0 0.0.15.255 4,096 4,094 4,091 AZ ごとの大きめサブネット(VPC を 16 分割)
/21 255.255.248.0 0.0.7.255 2,048 2,046 2,043 部門・環境単位
/22 255.255.252.0 0.0.3.255 1,024 1,022 1,019 部門・環境単位
/23 255.255.254.0 0.0.1.255 512 510 507 /24 を 2 つつなげたサブネット
/24 255.255.255.0 0.0.0.255 256 254 251 もっとも一般的なサブネット、旧クラス C
/25 255.255.255.128 0.0.0.127 128 126 123 /24 の半分
/26 255.255.255.192 0.0.0.63 64 62 59 小さなセグメント
/27 255.255.255.224 0.0.0.31 32 30 27 小さなセグメント
/28 255.255.255.240 0.0.0.15 16 14 11 AWS の VPC・サブネットの最小サイズ
/29 255.255.255.248 0.0.0.7 8 6 - 機器数個の接続用
/30 255.255.255.252 0.0.0.3 4 2 - 従来のポイントツーポイント接続
/31 255.255.255.254 0.0.0.1 2 2(RFC 3021) - ポイントツーポイント接続(2 個とも使える)
/32 255.255.255.255 0.0.0.0 1 1 - ホスト 1 台の指定(ルート・セキュリティグループ)

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「CIDR計算・サブネット早見表|/0〜/32一覧とPython計算コード」

CIDR 表記の読み方(ネットワーク部とホスト部)

IPv4 アドレスは 32 ビットで、CIDR の「/n」は先頭 n ビットがネットワーク部、残り 32−n ビットがホスト部であることを表します。 サブネットマスクは「ネットワーク部を 1、ホスト部を 0」で書いた 32 ビット、ワイルドカードマスクはその反転(ネットワーク機器のアクセスリストで使う書き方)です。

用語 意味 192.168.10.77/26 の場合
プレフィックス長 ネットワーク部のビット数 26
サブネットマスク 先頭 26 ビットが 1 255.255.255.192
ワイルドカードマスク マスクの反転 0.0.0.63
ネットワークアドレス ホスト部をすべて 0 にしたもの(範囲の先頭) 192.168.10.64
ブロードキャストアドレス ホスト部をすべて 1 にしたもの(範囲の末尾) 192.168.10.127
ホスト範囲 先頭と末尾を除いた範囲 192.168.10.65〜192.168.10.126
アドレス数 2 の (32−n) 乗 64
使えるホスト数 アドレス数 − 2 62

ポイントは「アドレス数は必ず 2 のべき乗」で「範囲の先頭はアドレス数の倍数から始まる」ことです。 /26 なら 64 個ずつ、0・64・128・192 のどれかから始まります。この性質を使うと、次の手計算がとても短くなります。

2 進数で手計算する手順(192.168.10.77/26 の例)

手計算は「マスクをかける(AND)」「ホスト部を全部 1 にする(OR)」の 2 回で終わります。 /26 は先頭 3 オクテット(24 ビット)が丸ごとネットワーク部なので、見るのは 4 番目のオクテット「77」だけです。

手順 1:4 番目のオクテットを 2 進数にする

桁の重み 128 64 32 16 8 4 2 1
77 = 64 + 8 + 4 + 1 0 1 0 0 1 1 0 1

手順 2:マスクの 4 番目のオクテットを書く

/26 は 24 ビット + 2 ビットなので、4 番目のオクテットは先頭 2 ビットが 1 です。

桁の重み 128 64 32 16 8 4 2 1
マスク(192) 1 1 0 0 0 0 0 0

手順 3:AND でネットワークアドレス、ホスト部を 1 で埋めてブロードキャスト

128 64 32 16 8 4 2 1 10 進
アドレス 77 0 1 0 0 1 1 0 1 77
マスク 192 1 1 0 0 0 0 0 0 192
AND(ネットワーク) 0 1 0 0 0 0 0 0 64
ホスト部を 1 に(ブロードキャスト) 0 1 1 1 1 1 1 1 127

結果は次のとおりです。

項目 値
ネットワークアドレス 192.168.10.64
ブロードキャストアドレス 192.168.10.127
ホストに使える範囲 192.168.10.65〜192.168.10.126(62 個)
次のサブネット 192.168.10.128/26

2 進数を使わない近道:ブロックサイズ = 256 − マスクのオクテット値。 /26 なら 256 − 192 = 64。77 を 64 で割った商は 1 なので、先頭は 64 × 1 = 64、末尾は 64 + 64 − 1 = 127 です。/27 なら 256 − 224 = 32 刻み、/28 なら 16 刻みになります。慣れるとこの割り算だけで済みます。

Python 標準 ipaddress で計算する(コピペ用・実行結果つき)

Python 3 の標準ライブラリ ipaddress は追加インストール不要で、含まれるか判定・重なり判定・分割・集約まで一通りそろっています。 以下は Python 3.11.15 で実行した結果です(3.14 でも同じ API です)。

基本情報・含まれるか判定・重なり判定・分割・集約・列挙

import ipaddress

# 1. 基本情報:ネットワークアドレス・ブロードキャスト・範囲
net = ipaddress.ip_network("192.168.10.77/26", strict=False)   # ホストのアドレスから求めるときは strict=False
print("ネットワーク     :", net)
print("ネットマスク     :", net.netmask)
print("ワイルドカード   :", net.hostmask)
print("ブロードキャスト :", net.broadcast_address)
print("アドレス数       :", net.num_addresses)
hosts = list(net.hosts())
print("ホスト範囲       :", hosts[0], "-", hosts[-1], f"({len(hosts)}個)")

# 2. 含まれるか判定
print("\n--- 含まれるか判定 ---")
for ip in ["192.168.10.100", "192.168.10.130"]:
    print(ip, "in", net, "->", ipaddress.ip_address(ip) in net)

# 3. 重なり判定
print("\n--- 重なり判定 ---")
a = ipaddress.ip_network("10.0.0.0/16")
b = ipaddress.ip_network("10.0.128.0/17")
c = ipaddress.ip_network("10.1.0.0/16")
print(a, "と", b, "->", a.overlaps(b))
print(a, "と", c, "->", a.overlaps(c))
print(b, "は", a, "の内側 ->", b.subnet_of(a))

# 4. 等分割
print("\n--- /16 を /18 に4分割 ---")
for s in ipaddress.ip_network("10.0.0.0/16").subnets(new_prefix=18):
    print(" ", s)

# 5. 集約(連続する範囲を1つにまとめる)
print("\n--- 集約 ---")
nets = [ipaddress.ip_network(x) for x in
        ["10.0.0.0/24", "10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]]
print(list(ipaddress.collapse_addresses(nets)))
nets2 = [ipaddress.ip_network(x) for x in ["10.0.0.0/24", "10.0.1.0/24", "10.0.3.0/24"]]
print(list(ipaddress.collapse_addresses(nets2)))

# 6. ホスト列挙
print("\n--- ホスト列挙 ---")
for h in ipaddress.ip_network("10.0.0.0/29").hosts():
    print(" ", h)

# 7. 開始IPと終了IPからCIDRを求める
print("\n--- 範囲 -> CIDR ---")
start, end = ipaddress.ip_address("10.0.0.0"), ipaddress.ip_address("10.0.0.255")
print([str(n) for n in ipaddress.summarize_address_range(start, end)])
start, end = ipaddress.ip_address("10.0.0.0"), ipaddress.ip_address("10.0.1.127")
print([str(n) for n in ipaddress.summarize_address_range(start, end)])

実行結果:

ネットワーク     : 192.168.10.64/26
ネットマスク     : 255.255.255.192
ワイルドカード   : 0.0.0.63
ブロードキャスト : 192.168.10.127
アドレス数       : 64
ホスト範囲       : 192.168.10.65 - 192.168.10.126 (62個)

--- 含まれるか判定 ---
192.168.10.100 in 192.168.10.64/26 -> True
192.168.10.130 in 192.168.10.64/26 -> False

--- 重なり判定 ---
10.0.0.0/16 と 10.0.128.0/17 -> True
10.0.0.0/16 と 10.1.0.0/16 -> False
10.0.128.0/17 は 10.0.0.0/16 の内側 -> True

--- /16 を /18 に4分割 ---
  10.0.0.0/18
  10.0.64.0/18
  10.0.128.0/18
  10.0.192.0/18

--- 集約 ---
[IPv4Network('10.0.0.0/22')]
[IPv4Network('10.0.0.0/23'), IPv4Network('10.0.3.0/24')]

--- ホスト列挙 ---
  10.0.0.1
  10.0.0.2
  10.0.0.3
  10.0.0.4
  10.0.0.5
  10.0.0.6

--- 範囲 -> CIDR ---
['10.0.0.0/24']
['10.0.0.0/24', '10.0.1.0/25']

集約は「連続していて、かつ境界がそろっている」ときだけ 1 つになります。 10.0.0.0/24〜10.0.3.0/24 の 4 つは /22 にまとまりましたが、10.0.2.0/24 が抜けた例では /23 と /24 の 2 つに分かれています。

よく使うメソッド・関数の逆引き表

やりたいこと 書き方 戻り値の例
ホストのアドレスからネットワークを求める ip_network("192.168.10.77/26", strict=False) 192.168.10.64/26
サブネットマスク → プレフィックス長 ip_network("0.0.0.0/255.255.255.224").prefixlen 27
プレフィックス長 → サブネットマスク ip_network("0.0.0.0/27").netmask 255.255.255.224
ワイルドカードで指定 ip_network("10.0.0.0/0.0.0.15").prefixlen 28
ある IP が範囲に含まれるか ip_address(ip) in net True / False
2 つの範囲が重なるか a.overlaps(b) True / False
a が b に含まれるか a.subnet_of(b) / b.supernet_of(a) True / False
等分割 net.subnets(new_prefix=20) / net.subnets(prefixlen_diff=2) ジェネレータ
1 段大きい範囲 net.supernet() 10.0.0.0/15
連続する範囲をまとめる collapse_addresses([...]) イテレータ
開始〜終了 IP を CIDR に summarize_address_range(start, end) イテレータ
プライベートアドレスか ip_address("10.1.2.3").is_private True
ホスト数 net.num_addresses、len(list(net.hosts())) 64, 62

早見表を自分で生成するスクリプト

冒頭の表は次のスクリプトで生成しました。列を足したいときはそのまま書き換えられます。

import ipaddress

print("| プレフィックス | サブネットマスク | ワイルドカード | アドレス数 | 使えるホスト数 | AWS VPC で使える数 |")
print("|---|---|---|---|---|---|")
for p in range(0, 33):
    net = ipaddress.ip_network(f"0.0.0.0/{p}")
    total = net.num_addresses
    hosts = 1 if p == 32 else 2 if p == 31 else total - 2
    aws = f"{total - 5:,}" if 16 <= p <= 28 else "-"
    print(f"| /{p} | {net.netmask} | {net.hostmask} | {total:,} | {hosts:,} | {aws} |")

AWS VPC とサブネットの設計例(10.0.0.0/16 を AZ × 用途で分ける)

AWS では各サブネットの先頭 4 個と末尾 1 個、合計 5 個が予約されるため、/24 のサブネットで使えるのは 251 個です。 公式ドキュメント「Subnet CIDR blocks」に、10.0.0.0/24 の例として次の 5 個が挙げられています。

アドレス 予約の理由
10.0.0.0 ネットワークアドレス
10.0.0.1 VPC ルーター用に AWS が予約
10.0.0.2 DNS サーバー用に AWS が予約(VPC の範囲の先頭 + 2)
10.0.0.3 将来の利用のために AWS が予約
10.0.0.255 ネットワークブロードキャストアドレス(VPC ではブロードキャストを使わないため予約)

VPC と サブネットの CIDR は /16〜/28 の範囲で作ります。推奨されているのは RFC 1918 のプライベート範囲(10.0.0.0/8、172.16.0.0/12、192.168.0.0/16)で、後から別の VPC やオンプレミスとつなぐ(ピアリング、VPN)ときに重ならないことが重要になります。

設計例:/16 を /20 で 16 分割し、3 AZ × 3 用途に割り当てる

「AZ ごと・用途ごとに 1 サブネット」を基本にし、将来のために空きを残すのがよくある形です。 次の表は 10.0.0.0/16 を /20(4,096 個、AWS で使えるのは 4,091 個)で 16 個に分け、public / private / db の 3 用途 × 3 AZ に 9 個を割り当て、7 個を予約として残した例です。

用途 AZ CIDR 範囲 AWS で使える数
public a 10.0.0.0/20 10.0.0.0〜10.0.15.255 4,091
public c 10.0.16.0/20 10.0.16.0〜10.0.31.255 4,091
public d 10.0.32.0/20 10.0.32.0〜10.0.47.255 4,091
(予約) - 10.0.48.0/20 10.0.48.0〜10.0.63.255 -
private a 10.0.64.0/20 10.0.64.0〜10.0.79.255 4,091
private c 10.0.80.0/20 10.0.80.0〜10.0.95.255 4,091
private d 10.0.96.0/20 10.0.96.0〜10.0.111.255 4,091
(予約) - 10.0.112.0/20 10.0.112.0〜10.0.127.255 -
db a 10.0.128.0/20 10.0.128.0〜10.0.143.255 4,091
db c 10.0.144.0/20 10.0.144.0〜10.0.159.255 4,091
db d 10.0.160.0/20 10.0.160.0〜10.0.175.255 4,091
(予約) - 10.0.176.0/20〜10.0.240.0/20 残り 5 ブロック -

用途ごとに上位ビットをそろえる(public は 10.0.0〜63、private は 10.0.64〜127、db は 10.0.128〜191)と、ルートテーブルやセキュリティグループで「10.0.64.0/18 = private 全体」のように 1 行で指定できます。 これが「境界をそろえて切る」ことの実務上の利点です。

小規模なら /24 で切る形でも十分です(各 251 個)。

用途 AZ-a AZ-c AZ-d
public 10.0.0.0/24 10.0.1.0/24 10.0.2.0/24
private 10.0.10.0/24 10.0.11.0/24 10.0.12.0/24
db 10.0.20.0/24 10.0.21.0/24 10.0.22.0/24

設計の重なりを機械的に確認するスクリプト

import ipaddress

vpc = ipaddress.ip_network("10.0.0.0/16")
subnets = list(vpc.subnets(new_prefix=20))   # 16個
plan = [
    ("public-a",  subnets[0]),  ("public-c",  subnets[1]),  ("public-d",  subnets[2]),
    ("private-a", subnets[4]),  ("private-c", subnets[5]),  ("private-d", subnets[6]),
    ("db-a",      subnets[8]),  ("db-c",      subnets[9]),  ("db-d",      subnets[10]),
]
for name, s in plan:
    print(f"{name:10} {s!s:16} {s.network_address} - {s.broadcast_address}  usable(AWS)={s.num_addresses - 5:,}")

used = {s for _, s in plan}
print("予約(未割り当て):", [str(s) for s in subnets if s not in used])

cidrs = [s for _, s in plan]
overlaps = [(a, b) for i, a in enumerate(cidrs) for b in cidrs[i + 1:] if a.overlaps(b)]
print("重なり:", overlaps or "なし")

other = ipaddress.ip_network("10.1.0.0/16")   # ピアリング先の VPC
print(f"{vpc} と {other} の重なり ->", vpc.overlaps(other))

実行結果(抜粋):

public-a   10.0.0.0/20      10.0.0.0 - 10.0.15.255  usable(AWS)=4,091
public-c   10.0.16.0/20     10.0.16.0 - 10.0.31.255  usable(AWS)=4,091
...
db-d       10.0.160.0/20    10.0.160.0 - 10.0.175.255  usable(AWS)=4,091
予約(未割り当て): ['10.0.48.0/20', '10.0.112.0/20', '10.0.176.0/20', '10.0.192.0/20', '10.0.208.0/20', '10.0.224.0/20', '10.0.240.0/20']
重なり: なし
10.0.0.0/16 と 10.1.0.0/16 の重なり -> False

サイズを決めるときの判断表

状況 目安
VPC 全体 /16 を基本に。将来の接続先と重ならない範囲を選ぶ(VPC ごとに 10.0、10.1、10.2… とずらす)
コンテナやサーバーレスを多く置くサブネット /20〜/22。ENI(ネットワークインターフェース)ごとに IP を消費するので余裕を持たせる
一般的なアプリケーションサーバー /24(251 個)
データベースなど台数が少ない層 /24〜/26。小さくしすぎるとフェイルオーバーやスケール時に足りなくなる
最小 /28(11 個)。検証用など

IPv6 の簡易早見表(/48・/56・/64)

IPv6 は 128 ビットで、サブネットは /64 で切るのが標準です。 ホスト数を数える発想はなく、「/64 のサブネットをいくつ持てるか」で考えます。

プレフィックス 位置づけ 含まれる /64 の数 例
/48 拠点・組織単位で割り当てられる典型的なサイズ 65,536 2001:db8:abcd::/48
/56 AWS の VPC に Amazon 提供の IPv6 CIDR として割り当てられるサイズ 256 2001:db8:1234:1a00::/56
/64 サブネット 1 つ(AWS のサブネットの標準。/44〜/64 を選べる) 1 2001:db8:1234:1a00::/64

AWS の IPv6 サブネットでも、先頭 4 個(::、::1、::2、::3)と末尾 1 個が予約されます(公式「Subnet CIDR blocks」)。

Python では IPv6 も同じ API です。

import ipaddress
v6 = ipaddress.ip_network("2001:db8:abcd::/48")
print(v6.num_addresses)                                        # 1208925819614629174706176
print([str(s) for s in list(v6.subnets(new_prefix=56))[:3]])   # ['2001:db8:abcd::/56', '2001:db8:abcd:100::/56', '2001:db8:abcd:200::/56']
print(2 ** (56 - 48), 2 ** (64 - 48))                          # 256 65536

コマンドで計算する:ipcalc と sipcalc(実行結果)

Linux では ipcalc(2 進数の内訳つき)と sipcalc(IPv6 対応)が手軽です。 どちらも apt で入ります。以下は ipcalc 0.51、sipcalc 1.1.6(Ubuntu の apt 版)の実行結果です。

sudo apt-get install -y ipcalc sipcalc
ipcalc 192.168.10.77/26
Address:   192.168.10.77        11000000.10101000.00001010.01 001101
Netmask:   255.255.255.192 = 26 11111111.11111111.11111111.11 000000
Wildcard:  0.0.0.63             00000000.00000000.00000000.00 111111
=>
Network:   192.168.10.64/26     11000000.10101000.00001010.01 000000
HostMin:   192.168.10.65        11000000.10101000.00001010.01 000001
HostMax:   192.168.10.126       11000000.10101000.00001010.01 111110
Broadcast: 192.168.10.127       11000000.10101000.00001010.01 111111
Hosts/Net: 62                    Class C, Private Internet

2 進数の列で、ネットワーク部(左)とホスト部(右)が空白で区切られているので、手計算の答え合わせにも使えます。-s で「必要なホスト数」から分割案を出せます。

ipcalc 10.0.0.0/24 -s 60 60 20
1. Requested size: 60 hosts
Netmask:   255.255.255.192 = 26 11111111.11111111.11111111.11 000000
Network:   10.0.0.0/26          00001010.00000000.00000000.00 000000
HostMin:   10.0.0.1             00001010.00000000.00000000.00 000001
HostMax:   10.0.0.62            00001010.00000000.00000000.00 111110
Broadcast: 10.0.0.63            00001010.00000000.00000000.00 111111
Hosts/Net: 62                    Class A, Private Internet

2. Requested size: 60 hosts
Network:   10.0.0.64/26         ...
Hosts/Net: 62

3. Requested size: 20 hosts
Netmask:   255.255.255.224 = 27 11111111.11111111.11111111.111 00000
Network:   10.0.0.128/27        00001010.00000000.00000000.100 00000
Hosts/Net: 30                    Class A, Private Internet

Needed size:  160 addresses.
Used network: 10.0.0.0/24
Unused:
10.0.0.160/27
10.0.0.192/26

sipcalc は IPv6 も扱えます。

sipcalc 192.168.10.77/26
sipcalc 2001:db8:abcd::/48
-[ipv4 : 192.168.10.77/26] - 0

[CIDR]
Host address        - 192.168.10.77
Host address (decimal)  - 3232238157
Host address (hex)  - C0A80A4D
Network address     - 192.168.10.64
Network mask        - 255.255.255.192
Network mask (bits) - 26
Network mask (hex)  - FFFFFFC0
Broadcast address   - 192.168.10.127
Cisco wildcard      - 0.0.0.63
Addresses in network    - 64
Network range       - 192.168.10.64 - 192.168.10.127
Usable range        - 192.168.10.65 - 192.168.10.126

-[ipv6 : 2001:db8:abcd::/48] - 0

[IPV6 INFO]
Expanded Address    - 2001:0db8:abcd:0000:0000:0000:0000:0000
Compressed address  - 2001:db8:abcd::
Subnet prefix (masked)  - 2001:db8:abcd:0:0:0:0:0/48
Address ID (masked) - 0:0:0:0:0:0:0:0/48
Prefix address      - ffff:ffff:ffff:0:0:0:0:0
Prefix length       - 48
Address type        - Aggregatable Global Unicast Addresses
Network range       - 2001:0db8:abcd:0000:0000:0000:0000:0000 -
              2001:0db8:abcd:ffff:ffff:ffff:ffff:ffff

よくあるつまずきと直し方

つまずきの多くは「/31 と /32 の扱い」「先頭・末尾を機器に割り当ててしまう」「範囲の重なり」「Python の strict 引数」の 4 つです。 それぞれ、こうなる → こうするとよい、の形でまとめます。

つまずき こうなる こうするとよい
/30 と /31 の違い /30 は 4 個中 2 個しか使えない。/31 は RFC 3021 により 2 個とも使える(ポイントツーポイント専用) 機器同士の 1 対 1 接続は /31 が使える環境なら /31。対応していない機器なら /30
/32 の意味 「ホスト 1 台」を表す。ネットワークではないので範囲の概念がない ルートやセキュリティグループで「この 1 台だけ」を指すときに 203.0.113.10/32 のように書く
先頭アドレスを機器に割り当てる 10.0.0.0/24 の 10.0.0.0 はネットワークアドレスなので、機器に設定すると通信できない ホスト範囲は .1〜.254。AWS では .1〜.3 も予約なので .4 から
ブロードキャストを機器に割り当てる 10.0.0.255/24 を機器に設定すると通信できない(/24 での末尾) 末尾はブロードキャスト。/23 では 10.0.1.255 が末尾で、10.0.0.255 は普通のホスト。プレフィックス長で末尾が変わることに注意
サブネットの重なり 10.0.0.0/16 と 10.0.128.0/17 は重なる。ルーティングで意図しない経路が選ばれたり、ピアリングが張れなくなったりする 設計表を作ったら overlaps() で全組み合わせを機械チェック(上のスクリプト)
ホストビットが立った CIDR ip_network("192.168.10.77/26") は ValueError: 192.168.10.77/26 has host bits set ネットワークを求めたいなら strict=False。設定ファイルの検証なら既定の strict のままエラーにする
172.32.x.x をプライベートだと思う 172.16.0.0/12 は 172.16.0.0〜172.31.255.255。172.32 は含まれない ip_address("172.32.0.1").is_private は False。/12 の範囲を覚える

Python で確かめた結果です(3.11.15)。

ValueError: 192.168.10.77/26 has host bits set
/31 hosts: [IPv4Address('10.0.0.0'), IPv4Address('10.0.0.1')]
/32 hosts: [IPv4Address('10.0.0.1')]
/30 hosts: [IPv4Address('10.0.0.1'), IPv4Address('10.0.0.2')]
10.0.0.0 -> ネットワークアドレス
10.0.0.255 -> ブロードキャスト
10.0.0.10 -> ホストに割り当て可
172.16.0.1 private
172.32.0.1 global

hosts() が /31 では 2 個、/32 では 1 個を返すのは、Python 3.9 以降で RFC 3021 の扱いに合わせた仕様です。

設計前チェックリスト

確認項目 見るところ
必要なホスト数に対して 2 のべき乗で切り上げたか 早見表の「使えるホスト数」または「AWS VPC で使える数」
範囲の先頭がブロックサイズの倍数か 256 − マスク値で割り切れるか
他のネットワーク(他 VPC・オンプレ・VPN 先)と重なっていないか overlaps()
用途ごとに上位ビットがそろっているか(集約できるか) collapse_addresses() で 1 つにまとまるか
将来の拡張分を残したか 予約ブロックの有無

よくある質問

Q. /24 と 255.255.255.0 は同じ意味ですか? A. 同じです。/24 は「先頭 24 ビットがネットワーク部」、255.255.255.0 はそれを 10 進数のマスクで書いたものです。ワイルドカード表記なら 0.0.0.255 になります。早見表の同じ行がこの 3 つの対応です。

Q. 使えるホスト数が「アドレス数 − 2」なのはなぜですか? A. 先頭(ホスト部がすべて 0)はネットワークそのものを表すアドレス、末尾(ホスト部がすべて 1)はブロードキャストアドレスとして予約されているためです。例外として /31 はポイントツーポイント用に 2 個とも使え(RFC 3021)、/32 は 1 台を指す表記です。AWS の VPC ではさらに 3 個が予約されるので「アドレス数 − 5」になります。

Q. 必要なホスト数からプレフィックス長を決めるにはどうすればよいですか? A. 必要数 + 2(AWS なら + 5)を 2 のべき乗に切り上げ、そのべき数を 32 から引きます。たとえば 100 台なら 102 → 128 = 2 の 7 乗 → /25。AWS で 100 台なら 105 → 128 → /25(使えるのは 123 個)です。Python なら ipaddress.ip_network("10.0.0.0/16").subnets(new_prefix=25) で候補を列挙できます。

Q. CIDR が重なっているかを大量に確認したいときは? A. Python の ipaddress で全組み合わせを overlaps() にかけるのが確実です。この記事の「設計の重なりを機械的に確認するスクリプト」がそのまま使えます。設定ファイルから読み込んで CI で回す形にしておくと、追加のたびに手で見返す必要がなくなります。

まとめ

  • CIDR の「/n」は先頭 n ビットがネットワーク部。アドレス数は 2 の (32−n) 乗、使えるホスト数はそこから 2 を引いた数
  • 早見表は /0〜/32 で、AWS VPC のサブネットでは 5 個が予約されるので「アドレス数 − 5」が実際に使える数
  • 手計算は「ブロックサイズ = 256 − マスク値」で範囲の先頭と末尾を求めるのが早い(例:/26 は 64 刻み)
  • Python 標準の ipaddress で、含まれるか判定・重なり判定・等分割・集約・ホスト列挙がコピペで動く
  • VPC 設計は「AZ × 用途で 1 サブネット」「用途ごとに上位ビットをそろえる」「予約ブロックを残す」が基本
  • /31 は 2 個とも使える、/32 は 1 台の指定、先頭と末尾は機器に割り当てない、重なりは overlaps() で機械チェック
  • ipcalc は 2 進数の内訳と分割案、sipcalc は IPv6 まで扱える

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「CIDR計算・サブネット早見表|/0〜/32一覧とPython計算コード」

株式会社RJCでは、ネットワークやクラウドの設計で迷わないための基礎知識を、プロジェクトの中で仲間と学び合っています。こうした知識を共有しながら、日々技術を磨いています。

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?