ARP: IPv4 주소를 로컬 네트워크의 MAC 주소로 해석하는 프로토콜
주소 결정 프로토콜(ARP)은 같은 브로드캐스트 도메인에서 IPv4 주소에 대응하는 MAC 주소를 찾는다. 호스트는 ARP 요청을 브로드캐스트하고, 대상은 자신의 MAC 주소를 담은 ARP 응답을 보낸다. 확인한 대응 관계는 ARP 캐시에 일정 시간 저장해 반복 조회를 줄인다.
By 송민성
1. 개념
주소 결정 프로토콜(ARP, Address Resolution Protocol)은 IPv4 주소를 링크 계층의 매체 접근 제어 주소(MAC address)로 변환하는 프로토콜이다.
애플리케이션이 192.168.0.20으로 데이터를 보내더라도 이더넷 프레임에는 목적지 MAC 주소가 필요하다. 송신 호스트는 ARP를 사용해 해당 IPv4 주소에 대응하는 MAC 주소를 알아낸다.
ARP는 다음 조건에서 사용된다.
- IPv4와 이더넷을 사용하는 네트워크
- 송신 대상이 같은 서브넷에 있을 때
- 다른 서브넷으로 보낼 패킷의 기본 게이트웨이(default gateway) MAC 주소를 찾을 때
ARP 메시지는 IP 패킷이나 전송 계층 프로토콜에 담기지 않고 이더넷 프레임에 직접 실린다. 이더타입(EtherType)은 0x0806이다. TCP·UDP 포트는 사용하지 않는다.
IPv6에서는 ARP 대신 이웃 탐색 프로토콜(NDP, Neighbor Discovery Protocol)을 사용한다.
2. 왜 사용하는가
IPv4 주소와 MAC 주소는 서로 다른 역할을 한다.
- IPv4 주소: 여러 네트워크를 거쳐 최종 호스트까지 패킷을 전달하는 논리 주소
- MAC 주소: 같은 링크에서 이더넷 프레임을 전달하는 링크 계층 주소
예를 들어 호스트의 설정이 다음과 같다고 가정한다.
호스트 IPv4 주소: 192.168.10.15
서브넷 마스크: 255.255.255.0
기본 게이트웨이: 192.168.10.1192.168.10.20으로 패킷을 보내면 대상은 같은 서브넷에 있다. 호스트는 ARP로 192.168.10.20의 MAC 주소를 찾는다.
8.8.8.8로 패킷을 보내면 대상은 다른 서브넷에 있다. 호스트는 8.8.8.8의 MAC 주소를 찾지 않는다. 다음 홉(next hop)인 기본 게이트웨이 192.168.10.1의 MAC 주소를 ARP로 찾는다.
같은 서브넷:
IP 목적지 = 192.168.10.20
MAC 목적지 = 192.168.10.20 호스트의 MAC 주소
다른 서브넷:
IP 목적지 = 8.8.8.8
MAC 목적지 = 기본 게이트웨이의 MAC 주소라우터를 통과할 때 IP 목적지 주소는 일반적으로 유지되지만, 이더넷 출발지·목적지 MAC 주소는 링크마다 바뀐다.
3. 동작 원리
3.1 다음 홉 결정
송신 호스트는 자신의 IPv4 주소, 서브넷 마스크, 목적지 IPv4 주소를 사용해 목적지가 같은 서브넷에 있는지 판단한다.
내 네트워크 = 내 IPv4 주소 AND 서브넷 마스크
대상 네트워크 = 대상 IPv4 주소 AND 서브넷 마스크두 결과가 같으면 대상 호스트가 다음 홉이다. 다르면 라우팅 테이블에서 다음 홉을 찾으며, 일반적인 단일 네트워크 환경에서는 기본 게이트웨이가 다음 홉이 된다.
3.2 ARP 캐시 확인
호스트는 먼저 ARP 캐시(ARP cache), 운영체제에 따라 이웃 테이블(neighbor table)이라고 부르는 저장소를 확인한다.
192.168.10.1 → 00:11:22:33:44:55
192.168.10.20 → aa:bb:cc:dd:ee:ff유효한 항목이 있으면 ARP 요청 없이 해당 MAC 주소를 사용한다.
3.3 ARP 요청
캐시에 항목이 없으면 ARP 요청(ARP Request)을 브로드캐스트한다.
이더넷 목적지 MAC: ff:ff:ff:ff:ff:ff
송신자 IPv4 주소: 192.168.10.15
송신자 MAC 주소: 02:00:00:00:00:15
대상 IPv4 주소: 192.168.10.20
대상 MAC 주소: 00:00:00:00:00:00
의미: 192.168.10.20을 사용하는 장치는 MAC 주소를 알려 달라.같은 브로드캐스트 도메인의 모든 장치가 요청을 수신하지만, 요청된 IPv4 주소를 가진 장치만 응답한다.
라우터는 일반적인 ARP 브로드캐스트를 다른 네트워크로 전달하지 않는다.
3.4 ARP 응답
대상 호스트는 보통 요청자에게 유니캐스트로 ARP 응답(ARP Reply)을 보낸다.
송신자 IPv4 주소: 192.168.10.20
송신자 MAC 주소: aa:bb:cc:dd:ee:ff
대상 IPv4 주소: 192.168.10.15
대상 MAC 주소: 02:00:00:00:00:15
의미: 192.168.10.20의 MAC 주소는 aa:bb:cc:dd:ee:ff다.요청자는 이 정보를 ARP 캐시에 저장한 뒤 원래 보내려던 IP 패킷을 이더넷 프레임에 담아 전송한다.
송신 호스트 대상 호스트
| |
| ARP 요청: 192.168.10.20은 누구인가? |
|------------- 브로드캐스트 -------->|
| |
| ARP 응답: MAC은 aa:bb:cc:dd:ee:ff |
|<-------------- 유니캐스트 ---------|
| |
| IP 패킷을 담은 이더넷 프레임 |
|-------------- 유니캐스트 --------->|3.5 ARP 캐시 만료
동적 ARP 항목은 영구 저장되지 않는다. 운영체제는 상태와 타이머에 따라 항목을 재검증하거나 제거한다.
MAC 주소가 바뀌거나 장치가 이동할 수 있으므로 오래된 항목을 무기한 사용하면 통신 장애가 발생할 수 있다. 구체적인 상태 이름과 만료 시간은 운영체제 구현과 설정에 따라 다르다.
4. 코드 예제
다음 코드는 이더넷·IPv4용 ARP 요청 페이로드를 만들고 다시 해석한다. 네트워크 전송 없이 Python 표준 라이브러리만 사용한다.
import ipaddress
import struct
ARP_FORMAT = "!HHBBH6s4s6s4s"
ARP_REQUEST = 1
ETHERNET = 1
IPV4_ETHERTYPE = 0x0800
def mac_to_bytes(mac: str) -> bytes:
parts = mac.split(":")
if len(parts) != 6:
raise ValueError("MAC 주소는 6바이트여야 합니다.")
return bytes(int(part, 16) for part in parts)
def bytes_to_mac(value: bytes) -> str:
return ":".join(f"{byte:02x}" for byte in value)
def build_arp_request(
sender_mac: str,
sender_ip: str,
target_ip: str,
) -> bytes:
return struct.pack(
ARP_FORMAT,
ETHERNET, # 하드웨어 유형
IPV4_ETHERTYPE, # 프로토콜 유형
6, # MAC 주소 길이
4, # IPv4 주소 길이
ARP_REQUEST, # 연산 코드
mac_to_bytes(sender_mac),
ipaddress.IPv4Address(sender_ip).packed,
b"\x00" * 6, # 아직 모르는 대상 MAC
ipaddress.IPv4Address(target_ip).packed,
)
def parse_arp(payload: bytes) -> dict[str, object]:
if len(payload) != struct.calcsize(ARP_FORMAT):
raise ValueError("이더넷·IPv4 ARP 페이로드는 28바이트여야 합니다.")
(
hardware_type,
protocol_type,
hardware_length,
protocol_length,
operation,
sender_mac,
sender_ip,
target_mac,
target_ip,
) = struct.unpack(ARP_FORMAT, payload)
return {
"하드웨어 유형": hardware_type,
"프로토콜 유형": f"0x{protocol_type:04x}",
"하드웨어 주소 길이": hardware_length,
"프로토콜 주소 길이": protocol_length,
"연산": "요청" if operation == ARP_REQUEST else "응답",
"송신자 MAC": bytes_to_mac(sender_mac),
"송신자 IPv4": str(ipaddress.IPv4Address(sender_ip)),
"대상 MAC": bytes_to_mac(target_mac),
"대상 IPv4": str(ipaddress.IPv4Address(target_ip)),
}
def main() -> None:
request = build_arp_request(
sender_mac="02:00:00:00:00:15",
sender_ip="192.168.10.15",
target_ip="192.168.10.20",
)
parsed = parse_arp(request)
assert len(request) == 28
assert parsed["연산"] == "요청"
assert parsed["대상 IPv4"] == "192.168.10.20"
for key, value in parsed.items():
print(f"{key}: {value}")
if __name__ == "__main__":
main()Linux에서는 ip 명령으로 현재 이웃 테이블을 확인할 수 있다.
ip neigh show특정 IPv4 주소로 가는 경로와 다음 홉을 확인한다.
ip route get 8.8.8.8출력 예시는 다음과 같다.
8.8.8.8 via 192.168.10.1 dev eth0 src 192.168.10.15이 경우 ARP로 확인할 주소는 최종 목적지 8.8.8.8이 아니라 다음 홉 192.168.10.1이다.
5. 시간 복잡도 또는 성능 특성
ARP 주소 해석이 필요하면 일반적으로 다음 트래픽이 발생한다.
- ARP 요청 브로드캐스트 1회
- 대상의 ARP 응답 1회
- 원래 전송하려던 데이터 프레임
응답이 없으면 운영체제가 정해진 횟수와 간격으로 요청을 재전송한다. 재전송 정책은 운영체제마다 다르다.
ARP 캐시 적중(cache hit) 시 추가 네트워크 왕복 없이 MAC 주소를 사용한다. 캐시 미스(cache miss) 시 ARP 응답을 기다리는 지연이 추가되며, 그동안 원래 패킷이 잠시 대기할 수 있다.
브로드캐스트 프레임은 같은 브로드캐스트 도메인의 모든 장치가 처리해야 한다. 정상적인 규모에서는 부담이 작지만, 과도한 ARP 요청이나 큰 브로드캐스트 도메인은 CPU와 네트워크 자원을 소모한다.
ARP 테이블 조회의 계산 복잡도는 운영체제 내부 자료구조에 따라 달라지므로 프로토콜 자체의 고정된 시간복잡도로 표현할 수 없다.
6. 실무 사용 사례
기본 게이트웨이 통신
웹 서버가 외부 API로 요청을 보낼 때 서버는 외부 API의 MAC 주소를 조회하지 않는다. 라우팅 테이블이 선택한 게이트웨이의 MAC 주소를 ARP로 조회한다.
무상 ARP
무상 ARP(Gratuitous ARP)는 호스트가 자신의 IPv4 주소에 관한 ARP 메시지를 별도 요청 없이 전송하는 방식이다.
주요 용도는 다음과 같다.
- 다른 장치의 ARP 캐시 갱신
- 중복 IPv4 주소 감지 보조
- 장애 조치 후 가상 IPv4 주소의 MAC 변경 알림
- 네트워크 인터페이스 전환 알림
고가용성 구성에서 가상 IPv4 주소가 다른 서버로 이동하면 새 서버가 무상 ARP를 보내 주변 장치의 캐시를 갱신할 수 있다.
프록시 ARP
프록시 ARP(Proxy ARP)는 라우터가 다른 장치의 IPv4 주소에 대한 ARP 요청에 대신 응답하는 기능이다. 요청자는 대상이 같은 링크에 있다고 판단하지만, 실제 패킷은 프록시 역할을 하는 라우터를 통해 전달된다.
네트워크 구조를 숨기거나 일부 레거시 환경을 연결할 때 사용되지만, 경로 파악을 어렵게 만들 수 있다.
장애 분석
같은 서브넷의 서버와 통신되지 않을 때 다음 순서로 확인할 수 있다.
ip route get 192.168.10.20
ip neigh show 192.168.10.20
ping -c 1 192.168.10.20
ip neigh show 192.168.10.20이웃 항목이 계속 INCOMPLETE 또는 FAILED 상태라면 다음 문제를 의심할 수 있다.
- 대상 장치가 꺼져 있음
- VLAN이 서로 다름
- 잘못된 서브넷 마스크
- 스위치 포트 또는 무선 연결 문제
- ARP 응답 차단
- 중복 IPv4 주소
상태 이름은 Linux 기준이며 다른 운영체제에서는 다르게 표시될 수 있다.
7. 주의할 점
ARP 스푸핑
ARP에는 응답자의 신원을 인증하는 기능이 없다. 공격자는 위조된 ARP 응답을 보내 자신의 MAC 주소를 게이트웨이 주소로 등록시킬 수 있다. 이를 ARP 스푸핑(ARP spoofing) 또는 ARP 포이즈닝(ARP poisoning)이라고 한다.
공격이 성공하면 중간자 공격(MITM), 트래픽 도청, 세션 탈취, 서비스 거부가 가능하다.
대응 방법은 다음과 같다.
- 스위치의 동적 ARP 검사(DAI, Dynamic ARP Inspection) 사용
- DHCP 스누핑(DHCP snooping) 정보와 ARP 응답 검증
- 중요 장비에 정적 ARP 항목 사용
- 종단 간 전송 계층 보안(TLS) 적용
- 네트워크를 VLAN으로 분리해 브로드캐스트 범위 축소
오래된 ARP 캐시
서버 교체나 장애 조치로 MAC 주소가 바뀌었는데 주변 장치가 기존 캐시를 유지하면 새 서버로 패킷이 전달되지 않는다. 무상 ARP로 캐시 갱신을 유도할 수 있지만, 장비의 보안 정책이나 구현에 따라 반영되지 않을 수 있다.
ARP와 DNS 혼동
도메인 이름을 IPv4 주소로 바꾸는 작업은 도메인 네임 시스템(DNS)이 담당한다. IPv4 주소를 같은 링크에서 사용할 MAC 주소로 바꾸는 작업은 ARP가 담당한다.
www.example.com
|
| DNS
v
93.184.216.34
|
| 라우팅으로 다음 홉 결정
v
192.168.10.1
|
| ARP
v
00:11:22:33:44:55라우터를 넘지 않는 범위
ARP 요청은 링크 계층 브로드캐스트이므로 일반적으로 라우터를 통과하지 않는다. 원격 호스트의 MAC 주소를 직접 알아내려는 접근은 네트워크 계층 구조와 맞지 않는다.
8. 핵심 정리
- ARP는 IPv4 주소에 대응하는 로컬 링크의 MAC 주소를 찾는다.
- 같은 서브넷의 목적지는 대상 호스트의 MAC 주소를 조회한다.
- 다른 서브넷의 목적지는 라우팅으로 선택된 다음 홉의 MAC 주소를 조회한다.
- ARP 요청은 브로드캐스트이고, ARP 응답은 일반적으로 유니캐스트다.
- 확인한 대응 관계는 ARP 캐시에 저장되며 운영체제 정책에 따라 갱신·만료된다.
- ARP에는 인증 기능이 없어 ARP 스푸핑 공격에 취약하다.
- IPv6는 ARP 대신 이웃 탐색 프로토콜(NDP)을 사용한다.