본문 바로가기

네트워크

IKE는 붙는데 인증이 안 된다 — 원인이 하나가 아니라 다섯 개였다 (Part 5)

같은 증상으로 검색해 오신 분들께

증상: IKEv2 dialup + EAP-TTLS 구성에서 인증이 실패하거나, 인증은 성공하는데 트래픽이 통하지 않음. 실패 양상이 시도마다 다름. 환경: FortiGate 201F / FortiOS 7.4.11 / FortiClient 7.4.3 / FreeRADIUS 3.0.20 결론: 독립적인 원인 5개가 동시에 존재했다. 하나를 고칠 때마다 증상이 바뀌어서 계속 헛다리를 짚었다. 핵심 교훈: 증상이 시도마다 다르면 원인이 하나가 아니라고 가정하고, 원인을 세는 방식으로 접근한다. 검색 키워드: IKE SA created EAP-TTLS authentication failed sites-enabled FortiClient eap_method assign-ip-from usrgrp


1. 증상 — 무엇이 어떻게 실패했는가

Part 3, 4의 구성을 마치고 첫 접속을 시도했다. 실패했다. 여기까지는 예상 범위다.

문제는 그다음이었다. 같은 조건으로 다시 시도할 때마다 다른 곳에서 실패했다.

시도결과
1회차 IKE 성립, 인증 실패
2회차 인증 성공, IP 할당 안 됨
3회차 인증 성공, IP 할당됨, 내부망 통신 안 됨
4회차 인증 실패 (1회차와 다른 로그)
5회차 특정 노트북에서만 성공

이 표를 만든 순간이 전환점이었다. 설정 하나를 못 찾는 상황이 아니라, 서로 무관한 문제가 여러 개 겹쳐 있는 상황이라는 게 여기서 보였다.

2. 처음 세운 가설과, 그것이 왜 틀렸는가

첫 가설: RADIUS 설정 어딘가가 잘못됐다. 인증 계층이 가장 새로 만든 부분이니까.

합리적이었지만 접근 방식이 틀렸다. 나는 하나의 원인을 찾으려 했다.

그래서 이런 루프를 돌았다. FreeRADIUS 설정을 바꾼다 → 접속해본다 → 다른 데서 실패한다 → "아직 못 찾았구나" → 다시 FreeRADIUS를 바꾼다. 실제로는 첫 번째 변경으로 원인 하나를 이미 고쳤는데, 남은 네 개 때문에 여전히 실패하니까 그 변경을 되돌려버린 적도 있었다.

이게 이 편에서 가장 값비싼 교훈이다.

증상이 매번 다르면, "고쳤는데도 실패한다"가 아니라 "하나 고쳤고 아직 남았다"일 수 있다. 이때 변경을 되돌리면 이미 해결한 것까지 잃는다.

그 뒤로 방식을 바꿨다. 변경사항을 기록하고, 효과가 없어 보여도 되돌리지 않았다. 대신 각 계층을 독립적으로 검증할 수 있는 방법을 찾았다.

3. 계층별 독립 검증 — 이걸 먼저 했어야 했다

전체 경로를 한 번에 테스트하지 않고 구간별로 쪼갰다.

 
[클라이언트] --(A)--> [FortiGate] --(B)--> [FreeRADIUS]
                          |
                        (C) 정책/라우팅
구간검증 방법이 방법이 알려주는 것
A diagnose vpn ike log filter rem-addr4 <IP> + IKE 디버그 IKE 협상 어디까지 갔는지
B diagnose test authserver radius <서버> pap <계정> <PW+OTP> RADIUS 왕복이 되는지 (VPN과 무관하게)
B 서버에서 radiusd -X RADIUS 내부에서 어떤 모듈까지 갔는지
C diagnose debug flow 인증 후 트래픽이 어느 정책에 걸리는지

B 구간을 VPN과 분리해서 테스트할 수 있다는 것이 가장 중요했다. diagnose test authserver는 IKE를 거치지 않고 FortiGate에서 RADIUS로 직접 요청을 보낸다. 이게 성공하면 RADIUS는 무죄고, 문제는 A나 C에 있다.

이 명령 하나가 탐색 범위를 절반으로 줄였다.

4. 찾아낸 원인 다섯 개

발견 순서대로 쓴다. 논리적 순서가 아니라 실제 순서다.

원인 1 — 방화벽 정책이 없었다

증상: 인증 성공, IP 할당 성공, 그런데 내부망으로 아무것도 안 감. 사용자 화면에는 "연결됨"으로 표시된다.

가장 찾기 어려운 종류의 실패다. 모든 게 성공했다는 신호만 보이기 때문이다.

 
bash
diagnose debug flow filter addr 10.10.60.20
diagnose debug flow show function-name enable
diagnose debug flow trace start 20
diagnose debug enable

출력에서 확인한 것:

 
... find a route: ...
... Denied by forward policy check (policy 0)

policy 0은 "매칭되는 정책 없음"을 뜻한다. VPN 인터페이스에서 내부망으로 가는 정책을 만들지 않았다.

Part 3에 정책 설정을 넣어뒀지만, 실제 작업 순서에서는 Phase1/Phase2를 만들고 곧바로 테스트에 들어가서 이걸 건너뛰었다.

교훈: Denied by forward policy check (policy 0)을 보면 정책 부재다. 정책 번호가 실제 번호로 나오면 그 정책의 조건을 보면 된다. 0이면 매칭 자체가 없다는 뜻이고, 이 차이가 진단 시간을 크게 가른다.

원인 2 — Phase2가 없었다

증상: IKE 협상은 완료되는데 터널이 올라오지 않음.

 
bash
diagnose vpn tunnel list | grep -A5 ra-ipsec

Phase1은 있고 Phase2 SA가 없었다. GUI 마법사를 쓰면 자동으로 만들어지는데, CLI로 Phase1만 손으로 쓰다가 잊었다.

 
bash
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

부끄러운 실수지만 이 편에 넣는 이유가 있다. 로그가 "Phase2가 없다"고 말해주지 않는다. IKE SA는 정상적으로 생성되고, 그 뒤에 아무 일도 일어나지 않는다. 이 침묵의 패턴은 Part 8에서 훨씬 어려운 형태로 다시 나온다.

원인 3 — sites-enabled/의 백업 파일

이게 가장 오래 걸렸다. 상세는 Part 2에 썼으니 요약만.

sites-enabled/default를 수정하기 전에 습관적으로 같은 디렉터리에 default.bak을 만들었다. FreeRADIUS는 이 디렉터리의 모든 파일을 읽고, 확장자를 보지 않는다. 가상 서버가 둘이 되어 요청이 예측 불가능하게 갈렸다.

이게 "매번 다른 곳에서 실패하는" 증상의 주범이었다. 어느 서버가 처리하느냐에 따라 결과가 달랐던 것이다.

 
bash
# 확인: 심볼릭 링크가 아닌 파일이 있는지
ls -la /etc/raddb/sites-enabled/
ls -la /etc/raddb/mods-enabled/

교훈: 재현성이 없는 실패를 만나면 설정이 유일하게 로드되고 있는지부터 확인한다. 중복 로드는 무작위성을 만들고, 무작위성은 모든 가설 검증을 무력화한다.

원인 4 — FortiClient XML의 태그 세 개

상세는 Part 4에 있다. 요약:

조치내용안 하면
추가 <enable_ike_fragmentation>1</...> 큰 IKE 페이로드가 중간 노드에서 버려짐
삭제 <mode> 태그 transport 설정과 충돌
이동 <eap_method>를 </auth_data> 직후로 EAP 협상 자체를 시도하지 않음

교훈: 클라이언트 측 설정이 무시되고 있는지 확인하는 방법은 가져온 뒤 GUI에서 값을 육안으로 확인하는 것이다. 무시된 필드는 오류를 내지 않고 기본값으로 표시된다.

원인 5 — 클라이언트에 CA 인증서가 없었다

증상: 특정 노트북에서만 실패. 성공하는 노트북과 설정이 동일.

RADIUS 서버 인증서를 새 CA로 갱신했는데, 새 CA를 신뢰 저장소에 넣은 장비에서만 성공했던 것이다. EAP-TTLS는 클라이언트가 서버 인증서 체인을 검증하므로, 체인을 세울 수 없으면 터널 수립 단계에서 실패한다.

 
powershell
# 확인
Get-ChildItem Cert:\LocalMachine\Root | Where-Object { $_.Subject -like "*example*" }

# 설치
Import-Certificate -FilePath .\radius-ca.crt -CertStoreLocation Cert:\LocalMachine\Root

교훈: "특정 장비에서만"이라는 조건은 거의 항상 클라이언트 상태 차이를 가리킨다. 서버 설정을 아무리 봐도 나오지 않는다. Part 9에서 이 교훈의 더 극단적인 사례가 나온다.

5. 원인 다섯 개의 상호작용

이 다섯 개가 왜 그렇게 진단을 어렵게 만들었는지 정리하면.

원인어느 단계에서 실패시키나증상
3. sites-enabled 중복 인증 (무작위) 매번 다름 ← 여기가 핵심
4. XML 태그 EAP 협상 시작 전 인증 실패
5. CA 미설치 TTLS 터널 수립 특정 장비만 실패
2. Phase2 부재 인증 후 터널 수립 연결 안 됨
1. 정책 부재 터널 후 트래픽 연결됨인데 통신 불가

원인 3이 무작위성을 주입하고 있었기 때문에, 나머지 네 개에 대한 모든 가설 검증이 신뢰할 수 없었다.

A를 바꾸고 성공하면 "A가 원인"이라 결론 내리는데, 실제로는 우연히 정상 가상 서버로 갔을 뿐이었다. 다음 시도에서 실패하면 A를 되돌린다. 이 루프가 며칠 갔다.

재현성 없는 실패를 만나면 다른 모든 디버깅을 멈추고 무작위성의 원인부터 제거한다. 무작위성이 남아 있는 상태에서의 실험 결과는 전부 노이즈다.

6. 조치 후 확인 절차

전부 고친 뒤, 다음 사고를 위해 검증 순서를 문서로 만들었다.

 
bash
# 1. 설정 유일 로드 확인 (서버)
ls -la /etc/raddb/sites-enabled/ /etc/raddb/mods-enabled/
radiusd -XC

# 2. RADIUS 왕복 (FortiGate에서, VPN 무관)
diagnose test authserver radius radius-primary pap <계정> '<비밀번호+OTP>'

# 3. IKE 협상 (특정 클라이언트만)
diagnose vpn ike log filter clear
diagnose vpn ike log filter rem-addr4 <클라이언트공인IP>
diagnose debug application ike -1
diagnose debug enable

# 4. 터널 SA 확인
diagnose vpn tunnel list | grep -A5 ra-ipsec

# 5. 트래픽 경로 확인
diagnose debug flow filter addr <할당된VPN IP>
diagnose debug flow trace start 20

# 6. 클라이언트 로그 (Windows)
# C:\Users\<사용자>\AppData\Roaming\Fortinet\FortiClient\logs\trace\FortiIKE_1.log

이 6단계는 아래에서 위로 올라가지 않고 위에서 아래로 진행한다. 1번이 깨져 있으면 2~6번 결과는 의미가 없다.

7. 아직 해결되지 않은 것

이 시점에서 UDP transport로는 안정적으로 동작하게 됐다. 하지만 TCP transport에서는 여전히 이상했다.

절반은 붙고 절반은 안 붙었다. 그런데 위 다섯 개를 다 고친 뒤였으므로, 나는 이것도 같은 종류의 설정 문제라고 생각했다.

그게 아니었다. Part 8에서 다룬다.

8. 여기서 배운 것

  • 증상이 시도마다 달라지면 원인을 세라. 하나를 찾으려는 접근이 실패의 원인이었다.
  • 효과가 없어 보이는 변경을 되돌리지 말고 기록만 해둔다. 남은 원인 때문에 효과가 가려질 수 있다.
  • 재현성 없음은 다른 모든 디버깅의 전제를 무너뜨린다. 무작위성 제거가 항상 최우선이다.
  • 전체 경로 테스트 대신 구간별 독립 검증 수단을 먼저 확보한다. diagnose test authserver처럼 한 계층만 떼어내 테스트하는 도구가 있는지 찾는 것이 초기 투자로 가장 남는다.
  • policy 0 같은 특수값의 의미를 아는 것이 진단 시간을 결정한다. 0은 "정책이 거부함"이 아니라 "매칭되는 정책 없음"이다.

다음 편에서는

Part 6에서 이해할 수 없었던 현상을 다룬다. 어떤 프로파일은 TCP로 붙는다고 표시되는데 실제로는 UDP로 붙고 있었다. 원인은 XML 값의 자료형이었다.

반응형