이번 글은 회사 업무중 발생한 이슈 상황에 대해 공유해보고자 합니다.
저는 현재 Email 서비스를 담당하여 서비스 개발을 진행하고 있습니다.
문제가 발생한 것은 4월 25일 (화)요일 회사 서비스 정기점검이었습니다. 서비스 개선 사항을 배포한 뒤 고객사로부터 Email SMTP 서비스로 발송이 되지 않는다는 문의를 받게 되었습니다. 주된 문의는 TLS 버전 관련 에러 로그가 발생하며 메일 발송이 실패처리가 된다는 것이었습니다.
4월 25일
06:00: 서비스 배포 시작
09:00: 배포 및 서비스 확인 완료
12:20: 고객사 문의 (Email SMTP 서비스 발송 실패 현상)
12:30: 서비스 롤백 (고객사 재확인시 정상 발송됨을 확인)
13:30: 일부 수정 후 개선 버전으로 배포 (고객사 재확인시 이슈 없다고 답변)
13:40: 이슈 대응 종료4월 26일
13:40: 다른 고객사 문의 (Email SMTP 서비스 발송 실패 현상)
- javax.mail.MessagingException: Could not convert socket to TLS; 메세지 발생
- prop.put("mail.smtp.ssl.protocols", "TLSv1.2"); 버전 명시 후 정상 발송
17:00: 관련 원인 추가 파악 진행 (원인 파악)4월 27일
14:00: 고객사에 실패 발송 코드 및 사용 jdk 버전, 사용중인 mail 라이브러리 공유 요청
15:00: 구체적인 이슈 파악 완료 후 공유
원인 파악에 있어 고려했던 요소들은 다음과 같습니다.
큰 특이사항은 두 가지가 있었습니다.
배포 후 특이했던 부분은 서비스 운영간 TLS 버전을 명시하지 않을 경우 실패한다는 점이었습니다. TLS 버전을 명시하면 정상 발송이 됐었기에 서비스를 롤백하지 않아도 됐었다는 점은 아쉬운 대응으로 남아 아래 회고에 추가로 작성했습니다.
장애 원인이 있을만한 지점으로는 크게 두 가지였으나 CustomNettyServer의 경우 상속만 받았을 뿐 큰 개선사항이 없었기에 해당 장애를 유발시킬 수 없다는 판단이 되어 jdk 버전간 변경사항을 확인하게 되었습니다.
생각보다 jdk 8로 백포트된 업데이트 사행이 몇가지 존재했습니다. 이 중 TLS 관련 개선 사항만을 확인했습니다.
JDK-8257122 Disable TLS 1.0 and 1.1 - Java Bug System
JDK-8270344 Session resumption errors
JDK-8245263 Enable TLSv1.3 by default on JDK 8u for Client roles
세가지 이슈를 토대로 다음과 8u362b09로 버전이 업데이트되며 같은 개선 사항이 있음을 확인했습니다.
그렇다면 에러 케이스는 어떻게 발생한 것일지 확인이 필요했습니다. 개선사항을 확인했을 경우 TLS1.0 TLS1.1로 통신을 했거나, TLS 세션 재개 시나리오에서 TLSv1을 사용했을 확률이 높아졌습니다.
추가로 관련 내용을 확인해보니 다음 이슈 두가지로 원인이 확실해졌습니다.
Could not convert socket to TLS; 문제 해결
현재 jdk 업데이트를 통해 보안성이 낮은 TLSv1.0, TLSv.1.1을 제거했으며 TLSv1.2 또는 TLSv1.3을 사용하는 것을 권장하도록 개선된 것이기에 배포된 버전이 좀 더 보안적으로 향상되어 발생한 이슈였습니다.
문제가 발생한 고객사의 dependency를 확인한 결과 java-mail 1.4.7을 사용하고 있었는데 java-mail 1.4.7은 default TLS 버전으로 TLSv1.0을 사용하고 있습니다. java-mail 1.6 버전부터는 TLSv1.2가 default TLS이기에 이슈가 없을 것으로 확인됩니다.
해결 방안은 다음과 같습니다.
쉬운 내용에도 불구하고 원인 파악에 오래걸린 이유는 다음과 같습니다.