성장일지 3기 2차

이태형·2025년 3월 29일

Growth Log

목록 보기
14/18

Azure Resource Manage API 를 호출하는 도중에 발생한 에러를 기록하기로 했다.
회사에서 Azure API 를 활용하여 VM 을 생성하고 배포하는 기능을 제공하고 있는데, Java 8 을 사용하던 도중에 Java 11 로 변경하면서
처음에는 통신이 잘 되다가 하루 이상 지나고나면 소켓이 끊겨버리는 이슈가 발생했다.

그래서 일단은 Java 8 과 Java 11 에서 통신 부분에서 변경된 사항을 찾아봤다.
여러 변경 사항이 있었지만, 그 중 가장 의심이 된 부분은 TLS 버전이다.

Java 8 은 기본적으로 TLS1.2 까지 지원을 하지만, Java 11 이 TLS1.2 과 TLS1.3 을 지원하는데 11은 기본적으로 TLS1.3 을 사용한다.
현재 발생한 에러 로그를 분석해 봤는데, 일정 시간 후에 handshake를 재진행 하는데, 이때 기존 정보를 찾을 수가 없어서 연결이 끊기고 있었다.
그럼 TLS1.2 와 TLS1.3 이 어떻게 다르길래 기존 정보를 찾지 못하는 걸까??

TLS1.2 는 세션 ID 방식을 사용한다. 처음 연결이 될 때, SessionID 를 공유하고 이후 동일한 클라이언트가 다시 연결하면 Session ID 를 전송해서 기존 세션을 재사용한다. (세션 로그인과 동일한 방식)
서버에서 세션 ID 를 저장해서 사용하기 때문에, 동일한 세션 ID를 가진 클라이언트가 들어오면 기존 세션을 재사용하는 방식이다.

TLS1.3 은 Session Ticket 방식을 사용하는데, 서버가 세션 정보를 암호화해서 전달해주면 클라이언트가 저장한다. (jwt 토큰과 유사한 방식)
그래서 클라이언트가 요청시 Session Ticket 을 같이 전달하면 기존 세션 정보를 복원해서 재연결하는 방식이다.

예상으로는 현재 AzurePortal 은 TLS1.2 방식을 사용하는 것으로 보여진다.
이유는 이전엔 Java8 에서 Socket 재연결 이슈가 없었기 때문... Java 11 로 변경하자마자 Socket 재연결 이슈가 발생.. Java 11은 기본적으로 TLS1.3 을 사용..

우선 해당 원인을 찾기 위해서 Application 실행 시에 argument 를 추가했다

프로퍼티 추가

logging.level.org.springframework=DEBUG
logging.level.org.apache.tomcat.util.net=DEBUG
logging.level.org.apache.coyote.http11.Http11NioProtocol=DEBUG

Jvm 실행 옵션 추가

-Djavax.net.debug=ssl,handshake

둘 중 아무거나 추가를 해서 이슈 재현 후, 원인 파악 -> 이때 에러 로그로 handshake fail 어쩌구 ticket 어쩌구가 발생

그럼 이제 이 현상을 해결하기 위해서 방법을 찾아봤다.

1. SSL 연결 시 신뢰 무시

사실 이 에러는 Azure Portal 에서 거부하는 것이 아니라, Java 에서 재연결 요청을 보낼때 실패해서 발생하는 에러다.
그래서 두가지 방법으로 하나는 ssl 연결을 할때 Java는 해당 인증서에 대해서 신뢰성 검토를 하는데, 이때 이것을 무시하는 방법이다. (실 운영에선 완전 비추천)
보안상으로 추천하지는 않지만, 내부적으로 통신하는 서버가 ssl로만 가능한 환경이고, 외부 접근이 완전히 차단된 환경이라면 크게 상관이 없을 것 같다.
코드는 구글에 많아서 생략

2. TLS1.2 로 고정

두 번째는 JVM 실행 옵션에 -Dhttps.protocols=TLSv1.2 로 TLS1.2로 고정시키는 방법이 있다.
현재 프로젝트에는 이걸로 적용

이렇게 에러가 발생했던 원인 파악 및 수정 했던 내용을 정리했다.

0개의 댓글