🌍 네트워크

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로 네트워크 접근 인증을 복합적으로 적용하세요.

🔗 관련 용어

📚 더 배우기