관리 메뉴

피터의 개발이야기

[MySQL] MySQL과 Java의 SSL 연결 방법 본문

Database/MySQL

[MySQL] MySQL과 Java의 SSL 연결 방법

기록하는 백앤드개발자 2024. 6. 17. 10:10
반응형

ㅁ 들어가며

ㅇ DBA인 동료와 MySQL의 SSL 통신 방법에 대해서 이야기 나누면서 공부한 내용이다.

ㅇ MySQL 문서와 AWS 문서를 보며 공부하였다.

 

 MySQL에서 TLS 연결은 어떻게 설명하는가?

ㅁ MySQL 참조 문서 링크

8.3 Using Encrypted Connections
 8.3.1 Configuring MySQL to Use Encrypted Connections
 8.3.2 Encrypted Connection TLS Protocols and Ciphers
 8.3.3 Creating SSL and RSA Certificates and Keys
 8.3.4 Connecting to MySQL Remotely from Windows with SSH
 8.3.5 Reusing SSL Sessions

ㅁ MySQL SSL 연결 방법

ㅇ MySQL을 IP 또는 도메인 이름을 통해 연결하는 경우 SSL/TLS를 사용하여 연결을 암호화하는 것이 중요하다.

ㅇ 이는 데이터 해킹으로부터 사용자 인증 정보와 데이터를 보호할 수 있다.

ㅁ  기본 필수 조건

ㅇ MySQL 서버가 설치 및 실행되고 있어야 한다.

ㅇ SSL 인증서가 있어야 하며, 인증서는 자체적으로 생성하거나 인증 기관(CA)에서 구매할 수 있다.

ㅇ MySQL 클라이언트가 설치되어 있어야 한다.

ㅁ MySQL SSL 구성 방법

1. MySQL 서버에서 SSL을 구성한다.

ㄴ SSL 인증서 및 개인 키를 적절한 위치에 저장

ㄴ MySQL 설정 파일 (보통 /etc/my.cnf)을 편집하고 다음 설정을 추가한다.

[ssl]
ca-file=/path/to/your/ca-cert.pem
certfile=/path/to/your/server-cert.pem
keyfile=/path/to/your/server-key.pem

ㄴ MySQL 서버를 다시 시작

 

2. IP 주소 또는 DNS를 사용하여 SSL 연결한다.

# IP
$ mysql -h <your_mysql_server_ip_address> -u <username> -p -ssl
# DNS
$ mysql -h <your_mysql_server_domain_name> -u <username> -p -ssl

 

ㅇ SSL 연결을 사용할 때는 -ssl 옵션을 MySQL 클라이언트에 항상 지정해야 한다.

ㅇ MySQL 8.0부터는 기본적으로 SSL 연결이 사용 가능하도록 설정되어 있다.

 

 mysql connector 버전별 SSL 버전에 대해서 알아보자.

ㅁ mysql connector 버전별 SSL 버전

- Since Connector/J 8.0.28, the connection property enabledTLSProtocols has been renamed to tlsVersions, and enabledSSLCipherSuites has been renamed to tlsCiphersuites; the original names remain as aliases.

- For Connector/J 8.0.26 and later: TLSv1 and TLSv1.1 were deprecated in Connector/J 8.0.26 and removed in release 8.0.28; the removed values are considered invalid for use with connection options and session settings. Connections can be made using the more-secure TLSv1.2 and TLSv1.3 protocols. Using TLSv1.3 requires that the server be compiled with OpenSSL 1.1.1 or higher and Connector/J be run with a JVM that supports TLSv1.3 (for example, Oracle Java 8u261 and above).

- For Connector/J 8.0.18 and earlier when connecting to MySQLCommunity Server 5.6 and 5.7 using the JDBC API: Due to compatibility issues with MySQL Server compiled with yaSSL, Connector/J does not enable connections with TLSv1.2 and higher by default. When connecting to servers that restrict connections to use those higher TLS versions, enable them explicitly by setting the Connector/J connection property enabledTLSProtocols (e.g., set enabledTLSProtocols=TLSv1.2,TLSv1.3).

 

ㅇ 속성 이름 변경 (Connector/J 8.0.28부터)

- enabledTLSProtocols -> tlsVersions

- enabledSSLCipherSuites -> tlsCiphersuites

- 이전 이름은 여전히 별칭으로 사용 가능하다.

 

 지원되는 TLS 버전 변화

  • Connector/J 8.0.26 이후
    • TLSv1과 TLSv1.1은 더 이상 안전하지 않아 사용하지 않는 것이 좋다. (8.0.28에서 완전히 제거)
    • 보다 안전한 TLSv1.2 및 TLSv1.3 사용을 권장다.
    • TLSv1.3은 다음 조건에서만 사용 가능:
      • MySQL 서버: OpenSSL 1.1.1 이상 컴파일
      • Connector/J: TLSv1.3 지원하는 JVM (예: Oracle Java 8u261 이상)
  • Connector/J 8.0.18 이전 (MySQL 5.6/5.7 연결)
    • yaSSL 라이브러리와의 호환성 문제로 기본적으로 TLSv1.2 이상 연결 사용 안 함.
    • TLSv1.2 이상 연결을 요구하는 서버에 연결하려면 enabledTLSProtocols 속성을 명시적으로 설정해야 한다. (예: enabledTLSProtocols=TLSv1.2,TLSv1.3)

 

AWS AutoraDB는 TLS 인증서를 어떻게 연결하는가?

ㅁ AWS AuroraDB와 TLS 인증서 연결방법(aws doc)

ㅇ 2023년 1월 13일부터 Amazon RDS는 전송 계층 보안(TLS)을 사용하여 Aurora DB 클러스터에 연결하기 위한 용도의 새 인증 기관(CA) 인증서를 게시하였다.

 

ㅇ 애플리케이션 trustStore 업데이트

// JAVA 설정
System.setProperty("javax.net.ssl.trustStore", certs);
System.setProperty("javax.net.ssl.trustStorePassword", "password");

// JAVA 구동 시
java -Djavax.net.ssl.trustStore=/path_to_truststore/MyTruststore.jks \
  -Djavax.net.ssl.trustStorePassword=my_truststore_password \
  com.companyName.MyApplication

 

ㅇ TLS 연결 설정을 위한 Java 코드 예제

public class MySQLSSLTest {

        private static final String DB_USER = "user name";
        private static final String DB_PASSWORD = "password";
        // This key store has only the prod root ca.
        private static final String KEY_STORE_FILE_PATH = "file-path-to-keystore";
        private static final String KEY_STORE_PASS = "keystore-password";

    public static void test(String[] args) throws Exception {
        Class.forName("com.mysql.jdbc.Driver");


        System.setProperty("javax.net.ssl.trustStore", KEY_STORE_FILE_PATH);
        System.setProperty("javax.net.ssl.trustStorePassword", KEY_STORE_PASS);

        Properties properties = new Properties();
        properties.setProperty("sslMode", "VERIFY_IDENTITY");
        properties.put("user", DB_USER);
        properties.put("password", DB_PASSWORD);

        Connection connection = DriverManager.getConnection("jdbc:mysql://jagdeeps-ssl-test.cni62e2e7kwh.us-east-1.rds.amazonaws.com:3306",properties);
        Statement stmt=connection.createStatement();

        ResultSet rs=stmt.executeQuery("SELECT 1 from dual");

        return;
    }
}
 
공인 CA 인증서를 사용한 Java 클라이언트 연결 방법은?

ㅁ 공인 CA 인증서를 사용한 Java 클라이언트 연결 방법

공인 CA(Certification Authority) 인증서를 사용하여 Java 클라이언트에서 서버에 안전하게 연결하려면 다음 단계를 수행해야 한다.

 

필수 조건

ㅇ Java Development Kit (JDK)가 설치되어 있어야 한다.

ㅇ 공인 CA 인증서

 ㄴ 서버 인증을 위해 신뢰할 수 있는 인증기관(CA)에서 발급한 인증서가 필요하다.

ㅇ Java 트러스트스토어

 ㄴ CA 인증서를 포함하는 Java 트러스트스토어가 설정되어 있어야 한다.

 ㄴ 기본 트러스트스토어는 JDK 설치 디렉토리의 cacerts 파일이다.

 

ㅁ 설정방법

ㅇ CA 인증서 가져오기

 - 웹 브라우저에서 서버 인증서를 DER 형식으로 다운로드한다.

 - keytool 명령을 사용하여 인증서를 Java 트러스트스토어에 추가한다.

keytool -import -alias <인증서 별칭> -file <인증서 파일 경로> -keystore <트러스트스토어 파일 경로>
#예시
keytool -import -alias my_ca_cert -file cacert.der -keystore /path/to/cacerts

 

ㅇ Java 클라이언트 코드 업데이트

 다음과 같은 코드를 사용하여 SSL/TLS 연결을 설정한다.

 
import javax.net.ssl.*;

// ... (라이브러리 및 클래스 import)

SSLContext sslContext = SSLContext.getInstance("TLS");
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509");
KeyStore trustStore = KeyStore.getInstance("JKS");
trustStore.load(new FileInputStream("/path/to/cacerts"), "password");
trustManagerFactory.init(trustStore);
X509TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
sslContext.init(null, trustManagers, null);
SSLSocketFactory socketFactory = sslContext.getSocketFactory();

// ... (소켓 생성 및 연결 코드)

 

ㅇ 참고

 - keytool 명령은 JDK bin 디렉토리에서 사용할 수 있다.

 - trustStore 파일의 기본 비밀번호는 "changeit"이라, 보안을 위해 변경하는 것이 좋다.

 

ㅁ 함께 보면 좋은 사이트

ㅇ  MySQL Doc - 8.3 Using Encrypted Connections

 AWS DOC - TLS 인증서를 이용한 Aurora MySQL DB와 애플리케이션 방법

 MySQL Connector SSL 접속 오류 해결 회고

반응형
Comments