컴퓨터 구조 운영체제 네트워크 자료구조 알고리즘 데이터베이스 내 학습
network · 14

서브네팅 / CIDR

IPCIDR서브넷

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 요약 (슈퍼네팅)

이어진 여러 네트워크를 더 짧은 접두사 하나로 합치는 것입니다. 라우팅 표의 항목 수를 줄여 라우터의 부담을 덜어 줍니다.

/n이 크면 네트워크가 작습니다 — 접두사가 길수록 호스트 비트가 적어 주소 수가 줄어듭니다. /24는 254개, /26은 62개, /30은 2개의 호스트를 둡니다.
AND 한 번으로 네트워크가 정해집니다 — IP와 마스크의 AND가 같은 두 주소는 같은 네트워크이고, 다르면 라우터를 거쳐야 합니다.
빌리는 비트마다 서브넷은 2배입니다 — 호스트 비트 2개를 빌리면 서브넷은 4개가 되고 서브넷마다 주소는 4분의 1이 됩니다.
합치려면 이어지고 정렬되어야 합니다 — CIDR 요약은 합쳐진 크기의 경계에 맞는 연속된 네트워크만 정확히 하나의 접두사가 됩니다.
이 시각화에서 확인할 것 — "비트로 계산" 탭에서 AND로 네트워크 주소를 구하는 과정을, "서브넷 나누기" 탭에서 /24를 /26 네 개로 나누는 과정을, "CIDR 요약" 탭에서 합칠 수 있는 경우와 없는 경우를 STEP으로 확인하세요.

서브네팅과 CIDR의 배경

서브넷 개념은 RFC 950(1985)이 IP 네트워크를 안쪽에서 나누는 방법으로 정했습니다. 그 뒤 클래스 방식의 주소 낭비와 라우팅 표의 급증이 문제가 되자 1993년 RFC 1519가 CIDR을 도입했고, 현재의 규격은 RFC 4632입니다. CIDR은 클래스 구분 없이 접두사 길이로 네트워크를 나타내고 여러 네트워크를 접두사 하나로 합칠 수 있게 했습니다. 오늘날 인터넷 라우팅은 CIDR을 기본으로 합니다.

숫자로 확인하기

호스트 수 계산 — /24는 호스트 비트가 8개라 2^8 = 256개 주소 중 2개를 빼 254개, /26은 호스트 비트 6개라 2^6 − 2 = 62개, /30은 2^2 − 2 = 2개입니다.
마스크의 십진 표기 — /26 마스크는 마지막 옥텟의 앞 2비트가 1이라 11000000 = 192이므로 255.255.255.192입니다.
시각화의 계산 예 — 192.168.1.130/26에서 마지막 옥텟 130(10000010)에 마스크 192(11000000)를 AND하면 10000000 = 128이어서 네트워크 주소는 192.168.1.128, 브로드캐스트는 192.168.1.191, 호스트는 129부터 190까지 62개입니다.
나누기의 손실 — /24(호스트 254개)를 /26 네 개로 나누면 호스트가 62 × 4 = 248개로 6개 줄어듭니다. 서브넷마다 네트워크 · 브로드캐스트 주소를 쓰기 때문입니다.
요약의 예 — 192.168.0.0/24와 192.168.1.0/24는 세 번째 옥텟이 00000000과 00000001이라 앞 23비트가 같아 192.168.0.0/23 하나로 합쳐지고, 주소 512개가 정확히 일치합니다.

자주 하는 오해

/24는 호스트가 256개다 — 주소는 256개이지만 네트워크 주소와 브로드캐스트 주소를 빼고 호스트에 줄 수 있는 것은 254개입니다. 점대점 링크용 /31(RFC 3021)처럼 예외 규칙이 있는 경우도 있습니다.
/16은 호스트가 16개라는 뜻이다 — /16의 16은 네트워크 부분의 비트 수입니다. 호스트 비트는 32 − 16 = 16개라 2^16 − 2 = 65,534개가 됩니다.
서브넷 마스크는 아무 비트나 1로 만들 수 있다 — 마스크는 앞쪽에 1이 연속으로 이어지고 뒤쪽이 모두 0이어야 합니다. 그래서 /n 하나로 표현됩니다.
이어진 네트워크는 항상 하나로 합쳐진다 — 합친 크기의 경계에 맞게 정렬된 경우에만 정확히 하나의 접두사가 됩니다. 예를 들어 192.168.1.0/24와 192.168.2.0/24는 정렬이 맞지 않아 /23 하나로 합칠 수 없습니다.

면접에서 이렇게 물어요

면접 질문

서브넷 마스크는 무엇이고 왜 필요한가요?

IP 주소에서 네트워크 부분과 호스트 부분을 가르는 값입니다. IP와 마스크를 AND해 네트워크 주소를 구하고, 목적지가 같은 네트워크인지 판단해 직접 보낼지 라우터로 보낼지 정합니다.

면접 질문

192.168.1.0/24에서 쓸 수 있는 호스트 주소는 몇 개인가요?

호스트 비트가 8개이므로 2^8 = 256개 주소 중 네트워크 주소와 브로드캐스트 주소를 뺀 254개입니다.

면접 질문

CIDR이 클래스 방식보다 나은 점은 무엇인가요?

클래스 방식은 네트워크 크기가 A, B, C 셋으로 고정되어 주소가 낭비되었습니다. CIDR은 접두사 길이를 자유롭게 정해 필요한 크기만 쓰고, 여러 네트워크를 요약해 라우팅 표를 줄입니다.

면접 질문

두 IP가 같은 서브넷인지 어떻게 확인하나요?

각 IP에 같은 서브넷 마스크를 AND해서 얻은 네트워크 주소가 같은지 비교합니다. 같으면 같은 서브넷이어서 라우터 없이 직접 통신할 수 있습니다.

실제 시스템에서는

호스트의 판단 — 운영체제는 자기 IP와 마스크로 목적지가 같은 서브넷인지 확인해, 같으면 ARP로 상대의 MAC을 찾아 직접 보내고 아니면 기본 게이트웨이로 보냅니다.
사설 대역 — RFC 1918의 사설 주소는 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16이며, 클라우드 가상 네트워크(VPC)도 이런 대역을 주로 서브넷으로 나눠 씁니다.
라우팅 표 — 라우터는 접두사가 가장 긴(가장 구체적인) 경로를 우선하는 최장 접두사 일치로 경로를 고르고, 요약된 경로로 표 크기를 줄입니다.
IPv6 — IPv6도 접두사 길이 표기(/64 등)를 같은 방식으로 씁니다.

함께 보면 좋은 토픽

TCP/IP — IP 주소의 구조와 전달 흐름을 봅니다.
라우팅 — 라우팅 표와 최장 접두사 일치를 봅니다.
ARP — 같은 서브넷 안에서 MAC 주소를 찾는 방법을 봅니다.
NAT — 사설 주소 대역과 공인 주소의 변환을 봅니다.

참고 자료

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 네트워크에서 호스트에 할당할 수 있는 주소는 몇 개일까?

호스트 비트 수는 32 - 24 = 8 입니다. 전부를 쓸 수는 없습니다.
호스트 비트가 8개이므로 2^8 = 256개 주소 중, 네트워크 주소(모든 호스트 비트가 0)와 브로드캐스트 주소(모두 1) 2개를 제외한 254개를 호스트에 할당할 수 있습니다.

Q2

CIDR 표기 /26 에 해당하는 서브넷 마스크는?

/24 에서 2비트를 더 네트워크로 가져옵니다.
/26은 앞 26비트가 1입니다. 마지막 옥텟에서는 상위 2비트가 1이므로 11000000 = 192가 되어 255.255.255.192입니다.

Q3

CIDR 표기 10.0.0.0/16 에서 /16의 의미는?

슬래시 뒤 숫자는 1로 채워진 서브넷 마스크 비트 수입니다.
/n은 서브넷 마스크에서 앞쪽 n비트가 1이라는 뜻이며, IP 주소의 앞 n비트가 네트워크 부분을 나타냅니다. 나머지 비트는 호스트 부분입니다.