📚 네트워크 · 패킷 분석 › 04. 네트워크 장비 실습 — 166편
이전 글: 165. Trunk Port · 다음 글: 167. Inter-VLAN Routing
IEEE 802.1Q는 Ethernet 프레임에 4바이트 VLAN 태그를 넣어 "이 프레임은 몇 번 VLAN 소속인가"를 표시하는 표준입니다. Trunk 포트(165. Trunk Port)가 여러 VLAN을 한 링크에 실어 나를 수 있는 것은 이 태그 덕분입니다.
Wireshark에서 태그 필드(vlan.id, vlan.priority, vlan.etype)를 읽는 방법은 03 영역 112. Ethernet 프레임 필드 분석 — eth.src·eth.dst·eth.type로 읽는 2계층 증거에서 다뤘으므로, 이 글은 장비 관점에서 태그가 언제 붙고 떨어지며, 어떤 값이 어떤 의미를 갖는가에 집중합니다.
태그 없는 프레임
| 목적지 MAC 6 | 출발지 MAC 6 | EtherType 2 | Payload 46~1500 | FCS 4 |
802.1Q 태그 프레임 (출발지 MAC 뒤에 4바이트 삽입)
| 목적지 MAC 6 | 출발지 MAC 6 | TPID 2 | TCI 2 | EtherType 2 | Payload 46~1500 | FCS 4 |
0x8100 ↓
PCP 3비트 | DEI 1비트 | VID 12비트
| 필드 | 크기 | 의미 |
|---|---|---|
| TPID (Tag Protocol Identifier) | 16비트 | 0x8100 — 원래 EtherType 자리에 와서 "태그가 있음"을 알림 |
| PCP (Priority Code Point) | 3비트 | 0~7 우선순위(IEEE 802.1p). 0 = 기본(Best Effort) |
| DEI (Drop Eligible Indicator) | 1비트 | 혼잡 시 먼저 버려도 되는 프레임 표시(과거 이름 CFI) |
| VID (VLAN Identifier) | 12비트 | 0~4095, 실제 VLAN은 1~4094 (0·4095 예약) |
태그는 Trunk 링크 위에서만 존재하는 것이 일반적입니다. 단말은 태그 없는 프레임을 주고받고, 스위치가 경계에서 태그를 붙이고 뗍니다.
PC-A (VLAN 10) 스위치 1 스위치 2 PC-B (VLAN 10)
태그 없음 ──→ Access 수신 → Trunk 송신 ──[0x8100, VID 10]──→ Trunk 수신 → Access 송신 ──→ 태그 없음
(태그 삽입 + FCS 재계산) (태그 제거 + FCS 재계산)
태그를 넣거나 빼면 프레임 내용이 바뀌므로 FCS는 매번 다시 계산됩니다. 태그 때문에 최대 프레임 크기는 1518바이트에서 1522바이트로 늘지만, Payload 최대값(MTU 1500)은 그대로입니다.
VID 값별 의미입니다.
| VID | 의미 |
|---|---|
| 0 | Priority Tag — VLAN 정보 없이 PCP(우선순위)만 전달, 수신 포트의 VLAN으로 처리 |
| 1 | 대부분 장비의 기본 VLAN |
| 2~4094 | 일반 VLAN |
| 4095 | 예약 (사용 불가) |
태그 4바이트를 16진수로 읽는 예입니다(형식 예시).
| 바이트 | TPID | TCI 해석 | 의미 |
|---|---|---|---|
81 00 00 0a | 0x8100 | 0x000A → PCP 0, DEI 0, VID 10 | VLAN 10, 기본 우선순위 |
81 00 a0 0a | 0x8100 | 0xA00A → PCP 5, DEI 0, VID 10 | VLAN 10, 우선순위 5(음성에 흔히 사용) |
Q-in-Q(IEEE 802.1ad) 는 태그를 두 겹으로 쓰는 방식입니다. 통신사·데이터센터가 고객의 VLAN 태그(C-Tag, 0x8100) 바깥에 자기 태그(S-Tag, TPID 0x88A8)를 한 겹 더 씌워, 고객별 VLAN 공간을 분리합니다.
| 구분 | 802.1Q | 802.1ad (Q-in-Q) |
|---|---|---|
| 태그 수 | 1개 | 2개 (바깥 S-Tag + 안쪽 C-Tag) |
| TPID | 0x8100 | 바깥 0x88A8, 안쪽 0x8100 |
| 쓰는 곳 | 기업 LAN Trunk | 사업자망, 데이터센터 |
| 최대 VLAN 조합 | 4094 | 바깥 × 안쪽 조합 |
반면 기업 LAN에서 사용자 쪽으로부터 들어오는 이중 0x8100 태그는 정상 구성에서는 거의 없습니다. 이것이 Native VLAN을 악용하는 이중 태그(Double Tagging) VLAN Hopping의 흔적입니다. 원리는 다음과 같습니다(탐지 이해 목적).
조건: 공격 단말의 Access VLAN = Trunk의 Native VLAN (예: 둘 다 VLAN 1)
프레임: [바깥 태그 VID 1][안쪽 태그 VID 20] ...
↓ 스위치 1: 바깥 태그 VID 1 = Native → Trunk로 보낼 때 바깥 태그 제거(태그 없이 전송)
↓ 스위치 2: 남은 안쪽 태그 VID 20을 읽음 → VLAN 20으로 전달
결과: VLAN 20으로 프레임이 넘어감 (응답은 돌아오지 않는 단방향)
Native VLAN을 사용하지 않는 VLAN으로 바꾸거나, Native VLAN에도 태그를 붙이도록 설정하면 이 조건이 사라집니다(165. Trunk Port).
실습 예시 — Linux에서 802.1Q·802.1ad 인터페이스를 만들고 설정을 확인합니다(Rocky/Ubuntu 공통, 8021q 커널 모듈 사용). 인터페이스 이름·값은 예시(값은 환경마다 다름)이며, 실습 후 삭제합니다.
# 802.1Q: ens37 위에 VLAN 10 인터페이스
sudo ip link add link ens37 name ens37.10 type vlan id 10
ip -d link show ens37.10 # "vlan protocol 802.1Q id 10" 확인
# 802.1ad(Q-in-Q) 바깥 태그 형식 확인용
sudo ip link add link ens37 name ens37.100 type vlan proto 802.1ad id 100
ip -d link show ens37.100 # "vlan protocol 802.1ad id 100" 확인
# NIC의 VLAN 오프로드 상태 (캡처에 태그가 보일지에 영향)
ethtool -k ens37 | grep -i vlan
# 정리
sudo ip link del ens37.100
sudo ip link del ens37.10
분석 방법 예시 — 캡처에서 이중 태그 프레임을 찾는 Wireshark Display Filter입니다(# 뒤는 설명이므로 입력하지 않습니다).
vlan # 802.1Q 태그가 있는 모든 프레임
eth.type == 0x8100 && vlan.etype == 0x8100 # 태그 안에 또 태그 (이중 0x8100)
eth.type == 0x88a8 # 802.1ad S-Tag
📷 [실습 화면 삽입 위치] Wireshark Packet Bytes 창에서 출발지 MAC 바로 뒤의
81 00 00 0a4바이트를 선택하고, Packet Details의 802.1Q Virtual LAN 트리에 PRI·DEI·ID가 표시된 화면
| 흔적 | 확인할 수 있는 것 |
|---|---|
| Trunk·SPAN 구간 캡처 | 프레임의 VLAN ID, 우선순위, 이중 태그 |
| NSM·IDS 로그 | 장비에 따라 VLAN ID 필드 기록(예: Suricata vlan 필드) — 같은 IP가 다른 VLAN에서 보이는지 |
| 스위치 설정 | Trunk의 Native VLAN·허용 목록 — 이중 태그 조건 성립 여부 |
관제자가 확인할 질문
오탐 주의: 사업자 회선·데이터센터 구간에서는 Q-in-Q(0x88A8)나 이중 태그가 정상적으로 쓰입니다. 캡처 위치가 어디인지 확인한 뒤 판단합니다.
0x8100 + TCI)이며, TCI는 PCP 3비트·DEI 1비트·VID 12비트입니다.0x88A8를 쓰는 정상 이중 태그 방식입니다.