🐬MySQL

MySQL: useSSL의 대안 sslMode

limdaeil 2025. 10. 21. 23:33

질문의 배경

MySQL 데이터베이스 URL을 보면 늘 useSSL이 눈에 띄는데, “SSL = HTTPS처럼 CA 인증서를 두고 통신하는 거 아냐?”라는 의문이 먼저 떠올랐습니다. 정확히 어떤 인증·암호화 매커니즘으로 동작하는지, 그리고 MySQL 8.0 이상에서 이제는 useSSL 대신 사용하는 sslMode 을 올바르게 사용하는 방법을 정리하고 싶었습니다.

 

useSSLsslMode는 데이터베이스 연결 시 SSL/TLS 암호화 방식을 설정하는 데 사용되는 옵션입니다. JDBC URL이나 DataSource 속성에서만 쓰는 연결(세션) 단의 정책입니다. MySQL Connector/J 8.0부터 useSSL은 더이상 권장되지 않는 구식 옵션이며, sslMode가 더 정교하고 안전한 연결을 위해 도입되었습니다.

  • useSSL은 “암호화 쓸까 말까”만 켜는 구식 스위치
  • sslMode암호화 여부 + 검증 강도(=신뢰할 CA인지, 호스트명 일치인지)까지 한 번에 지정하는 현행 표준
  • 운영은 sslMode=VERIFY_IDENTITY 권장. 개발/로컬은 상황에 따라 PREFERRED/REQUIRED로 타협 가능

1. useSSL vs sslMode 비교

구분 useSSL (레거시) sslMode (현행)
목적 TLS 사용 여부만 단순 제어 (true/false) TLS 사용 + 검증 강도까지 정책화
검증 수준 기본적으로 약함: 자체서명도 통과 가능,
호스트명 불일치도 걸러내지 못할 수 있음
DISABLED / PREFERRED / REQUIRED
/ VERIFY_CA / VERIFY_IDENTITY 로 단계적 제어
안전성 의도와 달리 평문으로 붙거나,
암호화라도 검증 미흡으로 MITM 위험
정책에 따라
CA 검증 + 호스트명 검증까지 강제 가능
사용 범위/버전 5.x~초기 8.x에서 흔함(역사적 호환) 8.x에서 권장 표준
연관 옵션 verifyServerCertificate,
requireSSL 등과 조합 필요
단일 옵션으로 정책 완결
권장도 학습/레거시 이해용 실무/운영 기본값

2.구버전 옵션 → sslMode 매핑 표

예전 조합 대략적 의미 sslMode로 대응
useSSL=false 평문 연결 DISABLED
useSSL=true,
requireSSL=false, verifyServerCertificate=false
가능하면 TLS, 검증 느슨 PREFERRED
useSSL=true,
requireSSL=true, verifyServerCertificate=false
TLS 필수, 검증 없음 REQUIRED
useSSL=true,
requireSSL=true, verifyServerCertificate=true + 신뢰 CA
TLS + CA 검증 VERIFY_CA
위 + 호스트명 일치 TLS + CA + 호스트명 VERIFY_IDENTITY

정확한 1:1 치환은 아니지만, 실무 감각상 이렇게 이행하면 안전합니다.

3. sslMode 가이드라인

3.1 환경에 따른 선택

  • 운영: VERIFY_IDENTITY → CA 신뢰 + 호스트명 매칭으로 MITM·오접속을 차단
  • 스테이징(암호화 필요, 검증 미흡): REQUIRED → 암호화는 강제하고, 자체서명/호스트명 미정 상태에서도 동작
  • 개발(간편성 우선): PREFERRED 또는 DISABLED → 빠른 실험/디버깅. 단, 민감 데이터가 오간다면 REQUIRED 권장

3.2 마이그레이션 점검

  1. URL 교체
    • useSSL, verifyServerCertificate, requireSSL 제거 → sslMode=...로 통합합니다.
    • TLS를 쓴다면 allowPublicKeyRetrieval=true 제거(이유는 아래 정리했습니다.)
  2. 서버 인증서 준비
    • RDS/Aurora: 기본 CA 신뢰합니다.
    • 자체 MySQL: ssl_ca, ssl_cert, ssl_key 구성
  3. 호스트명 일치(특히 VERIFY_IDENTITY)
    • 접속 URL의 호스트명 = 인증서 SAN(CN)
    • IP로 붙으면 인증서에 IP SAN 필요합니다.
  4. JVM truststore
    • 공인 CA면 보통은 해당 작업은 불필요합니다.
    • 사내/로컬 CA면 keytool -importcert로 신뢰 추가합니다.
  5. 검증
    • DB에서 SHOW SESSION STATUS LIKE 'Ssl_cipher'; → 값이 있으면 TLS
    • 일부러 잘못된 호스트명으로 붙여 실패 확인합니다. (검증이 실제로 동작하는지)

 

💡TLS 사용하면 allowPublicKeyRetrieval=true 제거하는 이유

allowPublicKeyRetrieval=true 옵션은 MySQL 8.0부터 기본 인증 방식인 caching_sha2_password 때문에 발생하는 문제를 해결하기 위한 임시 방편으로 도입되었습니다. 그러나 allowPublicKeyRetrieval=true 옵션을 사용하면 중간자 공격(Man-in-the-Middle, MITM)에 노출될 위험이 있습니다. 따라서 운영 환경에서 강력한 보안을 유지하려면, TLS 인증서를 통해 안전하게 연결하고, allowPublicKeyRetrieval=true 옵션은 제거하는 것이 올바른 보안 관행입니다.

 

좀 더 깊게 들어가서, TLS를 사용 중일 때 이 옵션을 제거해야 하는 구체적인 이유는 다음과 같습니다.

 

1. 보안 메커니즘의 이중화 및 충돌

caching_sha2_password 인증 방식은 비밀번호 전송 시 암호화를 위해 RSA 공개 키를 사용합니다. 이 때 클라이언트가 서버의 공개 키를 자동으로 요청하도록 허용하는 것이 allowPublicKeyRetrieval=true 옵션입니다. 그러나 TLS는 이미 자체적으로 강력한 암호화 및 인증 메커니즘을 제공합니다.

  • 정상적인 TLS 통신: TLS 핸드셰이크 과정에서 서버는 클라이언트에게 신뢰할 수 있는 기관이 서명한 인증서를 전달합니다. 이 인증서에는 서버의 공개 키가 포함되어 있으며, 클라이언트는 이 공개 키를 사용하여 암호화된 통신을 시작합니다.
  • 이중 메커니즘의 불필요성: 이미 TLS가 암호화된 통신 채널을 안전하게 구축했으므로, 비밀번호를 전송하기 위해 별도로 공개 키를 요청하는 것은 불필요한 과정입니다.

2. 중간자 공격(MITM)의 위험

allowPublicKeyRetrieval=true 옵션이 가장 위험한 상황은 TLS를 사용하지 않으면서( useSSL=false ) 이 옵션을 함께 사용할 때입니다. 하지만 TLS를 사용하더라도 이 옵션은 잠재적인 보안 위험을 내포합니다.

  • 취약점 발생 가능성: 만약 클라이언트와 서버 사이의 TLS 연결이 어떤 이유로든 불안정하거나 깨질 경우, 공격자는 이 옵션을 악용하여 클라이언트가 평문으로 비밀번호를 전송하게 유도할 수 있습니다.
  • 데이터 탈취 가능성: 악의적인 프록시가 중간에 끼어들어 서버인 척하며 공개 키를 가로채고, 클라이언트가 전송하는 평문 비밀번호를 탈취할 수 있습니다.

3. 일관성 있는 보안 유지

운영 환경에서는 항상 일관되고 강력한 보안 설정을 유지해야 합니다.

  • 개발 환경과의 분리: allowPublicKeyRetrieval=true는 주로 로컬 개발 환경에서 편의를 위해 사용되지만, 운영 환경에서는 엄격한 보안을 위해 TLS 인증서를 사용하고, 별도의 공개 키 요청 없이 TLS 핸드셰이크를 통해 안전하게 공개 키를 교환하는 것이 올바른 방법입니다.

4. 결론 및 권장 사항

  • MySQL Connector/J 8.0 이상 버전을 사용하는 경우: 더 이상 구식 옵션인 useSSL을 사용하지 말고, sslMode를 사용하여 원하는 보안 수준을 명확히 지정하는 것이 좋습니다.
  • 최고의 보안을 원한다면: sslMode=VERIFY_IDENTITY를 사용하는 것이 권장됩니다. 이 옵션은 데이터 암호화는 물론, 서버 인증서의 유효성 및 호스트 이름까지 검증하므로 가장 안전한 연결을 보장합니다.