기업 시스템 연동 프로젝트를 진행하다 보면 **"SSO(Single Sign-On) 적용을 위해 웹 서버의 DNS를 SSO 장비 IP로 변경해 주세요"**라는 요청을 받게 됩니다. 이는 리버스 프록시(Reverse Proxy) 또는 게이트웨이(Gateway) 방식의 표준적인 연동 절차입니다.

하지만 이 과정에서 **절대 놓쳐선 안 될 '한 가지 설정'**이 있습니다. 이것을 누락할 경우, 여러분의 서버는 비밀번호 없이 관리자 권한을 탈취당하는 치명적인 보안 구멍이 생기게 됩니다.

오늘은 리버스 프록시 SSO의 동작 원리와, 왜 **'백엔드 직접 접속 차단'**이 생명인지 기술적으로 깊이 파헤쳐 보겠습니다.

1. 리버스 프록시(Gateway) SSO의 동작 원리

먼저 정상적인 상황에서의 트래픽 흐름을 이해해 봅시다. 이 방식은 웹 서버(Agentless)가 인증을 직접 처리하지 않고, 앞단의 SSO 장비가 인증을 대행하는 구조입니다.

정상적인 흐름 (The Happy Path)

  1. 사용자: my-web.com에 접속 (DNS는 SSO IP 222.222.222.222를 가리킴).
  2. SSO 서버: 사용자의 로그인 여부를 확인합니다.
  3. 헤더 주입 (Injection): 인증된 사용자라면, SSO 서버는 백엔드 웹 서버(111.111.111.111)로 요청을 넘기면서(Proxy Pass) HTTP 헤더에 사용자 정보를 심습니다.
    • SSO_USER_ID: gildong.hong
    • SSO_DEPT_CODE: IT_DEV
  4. 웹 서버: 헤더에 담긴 ID를 보고 "아, 홍길동 님이구나"라고 신뢰하며 로그인 세션을 생성해 줍니다.

2. 치명적인 질문: "누군가 내 서버 IP를 알아낸다면?"

여기서 아주 날카로운 보안적 의문이 생깁니다.

"웹 서버는 단순히 헤더(Header) 값만 믿고 로그인을 시켜주는 것 아닌가요? 그럼 SSO를 거치지 않고, 헤더를 조작해서 웹 서버로 직접 들어오면 어떻게 되나요?"

정답은 "뚫립니다." 이것이 바로 헤더 스푸핑(Header Spoofing) 또는 헤더 인젝션(Header Injection) 공격입니다.

공격 시나리오 (The Attack Vector)

만약 운영자가 DNS만 변경하고, 기존 운영 서버 IP(111.111.111.111)에 대한 **방화벽(Any Open)**을 그대로 두었다면 다음과 같은 일이 벌어집니다.

  1. 공격자: 다양한 스캐닝 도구로 도메인 뒤에 숨겨진 실제 서버 IP(111.111.111.111)를 찾아냅니다.
  2. 직접 접속 시도: 공격자는 Curl이나 Postman 같은 도구를 사용해 SSO를 우회하고 직접 IP로 접속을 시도합니다.
  3. 헤더 조작: 요청을 보낼 때 악의적으로 헤더를 심습니다.
    curl -H "SSO_USER_ID: admin" http://111.111.111.111/login
    
  4. 보안 사고: 웹 서버는 이 요청이 SSO에서 온 것인지, 해커가 보낸 것인지 구분하지 못합니다. 단순히 헤더에 admin이 있으므로, 공격자를 관리자로 로그인시켜 버립니다.

비밀번호도 필요 없습니다. IP가 노출되고 방화벽이 열려있다면, 프리패스(Free Pass)입니다.

3. 방어 전략: 어떻게 막아야 하는가?

이 취약점을 막기 위해선 **"신뢰할 수 있는 경로(SSO) 외에는 모든 문을 폐쇄"**해야 합니다.

전략 1: 네트워크 레벨 방어 (가장 확실한 방법)

운영 서버(VM)의 방화벽(Firewall, AWS Security Group 등) 정책을 수정하여 물리적인 접속 경로를 통제합니다.

  • Before (위험):
    • Source: Any (0.0.0.0/0) ->Action: Allow
  • After (안전):
    • Source: 222.222.222.222 (SSO L4 IP) -> Action: Allow
    • Source: Any -> Action: Deny / Drop

이렇게 설정하면 공격자가 실제 IP를 알아내어 접속을 시도하더라도, 네트워크 단에서 패킷이 차단되므로 안전합니다.

전략 2: 애플리케이션 레벨 방어 (이중 잠금)

네트워크 설정 실수를 대비해 웹 소스 코드에서도 검증 로직을 추가하는 것이 좋습니다.

  1. Client IP 검증: 요청을 보낸 클라이언트의 IP(request.getRemoteAddr())가 약속된 SSO 장비의 IP인지 확인합니다.
  2. Secret Header 공유: 단순히 ID만 보내는 것이 아니라, SSO와 웹 서버만 아는 **비밀 키(Secret Key)**를 헤더에 같이 보냅니다.
    • 예: SSO_AUTH_TOKEN: a1b2c3d4...
    • 웹 서버는 이 토큰 값이 일치할 때만 헤더의 ID를 신뢰합니다.

4. 결론 및 요약

리버스 프록시 방식의 SSO는 Agentless라는 편리함을 주지만, 그만큼 **'네트워크 접근 제어(ACL)'**가 보안의 핵심이 됩니다.

오늘의 체크리스트:

  1. [ ] DNS를 SSO IP로 변경했는가?
  2. [ ] 운영 서버의 방화벽에서 'SSO IP'를 제외한 모든 인바운드(Inbound)를 차단했는가? (핵심!)
  3. [ ] 웹 애플리케이션이 헤더 값을 읽어 로그인 처리하도록 수정되었는가?
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기