포스트

ARP와 L2/L3 경계 — IP는 아는데 왜 MAC을 또 묻나

같은 서브넷과 다른 서브넷 통신의 차이, ARP가 IP를 MAC으로 해석하는 과정(브로드캐스트→유니캐스트), ARP 캐시와 스푸핑, L2/L3 경계에서 목적지 MAC만 홉마다 바뀌는 원리를 설명합니다.

ARP와 L2/L3 경계 — IP는 아는데 왜 MAC을 또 묻나

“목적지 IP를 아는데, 왜 프레임을 못 보내지?”

라우팅 글에서 라우터는 “다음 홉(next-hop)의 IP”를 정했습니다. 그런데 실제로 옆 장비에게 데이터를 건네는 건 IP가 아니라 MAC 주소입니다 — 이더넷 프레임의 목적지 칸에는 IP가 아니라 MAC이 들어가니까요. “next-hop의 IP는 10.1.0.1”까진 알아도, 그 IP를 가진 장비의 MAC을 모르면 프레임을 못 만듭니다.

이 IP→MAC 변환을 같은 망 안에서 해결하는 게 ARP(Address Resolution Protocol) 입니다. 그리고 이 글의 더 중요한 절반은 그 앞 단계 — “목적지가 나와 같은 망(직접 전달)이냐, 다른 망(게이트웨이 경유)이냐”를 호스트가 매 패킷 어떻게 판단하는지, 즉 L2와 L3의 경계입니다. 여기를 정확히 이해하면 “같은 IP인데 왜 MAC은 게이트웨이 거냐” 같은 혼란이 영구히 사라집니다.

모든 송신의 첫 분기: 같은 서브넷인가?

호스트가 패킷을 보내기 직전, 단 하나의 비교를 합니다 — 목적지 IP와 내 IP를, 내 서브넷 마스크로 AND 해서 같은 네트워크인지 봅니다(서브넷팅 글).

같은 서브넷 → 목적지에게 직접 (dst MAC = 목적지) A B (같은 망) 다른 서브넷 → 게이트웨이로 (dst MAC = GW, 거기서 재작성) A 게이트웨이 외부 망 dst MAC 재작성
  • 같은 망이면(위): 목적지에게 직접 보냅니다. 프레임의 dst MAC = 목적지 호스트의 MAC. ARP로 목적지 IP의 MAC을 구합니다.
  • 다른 망이면(아래): 목적지에게 직접 못 갑니다. 기본 게이트웨이에게 떠넘깁니다. 프레임의 dst MAC = 게이트웨이의 MAC. ARP로 구하는 건 목적지가 아니라 게이트웨이 IP의 MAC입니다.

여기가 핵심 통찰입니다. 다른 망으로 가는 패킷에서, L3의 목적지 IP는 최종 목적지로 끝까지 유지되지만, L2의 목적지 MAC은 매 홉 바뀝니다(지금 프레임을 받을 바로 옆 장비의 MAC). 그래서 “패킷이 인터넷을 건넌다”는 건, 변하지 않는 IP 봉투 안의 내용물이, 홉마다 새로 쓰이는 MAC 겉봉에 담겨 옆집으로 계속 전달되는 것입니다. IP=목적지 주소, MAC=바로 다음 한 집 주소.

ARP: IP를 MAC으로 바꾸는 브로드캐스트 질문

이제 “이 IP의 MAC이 뭐지?”를 풀어야 합니다. 호스트는 같은 망 전체에 브로드캐스트로 묻고(“누가 10.0.0.7의 주인이냐?”), 해당 IP를 가진 호스트만 유니캐스트로 답합니다(“나야, 내 MAC은 …”).

A 10.0.0.5 스위치 B .6 C .8 D .7 ✓ "누가 10.0.0.7?" (브로드캐스트)

B와 C는 자기 IP가 아니라 조용히 무시하고, D만 자기 MAC을 담아 A에게 직접(유니캐스트) 답합니다. A는 이 결과를 ARP 캐시에 저장해, 다음부턴 묻지 않습니다.

1
2
3
$ ip neigh                 # (구버전: arp -a) — ARP 캐시 확인
10.0.0.7  dev eth0  lladdr  3c:22:fb:a1:09:7e  REACHABLE
10.0.0.1  dev eth0  lladdr  00:1a:2b:3c:4d:5e  STALE      # 게이트웨이, 곧 재검증

ARP 패킷 자체는 IP 헤더조차 없는 순수 L2 프로토콜입니다(EtherType 0x0806). 주요 필드: sender/target의 IP와 MAC 4쌍, opcode(1=request, 2=reply). request는 “target MAC = 00:00:..(모름)”으로 보내고, reply가 그 칸을 채워 돌아옵니다.

sequenceDiagram
    participant A as A (10.0.0.5)
    participant LAN as 같은 LAN(브로드캐스트)
    participant D as D (10.0.0.7)
    A->>LAN: ARP request "누가 10.0.0.7? (target MAC=?)"
    Note over LAN: B·C는 자기 IP 아님 → 무시
    D-->>A: ARP reply (유니캐스트) "10.0.0.7 = 3c:22:fb:a1:09:7e"
    Note over A: ARP 캐시에 저장 → 이후 생략

전체 그림: 다른 망으로 보낼 때 실제로 일어나는 일

10.0.0.5의 A가 인터넷의 8.8.8.8로 패킷을 보낸다고 합시다.

  1. 분기: 8.8.8.8을 내 마스크로 AND → 내 서브넷이 아님 → 게이트웨이로 보낸다.
  2. ARP: 목적지(8.8.8.8)가 아니라 게이트웨이 10.0.0.1의 MAC을 ARP로 구한다.
  3. 프레임 작성: dst IP = 8.8.8.8(최종), dst MAC = 게이트웨이 MAC(바로 옆).
  4. 게이트웨이(라우터): 프레임을 받아 IP는 그대로 두고, 다음 홉을 향해 dst MAC만 새로 써서(다음 라우터의 MAC) 내보낸다. 이게 매 홉 반복된다.

즉 ARP는 “내 망 안에서 옆 장비의 MAC을 구하는 도구“일 뿐이고, 인터넷을 건너는 동안 IP는 불변, MAC은 홉마다 교체됩니다.

보안 함정: ARP 스푸핑 — 신뢰가 없는 프로토콜

ARP에는 인증이 없습니다. “내가 10.0.0.1(게이트웨이)다”라는 거짓 reply를 보내면, 같은 망의 호스트들은 그대로 믿고 게이트웨이로 갈 트래픽을 공격자에게 보냅니다(중간자 공격, MITM). gratuitous ARP(요청 없이 보내는 ARP — 원래는 IP 충돌 감지·페일오버용)가 이 공격의 흔한 수단입니다.

대응: 스위치의 Dynamic ARP Inspection(DAI) + DHCP Snooping으로 위조 ARP를 포트 레벨에서 차단, 중요 장비엔 static ARP 고정. 클라우드는 아예 ARP를 우회합니다 — AWS VPC는 가상 L2라 ARP 스푸핑이 구조적으로 불가능합니다(VPC 글).

진단:

1
2
$ tcpdump -n -e arp                 # 누가 어떤 ARP를 뿌리는지 실시간
$ ip neigh | grep 10.0.0.1          # 게이트웨이 MAC이 갑자기 바뀌었나?

게이트웨이의 MAC이 어느 순간 다른 값으로 바뀌어 있다면, 스푸핑을 의심해야 합니다.

면접/리뷰 단골 질문

  • Q. IP를 아는데 ARP가 왜 필요한가? → 실제 프레임 전달은 L2(MAC)로 한다. IP를 같은 망 안의 MAC으로 변환해야 프레임을 만들 수 있다.
  • Q. 다른 서브넷으로 보낼 때 dst MAC은 누구 것? → 최종 목적지가 아니라 게이트웨이의 MAC. dst IP만 최종 목적지로 유지된다. (L2 MAC은 홉마다 교체, L3 IP는 불변.)
  • Q. ARP request는 왜 브로드캐스트, reply는 유니캐스트? → 누가 그 IP의 주인인지 모르니 전체에 묻고(브로드캐스트), 답하는 쪽은 묻는 이를 알므로 직접 답한다(유니캐스트).
  • Q. ARP 스푸핑이 가능한 근본 이유? → ARP에 인증이 없어 거짓 reply를 검증 없이 믿는다. 대응은 DAI+DHCP Snooping, static ARP.
  • Q. 게이트웨이 통신이 갑자기 끊겼는데 핑도 안 된다, 첫 확인은? → ip neigh로 게이트웨이 MAC이 정상인지(스푸핑/캐시 STALE) 확인.

정리

  • 모든 송신의 첫 분기 = 목적지가 같은 서브넷인가(IP를 마스크로 AND). 같으면 직접, 다르면 게이트웨이로.
  • ARP = 같은 망 안에서 IP→MAC을 푸는 도구. request는 브로드캐스트, reply는 유니캐스트, 결과는 캐시.
  • 다른 망으로 갈 때: dst IP는 최종 목적지(불변), dst MAC은 게이트웨이(홉마다 교체). IP=목적지, MAC=다음 한 집.
  • ARP는 인증이 없어 스푸핑(MITM) 에 취약 → DAI·DHCP Snooping·static ARP. 클라우드(VPC)는 가상 L2로 원천 차단.

다음 글: 같은 망 안에서 MAC으로 프레임을 실어 나르고, 스위치가 그 MAC을 학습해 포워딩하는 이더넷·MAC·스위치로 이어집니다. 한편 다른 망으로 넘기는 결정의 근거였던 서브넷 계산은 IP 주소와 서브넷팅에서 다룹니다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.

시리즈 · 네트워크 A-Z (20편)

  1. 네트워크란 무엇인가 — 회선 교환 vs 패킷 교환, 왜 인터넷은 패킷을 선택했나
  2. OSI 7계층과 TCP/IP — 왜 네트워크를 굳이 층으로 쪼갰나
  3. 이더넷·MAC·스위치 — 스위치는 어떻게 "어느 포트로 보낼지" 스스로 배우나
  4. IP 주소와 서브넷팅 — /24를 /26으로 쪼갠다는 게 비트 단위로 무슨 뜻인가
  5. 라우팅은 어떻게 길을 찾나 — 라우팅 테이블, Longest Prefix Match, 그리고 BGP
  6. ARP와 L2/L3 경계 — IP는 아는데 왜 MAC을 또 묻나 지금 보는 글
  7. TCP는 어떻게 신뢰를 만드나 — 3-way handshake, 상태 머신, 그리고 TIME_WAIT
  8. TCP는 얼마나 빨리 보낼까 — 흐름 제어 vs 혼잡 제어, 그리고 톱니파의 비밀
  9. UDP와 QUIC — TCP를 버려야 더 빨라지는 순간
  10. DNS는 어떻게 이름을 주소로 바꾸나 — 루트부터 권한 서버까지, 그리고 캐시의 마법
  11. HTTP의 진화 — 1.1의 줄 서기에서 HTTP/2 멀티플렉싱, HTTP/3까지
  12. TLS/HTTPS는 어떻게 도청 불가능한 채널을 만드나 — 핸드셰이크부터 인증서 체인까지
  13. NAT와 사설망 — 주소 하나로 수백 대가 인터넷을 쓰는 법, 그리고 P2P가 막히는 이유
  14. 로드 밸런싱 — L4와 L7은 무엇이 다르며, 왜 헬스체크가 서비스를 살리고 죽이나
  15. 프록시·리버스 프록시·CDN — 콘텐츠를 사용자 코앞으로 옮기는 기술
  16. 방화벽·보안그룹·네트워크 ACL — stateful과 stateless가 가르는 모든 것
  17. VPC & 클라우드 네트워킹 — 라우팅 테이블 한 줄이 퍼블릭과 프라이빗을 가른다
  18. 소켓과 커널 네트워크 스택 — accept 한 줄 뒤에서 벌어지는 일
  19. 네트워크 성능 — 대역폭은 왜 빠름이 아닌가 (RTT·BDP·처리량의 진실)
  20. 현대 네트워킹 — 사이드카, eBPF, 그리고 경계가 사라진 신뢰