Java JDK 8 버전 업데이트간 TLS 버전으로 인한 발송 실패 이슈 회고

겔로그·2023년 8월 12일
0

이번 글은 회사 업무중 발생한 이슈 상황에 대해 공유해보고자 합니다. 

문제 상황

저는 현재 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: 구체적인 이슈 파악 완료 후 공유 

원인 파악

원인 파악에 있어 고려했던 요소들은 다음과 같습니다.

1. 서비스 배포간 큰 변경 사항이 있었는가?

큰 특이사항은 두 가지가 있었습니다.

  • jdk 버전이 openjdk 8u242b08에서 openjdk 8u362b09 버전으로 업데이트 되었습니다.
  • NettyServer를 그대로 사용할 경우 서비스 내부적으로 사소한 이슈가 있어 클래스를 상속받아 일부 로직을 추가 구현했습니다.

2. 서비스 전체가 실패하는가?

배포 후 특이했던 부분은 서비스 운영간 TLS 버전을 명시하지 않을 경우 실패한다는 점이었습니다. TLS 버전을 명시하면 정상 발송이 됐었기에 서비스를 롤백하지 않아도 됐었다는 점은 아쉬운 대응으로 남아 아래 회고에 추가로 작성했습니다.

장애 원인이 있을만한 지점으로는 크게 두 가지였으나 CustomNettyServer의 경우 상속만 받았을 뿐 큰 개선사항이 없었기에 해당 장애를 유발시킬 수 없다는 판단이 되어 jdk 버전간 변경사항을 확인하게 되었습니다.

8u242b08에서 8u362b09 개선사항

생각보다 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이 포함될 경우 요청을 거부합니다.
  • TLS1.3이 Client default TLS 버전이 되었습니다.

그렇다면 에러 케이스는 어떻게 발생한 것일지 확인이 필요했습니다. 개선사항을 확인했을 경우 TLS1.0 TLS1.1로 통신을 했거나, TLS 세션 재개 시나리오에서 TLSv1을 사용했을 확률이 높아졌습니다.

추가로 관련 내용을 확인해보니 다음 이슈 두가지로 원인이 확실해졌습니다.

FE-7294 Update JavaMail library from 1.4 to 1.6 in order to support TLS 1.2 - Create and track feature requests for Atlassian

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이기에 이슈가 없을 것으로 확인됩니다.

해결 방안은 다음과 같습니다.

  • 라이브러리 별 Default TLS 버전을 확인하고 default가 TLSv1.0, TLSv.1.1일 경우 버전을 명시해 사용한다.
    • props.put("mail.smtp.ssl.protocols", "TLSv1.2");
  • jdk 버전을 낮춘 상태로 유지한다.

회고

쉬운 내용에도 불구하고 원인 파악에 오래걸린 이유는 다음과 같습니다.

  • 4월 25일에 롤백 -> 재배포간 고객사에서 정상 발송이 된다고 답변받음 (서비스에 이슈가 없다고 파악해 원인 파악에 있어 하루 지연)
  • Email SMTP 코드 내에서 자체적으로 통신 테스트를 재현해봤으나, 정상적인 통신이 되어 문제 상황 파악 불가능
    • jakarta 1.6.5와 java-mail 1.4.7을 사용할 경우 기본으로 jakarta 1.6.5이 사용되는데  jakarta 1.6.5는 TLS 1.2을 사용하고 있어 문제상황 재현이 불가능
    • 인지후 새 프로젝트를 만들어 재현
profile
Gelog 나쁜 것만 드려요~

0개의 댓글