서브네팅 / CIDR
IP 주소 192.168.1.130만 보아서는 이 주소가 어느 네트워크에 속하는지 알 수 없습니다. 같은 네트워크 안의 장치끼리는 라우터 없이 직접 통신하고, 다른 네트워크의 장치에는 라우터를 거쳐 가야 하므로, 장치는 목적지가 "같은 네트워크"인지 먼저 판단해야 합니다. 이 판단의 기준이 서브넷 마스크입니다. 마스크가 1로 채워진 앞쪽 비트는 네트워크를 가리키는 부분이고, 0인 뒤쪽 비트는 그 네트워크 안의 호스트를 가리키는 부분입니다. 큰 네트워크를 필요한 크기의 작은 네트워크(서브넷)로 나누는 것을 서브네팅이라고 합니다.
예전에는 주소의 앞쪽 비트 패턴으로 A, B, C 클래스를 정해 네트워크 크기가 고정되어 있었습니다. 이 방식은 크기가 맞지 않아 주소가 낭비되었고, 이를 풀기 위해 접두사 길이를 자유롭게 정하는 CIDR(Classless Inter-Domain Routing) 표기(192.168.1.0/24처럼 주소 뒤에 슬래시와 접두사 길이를 붙임)가 쓰이게 되었습니다. 이 토픽에서는 마스크로 네트워크 주소를 계산하는 법, 네트워크를 서브넷으로 나누는 법, 여러 네트워크를 접두사 하나로 합치는 CIDR 요약을 단계별로 봅니다.
핵심 개념
네트워크 부분과 호스트 부분
IPv4 주소 32비트는 앞쪽 네트워크 부분과 뒤쪽 호스트 부분으로 나뉩니다. 같은 네트워크의 장치는 네트워크 부분이 같고 호스트 부분만 다릅니다.
핵심 개념
서브넷 마스크
앞쪽이 1이고 뒤쪽이 0인 32비트 값입니다. IP 주소와 마스크를 비트마다 AND하면 호스트 부분이 지워져 네트워크 주소가 나옵니다. /24는 255.255.255.0입니다.
핵심 개념
CIDR 표기 (/n)
주소 뒤에 슬래시와 접두사 길이를 적는 방식입니다. /n은 마스크의 앞 n비트가 1이라는 뜻이고, IP 주소의 앞 n비트가 네트워크 부분을 가리킵니다. 호스트 비트는 32 − n개입니다.
핵심 개념
네트워크 · 브로드캐스트 주소
호스트 비트가 모두 0인 주소는 네트워크 자체를, 모두 1인 주소는 네트워크 전체에 보내는 브로드캐스트를 뜻해 호스트에 줄 수 없습니다. 그래서 호스트 수는 보통 2^(32−n) − 2입니다(/31, /32는 예외).
핵심 개념
서브네팅과 VLSM
호스트 비트를 네트워크 부분으로 빌려 와 네트워크를 둘 이상으로 나눕니다. 서브넷마다 접두사 길이를 다르게 해 필요한 크기만큼 주소를 주는 방식을 VLSM(가변 길이 서브넷 마스크)이라고 합니다.
핵심 개념
CIDR 요약 (슈퍼네팅)
이어진 여러 네트워크를 더 짧은 접두사 하나로 합치는 것입니다. 라우팅 표의 항목 수를 줄여 라우터의 부담을 덜어 줍니다.
서브네팅과 CIDR의 배경
서브넷 개념은 RFC 950(1985)이 IP 네트워크를 안쪽에서 나누는 방법으로 정했습니다. 그 뒤 클래스 방식의 주소 낭비와 라우팅 표의 급증이 문제가 되자 1993년 RFC 1519가 CIDR을 도입했고, 현재의 규격은 RFC 4632입니다. CIDR은 클래스 구분 없이 접두사 길이로 네트워크를 나타내고 여러 네트워크를 접두사 하나로 합칠 수 있게 했습니다. 오늘날 인터넷 라우팅은 CIDR을 기본으로 합니다.
숫자로 확인하기
자주 하는 오해
면접에서 이렇게 물어요
면접 질문
서브넷 마스크는 무엇이고 왜 필요한가요?
IP 주소에서 네트워크 부분과 호스트 부분을 가르는 값입니다. IP와 마스크를 AND해 네트워크 주소를 구하고, 목적지가 같은 네트워크인지 판단해 직접 보낼지 라우터로 보낼지 정합니다.
면접 질문
192.168.1.0/24에서 쓸 수 있는 호스트 주소는 몇 개인가요?
호스트 비트가 8개이므로 2^8 = 256개 주소 중 네트워크 주소와 브로드캐스트 주소를 뺀 254개입니다.
면접 질문
CIDR이 클래스 방식보다 나은 점은 무엇인가요?
클래스 방식은 네트워크 크기가 A, B, C 셋으로 고정되어 주소가 낭비되었습니다. CIDR은 접두사 길이를 자유롭게 정해 필요한 크기만 쓰고, 여러 네트워크를 요약해 라우팅 표를 줄입니다.
면접 질문
두 IP가 같은 서브넷인지 어떻게 확인하나요?
각 IP에 같은 서브넷 마스크를 AND해서 얻은 네트워크 주소가 같은지 비교합니다. 같으면 같은 서브넷이어서 라우터 없이 직접 통신할 수 있습니다.
실제 시스템에서는
함께 보면 좋은 토픽
참고 자료
Python — ipaddress로 네트워크 정보 구하기
import ipaddress net = ipaddress.ip_network("192.168.1.128/26") print(net.network_address) # 192.168.1.128 print(net.netmask) # 255.255.255.192 print(net.broadcast_address) # 192.168.1.191 print(net.num_addresses) # 64 hosts = list(net.hosts()) print(hosts[0], hosts[-1], len(hosts)) # 192.168.1.129 192.168.1.190 62 print(ipaddress.ip_address("192.168.1.130") in net) # True
파이썬 표준 라이브러리 ipaddress의 ip_network는 주소와 접두사 길이로 네트워크 객체를 만들고, 네트워크 주소, 넷마스크, 브로드캐스트 주소, 주소 개수를 속성으로 줍니다. hosts()는 보통 네트워크 주소와 브로드캐스트 주소를 뺀 호스트 주소(/31, /32는 예외)를 차례로 돌려주므로 /26에서는 62개입니다. in 연산자로 어떤 IP가 그 네트워크에 속하는지도 확인합니다. 접두사 뒤의 호스트 비트가 0이 아닌 주소(192.168.1.130/26)는 기본적으로 오류가 나며, strict=False를 주면 네트워크 주소로 맞춰서 받아 줍니다.
Python — 서브넷 나누기와 CIDR 요약
import ipaddress net = ipaddress.ip_network("192.168.1.0/24") for sub in net.subnets(new_prefix=26): print(sub, sub.broadcast_address) # 192.168.1.0/26 192.168.1.63 ... 192.168.1.192/26 192.168.1.255 a = ipaddress.ip_network("192.168.0.0/24") b = ipaddress.ip_network("192.168.1.0/24") c = ipaddress.ip_network("192.168.2.0/24") print(list(ipaddress.collapse_addresses([a, b]))) # 192.168.0.0/23 하나 print(list(ipaddress.collapse_addresses([b, c]))) # 합쳐지지 않고 둘 그대로
subnets(new_prefix=26)은 /24를 /26 네 개로 나눠 하나씩 돌려줍니다. 시각화의 서브넷 나누기 탭과 같은 결과입니다. collapse_addresses는 합칠 수 있는 네트워크를 가능한 한 적은 수의 네트워크로 합쳐 줍니다. 192.168.0.0/24와 192.168.1.0/24는 /23 하나가 되지만, 192.168.1.0/24와 192.168.2.0/24는 정렬이 맞지 않아 둘 그대로 남습니다. 이 함수는 정확히 같은 주소 범위만 합치므로 시각화에서 본 "원래 없던 네트워크까지 포함하는" 요약은 만들지 않습니다.
C — 비트 연산으로 네트워크 주소 구하기
#include <stdint.h> #include <stdio.h> int main(void) { uint32_t ip = (192u << 24) | (168u << 16) | (1u << 8) | 130u; int prefix = 26; uint32_t mask = prefix == 0 ? 0 : 0xFFFFFFFFu << (32 - prefix); uint32_t network = ip & mask; uint32_t broadcast = network | ~mask; printf("network %u.%u.%u.%u\n", network >> 24, (network >> 16) & 255, (network >> 8) & 255, network & 255); /* 192.168.1.128 */ return broadcast == network + 63 ? 0 : 1; }
IPv4 주소를 32비트 정수로 보면, 마스크는 앞쪽 prefix개의 비트만 1인 값이고 네트워크 주소는 IP와 마스크의 AND, 브로드캐스트 주소는 네트워크 주소에 마스크를 뒤집은 값(~mask)을 OR한 것입니다. prefix가 0일 때는 32비트 이동이 정의되지 않아 따로 처리해야 하고, 이동하는 값은 부호 없는 정수(u)로 써야 합니다. 이 계산은 시각화의 비트로 계산 탭과 같으며, 192.168.1.130/26에서 네트워크 주소 192.168.1.128과 브로드캐스트 192.168.1.191(= 128 + 63)을 얻습니다.
Q1
192.168.1.0/24 네트워크에서 호스트에 할당할 수 있는 주소는 몇 개일까?
Q2
CIDR 표기 /26 에 해당하는 서브넷 마스크는?
Q3
CIDR 표기 10.0.0.0/16 에서 /16의 의미는?