들어가며
개발자라면 한 번쯤 예상치 못한 환경에서 발생하는 문제와 씨름해본 경험이 있을 것입니다.
이번에 저희 회사의 타 팀에서 신규 솔루션 배포 중 경험한 문제는 "특정 고객사 네트워크에서만 발생하는 SSL 인증서 오류"였습니다.
이 글에서는 해당 이슈의 트러블슈팅에 제가 약간의 지원을 해주면서 알게된 것들과 해결책을 공유하고자 합니다.
1. 문제 상황
1.1 증상
저희 회사에서는 안드로이드 애플리케이션을 개발하여 고객사(L사)에 제공했습니다.
애플리케이션은 HTTPS를 통해 저희 백엔드 서버와 통신합니다.
그런데 저희 솔루션이 설치된 고객사의 일부 기기들로부터 애플리케이션이 서버에 연결할 수 없다는 보고가 들어왔습니다.
저희가 로그상에서 파악한 오류 메시지는 다음과 같았습니다.
외부 API 요청에 실패했습니다. [Trust anchor for certification path not found.]
1.2 특이한 점
이 문제에서 가장 흥미로운(?) 이상했던 점은 동일한 네트워크 환경에서 Chrome 브라우저로는 같은 URL에 접속이 가능했다는 것입니다.
즉, 저희 회사의 사이트에 크롬으로 접속하면 문제없이 연결되지만, 앱에서 요청을 시도하면 SSL 오류가 발생했습니다.
또한, 저희 회사의 네트워크 환경에서는 앱이 정상적으로 작동했습니다.
오직 고객사의 네트워크에서만 이 문제가 발생했습니다.
2. 원인 추적 과정
2.1 초기 가설
문제 상황을 분석하여 다음과 같은 가능한 원인들을 고려했습니다.
- 서버 인증서 문제: 우리 서버의 인증서가 유효하지 않거나, 중간 인증서가 누락되었을 수 있음
- 앱 구성 문제: 앱의 네트워크 라이브러리(Ktor) 설정이 잘못되었을 수 있음
- 네트워크 제한 정책: 고객사에서 특정 SSL/TLS 버전이나 암호화 방식을 제한하고 있을 수 있음
- 사용자 기기 문제: 특정 기기에서만 발생하는 문제일 수 있음
2.2 가설 검증
문제의 원인을 찾기 위해 다음과 같은 조사를 진행했습니다.
- 크롬의 인증서 정보 확인
고객사 네트워크에서 크롬으로 저희 웹 사이트에 접속한 후 인증서 정보를 확인했습니다.
인증서 뷰어에는 두 개의 인증서가 표시되었습니다.L사
와 당사의 인증서였습니다. - SSL 연결 정보 확인
브라우저에서 다음과 같은 SSL 연결 정보를 확인했습니다. 저희 웹에 대한 연결은 최신 암호화 기술을 사용하여 암호화됩니다. TLS 1.3 연결입니다. 이 연결은 AES_256_GCM을(를) 사용하여 암호화되고 인증되며 X25519을(를) 키 교환 매커니즘으로 사용합니다.
- Ktor 클라이언트 로그 확인
앱에서 발생하는 구체적인 SSL 오류를 확인하기 위해 로깅을 추가했습니다.
2.3 결정적 단서 발견
크롬에서 인증서 정보를 확인한 결과가 결정적인 단서였습니다.
인증서 뷰어에서 L사
와 당사
두 개의 인증서가 표시된다는 것은 중간에 고객사의 SSL 검사 시스템이 개입하고 있다는 명확한 증거였습니다.
더 자세히 살펴보니, 크롬에서 인증서 정보를 확인하면 "L사 업체가 이 웹사이트 인증서를 발급했음"이라는 메시지가 표시되었습니다.
이는 원래의 당사 인증서가 아닌, 고객사에서 재발급한 인증서로 바뀌었다는 것을 의미합니다.
3. 문제의 원인
3.1 SSL 중간자 검사(MITM)
이 현상의 원인은 고객사(L사)에서 운영하는 SSL 중간자 검사(SSL MITM Inspection) 시스템이었습니다.
이 시스템은 보안을 위해 모든 HTTPS 트래픽을 다음과 같이 처리합니다.
- 사용자가
당사 웹
과 같은 HTTPS 사이트에 접속 시도 - L사의 프록시 서버가 이 요청을 가로챔
- 프록시 서버가 실제
당사 웹
에 연결하여 원본 인증서 확인 - 프록시 서버가 L사 자체 CA로 새 인증서를 발급.
- 도메인: 당사 (원본과 동일)
- 발급자: L사 CA
- 이 새 인증서를 사용자에게 제공
결과적으로 두 개의 별도 암호화 채널이 형성됩니다.
클라이언트 <-- L사 CA 인증서 --> 프록시 서버 <-- 원본 인증서 --> 당사 웹
4. 해결 방법
4.1 네트워크 보안 설정으로 사용자 인증서 신뢰
문제를 해결하기 위해 Android의 네트워크 보안 설정(Network Security Configuration)을 사용하여 사용자 설치 인증서를 신뢰하도록 앱을 구성했습니다.
res/xml/network_security_config.xml
파일을 생성
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config>
<trust-anchors>
<certificates src="system" />
<certificates src="user" /> <!-- 사용자 추가 인증서(L사 CA) 신뢰 -->
</trust-anchors>
</base-config>
</network-security-config>
AndroidManifest.xml
에 이 설정을 적용
<application
...
android:networkSecurityConfig="@xml/network_security_config"
... >
4.2 인증서 설치 및 결과 검증
위 해결책을 적용한 후 고객사 네트워크에서 앱을 다시 테스트한 결과, SSL 오류가 사라지고 정상적으로 서버와 통신할 수 있게 되었습니다.
이제 앱은 L사 CA가 발급한 인증서를 신뢰하므로, SSL 중간자 검사 시스템이 있는 환경에서도 문제없이 작동합니다.
5. 교훈 및 추가 고려사항
5.1 기업 환경을 고려한 앱 개발
이번 경험을 통해 기업 네트워크 환경의 특수성을 고려한 앱 개발의 중요성을 깨달았습니다.
특히 금융, 의료, 대기업과 같이 보안이 중요한 환경에서는 SSL 중간자 검사가 흔히 사용되므로, 이를 염두에 두고 개발해야 합니다.
5.2 보안과 사용성의 균형
Android 7.0부터 사용자 인증서를 기본적으로 신뢰하지 않는 것은 보안을 강화하기 위한 조치입니다.
그러나 기업 환경에서는 이로 인해 문제가 발생할 수 있습니다.
따라서 보안과 사용성 사이의 균형을 찾는 것이 중요합니다.
5.3 도메인별 보안 설정
특정 도메인에 대해서만 사용자 인증서를 신뢰하도록 설정할 수도 있습니다.
<network-security-config>
<domain-config>
<domain includeSubdomains="true">{당사 도메인}</domain>
<trust-anchors>
<certificates src="system" />
<certificates src="user" />
</trust-anchors>
</domain-config>
</network-security-config>
이렇게 하면 당사 도메인
에 대해서만 사용자 인증서를 신뢰하므로 보안과 사용성의 균형을 더 잘 맞출 수 있습니다.
6. 결론
SSL/TLS 인증서 관련 문제는 디버깅이 어려울 수 있지만, 근본 원리를 이해하면 효과적으로 해결할 수 있습니다.
이번 케이스에서는 기업 네트워크의 SSL 중간자 검사 시스템으로 인해 발생한 문제를 안드로이드 네트워크 보안 설정을 통해 해결했습니다.
앱 개발 시 다양한 네트워크 환경을 고려하고, 특히 기업용 앱 개발 시에는 기업의 보안 정책과 호환되도록 설계하는 것이 중요합니다.
이를 통해 사용자에게 일관된 경험을 제공하고, 예상치 못한 오류로 인한 혼란을 방지할 수 있습니다.
이 트러블슈팅 경험이 비슷한 문제에 직면한 다른 개발자들에게 도움이 되길 바랍니다.
SSL/TLS와 인증서의 작동 원리를 이해하는 것은 현대 웹 개발의 필수 요소이며, 이러한 이해를 바탕으로 보다 안전한 앱을 만들 수 있을 것 입니다.
아래 링크는 관련된 이론을 정리한 블로그 포스팅 입니다.
2025.03.24 - [보안] - SSL/TLS 인증서와 프록시 환경의 기업 네트워크 보안의 이해
SSL/TLS 인증서와 프록시 환경의 기업 네트워크 보안의 이해
1. SSL/TLS 인증서의 기본 원리1.1 인증서의 개념과 역할SSL/TLS 인증서는 웹사이트나 서버의 신원을 디지털 방식으로 증명하는 전자 문서입니다.인증서는 다음과 같은 핵심 역할을 수행합니다.신원
shin-e-dog.tistory.com
'개발 경험 기록 > 안드로이드' 카테고리의 다른 글
Android 개발환경에서 ADB를 이용한 포트 포워딩 설정하기 (0) | 2024.12.30 |
---|---|
안드로이드 무선 디버깅 설정: ADB로 케이블 없이 개발하기 [2024.12.05.목] (1) | 2024.12.05 |