icon

안동민 개발노트

4장 : IP 주소와 서브넷

서브넷과 CIDR


클래스 기반 주소 체계의 가장 큰 문제는 유연성이 없다는 것이었습니다. 호스트가 300대 필요한 조직에 클래스 C(254대)를 주면 부족하고, 클래스 B(65,534대)를 주면 65,000개 이상의 주소가 낭비됩니다.

이 문제를 해결하기 위해 등장한 것이 서브넷(Subnet)CIDR(Classless Inter-Domain Routing)입니다.


서브넷 마스크의 역할

서브넷 마스크(Subnet Mask)는 IP 주소에서 어디까지가 네트워크부이고 어디서부터가 호스트부인지를 알려주는 값입니다.

서브넷 마스크 AND 연산
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

IP 주소:      192.168.1.100
              11000000.10101000.00000001.01100100

서브넷 마스크: 255.255.255.0
              11111111.11111111.11111111.00000000
              ├─── 1: 네트워크부 ──────┤├ 0: 호스트 ┤

AND 연산:     11000000.10101000.00000001.00000000
결과:         192.168.1.0  ← 네트워크 주소

→ "192.168.1.100은 192.168.1.0 네트워크에 속한다"
→ 라우터도 정확히 이 방법으로 목적지 네트워크를 판단

CIDR 표기법

CIDR는 클래스에 얽매이지 않고, 네트워크부의 비트 수를 자유롭게 지정하는 방식입니다.

192.168.1.0/24앞 24비트가 네트워크부라는 뜻입니다. 서브넷 마스크 255.255.255.0과 같은 의미이지만, 표기가 훨씬 간결합니다.

CIDR서브넷 마스크호스트부 비트사용 가능 호스트용도 예시
/8255.0.0.02416,777,214대형 ISP
/16255.255.0.01665,534기업 VPC
/20255.255.240.0124,094대규모 서브넷
/24255.255.255.08254일반 LAN
/25255.255.255.1287126중간 서브넷
/26255.255.255.192662소규모 서브넷
/27255.255.255.224530서버 팜
/28255.255.255.240414소규모 DMZ
/30255.255.255.25222포인트투포인트 링크
/32255.255.255.25501단일 호스트

호스트 수에서 2를 빼는 이유는, 호스트부가 모두 0인 주소(네트워크 주소)와 모두 1인 주소(브로드캐스트 주소)는 호스트에 할당할 수 없기 때문입니다.

호스트수=2(32n)2\text{호스트수} = 2^{(32 - n)} - 2

nn은 프리픽스 길이입니다.


서브넷 분할 계산

192.168.1.0/24 네트워크를 4개의 서브넷으로 나누어야 합니다.

4개의 서브넷이 필요하므로 22=42^2 = 4, 즉 호스트부에서 2비트를 빌려 네트워크부를 확장합니다.

/24에서 2비트 추가 → /26
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

원래: 192.168.1.xxxxxxxx  (호스트 8비트 = 254개)
              ├─네트워크─┤├─호스트─┤

분할: 192.168.1.XX xxxxxx  (서브넷 2비트 + 호스트 6비트)
              ├─네트워크──┤├호스트┤

서브넷 1: 192.168.1.00 000000 = .0/26    호스트: .1 ~ .62
서브넷 2: 192.168.1.01 000000 = .64/26   호스트: .65 ~ .126
서브넷 3: 192.168.1.10 000000 = .128/26  호스트: .129 ~ .190
서브넷 4: 192.168.1.11 000000 = .192/26  호스트: .193 ~ .254
서브넷네트워크 주소호스트 범위브로드캐스트게이트웨이 (관례)
1192.168.1.0/26.1 ~ .62.63.1
2192.168.1.64/26.65 ~ .126.127.65
3192.168.1.128/26.129 ~ .190.191.129
4192.168.1.192/26.193 ~ .254.255.193
subnet_calculator.py
"""서브넷 분할 계산기"""
import ipaddress

def subnet_divide(network_str, new_prefix):
    """네트워크를 지정된 프리픽스로 분할"""
    network = ipaddress.ip_network(network_str, strict=False)
    subnets = list(network.subnets(new_prefix=new_prefix))

    print(f"원래 네트워크: {network}")
    print(f"서브넷 마스크: {network.netmask}")
    print(f"총 호스트: {network.num_addresses - 2}\n")
    print(f"분할 결과 ({len(subnets)}개 /{new_prefix} 서브넷):")
    print(f"{'서브넷':<22} {'호스트 범위':<35} {'BC':<16} {'호스트수'}")
    print("-" * 90)

    for i, subnet in enumerate(subnets, 1):
        hosts = list(subnet.hosts())
        if hosts:
            first, last = hosts[0], hosts[-1]
            print(f"{str(subnet):<22} {str(first)} ~ {str(last):<20} "
                  f"{str(subnet.broadcast_address):<16} {len(hosts)}")

# 실습
subnet_divide("192.168.1.0/24", 26)   # 4개 분할
print()
subnet_divide("10.0.0.0/16", 20)      # 16개 분할

# 두 IP가 같은 서브넷에 있는지 확인
def same_subnet(ip1, ip2, prefix):
    """두 IP가 같은 서브넷에 있는지 확인"""
    net = ipaddress.ip_network(f"{ip1}/{prefix}", strict=False)
    return ipaddress.ip_address(ip2) in net

print(f"\n같은 서브넷? {same_subnet('192.168.1.100', '192.168.1.200', 24)}")
print(f"같은 서브넷? {same_subnet('192.168.1.100', '192.168.1.200', 25)}")

슈퍼넷팅 (경로 집약)

서브넷 분할이 큰 네트워크를 작게 나누는 것이라면, 슈퍼넷팅(Supernetting)은 반대로 여러 네트워크를 하나로 합치는 것입니다.

경로 집약 예시
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

4개의 /24 네트워크:
  192.168.0.0/24  → 192.168.0.00000000
  192.168.1.0/24  → 192.168.0.00000001
  192.168.2.0/24  → 192.168.0.00000010
  192.168.3.0/24  → 192.168.0.00000011
                            ├─공통─┤

  공통 비트: 앞 22비트 → 192.168.0.0/22 하나로 집약

라우팅 테이블
  집약 전: 4개 항목
  집약 후: 1개 항목 → 메모리 절약, 조회 속도 향상

클라우드 VPC 서브넷 설계

AWS VPC를 설계할 때 CIDR 계산이 직접적으로 필요합니다.

AWS VPC 서브넷 설계 예시
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

VPC: 10.0.0.0/16 (65,534 호스트)
├── AZ-a
│   ├── Public:  10.0.0.0/20   (4,094 호스트)
│   ├── Private: 10.0.16.0/20  (4,094 호스트)
│   └── DB:      10.0.32.0/20  (4,094 호스트)
├── AZ-b
│   ├── Public:  10.0.48.0/20
│   ├── Private: 10.0.64.0/20
│   └── DB:      10.0.80.0/20
└── AZ-c
    ├── Public:  10.0.96.0/20
    ├── Private: 10.0.112.0/20
    └── DB:      10.0.128.0/20

주의: AWS는 각 서브넷에서 5개 주소를 예약
  .0 (네트워크), .1 (VPC 라우터), .2 (DNS),
  .3 (예약), .255 (브로드캐스트)
→ 실제 사용 가능: 4,094 - 5 = 4,089개
설계 원칙이유
VPC CIDR은 넉넉하게 (/16)나중에 확장 불가능
AZ별로 균등 분할가용성 확보
Public/Private/DB 분리보안 계층화
/20 이상 권장EKS 노드 IP 소진 방지
network_info.sh
# Linux에서 서브넷 정보 확인
ip addr show eth0 | grep inet

# 네트워크 주소 계산 (ipcalc)
ipcalc 192.168.1.100/26
# 출력: Network, HostMin, HostMax, Broadcast, Hosts

# Docker 네트워크의 서브넷 확인
docker network inspect bridge | grep -A 5 IPAM

다음 절에서는 사설 IP를 사용하는 장치들이 어떻게 인터넷과 통신하는지, NAT와 DHCP의 동작 원리를 살펴보겠습니다.

목차