본문으로 건너뛰기

안동민 개발노트

본문 시작

서브넷과 CIDR

서브넷 마스크와 CIDR 접두어로 네트워크·호스트·브로드캐스트 범위를 계산하고 VPC 주소 공간을 설계합니다.

클래스 기반 주소 체계의 가장 큰 문제는 유연성이 없다는 것이었습니다.

호스트가 300대 필요한 조직에 클래스 C(254대)를 주면 부족하고, 클래스 B(65,534대)를 주면 65,000개 이상의 주소가 낭비됩니다.

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


서브넷 마스크의 역할

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

HTML 다이어그램: /docs/network/ch4/ch4-2/1.html

IP 주소와 서브넷 마스크를 비트 단위로 AND 연산하면 네트워크 주소가 나옵니다.

반대로 마스크에서 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포인트투포인트 링크
/31255.255.255.25412포인트투포인트 링크
/32255.255.255.25501단일 호스트

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

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

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

다만 /31은 포인트투포인트 링크에서 두 주소를 모두 사용할 수 있고, /32는 단일 호스트 경로를 나타내므로 위 공식의 예외로 다룹니다.


서브넷 분할 계산

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

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

HTML 다이어그램: /docs/network/ch4/ch4-2/2.html
서브넷네트워크 주소호스트 범위브로드캐스트게이트웨이 (관례)
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"사용 가능 호스트: {len(list(network.hosts()))}\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)은 반대로 여러 네트워크를 하나로 합치는 것입니다.

HTML 다이어그램: /docs/network/ch4/ch4-2/3.html

경로 집약은 아무 네트워크나 합칠 수 있는 것이 아닙니다.

네트워크들이 연속된 주소 범위여야 하고, 합친 범위가 프리픽스 경계에 맞게 정렬되어 있어야 합니다.

또한 집약 대상 경로가 같은 방향으로 나가거나 같은 정책으로 처리될 수 있어야 합니다.

예를 들어 192.168.0.0/24부터 192.168.3.0/24까지 네 개의 연속된 네트워크는 192.168.0.0/22 하나로 표현할 수 있습니다.


클라우드 VPC 서브넷 설계

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

HTML 다이어그램: /docs/network/ch4/ch4-2/4.html
설계 원칙이유
VPC CIDR은 넉넉하게 선택기본 CIDR 크기는 나중에 변경할 수 없음
보조 CIDR 확장 가능성 고려필요 시 secondary IPv4 CIDR을 추가 가능
AZ별로 균등 분할가용성 확보
Public/Private/DB 분리보안 계층화
서브넷당 예약 IP 5개 고려AWS가 첫 4개와 마지막 1개 주소를 예약
EKS/컨테이너 IP 예산 확보노드와 Pod ENI/IP 소진 방지

AWS에서 IPv4 서브넷 크기는 /16부터 /28 범위 안에서 선택합니다.

각 서브넷에서는 첫 네 개 주소와 마지막 주소를 사용할 수 없으므로, 예를 들어 /24는 256개 주소가 있어도 실제 할당 가능한 주소는 251개입니다.

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의 동작 원리를 살펴보겠습니다.

HTML 다이어그램: /docs/network/ch4/ch4-2/5.html