안녕하세요.
이번에는 WKWebView로 특정 URL을 출력하는 상황에서 아래와 같은 에러가 발생할 때 쉽게 해결할 수 있는 터미널 명령어를 하나 소개해볼까 합니다.
Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made.
## nscurl을 씁시다
보통 저 에러가 나면 Info.plist > ATS > Allow Arbirarty Loads를 true로 설정하라고 합니다.
대부분 그걸로 해결이 되긴 하는데, Allow Arbirarty Loads 설정은 모든 웹사이트에 대한 보안성을 자체적으로 떨어뜨리는 설정이기 때문에 좀 속상하긴 하죠..
이럴 때 터미널에서 nscurl 명령어를 사용하면 특정 URL에 대한 ATS 관련 정보를 볼 수 있어요.
터미널에 아래 명령어를 입력해 주면 됩니다.
$ nscurl --ats-diagnostics --verbose https://example.com
## 예시
https://www.tistory.com 을 예로 들어볼게요.
터미널에 아래 명령어를 입력하면
$ nscurl --ats-diagnostics --verbose https://www.tistory.com
이런 로그가 나와요.
Starting ATS Diagnostics | |
Configuring ATS Info.plist keys and displaying the result of HTTPS loads to https://www.tistory.com/. | |
A test will "PASS" if URLSession:task:didCompleteWithError: returns a nil error. | |
================================================================================ | |
Default ATS Secure Connection | |
--- | |
ATS Default Connection | |
ATS Dictionary: | |
{ | |
} | |
Result : PASS | |
--- | |
================================================================================ | |
Allowing Arbitrary Loads | |
--- | |
Allow All Loads | |
ATS Dictionary: | |
{ | |
NSAllowsArbitraryLoads = true; | |
} | |
Result : PASS | |
--- | |
================================================================================ | |
Configuring TLS exceptions for www.tistory.com | |
--- | |
TLSv1.3 | |
ATS Dictionary: | |
{ | |
NSExceptionDomains = { | |
"www.tistory.com" = { | |
NSExceptionMinimumTLSVersion = "TLSv1.3"; | |
}; | |
}; | |
} | |
Result : FAIL | |
Error : Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSErrorFailingURLStringKey=https://www.tistory.com/, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <02DCCE22-5FC1-4FD9-BBF3-345684ADB20E>.<1>, _NSURLErrorRelatedURLSessionTaskErrorKey=( | |
"LocalDataTask <02DCCE22-5FC1-4FD9-BBF3-345684ADB20E>.<1>" | |
), NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=https://www.tistory.com/, NSUnderlyingError=0x6000036b90e0 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, _kCFNetworkCFStreamSSLErrorOriginalValue=-9836, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9836, _NSURLErrorNWPathKey=satisfied (Path is satisfied), viable, interface: en0[802.11], ipv4, dns}}, _kCFStreamErrorCodeKey=-9836} | |
--- | |
--- | |
TLSv1.2 | |
ATS Dictionary: | |
{ | |
NSExceptionDomains = { | |
"www.tistory.com" = { | |
NSExceptionMinimumTLSVersion = "TLSv1.2"; | |
}; | |
}; | |
} | |
Result : PASS | |
--- | |
--- | |
TLSv1.1 | |
ATS Dictionary: | |
{ | |
NSExceptionDomains = { | |
"www.tistory.com" = { | |
NSExceptionMinimumTLSVersion = "TLSv1.1"; | |
}; | |
}; | |
} | |
Result : PASS | |
--- | |
--- | |
TLSv1.0 | |
ATS Dictionary: | |
{ | |
NSExceptionDomains = { | |
"www.tistory.com" = { | |
NSExceptionMinimumTLSVersion = "TLSv1.0"; | |
}; | |
}; | |
} | |
Result : PASS | |
--- | |
================================================================================ | |
Configuring PFS exceptions for www.tistory.com | |
--- | |
Disabling Perfect Forward Secrecy | |
ATS Dictionary: | |
{ | |
NSExceptionDomains = { | |
"www.tistory.com" = { | |
NSExceptionRequiresForwardSecrecy = false; | |
}; | |
}; | |
} | |
Result : PASS | |
--- | |
================================================================================ | |
Configuring PFS exceptions and allowing insecure HTTP for www.tistory.com | |
--- | |
Disabling Perfect Forward Secrecy and Allowing Insecure HTTP | |
ATS Dictionary: | |
{ | |
NSExceptionDomains = { | |
"www.tistory.com" = { | |
NSExceptionAllowsInsecureHTTPLoads = true; | |
NSExceptionRequiresForwardSecrecy = false; | |
}; | |
}; | |
} | |
Result : PASS | |
--- | |
================================================================================ | |
Configuring TLS exceptions with PFS disabled for www.tistory.com | |
--- | |
TLSv1.3 with PFS disabled | |
ATS Dictionary: | |
{ | |
NSExceptionDomains = { | |
"www.tistory.com" = { | |
NSExceptionMinimumTLSVersion = "TLSv1.3"; | |
NSExceptionRequiresForwardSecrecy = false; | |
}; | |
}; | |
} | |
Result : FAIL | |
Error : Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSErrorFailingURLStringKey=https://www.tistory.com/, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <B8C72313-3B35-4ECF-AB6F-97AB89B66E6E>.<1>, _NSURLErrorRelatedURLSessionTaskErrorKey=( | |
"LocalDataTask <B8C72313-3B35-4ECF-AB6F-97AB89B66E6E>.<1>" | |
), NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=https://www.tistory.com/, NSUnderlyingError=0x6000036826a0 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, _kCFNetworkCFStreamSSLErrorOriginalValue=-9836, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9836, _NSURLErrorNWPathKey=satisfied (Path is satisfied), viable, interface: en0[802.11], ipv4, dns}}, _kCFStreamErrorCodeKey=-9836} | |
--- | |
--- | |
TLSv1.2 with PFS disabled | |
ATS Dictionary: | |
{ | |
NSExceptionDomains = { | |
"www.tistory.com" = { | |
NSExceptionMinimumTLSVersion = "TLSv1.2"; | |
NSExceptionRequiresForwardSecrecy = false; | |
}; | |
}; | |
} | |
Result : PASS | |
--- | |
--- | |
TLSv1.1 with PFS disabled | |
ATS Dictionary: | |
{ | |
NSExceptionDomains = { | |
"www.tistory.com" = { | |
NSExceptionMinimumTLSVersion = "TLSv1.1"; | |
NSExceptionRequiresForwardSecrecy = false; | |
}; | |
}; | |
} | |
Result : PASS | |
--- | |
--- | |
TLSv1.0 with PFS disabled | |
ATS Dictionary: | |
{ | |
NSExceptionDomains = { | |
"www.tistory.com" = { | |
NSExceptionMinimumTLSVersion = "TLSv1.0"; | |
NSExceptionRequiresForwardSecrecy = false; | |
}; | |
}; | |
} | |
Result : PASS | |
--- | |
================================================================================ | |
Configuring TLS exceptions with PFS disabled and insecure HTTP allowed for www.tistory.com | |
--- | |
TLSv1.3 with PFS disabled and insecure HTTP allowed | |
ATS Dictionary: | |
{ | |
NSExceptionDomains = { | |
"www.tistory.com" = { | |
NSExceptionAllowsInsecureHTTPLoads = true; | |
NSExceptionMinimumTLSVersion = "TLSv1.3"; | |
NSExceptionRequiresForwardSecrecy = false; | |
}; | |
}; | |
} | |
Result : FAIL | |
Error : Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSErrorFailingURLStringKey=https://www.tistory.com/, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <FDB40684-E932-4EF2-98D7-4D8248CC4634>.<1>, _NSURLErrorRelatedURLSessionTaskErrorKey=( | |
"LocalDataTask <FDB40684-E932-4EF2-98D7-4D8248CC4634>.<1>" | |
), NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=https://www.tistory.com/, NSUnderlyingError=0x600003685cb0 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, _kCFNetworkCFStreamSSLErrorOriginalValue=-9836, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9836, _NSURLErrorNWPathKey=satisfied (Path is satisfied), viable, interface: en0[802.11], ipv4, dns}}, _kCFStreamErrorCodeKey=-9836} | |
--- | |
--- | |
TLSv1.2 with PFS disabled and insecure HTTP allowed | |
ATS Dictionary: | |
{ | |
NSExceptionDomains = { | |
"www.tistory.com" = { | |
NSExceptionAllowsInsecureHTTPLoads = true; | |
NSExceptionMinimumTLSVersion = "TLSv1.2"; | |
NSExceptionRequiresForwardSecrecy = false; | |
}; | |
}; | |
} | |
Result : PASS | |
--- | |
--- | |
TLSv1.1 with PFS disabled and insecure HTTP allowed | |
ATS Dictionary: | |
{ | |
NSExceptionDomains = { | |
"www.tistory.com" = { | |
NSExceptionAllowsInsecureHTTPLoads = true; | |
NSExceptionMinimumTLSVersion = "TLSv1.1"; | |
NSExceptionRequiresForwardSecrecy = false; | |
}; | |
}; | |
} | |
Result : PASS | |
--- | |
--- | |
TLSv1.0 with PFS disabled and insecure HTTP allowed | |
ATS Dictionary: | |
{ | |
NSExceptionDomains = { | |
"www.tistory.com" = { | |
NSExceptionAllowsInsecureHTTPLoads = true; | |
NSExceptionMinimumTLSVersion = "TLSv1.0"; | |
NSExceptionRequiresForwardSecrecy = false; | |
}; | |
}; | |
} | |
Result : PASS | |
--- | |
================================================================================ |
로그를 잘 살펴보면, TSL exception 쪽에 눈에 띄는 로그가 있습니다.

이 정보를 토대로 추리해 보면 'https://www.tistory.com 은 TLS 1.3을 지원하지 않고 Minimum TLS Version을 1.3으로 설정했을 경우 NSURLErrorDomain Code=-1200 에러가 발생하는구나!' 라는 사실을 알 수 있어요.
이런 식으로 SSL 에러가 발생했을 때 nscurl 명령어를 사용하면 원인을 파악하는데 큰 도움이 되고, 더 나아가서 Info.plist > ATS > Exception Domains 쪽에 꼭 필요한 설정만 해줄 수 있겠죠?? 😁
## 참고
Apple Developer Documentation
developer.apple.com
이번 글은 여기서 마무리.
'TroubleShooting' 카테고리의 다른 글
[SwiftUI] iOS 15 이하에서 navigationBarHidden이 동작하지 않는 이슈 (0) | 2023.04.11 |
---|---|
[CocoaPods] [!] An unexpected error occurred: <!DOCTYPE html> (0) | 2023.03.23 |
[iOS] Unsupported Swift architecture 해결방법 (2) | 2023.02.11 |
[Xcode 14] Asset validation failed 해결방법 (0) | 2022.12.31 |
[SwiftUI] '__designTimeInteger(_:fallback:)' is only available in iOS 13.0 or newer 에러 해결방법 (0) | 2022.11.05 |