Devin.KR

출발지·목적지·포트 정책

80분 안팎

학습 목표

교직원 관리·학생 웹·게스트 외부 웹과 내부 차단 요구를 정책 표로 작성합니다.

개념

왜 통신 요청을 문장으로 받지 않는가

교무실에서 “관리 화면이 필요합니다”라는 요청이 왔습니다. 이 말만으로 학교 서버의 모든 포트를 열면 학생과 게스트에게도 관리 기능이 노출될 수 있습니다. 신입 담당자는 먼저 누가 어느 서비스에 어떤 방향으로 새 연결을 시작하는지 묻습니다. 이번 레슨의 결과물은 요청을 주소 범위·프로토콜·목적지 포트·동작·근거로 바꾼 policy.csv입니다. 설정 명령을 먼저 쓰지 않고 허용 이유와 차단해야 할 대조 조건부터 정합니다.

이 모듈의 공통 환경

브라우저 실습은 Python 3 표준 입력과 표준 출력만 사용합니다. 로컬 압축 파일은 m07 미션 solution 전체를 이어받았습니다. 맥에서는 python3 test_policy.py로 문서를 검사하고, 실제 망은 앞에서 준비한 Ubuntu 24.04 격리 VM에서 sudo bash check.sh로 실행합니다. Linux 네임스페이스·nftables 실측은 이 맥에서 실행하지 못하므로 external 확인 대기입니다. VM 준비와 도구 설치는 첫 모듈을 따르며 호스트 실제 회선을 연결하지 않습니다.

주소표의 현재 값부터 확인합니다

앞 모듈의 topology.json에는 초기 학생 주소 10.20.10.11이 남아 있지만 서비스 단계에서 DHCP로 받은 현재 주소는 10.20.10.111입니다. 정책을 단말 한 대로 제한할 때는 실행 시 lease.json을 확인합니다. 이번 요구는 역할 전체이므로 학생 10.20.10.0/24, 교직원 10.20.20.0/24, 서버 10.20.30.0/24, 게스트 10.20.40.0/24를 씁니다. 주소 문자열의 앞부분이 비슷하다는 이유로 포함을 판단하지 않고 CIDR 계산을 사용합니다.

열을 읽는 순서

policy.csv의 id는 규칙과 시험 자료를 잇는 고유 이름입니다. source와 destination은 IPv4 CIDR이며 단일 서버는 /32로 적습니다. protocol은 tcp 또는 udp, port는 목적지 포트, action은 accept 또는 drop입니다. hook은 라우터 자신의 서비스면 input, 다른 망으로 중계하면 forward로 정합니다. reason에는 역할의 업무 목적을 적습니다. 비어 있는 근거나 임시 전체 허용은 다음 담당자가 허용 범위를 판단하지 못하게 만듭니다.

학생 웹과 교직원 관리

학생은 학교 서버 10.20.30.11의 평문 TCP 8080 학습 웹을 사용합니다. 교직원은 같은 웹과 TCP 2222 관리 모의 서비스를 사용합니다. 여기서 2222 리스너는 HTTP로 만든 교육용 관리 응답이며 SSH 프로토콜을 검증하지 않습니다. 따라서 포트 이름을 SSH라고 쓰지 않습니다. 학생에서 관리 포트로 보내는 시험은 명시적 차단 행으로 남깁니다. 업무상 웹 사용과 관리자 권한을 분리해야 같은 서버라도 다른 접근 범위를 설계할 수 있습니다.

게스트 내부 차단의 예외를 씁니다

게스트는 가상 외부 198.51.100.2의 TCP 8080만 허용합니다. 학교 서버 웹·관리·미승인 UDP 9999는 차단합니다. 다만 라우터 10.20.30.1의 UDP 53 교육 DNS는 게스트에도 허용합니다. 그래서 “게스트는 모든 내부 주소에 접근할 수 없습니다”라는 문장은 이 정책과 맞지 않습니다. 정확히는 학교 서버 접근은 차단하고 라우터 DNS는 예외로 허용합니다. 외부 주소는 실습 안의 veth 상대일 뿐 실제 인터넷이 아닙니다.

포트 숫자만 보면 틀립니다

UDP 53 허용은 TCP 53 허용과 별개입니다. 일반 DNS 환경에서는 큰 응답이나 다른 조건 때문에 TCP도 설계할 수 있지만 이번 상속 DNS 서버는 UDP만 구현합니다. 요구사항에 그 한계를 기록합니다. UDP 9999는 세 역할 모두 금지해 프로토콜 차단의 음성 검사를 제공합니다. 서비스가 실제로 듣고 있더라도 업무상 승인하지 않았다면 차단 대상으로 남습니다. 사용 중인 포트와 허용할 포트는 서로 다른 목록입니다.

DHCP는 일반 서비스 행과 다릅니다

학생 DHCP의 첫 요청은 아직 주소가 없는 상태의 0.0.0.0 또는 현재 학생 주소에서 UDP 출발지 68, 목적지 67로 나갈 수 있습니다. 목적지는 브로드캐스트 또는 학생 게이트웨이입니다. 이를 일반 DNS 행처럼 source를 현재 단말 /32로만 제한하면 초기 주소 취득을 깨뜨릴 수 있습니다. 제공 생성기는 v10 인터페이스와 주소·포트 조건을 함께 묶은 student-dhcp input 규칙을 따로 만듭니다. 이 예외는 학생만 대상으로 하고 다른 역할 DHCP까지 구현했다고 하지 않습니다.

응답 방향을 별도 요구로 봅니다

학생이 웹 서버의 8080으로 요청하면 응답의 목적지 포트는 학생이 고른 임시 포트입니다. 응답을 위해 서버에서 학생으로 모든 신규 연결을 허용할 이유는 없습니다. 정책 표에는 새 연결의 시작 방향을 쓰고 상태 기반 규칙은 허용된 흐름의 응답을 다룹니다. 라우터 자신의 DNS·DHCP 응답은 output 방향이지만 이번 로컬 구성은 output을 제한하지 않습니다. 전달 정책을 작성했다는 말이 라우터 발신 정책까지 완성했다는 뜻은 아닙니다.

기본 차단과 명시적 차단

허용 목록 이외의 신규 요청은 기본 차단합니다. guest-web처럼 중요 금지 행은 별도 drop 규칙을 두어 카운터를 관측합니다. 명시적 금지 행이 있다고 기본 차단을 없애지 않습니다. 기본 차단은 아직 표에 없는 서버·포트 조합을 처리하고, 금지 행은 의도한 제한과 시험 증거를 연결합니다. 표의 accept와 drop 행이 같은 패킷에 겹치면 순서가 결과를 바꿀 수 있으므로 다음 레슨에서 그 충돌을 작은 입력으로 재현합니다.

NAT 위치를 표에 덧붙입니다

이번 망에서는 라우터 forward의 filter 우선순위 0에서 원래 학교 출발지 주소를 검사하고 postrouting의 srcnat 우선순위 100에서 198.51.100.1로 바꿉니다. DNAT은 사용하지 않습니다. 그래서 게스트 허용 source는 10.20.40.0/24입니다. 외부 캡처의 변환 주소를 그대로 source에 쓰면 forward의 게스트 요청과 일치하지 않습니다. 표 아래에 관측 위치를 적어 주소표와 NAT 자료가 서로 다른 이유를 설명합니다.

VLAN만으로 보장되지 않는 범위

역할 VLAN을 나눠도 라우팅을 연결하면 정책이 필요합니다. 반대로 같은 학생 VLAN의 단말 간 링크 전달은 이 라우터 inet forward 체인을 거치지 않을 수 있습니다. 이를 이 모듈의 내부 격리 성공으로 제출하지 않습니다. IPv4 규칙만 사용하므로 IPv6의 주소·필수 제어 통신은 별도 설계 대상입니다. 한 구성 요소의 검사 통과를 학교망 전체 보안으로 확장하지 않고 실제 정책이 적용되는 경로를 구성도에 표시합니다.

검토 가능한 표를 만듭니다

각 허용 행 옆에 대응 차단 행을 붙여 검토합니다. 교직원 관리 허용과 학생·게스트 관리 차단, 게스트 외부 웹 허용과 게스트 학교 웹 차단은 좋은 짝입니다. DNS 예외에는 router input이라는 이유를 남깁니다. 표가 길어지면 서비스 하나마다 전체 역할을 열었는지 확인하고 /0처럼 지나치게 넓은 주소는 업무 요구와 대조합니다. 승인 범위를 바꾸는 수정은 근거와 시험 목록을 함께 갱신해야 다음 변경에서도 판단을 유지할 수 있습니다.

정책 표를 끝냈다는 기준

제출물은 최소 여섯 허용·여섯 차단 시나리오와 실제 검사 계획을 포함합니다. 실습은 DHCP 한 건과 CSV 허용 일곱 건, 차단 여섯 건을 제공합니다. 이 레슨에서는 계획만 작성하며 실행 결과를 꾸며 쓰지 않습니다. 후속 시험에서 동일 출발지의 정상 리스너 대조, 제한 시간, 규칙 카운터, 복원 후 재시험을 남깁니다. 사건 기록을 보존하고 새로운 정책이 앞 DNS·경로 진단을 어떻게 바꾸는지도 함께 설명합니다.

따라하기

역할 주소의 경계 확인

Python 3에서 다음 계산을 실행하고 결과를 정책 판단에 연결합니다.

from ipaddress import ip_address, ip_network
net = ip_network('10.20.40.0/24')
for addr in ['10.20.40.11', '10.20.41.11']:
    print(addr, ip_address(addr) in net)

실행 결과

10.20.40.11 True
10.20.41.11 False

신규 요청과 응답 포트 구별

Python 3에서 다음 계산을 실행하고 결과를 정책 판단에 연결합니다.

request = ('10.20.10.111', 43000, '10.20.30.11', 8080)
reply = (request[2], request[3], request[0], request[1])
print('request dport', request[3])
print('reply dport', reply[3])

실행 결과

request dport 8080
reply dport 43000

정책 표 제출

policy.csv와 같은 열로 허용 6행 이상·차단 6행 이상을 적습니다. DNS input 예외, DHCP 입력 조건, SNAT 전 forward 주소와 범위 밖 항목을 표 아래에 설명합니다. 아직 실행 결과는 쓰지 않습니다.

확인 문제

실습

policy.csv 열 id·source·destination·protocol·port·action·hook·reason으로 학교 통신 표를 제출합니다. 허용·차단 각각 6행 이상, 학생 웹·교직원 관리·게스트 외부 웹·내부 차단·DNS 예외와 DHCP 조건을 포함합니다. 각 행의 시험 출발지와 기대 동작, 기본 차단, NAT 적용 전 주소 기준, 동일 VLAN·IPv6·output 범위를 설명합니다. 이 단계는 정책 문서 검토이며 실측 증거는 뒤 로컬 미션에서 제출합니다.

더 읽기

면접 질문

  • VLAN을 나누고 통신을 허용하는 구성을 설명합니다.
  • 방화벽 정책을 검증하는 실습 방법을 설명합니다.