📚 네트워크 · 패킷 분석 › 01. TCP/IP 구조 이해 — 13편
이전 글: 12. Subnet Mask란 무엇인가 · 다음 글: 14. IPv4 주소와 서브넷(CIDR) — 같은 네트워크인지 판단하는 법
서브넷 마스크로 IP 주소를 나누면 두 부분이 나옵니다.
여기서 특별한 두 주소가 정해집니다.
| 용어 | 정의 | 용도 |
|---|---|---|
| 네트워크 주소(Network Address) | 호스트 부분 비트가 모두 0인 주소 | 네트워크 자체를 가리키는 이름 (라우팅 테이블, 방화벽 정책) |
| 브로드캐스트 주소(Broadcast Address) | 호스트 부분 비트가 모두 1인 주소 | 그 네트워크 전체에 보내는 주소 |
| 호스트 주소(Host Address) | 그 사이의 주소 | 실제 장치에 할당 |
| 호스트 부분 값(Host ID) | IP에서 네트워크 부분을 뺀 나머지 값 | "네트워크 안의 몇 번째 주소인가" |
그래서 사용 가능한 호스트 수는 2^(호스트 비트) − 2 입니다. 마스크 자체의 원리는 12. Subnet Mask란 무엇인가에서 다뤘습니다.
계산은 비트 연산 두 번으로 끝납니다.
네트워크 주소 = IP AND 마스크 (호스트 비트를 0으로)
브로드캐스트 = 네트워크 주소 OR (NOT 마스크) (호스트 비트를 1로)
호스트 범위 = 네트워크 주소 + 1 ~ 브로드캐스트 − 1
Host ID = IP AND (NOT 마스크)
예) 192.168.10.100/26 마스크 255.255.255.192 (마지막 옥텟 11000000)
마지막 옥텟 100 = 01|100100
↓ 앞 2비트는 네트워크, 뒤 6비트는 호스트
네트워크 주소 : 01|000000 = 64 → 192.168.10.64
브로드캐스트 : 01|111111 = 127 → 192.168.10.127
호스트 범위 : 192.168.10.65 ~ 192.168.10.126 (62개)
Host ID : 100 − 64 = 36
손으로 빠르게 계산할 때는 블록 크기(256 − 해당 옥텟의 마스크 값) 를 씁니다. /26이면 256 − 192 = 64이므로 네트워크가 0, 64, 128, 192에서 시작합니다. 100은 64~127 블록에 속하므로 네트워크 주소는 .64입니다.
같은 방식으로 여러 프리픽스를 계산하면 다음과 같습니다.
| 주소/프리픽스 | 네트워크 주소 | 브로드캐스트 주소 | 사용 가능한 호스트 범위 | 호스트 수 |
|---|---|---|---|---|
192.168.10.25/24 | 192.168.10.0 | 192.168.10.255 | .1 ~ .254 | 254 |
192.168.10.100/26 | 192.168.10.64 | 192.168.10.127 | .65 ~ .126 | 62 |
10.20.35.77/20 | 10.20.32.0 | 10.20.47.255 | 10.20.32.1 ~ 10.20.47.254 | 4,094 |
192.168.10.9/30 | 192.168.10.8 | 192.168.10.11 | .9 ~ .10 | 2 |
/20 예시는 경계가 셋째 옥텟에 걸립니다. 마스크 셋째 옥텟이 240이므로 블록 크기는 16이고, 35는 32~47 블록에 속합니다. 그래서 10.20.35.0처럼 끝이 0인 주소도 이 네트워크에서는 정상적인 호스트 주소입니다. "끝자리가 0이면 네트워크 주소, 255면 브로드캐스트"라는 생각은 /24에서만 맞습니다.
예외도 있습니다.
/31: 점대점 링크용으로, 두 주소를 모두 호스트에 씁니다(RFC 3021)./32: 단일 호스트를 가리키며, 방화벽 정책·라우팅에서 "이 IP 하나"를 뜻합니다..1이나 .254에 두는 것은 관례일 뿐 규칙이 아닙니다.실습 예시 — Python으로 계산 결과 검증 (Rocky·Ubuntu 공통)
python3 - <<'EOF'
import ipaddress
for s in ["192.168.10.25/24", "192.168.10.100/26", "10.20.35.77/20"]:
i = ipaddress.ip_interface(s); n = i.network
hosts = list(n.hosts())
print(f"{s:18} net={n.network_address} bcast={n.broadcast_address} "
f"range={hosts[0]}~{hosts[-1]} hostid={int(i.ip) & int(n.hostmask)}")
EOF
# 출력 예시
192.168.10.25/24 net=192.168.10.0 bcast=192.168.10.255 range=192.168.10.1~192.168.10.254 hostid=25
192.168.10.100/26 net=192.168.10.64 bcast=192.168.10.127 range=192.168.10.65~192.168.10.126 hostid=36
10.20.35.77/20 net=10.20.32.0 bcast=10.20.47.255 range=10.20.32.1~10.20.47.254 hostid=845
Linux ip -4 addr 출력의 brd 값이 브로드캐스트 주소이고, ip route의 192.168.10.0/24 dev ens33 proto kernel scope link 줄이 네트워크 주소입니다(값은 환경마다 다름). 네트워크를 더 작게 나누는 방법은 15. Subnetting 기초에서 다룹니다.
192.168.10.64/26을 의도했는데 192.168.10.100/26처럼 호스트 주소를 적으면, 장비에 따라 자동으로 네트워크 주소로 보정하거나 오류를 내는 등 동작이 다르므로 작성 시 네트워크 주소로 정확히 적어야 합니다.관제에서는 개별 IP보다 네트워크 주소 단위로 묶어 보는 경우가 많습니다.
| 분석 상황 | 네트워크 주소 활용 |
|---|---|
| 스캔 판단 | 목적지 IP를 /24로 묶어, 한 출발지가 한 대역의 몇 개 호스트에 접근했는지 집계 |
| 공격 출발지 묶기 | 출발지를 대역 단위로 묶어 같은 호스팅 대역에서 오는 분산 시도 확인 |
| 자산 구역 판별 | 내부 IP의 네트워크 주소로 서버망·사용자망·DMZ 판별 |
| 차단 범위 결정 | 단일 IP(/32) 차단인지 대역 차단인지, 부작용 범위 계산 |
관제자가 확인할 질문은 다음과 같습니다.
⚠️ 오탐 주의: /24가 아닌 대역에서는 .0이나 .255로 끝나는 주소도 정상 호스트일 수 있습니다. 끝자리만 보고 "브로드캐스트로 가는 이상 트래픽"으로 판단하지 말고, 해당 대역의 실제 프리픽스로 계산해야 합니다. 대역 단위 스캔 분석은 05 영역 227. 다수 IP에 대한 Port 접근에서 다룹니다.
.0/.255 규칙은 /24에서만 맞으며, /31·/32는 예외입니다.