본문 바로가기

TIL

[TIL] ATS에 대하여

경험한 이슈

앱 출시를 위한 공공데이터포털 API 연결 중 아래와 같은 오류 문구를 만나게 되었습니다.

아래 오류 내용을 살펴보면 SSL 에러가 발생했고, 서버에 안전한 연결을 할 수 없다고 나와있는데요.

API는 단순히 연결만 하면되지! 라고만 생각했었던 저는 뜻하지 않은 오류를 만나게 되어 약간 당황했었습니다.

하!지!만! 또 이 처음 만난 오류에 대해 포스팅을 해보는 것도 괜찮겠다 싶어 블로그에 포스팅을 남기게 되었습니다.

sessionTaskFailed(error: Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made."

ATS란?

갑작스런 주제에 이게 뭐지? 싶으실 수도 있습니다. 왜냐면 제가 그랬거든요 ㅎㅎ

위 오류 내용을 구글에 검색해보면 공통적으로 ATS란 단어가 등장합니다.

 

그래서 이 ATS라는게 무엇이냐!!

그건 바로 ATS가 어떤 말에 줄임말인지 알면 쉽게 유추할 수 있습니다.

ATS는 App Transposrt Security의 약자로, 앱과 앱 외부에 있는 네트워크 간 안전한 연결을 보장하기 위해 사용되는 애플 플랫폼 안의 특성(feature)을 의미합니다.

그리고 ATS는 신뢰할 수 있는 인증서와 암호를 사용하는 TLS(Transport Layer Secruity) 프로토콜로 앱에서 이루어진 네트워크 연결을 보호하도록 요구함으로써 수행됩니다.

정리하자면, ATS는 TLS 기반의 네트워크의 안전한 연결을 위해 애플 플랫폼 내부적으로 수행하는 어떤 동작을 의미하는 것 같습니다.

 

 

에러 발생 원인 

위와 같은 ATS의 존재 이유를 살펴본다면 에러가 발생했던 이유는 해당 공공데이터포털 API가 애플 플랫폼과 네트워크 연결함에 있어 어떤한 조건을 충족시키지 못하여  발생하였다는 사실을 알 수 있었습니다.

 

ATS 진단방법

원인을 파악했으니 진단방법에 대해 알아볼까요?

 

애플 공식 문서를 살펴보니 터미널에서 아래 명령어를 입력하면 해당하는 URL의 도메인이 ATS에 대해 진단해볼 수 있다고 합니다.

$ /usr/bin/nscurl --ats-diagnostics --verbose https://example.com

 

가장 기본적인 ATS 진단인데 처음 진단부터 실패했네요..

 

오!! 처음으로 패스된 진단이네요!

 

음... 진단항목을 보아하니 TLS 최소 버전에 대한 진단인 것 같은데 모두 실패했네요

 

Perfect Foward Secrecy? 무슨진단일까요? 아무튼 진단이 통과되었네요.

 

이 이후에는 모두 Perfect Forward Secrecy에 대한 내용으로 아래 사진의 경우(TLS 최소단위 1.3에 대한 진단)을 제외하고 모두 통과되었습니다.

 

그렇다면 여기서 솓구치는 궁금증!! Perfect Forward Secrecy란 무엇일까요?

 

Perfect Forward Secrecy

Perfect Forward Secrecy를 설명하기 앞서 ECDHE란 알고리즘에 관해 간단히 설명해야할 것 같습니다

ECDHE 알고리즘이란 Handshaking 중 암호화 키를 교환하는 알고리즘을 의미합니다.

이 알고리즘에 대해 설명하는 이유는 ATS 최소 진단 기준을 보면 ECDHE 알고리즘을 기반으로 한 키교환을 기준으로 삼기 때문입니다.

더구나 ECDHE 알고리즘은 이제부터 설명할 Perfect Forward Secrecy에 대한 특징을 포함하고 있습니다.

 

자 이제 기다리고 기다리던 Perfect Forward Secrecy에 대해 살펴보겠습니다.

Perfect Forward ScrecySSL/TLS 통신 중 어떠한 경로로 비밀키가 누출되어 모든 암호화된 패킷이 누출될 경우를 대비하여 클라이언트와 서버만 알고 있는 세션키를 매우 짧은 주기로 지속적으로 변경하여 공격자가 과적 통신되었던 SSL/TLS 통신들에 대해 보호하는 특성을 말합니다.

 

해결방법

이제 원인에 대해 파악해 보았으니 해결방법에 대해 알아보겠습니다.

 

ATS 진단에서 알 수 있듯이 PFS(Perfect Forward Secrecy)에 관련하여 무언가 설정을 해주면 연결문제는 해결될 것 같습니다.

이는 info.plist에서 설정할 수 있다고 공식 문서에 나와있습니다.

 

공식 문서를 살펴보시면 info.plist에서 설정해줄 수 있는 key들은 다음과 같습니다.

NSAppTransportSecurity : Dictionary {
    NSAllowsArbitraryLoads : Boolean
    NSAllowsArbitraryLoadsForMedia : Boolean
    NSAllowsArbitraryLoadsInWebContent : Boolean
    NSAllowsLocalNetworking : Boolean
    NSExceptionDomains : Dictionary {
        <domain-name-string> : Dictionary {
            NSIncludesSubdomains : Boolean
            NSExceptionAllowsInsecureHTTPLoads : Boolean
            NSExceptionMinimumTLSVersion : String
            NSExceptionRequiresForwardSecrecy : Boolean
            NSRequiresCertificateTransparency : Boolean
        }
    }
}

 

각 항목에 대해 하나씩 살펴보면 아래와 같습니다.

NSAppTransportSecurity 는 ATS의 전반적인 설정에 대한 key입니다.

NSAllowsArbitraryLoads 는 모든 네트워크 연결에 대해 ATS 설정을 해줄지 말지에 대한 key입니다.

NSAllowsArbitraryLoadsForMedia 는 AV Foundation 프레임워크를 사용한 요청들에 관해 ATS 설정을 해줄지 말지에 대한 key입니다.

NSAllowsArbitraryLoadsInWebContent 는 웹 뷰에 관한 ATS 설정을 해줄지 말지에 대한 것입니다.

NSAllowsLocalNetworking .local 도메인들이나 IP 주소(IPv4 혹은 IPv6)에 대한 자원(resources) 로드에 대한 key입니다.

NSExceptionDomains 는 이름있는 특정 도메인들에 대한 커스텀 ATS 환경구성입니다.

<domain-name-string> 는 특정 도메인이 들어갑니다.

NSIncludesSubdomains 는 설정범위를 서브 도메인까지 확장시킬지에 대한 key입니다.

NSExceptionAllowsInsecureHTTPLoads 는 불안정한 HTTP 연결에 대한 허용 여부를 묻는 key입니다.

NSExceptionMinimumTLSVersion 는 TLS의 최소 버전을 지정해주는 key입니다.

NSExceptionRequiresForwardSecrecy 는 PFS(Perfect Forward Secrecy) 과정을 중단할지에 대한 key 입니다.

NSRequiresCertificateTransparency 는 CT(Certificate Transparency) 사용 여부에 대한 key입니다.(애플 공식 문서에 따르면 이 설정은 되도록이면 건들지 말라고 합니다.)

 

ATS 진단 결과를 보면 위 ATS 설정들 중 NSExceptionRequiresForwardSecrecy의 값이 false일 때, 대부분의 진단이 통과되는 것을 알 수 있습니다.

 

따라서 아래 사진처럼 해당 공공데이터 도메인만 따로 예외로 처리해주어 설정해주니 잘 동작하였습니다.

 

참고로 NSAllowsArbitraryLoads 값을 false로 바꾸는 방법도 있는데, 이는 ATS 설정을 전반적으로 끄는 것이기 때문에 보안성 측면에서 그리 좋지 못하여 추천되는 방법은 아니라고 합니다

 

이상 글 읽어주셔서 감사합니다!

참고자료

https://developer.apple.com/documentation/security/preventing_insecure_network_connections

https://developer.apple.com/documentation/security/preventing_insecure_network_connections/identifying_the_source_of_blocked_connections

https://jihwan-study.tistory.com/76

https://funveloper.tistory.com/18

https://m.boostcourse.org/mo326/lecture/20810