2편에서 VLAN을 정의하고 각 망에 게이트웨이 IP를 부여해, 한 대의 OPNsense가 여러 망의 게이트웨이가 되는 구조를 만들었습니다. 이번 편은 그 위에 DHCP(누구에게 IP를 자동으로 줄지)와 방화벽 룰(어느 망이 어디로 갈 수 있는지)을 얹습니다. 이 시리즈에서 가장 무겁고 가장 중요한 편입니다.
이번 편의 목표
VLAN으로 망을 갈라놓기만 하면, 기본 상태에서는 망끼리 서로 통신이 됩니다(또는 임시 Allow 룰로 열려 있습니다). 망분리의 진짜 가치는 “개발망이 운영 서버를 못 건드린다”, “전화기가 서버에 못 붙는다” 같은 격리에서 나옵니다. 그 격리를 만드는 게 방화벽 룰입니다.
작업 순서는 이렇습니다. 의존성이 있어서 순서가 중요합니다.
- DHCP 정책 정하기 (서버는 고정, 사람은 유동)
- Kea DHCP 설정 — 그리고 Kea의 함정(Pool/예약 충돌)
- Alias 설계 (방화벽 룰을 사람이 읽게 만드는 사전 작업)
- 방화벽 룰 표준 구조와 평가 순서
- 인터페이스별 룰 작성 순서 (왜 관리망부터인가)
- 점진적 강화 전략 (한 번에 잠그지 않기)
핵심 철학 두 가지를 먼저 박아둡니다. ① “일단 열고, 운영하며 점진적으로 조여간다.” 전환기에 통신을 한꺼번에 끊으면 사고가 납니다. ② “내 접속을 끊지 않는 순서로 작업한다.” 관리망 룰을 가장 먼저, 가장 조심스럽게 다룹니다.
1. DHCP 정책 — 서버는 고정, 사람은 유동
모든 망에 DHCP를 켜는 게 아닙니다. 망의 성격에 따라 나눕니다.
| 구분 | 대상 VLAN | 방식 | 이유 |
|---|---|---|---|
| 고정 IP | PRHQ, STG, MGHQ (서버·관리망) | Static | 서버는 주소가 고정돼야 관리·모니터링·방화벽 룰이 안정적 |
| DHCP | DEV, USR, TEL | Kea DHCPv4 Pool | 개발 단말·직원 PC·전화기는 수가 많고 유동적 |
서버와 관리망에 DHCP를 안 쓰는 이유는 단순합니다. Zabbix가 10.0.91.100을 보고 있는데 그 IP가 어느 날 바뀌면 모니터링이 깨집니다. 방화벽 룰도 “이 서버 대역은 허용” 식으로 IP에 기대는데, 주소가 흔들리면 룰이 무의미해집니다. 그래서 서버는 손으로 정한 고정 IP를 씁니다.
IP 배분 컨벤션
각 VLAN 안에서 IP를 역할별로 미리 구획해두면 운영이 깔끔합니다. 이 프로젝트에서 쓴 서버/관리망 공통 규칙은 이렇습니다.
.1 게이트웨이 (OPNsense)
.2 L2 스위치 관리 IP
.3~.9 예비 네트워크 장비
.11~.14 Proxmox 클러스터 노드
.90 PBS (물리 백업 서버)
.100 Zabbix / 모니터링
.101~.199 관리/서비스 VM
.200~.254 예비
사용자망(USR/TEL)은 다르게 갑니다. 사람이 많고 단말이 유동적이라 고정 구간과 DHCP Pool을 물리적으로 분리합니다.
.1 게이트웨이
.2~.9 네트워크 장비 (AP 등)
.10~.99 고정/특수 단말 (예약)
.100~.200 DHCP Pool ← 자동 할당은 여기서만
.201~.254 예비
이 “고정 구간과 Pool 분리”가 그냥 정리정돈이 아니라, 다음에 설명할 Kea의 함정을 피하는 핵심 장치입니다.
2. Kea DHCP 설정과 함정
OPNsense는 DHCP 서버로 Kea DHCPv4를 씁니다(과거 ISC DHCP에서 이전). 설정 위치는:
Services → Kea DHCP [IPv4]
각 DHCP 대상 인터페이스(DEV/USR/TEL)에 대해 Subnet을 추가하고, Pool을 지정합니다. 예를 들어 USR(192.168.1.0/24)이면 Pool을 192.168.1.100 - 192.168.1.200으로 잡습니다.
게이트웨이(router)와 DNS 옵션도 각 Subnet에 넣습니다. 이 프로젝트에서는 각 VLAN이 자기 게이트웨이(.1)를 DNS로 쓰게 했습니다(OPNsense Unbound가 응답).
⚠️ Kea의 함정: Pool 안에 예약을 두면 충돌
여기서 실제로 한 번 데인 부분입니다. Kea는 Pool 범위 안쪽에 정적 예약(Reservation)을 두면 충돌을 제대로 처리하지 못하는 특성이 있습니다. Pool이 .100~.200인데 그 안의 .150을 어떤 장비에 예약하면, Kea가 같은 IP를 다른 단말에 동적으로 내주는 상황이 생길 수 있습니다.
해결책은 처음부터 예약 구간과 Pool 구간을 물리적으로 겹치지 않게 나누는 것입니다.
.10~.99 → 정적 예약(Reservation) 구간 ← MAC 기준 고정
.100~.200 → 동적 Pool 구간 ← Kea가 자동 할당
이렇게 분리하면 “고정으로 주고 싶은 단말”은 .10~.99에서 MAC 예약으로 처리하고, Pool은 순수하게 동적 할당만 담당하므로 충돌이 원천 차단됩니다. 앞 절의 IP 컨벤션이 이래서 중요합니다.
DHCP Reservation은 MAC 주소 기준입니다. 화이트리스트 대상(특정 직원 PC 등)은 예약으로 IP를 고정해두면, 방화벽에서 그 IP를 특정해 예외 룰을 걸 수 있습니다.
3. Alias — 방화벽 룰을 사람이 읽게 만들기
방화벽 룰을 IP로 직접 쓰면 10.0.11.0/24 → 10.0.21.0/24 allow 같은 식이 되어, 나중에 보면 무슨 룰인지 알 수 없습니다. Alias는 IP/대역/포트에 이름을 붙이는 기능입니다. 룰을 쓰기 전에 Alias부터 만드는 이유가 여기 있습니다 — 룰의 가독성과 유지보수가 완전히 달라집니다.
설정 위치:
Firewall → Aliases
이 프로젝트에서 쓴 Alias 네이밍 컨벤션입니다.
| 종류 | 접두어 | 예시 | 내용 |
|---|---|---|---|
| 네트워크 | NET_ | NET_PRHQ, NET_MGHQ | 각 VLAN 대역 하나 |
| 그룹(묶음) | — | SERVER_NETS_HQ | PRHQ + STG + DEV 묶음 |
| 그룹(묶음) | — | MGMT_NETS | 관리망 묶음 |
| 호스트 그룹 | — | DEV_ALLOWED_USERS | DEV 접근 허용 개발자 PC들 |
| 포트 | PORT_ | PORT_WEB | 80, 443 등 |
이렇게 해두면 룰이 NET_MGHQ → SERVER_NETS_HQ allow처럼 문장으로 읽힙니다. 게다가 나중에 서버가 늘어도 Alias 멤버만 추가하면 관련 룰이 전부 자동으로 반영됩니다. 예를 들어 DEV_ALLOWED_USERS를 비워두고 룰만 먼저 걸어두면 “아무도 DEV 접근 불가” 상태로 시작했다가, 개발자 PC가 정해지면 Alias에 IP만 추가해 룰을 건드리지 않고 허용할 수 있습니다.
4. 방화벽 룰의 표준 구조와 평가 순서
OPNsense(pf) 룰은 위에서 아래로 평가되고, 마지막으로 매치된 규칙이 적용됩니다(quick 플래그가 붙으면 그 즉시 적용). 실무에서는 각 인터페이스 탭의 룰을 다음 표준 구조로 작성하면 디버깅이 쉽습니다.
┌─────────────────────────────────────────────┐
│ 1. Anti-Lockout (관리망 자기 자신 허용) │
│ 2. Block 우선 규칙 — "절대 금지" 먼저 │
│ 3. 관리/예외 허용 (구체적 허용) │
│ 4. 일반 허용 (인터넷, 공통 서비스) │
│ 5. 명시적 Block + Log (Catch-all) │
└─────────────────────────────────────────────┘
왜 Block을 위에 두나
허용 룰이 너무 포괄적이면, 그 아래의 차단 룰까지 평가가 도달하지 못할 수 있습니다.
잘못된 순서:
1. Allow USR → 인터넷 (목적지: 사설대역이 아닌 모든 곳)
2. Block USR → MGHQ ← 1번이 너무 넓으면 의미가 흐려짐
올바른 순서:
1. Block USR → MGHQ ← 민감한 망 차단을 먼저 명시
2. Allow USR → 인터넷
민감한 망(관리망 등)으로 가는 차단을 먼저 명시하고, 그 다음에 넓은 허용을 둡니다.
Catch-all + Log
각 인터페이스 맨 아래에 “전부 Block + 로그” 룰을 둡니다. OPNsense의 기본 정책도 차단이지만, 명시적으로 두면 로그에 무엇이 막혔는지 남아서 디버깅이 됩니다. “왜 이 통신이 안 되지?”를 추적할 때 이 로그가 결정적입니다.
Anti-Lockout 주의
OPNsense는 기본적으로 LAN 인터페이스에 Anti-Lockout 룰을 자동으로 겁니다(관리자가 스스로를 차단하지 못하게). 그런데 이 프로젝트는 최종 관리망을 MGHQ로 쓰기 때문에, 다음 중 하나를 해야 합니다.
Firewall → Settings → Advanced에서 Anti-Lockout 대상을 MGHQ로 변경, 또는- MGHQ 탭에 “MGHQ → OPNsense Self (22, 443) 허용” 룰을 수동으로 명시
이게 있어야 나중에 임시 LAN을 제거해도 관리 접속이 유지됩니다. (LAN 제거는 절체 편에서 다룹니다.)
5. 인터페이스별 룰 작성 순서
여기가 사고를 막는 핵심입니다. 어떤 인터페이스부터 손대느냐가 안전을 좌우합니다. 원칙은 “내 접속을 끊지 않는 것부터, 그리고 단순한 것부터”입니다.
| 순서 | 인터페이스 | 난이도 | 왜 이 순서인가 |
|---|---|---|---|
| 1 | MGHQ (관리망) | 낮음 | 내가 접속한 경로. 가장 먼저, 가장 조심스럽게. Anti-Lockout 확정 |
| 2 | TEL (전화) | 낮음 | 격리 수준이 명확(인터넷 + PBX만). 룰이 단순해 연습용으로 적합 |
| 3 | USR (직원) | 높음 | 예외가 가장 많음(STG 웹만, 특정 PC만 DEV…). 충분히 익숙해진 뒤에 |
| 4 | DEV (개발) | 중간 | 서버망 기본 패턴 |
| 5 | STG (검증) | 중간 | DEV와 유사 |
| 6 | PRHQ (운영) | 중간 | 운영망이라 가장 엄격하게 |
| 7 | IPsec (IDC 터널) | 중간 | 사이트 간 트래픽 |
| 8 | WAN | 낮음 | 인바운드 최소 개방 |
작업 도중에는 아직 손대지 않은 인터페이스의 임시 Allow 룰을 그대로 둡니다. 한 인터페이스를 정교화하고 → 통신을 테스트하고 → 다음으로 넘어갑니다. 절대 모든 탭을 한꺼번에 바꾸지 않습니다.
예시: 관리망(MGHQ) 룰
가장 먼저 작업하는 관리망의 룰을 예로 들면 이렇습니다(Alias 기반).
| # | Action | Source | Destination | Port | 설명 |
|---|---|---|---|---|---|
| 1 | PASS | NET_MGHQ | (OPNsense Self) | 22, 443 | 자기 자신 관리 (Anti-Lockout 수동화) |
| 2 | PASS | NET_MGHQ | NET_MGDC | ANY | IDC 관리망 (IPsec 경유) |
| 3 | PASS | NET_MGHQ | !PRIVATE_ALL | ANY | 인터넷(업데이트 등) |
| 4 | PASS | NET_MGHQ | SERVER_NETS_HQ | ANY | HQ 서버망 전체 관리 |
| 5 | BLOCK[LOG] | NET_MGHQ | NET_USR | ANY | 관리망이 사용자망 건드리지 않음 |
| 6 | BLOCK[LOG] | NET_MGHQ | NET_TEL | ANY | 관리망이 전화망 건드리지 않음 |
| 7 | BLOCK[LOG] | ANY | ANY | ANY | Catch-all (디버깅 로그) |
핵심은 관리망은 서버망 어디든 갈 수 있게(관리 특권) 하되, 사용자·전화망은 굳이 건드리지 않도록 차단하고, 모든 통신의 끝에 로그를 남기는 것입니다.
6. 점진적 강화 전략
방화벽을 한 번에 완성하려 하지 마세요. 이 프로젝트는 다음 순서로 단계적으로 조였습니다.
- TEL 격리 — 가장 안전한 첫 실전 작업. 전화망은 인터넷 + PBX(SIP/RTP)만 남기고 서버망 전면 차단.
- USR → 서버망 제한 — 직원망은 인터넷 OK, STG 웹(80/443)만 허용,
DEV_ALLOWED_USERS에 등록된 PC만 DEV 허용, 그 외 서버망 차단. - DEV ↔ STG ↔ PRHQ 상호 격리 — 서버망끼리도 기본 차단, 필요한 통신(CI/CD, 배포 검증)만 예외.
- MGHQ 역할 확정 — 마지막으로 관리망 룰을 최종 정리하고 임시 LAN 의존을 끊음.
각 단계 사이에 반드시 통신 테스트를 넣습니다. 예를 들어 USR 제한을 건 직후, 직원 PC에서 인터넷이 되는지·STG 웹이 열리는지·운영 서버는 막히는지를 확인하고 나서 다음으로 갑니다.
망 간 접근 정책 요약 (이 프로젝트 기준)
말로 풀면 최종 목표 정책은 이렇습니다.
- MGHQ/MGDC(관리망) → 모든 서버망 접근 허용. 단 외부에서 관리망으로 들어오는 건 엄격 차단(VPN 경유만).
- PRHQ ↔ STG ↔ DEV → 상호 차단, 필요한 통신만 예외.
- USR(직원) → 인터넷 OK / STG 웹만 / 개발자 PC만 DEV / 그 외 서버망 차단.
- TEL(전화) → 인터넷 OK / PBX 예외 / 그 외 전면 차단.
- 사이트 간(HQ↔IDC) → 관리 통신만 IPsec으로, 운영망끼리는 차단.
이번 편 체크포인트
여기까지 하면 도달하는 상태입니다.
- DEV/USR/TEL은 Kea DHCP로 자동 IP, 서버·관리망은 고정 IP (Pool과 예약 구간 분리로 충돌 없음)
- Alias 체계가 잡혀 방화벽 룰이 이름으로 읽힘
- 관리망(MGHQ)부터 룰이 표준 구조(Anti-Lockout → Block → Allow → Catch-all)로 정리됨
- 나머지 인터페이스는 정해진 순서로 점진적으로 격리 진행 중
- 모든 인터페이스 끝에 Catch-all 로그가 있어 막힌 통신을 추적 가능
아직 OPNsense는 상위 방화벽(SonicWall) 뒤에서 임시 LAN으로 작업되는 상태일 수 있습니다. 이걸 실제 WAN으로 끌어와 무중단으로 절체하고, 임시 LAN을 정리하는 게 다음 편의 주제입니다.
다음 편 예고
04. OPNsense 초기 설정: NAT·포트포워딩과 무중단 WAN 절체 — 외부 공개 서비스를 위한 NAT/포트포워딩 구성, 그리고 기존 SonicWall이 WAN을 쥐고 있는 상태에서 임시 LAN 작업 채널을 활용해 서비스 중단을 최소화하며 OPNsense로 회선을 넘기는 절체 시나리오, 절체 후 임시 LAN 정리와 관리 경로 단일화를 다룹니다.