중소기업 네트워크 구축 – 05. OPNsense 보안 설정 ①: 절체 전 보안 기반 (NTP·백업·GeoIP·ACME)

2026.06.30

·

4편에서 WAN 절체로 OPNsense를 메인 방화벽으로 올렸습니다. 그런데 실제 작업 순서를 보면, 절체 전에 미리 깔아두는 보안 작업들이 있습니다. 통신을 끊을 위험이 없어서 운영 중에도 안전하게 할 수 있고, 절체 순간 바로 효과를 내는 것들입니다. 이번 편은 그 절체 전 보안 기반 네 가지 — NTP, 설정 백업, GeoIP 차단, ACME 인증서 — 를 다룹니다.

왜 “절체 전”에 하나

보안·운영 플러그인은 성격에 따라 두 묶음으로 나뉩니다.

  • 절체 전 기반(이번 편): NTP, 백업, GeoIP, ACME — 위험이 없고, 절체 전에 준비해두면 절체 직후 바로 동작합니다.
  • 절체 후 방어선(다음 편): Caddy, Suricata, TOTP, VPN — 외부에 노출되기 시작한 뒤 세우는 능동 방어입니다.

핵심 원칙은 변하지 않습니다. 위험 없는 것부터, 통신을 끊을 수 있는 것은 뒤로. 그래서 이번 편의 작업들도 “준비는 다 하되, 실제로 트래픽을 차단하는 WAN 룰만은 방화벽 정리 단계로 미루는” 식으로 진행합니다.

Sponsored

작업 순서:

  1. NTP — 시간 동기화 (모든 로그·인증서의 기준)
  2. Configuration Backup — 암호화 백업, 여러 곳 분산
  3. GeoIP 차단 — DB 등록 + Alias 생성 (차단 룰은 뒤로)
  4. ACME — Let’s Encrypt 와일드카드 인증서 자동 발급

1. NTP — 시간 동기화

시간이 안 맞으면 인증서 검증, 로그 타임스탬프, 2FA(TOTP) 코드까지 줄줄이 틀어집니다. 그래서 보안 작업의 가장 처음에 NTP를 맞춥니다.

Services → Network Time → General

설정 포인트는 세 가지입니다.

  • NTP 서버: kr.pool.ntp.org 같은 지역 풀을 씁니다. 여러 개 넣으면 그중 가장 안정적인 하나가 자동으로 기준(Active Peer)이 됩니다.
  • Iburst 활성화: 켜두면 처음 동기화가 훨씬 빨리 잡힙니다. 안 켜면 첫 동기화까지 한참 걸립니다.
  • 그래프(Statistics) 활성화: offset 추이를 볼 수 있어 동기화 상태 확인이 쉽습니다.

⚠️ WAN에는 NTP 서비스를 열지 말 것

가장 중요한 보안 포인트입니다. OPNsense의 NTP를 WAN 인터페이스에서 서비스로 제공(listen)하면 안 됩니다. 외부에 열린 NTP 서버는 NTP 증폭 DDoS에 악용됩니다(작은 요청으로 큰 응답을 끌어내 제3자를 공격). NTP는 내부 인터페이스(관리망·서버망 등)에서만 제공하고, OPNsense 자신이 외부 NTP로 나가서 시간을 받아오는 것(클라이언트 방향)만 허용합니다.

이 프로젝트에서는 NTP를 내부망(관리/서버망)에만 바인딩하고 WAN은 제외했습니다. Iburst와 그래프를 켜니 offset이 0.1ms 수준으로 빠르게 안정됐습니다. 풀 항목 중 .POOL.(Stratum 16)로 표시되는 줄은 “풀에서 실제 서버를 뽑아내는 관리용 항목”이라 항상 그대로 남습니다 — 정상입니다.

동기화 확인은 같은 화면의 상태 표시에서 Active Peer가 떴고 offset이 작으면 성공입니다. 나머지 서버가 Pending/Unreach로 보여도 백업 후보로 계속 측정 중인 것이라 문제 없습니다.


2. Configuration Backup — 설정 백업

방화벽 설정은 수십 시간을 들여 쌓은 자산입니다. 한 번의 실수나 디스크 고장으로 날아가면 복구가 막막합니다. 암호화 백업을 받아 여러 곳에 분산해 둡니다.

System → Configuration → Backups

수동 백업 절차:

  1. “Encrypt this configuration file” 체크 → 비밀번호 입력(두 번).
  2. Download configuration 클릭 → config.xml이 암호화되어 내려받아집니다.
  3. 파일명에 날짜를 붙입니다. 예: opnsense-hq-2026-05-08-baseline.xml.

암호화가 중요한 이유는, config.xml 안에 VPN 키, 인증서, API 토큰, 해시된 비밀번호 등 민감 정보가 들어 있기 때문입니다. 평문으로 클라우드에 올리면 그 자체가 사고입니다.

보관은 최소 3곳에 분산합니다(예: 작업 PC + 개인 클라우드 + 비밀번호 관리자). 백업 파일의 암호도 비밀번호 관리자에 함께 저장합니다 — 암호를 잃으면 백업이 무용지물입니다.

자동 백업(API 사용자 + cron, 또는 os-google-drive 플러그인)도 있지만, 클라우드 연동 플러그인은 WAN이 살아 있어야 설치됩니다. 그래서 절체 전에는 수동 암호화 백업으로 최소한의 안전망을 확보하고, 자동화는 절체 후로 미루는 게 현실적입니다.

작업 단계마다(특히 큰 변경 전후) 백업을 새로 받는 습관을 들이면, 언제든 직전 상태로 돌아갈 수 있습니다. 콘솔 메뉴의 13) Restore a backup으로 복원합니다.


3. GeoIP 차단 — 준비 단계

특정 국가에서 오는 트래픽을 통째로 막는 게 GeoIP 차단입니다. 외부 노출 서비스(웹·VPN·메일)에 대한 무차별 스캔·공격의 상당수가 소수 고위험 지역에서 오기 때문에, 사업상 관계없는 국가를 막으면 공격 표면이 크게 줄어듭니다.

GeoIP는 네 단계인데, 이번 편에서는 위험 없는 ①~③(DB 등록 + Alias 생성)까지만 하고, ④ WAN 차단 룰은 방화벽 정리 단계로 미룹니다. WAN 룰은 잘못 넣으면 정상 트래픽까지 막아 사고가 나기 때문입니다.

① MaxMind 라이선스 키 발급

OPNsense의 GeoIP는 MaxMind의 무료 GeoLite2 DB를 씁니다.

  1. MaxMind 가입 → 이메일 인증.
  2. Account → Manage License Keys → Generate new license key.
  3. “Will this key be used for GeoIP Update?”에서 반드시 Yes 선택.
  4. 발급된 키는 한 번만 표시되므로 즉시 비밀번호 관리자에 저장.

키 하나로 여러 장비(HQ·IDC 등)에서 재사용할 수 있습니다. 단, 키가 채팅·문서·백업 등에 노출됐다면 반드시 폐기 후 재발급하세요. 재발급 시에는 “새 키 발급 → OPNsense URL의 license_key= 교체 → Apply → 기존 키 삭제” 순서를 지켜야 합니다. 순서를 거꾸로 하면 다음 자동 갱신에서 다운로드가 실패합니다.

② DB 등록 (자동 다운로드)

Firewall → Aliases → GeoIP settings 탭

Url 칸에 다음 형식을 넣습니다(키 부분만 교체).

https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-Country-CSV&license_key=발급받은키&suffix=zip

Save하면 OPNsense가 그 URL로 국가별 IP 대역 DB를 자동 다운로드합니다(수십 초~1분). 완료되면 화면에 Last updated 날짜와 Total number of ranges(약 120만 개)가 표시됩니다. 이 숫자가 보이면 DB가 정상적으로 받아진 것입니다.

③ 차단 Alias 생성

Firewall → Aliases → + (Add)
항목값
TypeGeoIP
NameGEO_BLOCK_HIGH_RISK
Content차단할 국가 선택(사업 관계없는 고위험국)

국가를 고르면 해당 국가들의 IP 대역(수만 개)이 이 Alias 하나로 묶입니다. 이 프로젝트에서는 고위험 5개국을 묶어 약 47,000개 대역의 Alias를 만들었습니다.

여기까지가 이번 편의 GeoIP 작업입니다. 이 Alias를 실제로 WAN에서 Block하는 룰은 방화벽 정리 단계에서 다른 WAN 인바운드 룰과 함께 신중히 추가합니다.

주의: GeoIP 차단은 강력하지만 거칠다는 점을 기억하세요. 막은 국가에서 정당한 접속(예: 해외 출장자, 해외 협력사)이 필요해질 수 있습니다. 그래서 “사업상 절대 관계없는 국가”부터 보수적으로 시작하고, VPN 등 우회 경로를 함께 설계합니다.


4. ACME — Let’s Encrypt 자동 인증서

외부 공개 서비스, 관리 GUI, VPN 등에 붙일 정식 SSL 인증서를 Let’s Encrypt에서 자동으로 발급·갱신합니다.

플러그인 설치

System → Firmware → Plugins → os-acme-client

os-acme-client는 커뮤니티 플러그인이라 기본 목록에 안 보일 수 있습니다. 플러그인 화면 우상단의 “Show community plugins” 체크박스를 켜야 검색에 나타납니다.

계정과 챌린지 방식

Services → ACME Client
  • Settings: Enable Plugin ✅, Auto Renewal ✅.
  • Accounts: Let’s Encrypt 계정 등록(이메일은 만료 알림용). 처음엔 Staging(Test CA)으로 테스트한 뒤 Production으로 전환하는 게 안전합니다 — LE는 발급 횟수 제한이 있습니다.
  • Challenge Type: DNS-01 + Cloudflare를 권장합니다.

DNS-01을 쓰는 이유가 중요합니다. HTTP-01 방식은 WAN으로 80포트 인바운드가 열려 있어야 하는데, 절체 전에는 아직 WAN이 OPNsense로 안 들어옵니다. 반면 DNS-01은 도메인 DNS에 TXT 레코드를 넣어 인증하므로 WAN 상태와 무관하게 발급됩니다. DNS를 Cloudflare로 옮겨두고 API 토큰을 연동하면, 와일드카드 인증서까지 완전 자동으로 발급·갱신됩니다.

와일드카드 인증서 발급

Services → ACME Client → Certificates → +
항목값(예시)
Common Name*.example.com
SAN Listexample.com (apex 포함 시)
ACME Account등록한 Let’s Encrypt 계정
Challenge TypeCloudflare DNS-01
Auto Renewal✅

Save → Issue/Renew. 와일드카드(*.example.com) 하나면 그 도메인의 모든 서브도메인(서비스·VPN·관리 GUI 등)에 재사용할 수 있어 관리가 단순해집니다. 이 프로젝트에서는 용도별로 여러 와일드카드(서비스용·개발용·검증용 등)를 발급해 일관된 패턴으로 관리했습니다.

발급된 인증서는 System → Trust → Certificates에 자동 임포트되어, Caddy·OpenVPN·관리 GUI 등 다른 서비스에서 바로 가져다 씁니다.

자동 갱신 Cron

ACME Settings에서 Apply하면, 매일 자정(0시 0분)에 갱신 필요 여부를 검사하는 Cron 작업이 자동 등록됩니다(System → Settings → Cron에서 확인). 덕분에 90일짜리 Let’s Encrypt 인증서가 사람 손 안 타고 갱신됩니다.

보안 주의: Cloudflare API 토큰은 DNS 레코드를 바꿀 수 있는 강력한 권한입니다. 백업(config.xml)이나 채팅·문서에 노출됐다면 작업 후 반드시 폐기하고 재발급하세요. DNS-01 + Cloudflare 조합은 WAN IP가 바뀌어도(IDC 이전 등) 갱신에 영향이 없다는 큰 장점이 있습니다.


이번 편 체크포인트

절체 전 보안 기반 네 가지가 갖춰진 상태입니다.

  • NTP — 내부망에만 제공(WAN 제외), Iburst로 빠르게 동기화. 모든 로그·인증서·2FA의 시간 기준 확보
  • Backup — 암호화 설정 백업을 여러 곳에 분산. 언제든 직전 상태로 복구 가능
  • GeoIP — 약 120만 대역 DB 등록 + 고위험국 차단 Alias 생성(WAN 차단 룰은 방화벽 정리 단계로 보류)
  • ACME — Cloudflare DNS-01로 와일드카드 인증서 발급, 매일 자정 자동 갱신. WAN 상태와 무관하게 동작

이 네 가지는 절체 순간 바로 효력을 냅니다. 인증서는 이미 준비돼 있고, 시간은 맞아 있고, GeoIP DB는 룰만 켜면 되는 상태입니다.


다음 편 예고

06. OPNsense 보안 설정 ② — 절체 후 방어선과 접근(Caddy·Suricata·TOTP·VPN) — 외부에 노출되기 시작한 뒤 세우는 능동 방어를 다룹니다. Caddy로 443 단일 진입점 리버스 프록시를 만들고(80/443 포트 충돌·Alternate Hostnames 트러블슈팅 포함), Suricata를 IDS로 시작해 1~2주 검증 후 IPS로 전환하며, 관리자 2FA(TOTP)를 걸고, 마지막으로 OpenVPN/WireGuard와 사이트 간 IPsec을 재구성합니다.


MORE POSTS

다른 글 보기

guniq 인사이트 썸네일 — 중소기업 OpenLDAP 통합 인증 구축 – 00. 왜 OpenLDAP인가: 비용과 자유, 그리고 표준의 중요성
테크 랩

중소기업 OpenLDAP 통합 인증 구축 – 00. 왜 OpenLDAP인가: 비용과 자유, 그리고 표준의 중요성

MS Active Directory 대신 OpenLDAP을 선택한 이유, 오픈소스 디렉토리 서버의 장단점, 그리고 연동 유연성을 결정짓는 LDAP 표준 준수의 중요성을 실제 운영 경험 기반으로 정리합니다.
2026.10.12
guniq 인사이트 썸네일 — Zabbix 인프라 모니터링 구축 – 15. 실전 이슈: 운영 중 마주친 오탐·누락·설정 오류 총정리 (트러블슈팅)
테크 랩

Zabbix 인프라 모니터링 구축 – 15. 실전 이슈: 운영 중 마주친 오탐·누락·설정 오류 총정리 (트러블슈팅)

Zabbix 모니터링 구축과 운영 중 실제로 마주친 문제들을 총정리합니다. Media Type 기본 비활성화, 트리거 표현식 포맷 변경, stale value 오탐, crontab 초기화, netstat 타입 오류 등 삽질의 기록과 해결책을 공유합니다.
2026.10.09
guniq 인사이트 썸네일 — Zabbix 인프라 모니터링 구축 – 14. 환경 분리: DEV·PRD를 하나의 Zabbix로 운영하기 (호스트그룹·권한)
테크 랩

Zabbix 인프라 모니터링 구축 – 14. 환경 분리: DEV·PRD를 하나의 Zabbix로 운영하기 (호스트그룹·권한)

개발과 운영 환경을 하나의 Zabbix 서버로 운영하면서 호스트 그룹, 사용자 권한, Slack 알림 채널을 분리하는 방법을 다룹니다. API 토큰, 스크립트, 로그까지 환경별 분리 전략 전체를 설명합니다.
2026.10.08

프로젝트 문의 환영합니다

기획부터 개발, 운영까지 함께 만들어 드립니다.

무료 3분 자가진단

우리 회사, 자체 클라우드가 답일까?

AWS vs 자체 인프라 · 11개 항목 3분 체크