🌍 네트워크

MAC Address

MAC 주소

48비트 하드웨어 주소로 NIC를 고유 식별. OUI로 제조사 확인, ARP로 IP 매핑, 스푸핑 주의.

📖 상세 설명

MAC Address(Media Access Control Address)는 네트워크 인터페이스 카드(NIC)에 제조 시 할당되는 48비트(6바이트) 고유 하드웨어 주소입니다. 물리 주소(Physical Address) 또는 이더넷 주소라고도 불리며, OSI 모델의 데이터 링크 계층(Layer 2)에서 장치를 고유하게 식별하는 역할을 합니다.

MAC 주소는 보통 16진수로 표기되며 00:1A:2B:3C:4D:5E 또는 00-1A-2B-3C-4D-5E 형식을 사용합니다. 앞의 24비트(3바이트)는 OUI(Organizationally Unique Identifier)로 IEEE에서 제조사에게 할당하며, 뒤의 24비트는 제조사가 각 장치에 고유하게 부여합니다. 예를 들어 00:1A:2B는 Ayecom Technology 제조사를 나타냅니다.

이더넷이나 Wi-Fi 네트워크에서 데이터 프레임이 전송될 때, 송신자와 수신자는 IP 주소가 아닌 MAC 주소로 식별됩니다. ARP(Address Resolution Protocol)는 IP 주소를 MAC 주소로 변환하여 같은 네트워크 내 통신을 가능하게 합니다. 스위치는 MAC 주소 테이블을 학습하여 프레임을 적절한 포트로만 전달함으로써 네트워크 효율을 높입니다.

최근에는 개인정보 보호를 위해 iOS, Android, Windows 10/11에서 랜덤 MAC 주소(MAC Randomization) 기능을 지원합니다. Wi-Fi 네트워크에 연결할 때마다 다른 MAC 주소를 사용하여 사용자 추적을 방지합니다. 한편, MAC 스푸핑(Spoofing)은 공격자가 자신의 MAC 주소를 위조하여 네트워크 접근 제어를 우회하거나 중간자 공격(MITM)을 수행하는 데 악용될 수 있어 보안상 주의가 필요합니다.

💻 코드 예제

import uuid
import subprocess
import re

# 현재 장치의 MAC 주소 조회 (내장 모듈)
mac_int = uuid.getnode()
mac_hex = ':'.join(('%012x' % mac_int)[i:i+2] for i in range(0, 12, 2))
print(f"MAC Address: {mac_hex}")  # 예: 00:1a:2b:3c:4d:5e

# getmac 라이브러리 사용 (pip install getmac)
from getmac import get_mac_address

# 로컬 인터페이스의 MAC 주소
local_mac = get_mac_address()
print(f"Local MAC: {local_mac}")

# 특정 인터페이스의 MAC 주소
eth_mac = get_mac_address(interface="eth0")
print(f"eth0 MAC: {eth_mac}")

# 특정 IP의 MAC 주소 (ARP 조회)
remote_mac = get_mac_address(ip="192.168.1.1")
print(f"Gateway MAC: {remote_mac}")

# OUI에서 제조사 정보 추출
def get_vendor_from_oui(mac):
    oui = mac.upper().replace(':', '').replace('-', '')[:6]
    # OUI 데이터베이스 예시 (실제로는 IEEE OUI 파일 참조)
    oui_db = {
        '00505A': 'Apple',
        '00248C': 'Intel',
        '001A2B': 'Ayecom'
    }
    return oui_db.get(oui, 'Unknown Vendor')

print(f"Vendor: {get_vendor_from_oui(mac_hex)}")
# macOS - MAC 주소 조회
ifconfig en0 | grep ether
# 출력: ether 00:1a:2b:3c:4d:5e

# Linux - MAC 주소 조회
ip link show eth0
cat /sys/class/net/eth0/address

# Windows - MAC 주소 조회
ipconfig /all | findstr "Physical"
getmac /v

# ARP 테이블 조회 (IP → MAC 매핑)
arp -a
# 출력: 192.168.1.1 (00:1a:2b:3c:4d:5e) [ether] on eth0

# ARP 캐시 삭제 (Linux)
sudo ip neigh flush all

# 특정 IP의 MAC 주소 조회
arping -c 1 192.168.1.1

# MAC 주소로 제조사 조회 (macOS)
networksetup -listallhardwareports

# MAC 주소 변경 (Linux - 임시)
sudo ip link set dev eth0 down
sudo ip link set dev eth0 address 00:11:22:33:44:55
sudo ip link set dev eth0 up

# MAC 주소 변경 (macOS - 임시)
sudo ifconfig en0 ether 00:11:22:33:44:55

# OUI 조회 (온라인)
curl -s "https://api.macvendors.com/00:1a:2b"
# 출력: Ayecom Technology Co., Ltd.
const os = require('os');

// 모든 네트워크 인터페이스 정보 조회
const interfaces = os.networkInterfaces();

// 각 인터페이스의 MAC 주소 출력
Object.entries(interfaces).forEach(([name, addrs]) => {
    addrs.forEach(addr => {
        if (addr.mac && addr.mac !== '00:00:00:00:00:00') {
            console.log(`${name}: ${addr.mac}`);
        }
    });
});

// 첫 번째 유효한 MAC 주소 가져오기
function getFirstMacAddress() {
    const nets = os.networkInterfaces();
    for (const name of Object.keys(nets)) {
        for (const net of nets[name]) {
            // 내부 루프백이 아닌 것 중 MAC이 있는 것
            if (!net.internal && net.mac !== '00:00:00:00:00:00') {
                return { interface: name, mac: net.mac };
            }
        }
    }
    return null;
}

console.log('Primary MAC:', getFirstMacAddress());

// MAC 주소 형식 검증
function isValidMac(mac) {
    const macRegex = /^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/;
    return macRegex.test(mac);
}

console.log(isValidMac('00:1A:2B:3C:4D:5E'));  // true
console.log(isValidMac('00-1A-2B-3C-4D-5E'));  // true
console.log(isValidMac('invalid-mac'));        // false

// MAC 주소 정규화 (콜론 형식으로 변환)
function normalizeMac(mac) {
    return mac.replace(/[:-]/g, '')
              .match(/.{2}/g)
              .join(':')
              .toLowerCase();
}

console.log(normalizeMac('001A2B3C4D5E'));   // 00:1a:2b:3c:4d:5e
console.log(normalizeMac('00-1A-2B-3C-4D-5E')); // 00:1a:2b:3c:4d:5e

🗣️ 실무에서 이렇게 말하세요

💬 네트워크 보안 회의에서
"MAC 필터링은 추가적인 보안 계층으로는 좋지만, MAC 스푸핑이 쉬워서 이것만으로 접근 제어를 하면 안 됩니다. 802.1X 인증과 함께 사용하거나, 포트 시큐리티로 특정 포트에 허용된 MAC 개수를 제한하는 것이 좋습니다."
💬 면접에서
"MAC 주소는 48비트 하드웨어 주소로, 앞 24비트는 OUI로 제조사를 식별하고 뒤 24비트는 장치 고유 번호입니다. ARP를 통해 같은 네트워크 내에서 IP와 MAC을 매핑하며, 스위치는 MAC 주소 테이블을 학습해서 유니캐스트 프레임을 효율적으로 전달합니다."
💬 장애 대응 중
"arp -a로 확인해보니 게이트웨이 IP에 대한 MAC 주소가 원래 장비가 아닌 다른 MAC으로 바뀌어 있습니다. ARP 스푸핑 공격이 의심되니 Dynamic ARP Inspection을 활성화하고, 정적 ARP 엔트리로 게이트웨이 MAC을 고정하겠습니다."

⚠️ 흔한 실수 & 주의사항

MAC 필터링만으로 보안 의존

MAC 주소는 쉽게 위조(스푸핑)할 수 있습니다. 공격자가 허용된 MAC을 알면 자신의 MAC을 변경해 접근할 수 있으므로, 반드시 추가 인증(802.1X, RADIUS)을 함께 사용하세요.

MAC 주소를 IP처럼 사용

MAC 주소는 로컬 네트워크(L2)에서만 유효합니다. 라우터를 지나면 프레임의 MAC 주소는 다음 홉의 MAC으로 변경됩니다. 원격 통신에서 MAC 주소로 장치를 추적하려는 시도는 실패합니다.

랜덤 MAC으로 인한 DHCP 문제

iOS/Android의 랜덤 MAC 기능이 활성화되면, 같은 장치가 매번 다른 MAC으로 연결되어 DHCP 주소 고갈이나 MAC 기반 접근 제어 문제가 발생할 수 있습니다. 기업 환경에서는 MDM으로 관리하세요.

올바른 MAC 보안 구성

스위치에서 포트 시큐리티(Port Security)로 MAC 개수 제한, Dynamic ARP Inspection(DAI)으로 ARP 스푸핑 방지, 802.1X로 네트워크 접근 인증을 복합적으로 적용하세요.

🔗 관련 용어

📚 더 배우기