FortiGate Phase1/Phase2와 IP 풀 설계 — 나중에 살아남을 대역 나누기 (Part 3)
개요
- IKEv2 dialup + PSK + eap enable + authusrgrp로 사용자 인증을 RADIUS에 위임한다.
- IP 풀을 그룹별로 미리 쪼개 설계한다. 나중에 이게 접근제어의 유일한 수단이 된다. (Part 7)
- 기본 transport는 UDP로 시작한다. TCP는 필요한 사용자에게만 별도 프로파일로 준다.
이걸 반대로 했다가 Part 8을 만났다. - 마법사(wizard)로 만든 설정은 참고만 하고, 최종본은 CLI로 확정한다.
이 글은 누구를 위한 글인가
FortiOS 7.4에서 원격접속 IPsec을 세워야 하고, GUI 마법사가 만들어준 설정이 왜 그렇게 생겼는지 이해하고 싶은 사람.
읽고 나면 각 파라미터가 왜 그 값인지 설명할 수 있게 된다. 이게 중요한 이유는, 장애가 났을 때 바꿔볼 값을 고르는 게 결국 이 이해에서 나오기 때문이다.
검증 환경
| 장비 | FortiGate 201F (Active-Passive HA) |
| 펌웨어 | FortiOS 7.4.11 |
| WAN | port1, 203.0.113.10 |
| RADIUS | 10.10.20.10 (FreeRADIUS 3.0.20) |
| VPN 풀 | 10.10.60.0/24 |
1. RADIUS 서버와 사용자 그룹
config user radius
edit "radius-primary"
set server "10.10.20.10"
set secret <REDACTED>
# 왜: PAP. EAP-TTLS 내부에서 PAP을 쓰기로 했으므로 여기도 맞춘다.
set auth-type pap
# 왜: RADIUS 응답의 Fortinet 벤더 속성을 그룹 매칭에 쓰기 위해
set radius-coa disable
next
end
config user group
edit "vpn-radius-grp"
set member "radius-primary"
next
end
auth-type을 auto로 두면 FortiGate가 여러 방식을 순차 시도한다. 동작하긴 하는데 디버그 로그가 지저분해지고, 실패 시 어느 방식에서 실패했는지 구분이 어려워진다. 명시하는 게 낫다.
2. Phase1 인터페이스
config vpn ipsec phase1-interface
edit "ra-ipsec"
set type dynamic
set interface "port1"
# 왜: 다중 공인 IP 환경에서 어느 IP로 리스닝할지 명시. (Part 10에서 중요해진다)
set local-gw 203.0.113.10
set ike-version 2
set peertype any
# 왜: dialup 클라이언트마다 인터페이스를 만들지 않는다. 150명이면 필수.
set net-device disable
# 왜: 클라이언트에 IP/DNS를 내려주는 mode-config
set mode-cfg enable
set proposal aes256gcm-prfsha384 aes256-sha256 aes128-sha256
set dhgrp 20 14
set dpd on-idle
set dpd-retryinterval 60
set authmethod psk
set psksecret <REDACTED>
# 왜: 사용자 인증을 EAP로 위임. PSK는 게이트웨이 식별용.
set eap enable
set eap-identity send-request
set authusrgrp "vpn-radius-grp"
# 왜: RADIUS(rlm_ippool)가 내려주는 IP를 쓴다
set assign-ip-from usrgrp
set ipv4-dns-server1 10.10.20.5
set ipv4-split-include "ra-split"
# 왜: 인증서/큰 페이로드로 IKE 패킷이 1500B를 넘으면 중간 노드가 버린다
set fragmentation enable
set fragmentation-mtu 1200
# 왜: 기본은 UDP. TCP는 필요한 사용자에게만 별도 프로파일로 준다. (아래 설명)
set transport udp
set save-password enable
set client-auto-negotiate enable
set client-keep-alive enable
next
end
dhgrp는 14 이상으로
커뮤니티 사례에서 반복해서 나오는 항목이다. 클라이언트 쪽 DH 그룹이 14 미만이면 dialup 템플릿과 협상이 실패한다는 보고가 여러 건 있다. 서버에서 14 이상만 제안하면 이 문제가 사전에 걸러진다.
fragmentation enable이 필요한 이유
공식 문서 설명이 명확하다. IKE 메시지에 큰 인증서나 긴 PSK가 들어가면 패킷이 1500바이트를 넘고, 중간 경로의 ISP나 경계 방화벽이 조각난 UDP 패킷을 통과시키지 못하거나 아예 차단한다. 결과는 "터널이 안 올라옴"이고, 원인 추적이 어렵다. IKE 프래그멘테이션은 IP 계층 조각화를 피하기 위해 IKE 자체를 더 작은 조각으로 나눈다.
fragmentation-mtu 값은 1200에서 시작했다. 이 값을 900까지 내려보는 실험이 나중에 있었는데, 결론은 Part 8에 있다. 미리 말하면: 이 값을 내려서 개선되는 것처럼 보이는 건 함정일 수 있다.
왜 처음부터 TCP를 쓰지 않았나 — 실은 반대로 했다
정직하게 쓴다. 우리는 처음에 TCP를 기본으로 갔다.
이유는 그럴듯했다. 기존 SSL VPN이 TCP 443으로 동작했고, 외부망에서 UDP 500/4500이 막히는 환경이 많다는 걸 알고 있었으니까. IPsec도 TCP를 지원하니 같은 조건을 재현하는 게 안전해 보였다.
이 판단이 Part 8의 원인이 됐다. 결과적으로 권장하는 순서는 이쪽이다.
UDP를 기본으로 세우고 안정화한 뒤, TCP가 필요한 사용자에게만 두 번째 프로파일을 준다.
UDP 경로가 확실히 동작하는 상태를 만들어두면, 나중에 TCP에서 문제가 생겨도 비교 기준선이 존재한다. 처음부터 TCP만 있으면 "이게 원래 이런 건지, 뭔가 잘못된 건지" 판단할 근거가 없다.
참고로 FortiOS 7.6.1부터 IKE TCP 기본 포트가 443으로 변경됐다(신규 배포 기준). GUI 관리 포트가 443인 환경에서는 충돌 가능성이 있으니 업그레이드 계획 시 확인이 필요하다. Auto 모드(UDP 실패 시 TCP로 폴백)도 7.6 계열의 기능이고, 7.4에는 없다. 이 사실이 Part 6의 함정과 직결된다.
3. Phase2 인터페이스
config vpn ipsec phase2-interface
edit "ra-ipsec-p2"
set phase1name "ra-ipsec"
set proposal aes256gcm aes256-sha256 aes128-sha256
set pfs enable
set dhgrp 20 14
set keepalive enable
next
end
이걸 빼먹으면 IKE는 성공하고 터널은 안 올라온다. GUI 마법사를 쓰면 자동 생성되지만, CLI로 Phase1만 손으로 만들다가 Phase2를 잊는 경우가 있다. 나는 실제로 잊었다. 증상과 진단법은 Part 5에 있다.
4. IP 풀 설계 — 여기에 시간을 쓸 것
이게 이 편에서 가장 중요한 부분이다.
처음엔 /24 하나를 통째로 풀로 던지려 했다. 그러다 생각을 바꿨다.
VPN 사용자를 그룹별로 다른 대역에 앉히면, 나중에 접근제어를 IP 기반으로 할 수 있다.
당시엔 이게 "있으면 좋은 것"이었다. Part 7에서 알게 되지만, 이건 유일하게 가능한 방법이었다.
| 10.10.60.1 – 15 | 관리자 고정 IP | 15 |
| 10.10.60.16 – 127 | 일반 직원 (기본 풀) | 112 |
| 10.10.60.128 – 143 | 시스템 관리 | 16 |
| 10.10.60.144 – 159 | 유지보수 벤더 | 16 |
| 10.10.60.160 – 175 | 파트너사 A | 16 |
| 10.10.60.176 – 183 | 파트너사 B | 8 |
| 10.10.60.184 – 191 | 특수 용도 | 8 |
| 10.10.60.192 – 254 | 특별 접근 권한 (고정 IP) | 63 |
설계 원칙 세 가지.
- 경계를 2의 거듭제곱에 맞춘다. 10.10.60.160-175는 /28로 딱 표현된다. 10.10.60.155-170 같은 대역은 방화벽 주소 객체를 만들 때 지옥이 된다.
- 각 그룹에 실제 필요량의 2배를 준다. 대역 재설계는 접속 중인 사용자 전원의 재접속을 요구한다.
- 고정 IP 구간을 양 끝에 몰아둔다. 동적 풀과 섞이면 충돌 진단이 어렵다.
주소 객체도 같이 만들어둔다. 나중에 정책에서 쓴다.
config firewall address
edit "VPN-Staff"
set subnet 10.10.60.0 255.255.255.128
next
edit "VPN-Vendor"
set subnet 10.10.60.144 255.255.255.240
next
edit "VPN-PartnerA"
set subnet 10.10.60.160 255.255.255.240
next
end
5. 방화벽 정책
config firewall policy
edit 0
set name "VPN-Staff-to-Internal"
set srcintf "ra-ipsec"
set dstintf "internal"
# 왜: 사용자 그룹 매칭이 아니라 IP 대역 매칭. 이유는 Part 7에서.
set srcaddr "VPN-Staff"
set dstaddr "Internal-Servers"
set action accept
set schedule "always"
set service "ALL"
set logtraffic all
next
end
정책이 없으면 IKE와 인증이 모두 성공한 뒤에 트래픽만 조용히 죽는다. 사용자에게는 "연결됨으로 보이는데 아무것도 안 됨"으로 나타난다. Part 5의 첫 번째 마일스톤이 정확히 이거였다.
6. HA 환경에서 확인할 것
A-P 클러스터에서는 설정이 동기화되지만, 인증 세션 상태는 페일오버 시 유지되지 않는다. 전환이 일어나면 VPN 사용자는 재접속해야 한다.
# 동기화 상태 확인
diagnose sys ha checksum cluster
get system ha status
체크섬이 노드 간에 다르면 설정 동기화가 깨진 것이다. VPN 설정을 바꾼 직후에는 항상 확인한다.
여기서 막힌 사람들을 위한 확인 순서
# 1. Phase1이 올라와 있는지 (설정 자체의 유효성)
diagnose vpn ike gateway list
# 2. 특정 클라이언트 IP에 대해서만 IKE 로그 필터링
# 주의: rem-addr4 뒤는 공백이다. 하이픈이 아니다.
diagnose vpn ike log filter clear
diagnose vpn ike log filter rem-addr4 <클라이언트공인IP>
diagnose debug application ike -1
diagnose debug enable
# 3. RADIUS 도달 여부
diagnose test authserver radius radius-primary pap <user> <password+OTP>
# 4. 세션 확인
diagnose vpn tunnel list | grep -A5 ra-ipsec
3번은 실제 OTP를 붙여야 한다. 안 붙이면 Part 2에서 설명한 이유로 결과가 이상하게 나온다.
이 편에서 배운 것
- IP 대역 설계는 나중에 바꿀 수 없는 결정이다. 30분 더 쓰는 게 6개월 뒤 이틀을 아낀다.
- 새 구성은 가장 단순한 경로부터 안정화한다. 최종 목표 구성으로 바로 가면 비교 기준선이 없어서 문제가 생겼을 때 판단할 근거가 사라진다.
- 마법사가 만든 설정은 좋은 참고 자료지만, 왜 그 값인지 설명할 수 없는 파라미터가 남아 있으면 장애 때 손을 못 댄다.
다음 편에서는
Part 4에서 FortiClient VPN-only 프로파일 XML을 만들고, EMS 없이 150명에게 배포한다. XML 태그 하나의 위치가 인증 성공과 실패를 갈랐던 이야기가 여기 있다.