VLAN 브리지 구성
100분 안팎
학습 목표
격리된 Linux 브리지의 VLAN 필터링과 태그 허용 목록을 구성합니다.
개념
Linux 브리지에 설계를 적용합니다
지난 레슨에서 승인한 포트 표를 실제 커널 설정으로 옮깁니다. 이번 실행기는 앞 모듈의 장비와 주소 파일을 그대로 읽되 학생 전용 브리지 하나를 두 VLAN 브리지로 확장합니다. r1 네임스페이스는 이번 단계에서 스위칭 공간으로만 사용합니다. 이름에 router가 포함돼 있어도 IPv4 전달과 게이트웨이 주소는 활성화하지 않습니다. 어떤 이름을 붙였는지보다 실제 링크·VLAN·주소 상태가 역할을 결정합니다.
필터를 켜고 기본 분류를 없앱니다
ip link add brschool type bridge vlan_filtering 1 vlan_default_pvid 0은 VLAN 필터링을 켠 브리지를 만듭니다. brannex에도 같은 조건을 사용합니다. 기본 PVID 0으로 자동 VLAN 1 membership을 피하고 필요한 포트에만 VLAN을 명시합니다. 기본값에 의존하면 문서에 없는 VLAN이 남을 수 있습니다. 정확한 ip-link 옵션은 연결된 매뉴얼로 확인하고 실행 후 상세 link 정보에서 적용 값을 다시 읽습니다.
브리지를 UP으로 만들고 veth 상대 포트를 붙이는 것만으로 VLAN 설정이 끝나지는 않습니다. bridge vlan add로 각 포트의 허용 항목을 등록해야 합니다. p1에 vid 10 pvid untagged를 넣고 p3에는 20을 넣는 식으로 수신 분류와 송신 형식을 정합니다. trunk u1·u2에는 vid 10,20,30,40을 각각 등록하되 pvid와 untagged를 붙이지 않습니다. access 설정을 trunk에 복사하면 태그 운반 계약이 바뀝니다.
Linux 브리지의 VLAN 표는 포트 membership과 브리지 자체의 local membership을 구분할 수 있습니다. 이번 브리지에는 IP를 배정하지 않고 로컬 단말로 통신시키지 않으므로 브리지 self에 게이트웨이용 VLAN을 추가하지 않습니다. bridge vlan add dev brschool vid 10 self만으로 p1·u1 전달 권한을 대신하지도 못합니다. 다음 라우팅 모듈에서는 게이트웨이 인터페이스를 만들 때 로컬 처리 경로를 다시 설계해야 합니다.
veth의 양 끝을 확인합니다
단말마다 eth0와 p1부터 p5까지의 veth 쌍을 만들고 단말 쪽을 각 bcnet-* 공간에 둡니다. s2의 상대 p2만 brannex에 붙이고 나머지는 brschool에 둡니다. u1과 u2는 r1 내부에서 서로 연결된 별도 veth 쌍입니다. 실제 호스트 eth0를 붙이지 않습니다. 가상 스위치 둘이 연결됐다는 그림은 bridge 소속과 veth peer를 모두 확인해야 성립하므로 검사는 ifindex와 link_index를 서로 비교합니다.
주소는 기존 topology의 단말 aAddress만 적용합니다. bAddress의 .1은 단말 default의 예약 다음 홉으로 남지만 라우터 쪽에는 배정하지 않습니다. 따라서 다른 /24 목적지는 기본 경로를 선택해도 게이트웨이 ARP가 해결되지 않습니다. 이는 이번 기준 상태입니다. 이전 setup을 함께 실행하면 학생 게이트웨이와 IP 전달이 살아나 의도한 조건이 깨질 수 있으므로 m02 파일은 이력으로 보관하고 현재 setup.sh만 실행합니다.
모든 실습 공간의 IPv4 forwarding을 0으로 맞추고 IPv6를 비활성화합니다. 호스트 기본 네트워크 공간의 sysctl이나 default route는 변경하지 않습니다. check.sh는 실행 전후 호스트 링크·주소·IPv4와 IPv6 경로를 비교해 실습 범위를 벗어난 설정 변경이 없는지 확인합니다. 이 비교는 알려진 커널 설정 범위를 확인하는 것이며 VM의 모든 파일 변경이나 응용 상태까지 감사하는 검사라고 주장하지 않습니다.
입력 파일을 수정하고 작은 검사부터 돌립니다
이 레슨 starter에서는 u1 trunk의 허용 목록에 VLAN 10이 빠져 있습니다. ports.csv의 해당 행을 u2와 비교하고 10;20;30;40으로 맞춥니다. python3 test_docs.py는 기존 주소표를 검사한 뒤 access·trunk·PVID·송신 형식·중복 포트·게이트웨이 활성 선언·주소 중복을 주입해 거부를 확인합니다. 표가 정상인데 오류 주입이 통과해 버리면 검사의 의미가 약해진 것이므로 성공으로 처리하지 않습니다.
문서 검사를 통과하면 전용 Linux VM에서 sudo bash check.sh를 실행합니다. 검사기는 구성, 관측, 음성 시험, 복구, 정리를 한 번에 수행합니다. 수동 관찰을 하려면 setup.sh를 실행하고 bridge vlan show와 상세 link를 읽은 뒤 cleanup.sh로 정리합니다. 이미 수동 공간이 있는 상태에서 check.sh를 다시 실행하면 이름 충돌로 중단됩니다. 먼저 소유 기록을 확인해 자기 실습 공간을 정리합니다.
ports: role VLAN/access/trunk mismatch는 실제 패킷 실패가 아니라 포트 계약이 맞지 않다는 문서 오류입니다. 이번 starter의 경우 u1이 누락된 역할 VLAN을 허용하도록 고치면 해결됩니다. 테스트에서 기대하는 일곱 행을 지우거나 비교식을 느슨하게 바꾸지 않습니다. 검사기를 수정해 green으로 만드는 것은 설계를 적용한 증거가 아니므로 제출할 때 변경한 ports.csv 행과 이유를 함께 보여 줍니다.
실제 표를 읽는 순서를 정합니다
bridge vlan show에서 p1의 VLAN 10 옆 PVID와 Egress Untagged를 찾습니다. u1·u2의 네 VLAN에는 그 두 플래그가 없어야 합니다. 출력이 여러 줄로 접혀도 한 포트의 membership을 모두 읽습니다. 일부 iproute2 출력은 VLAN 범위를 표현할 수 있으나 이번 VID는 연속된 10~40 전체가 아니라 네 개의 개별 값입니다. 숫자를 한 범위로 잘못 등록해 불필요한 VLAN을 허용하지 않습니다.
ip -d link show는 brschool·brannex의 vlan_filtering과 vlan_default_pvid를 확인하는 증거입니다. bridge fdb show는 학습된 MAC을 관찰하지만 로컬 permanent 항목도 섞일 수 있습니다. 모든 줄을 학생 MAC으로 세지 말고 단말 eth0 MAC과 포트·VLAN을 대조합니다. ping 이전에 학습 항목이 없다고 설정 실패를 단정하지 않습니다. 프레임을 보내야 동적 학습이 시작된다는 첫 레슨의 처리 순서를 적용합니다.
RTNETLINK answers: Operation not permitted는 권한이나 실행 환경 문제를 먼저 의심할 신호입니다. 이 프로젝트에서는 관리자 권한이 있는 전용 Linux VM에서만 구성합니다. Cannot find device는 네임스페이스 선택과 생성 순서를 확인합니다. r1 안의 p1을 호스트 공간에서 조회하면 같은 이름을 못 찾을 수 있습니다. 오류 문자열 하나를 보고 무작정 인터페이스를 다시 만들지 말고 명령의 실행 공간과 앞 단계 종료 상태를 기록합니다.
RTNETLINK answers: File exists나 namespace collision은 기존 객체 충돌 가능성을 보여 줍니다. 실행기는 충돌 이름을 자동 삭제하지 않고 중단합니다. .owned.json은 이번 실행에서 만든 공간 목록이며 cleanup은 그 목록에 있는 이름만 대상으로 삼습니다. 남은 프로세스가 있으면 삭제를 중단하고 알립니다. 이 실습에서는 장기 실행 서버를 시작하지 않으며 정리 명령에 프로세스 kill을 넣지 않습니다.
두 브리지를 잇는 trunk는 하나뿐이고 루프가 없어 이 묶음에서는 STP를 끕니다. 링크를 하나 더 연결한 뒤 같은 설정을 그대로 사용하면 브로드캐스트 루프를 만들 수 있습니다. 케이블을 늘려 이중화한다고 자동으로 안정성이 생기지는 않습니다. 확장 전에 루프 방지와 전환 절차가 필요하므로 이 레슨의 토폴로지는 그대로 유지합니다. 실제 VLAN 전달과 음성 시험 로그는 다음 레슨에서 기대 결과와 대조합니다.
명령과 플래그 확인: bridge 매뉴얼, ip-link 매뉴얼. 실제 커널 적용 결과는 외부 검증 대상으로 남습니다.
따라하기
누락된 trunk VLAN을 고칩니다
network-bridge-vlan starter의 ports.csv에서 brschool u1 행에 빠진 10을 넣습니다. python3 검사에서 ports 오류가 사라지고 여덟 문서 검사가 통과하는지 확인합니다.
python3 test_docs.py격리된 VLAN 브리지를 만듭니다
전용 Linux VM에서 문서 검사 후 구성합니다. 기존 bcnet 이름이나 소유 기록이 있으면 중단하며 자기 공간을 정리한 뒤 재시도합니다. READY 메시지는 직접 관측해 저장합니다.
sudo bash setup.sh실제 filtering과 membership을 조회합니다
brschool과 brannex의 filtering=1/default PVID=0, access의 PVID/Egress Untagged, 양쪽 trunk의 네 VLAN tagged를 대조합니다.
sudo ip -n bcnet-r1 -d link show
sudo ip netns exec bcnet-r1 bridge vlan show
sudo ip -n bcnet-r1 -4 addr show학생 전달과 학습을 관찰합니다
s1에서 s2의 ICMP 응답을 확인하고 eth0 MAC과 동적 FDB의 포트·VLAN을 비교합니다. 로컬 permanent 항목과 구분하며 실측 RTT를 별도 기록합니다.
sudo ip netns exec bcnet-s1 ping -n -c 1 -W 1 -w 2 10.20.10.12
sudo ip -n bcnet-s2 link show dev eth0
sudo ip netns exec bcnet-r1 bridge fdb show정리하고 전체 검사로 재구성합니다
수동 공간을 정리한 뒤 전체 검사를 실행합니다. 검사기는 결함 주입과 복구, 최종 호스트 비교도 포함합니다. Linux 실행 결과는 external 확인 대기입니다.
sudo bash cleanup.sh
sudo bash check.sh확인 문제
실습
u1 trunk의 VLAN 10 누락을 고치고 ports.csv와 실제 브리지 표를 일치시킵니다. python3 test_docs.py로 문서를 검사하고 전용 Linux VM에서 sudo bash check.sh를 실행합니다. README의 수동 관찰 절차도 제공됩니다. 검사기는 문서·허용 VLAN 및 플래그·veth·주소·forwarding, 학생 왕복, 다른 VLAN의 임시 같은 /24 주소 격리, access와 trunk 음성 시험 및 복구, 호스트 전후 동일을 확인합니다. 임시 주소는 제거합니다. 실제 환경·명령·실패 근거와 복구 결과를 제출하며 커널 실행은 external로 확인 대기입니다.
실행 명령
sudo bash check.sh
기대 결과
8개 문서 검사 통과, 실제 VLAN membership·학생 왕복·직접 ARP 격리·access/trunk 결함과 복구·정리 후 호스트 동일. Linux 실행은 외부 확인 대기입니다.
모범 답안
모범 답안 내려받기더 읽기
면접 질문
- VLAN을 나누고 통신을 허용하는 구성을 설명합니다.