JAVA 스프링 프로젝트를 AWS로 배포하는 과정에서 이메일 전송 오류가 발생했다.
DB 연결까지 잘 되었는데 회원가입, 비밀번호 찾기 등등 메일 전송이 되지 않아서 문제를 찾아 해결했다.
👾 오류메세지 javax.mail.MessagingException
javax mail Could not convert socket to TLS;
메인 원인이 SSLHandshakeException 인것을 확인하고, 구글링한 결과 서버/클라이언트간 사용하려는 SSL/TLS 버전이 맞지 않을 경우 해당 오류가 발생한다는 사실을 알아냈다.
그래서 mailSender 빈 객체를 선언하는 context 파일에서 props 속성코드를 추가했다.
기존코드
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="smtp.gmail.com" />
<property name="port" value="587" />
<property name="username" value="이메일주소" />
<property name="password" value="이메일계정비밀번호" />
<property name="javaMailProperties">
<props>
<prop key="mail.smtp.starttls.enable">true</prop>
<prop key="mail.smtp.auth">true </prop>
<prop key="mail.transport.protocol">smtp</prop>
<prop key="mail.debug">true</prop>
</props>
</property>
</bean>
기존 prop에 ssl 관련 코드를 추가해주었다.
특히, 프로토콜 관련 예외처리를 해주기위해 TLS 버전을 지정해서 해당 오류를 해결했다.
추가 코드
<prop key="mail.smtp.ssl.trust">smtp.gmail.com</prop>
<prop key="mail.smtp.ssl.protocols">TLSv1.2</prop>
완성 코드
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="smtp.gmail.com" />
<property name="port" value="587" />
<property name="username" value="이메일주소" />
<property name="password" value="이메일계정비밀번호" />
<property name="javaMailProperties">
<props>
<prop key="mail.smtp.starttls.enable">true</prop>
<prop key="mail.smtp.auth">true </prop>
<prop key="mail.transport.protocol">smtp</prop>
<prop key="mail.debug">true</prop>
<prop key="mail.smtp.ssl.trust">smtp.gmail.com</prop>
<prop key="mail.smtp.ssl.protocols">TLSv1.2</prop>
</props>
</property>
</bean>
여기까지 하고나면 이 다음으로 권한관련 오류가 발생할 가능성이 있다.
javax.mail.AuthenticationFailedException
이 경우, 지메일 계정에서 보안 부분을 해결하면 된다.
권한 관련 오류 해결 방법은 해당 티스토리 내용을 참고했다.
https://greensul.tistory.com/31
변경된 내용을 저장하고, 다시 war 파일로 만들어 우분투를 통해 서버에 배포했더니 이메일이 성공적으로 전송됐다.
생각보다 간단하게 해결되었지만, 난 원인이 궁금하다!!
근본 원인을 파악해보자
tls version을 지정해주면 왜 오류가 해결되는 건지 생각해보기 (tls는 ssl의 구버전임)
브라우저의 tls or ssl 버전과 tomcat server의 tls ssl 버전이 맞지 않아서?
초기 SSL Protocol 을 기반으로 개발된 TLS 는 클라이언트-서버 간의 통신 채널을 보호하고 암호화 하기 위해 사용되는 암호화 프로토콜이다.
메일 전송에 사용되는 프로토콜을 TLSv1.2 로 지정해 준 뒤 해결되는 것으로 보아 기본적으로 지정되는 TLS 버전이 기존 지원이 중단된 TLS 버전 1.0 이나 1.1으로 사용되는 예외가 있어서 발생하는 문제로 파악했다. 구 버전인 TLS 1.0, 1.1 은 POODLE 과 BEAST 와 같은 여러 공격에 취약한 이유로 2020년 이후부터 주요 브라우저에서는 지원을 중단하였기 때문이다.
* TLS 1.2 를 지원하기 위해서는 JDK 1.7 이상이 필요하다
참고 :
How to determine if a browser is using an SSL or TLS connection?
javamail-could-not-convert-socket-to-tls-gmail
'디버깅∕오류해결' 카테고리의 다른 글
[SQL script] Unterminated dollar quote $$ 오류 스프링 설정으로 해결하기 (0) | 2021.09.14 |
---|---|
[Spring Boot] org.springframework.beans.factory.BeanCreationException (2) | 2021.09.03 |
[Spring Boot] To display the conditions report re-run your application with 'debug' enabled (0) | 2021.09.02 |
[JUnit 5] org.junit.platform.launcher.core.EngineDiscoveryOrchestrator (0) | 2021.09.02 |
[Oracle] BadSql / ORA-01427 (0) | 2021.02.27 |