DB SSL은
클라이언트와 데이터베이스 서버 간의 통신을 TLS로 암호화하여, 네트워크 구간에서 데이터가 노출되는 것을 방지하는 기술입니다.
SSL이 적용되지 않은 경우 쿼리나 결과 데이터가 평문으로 전송되어 패킷 캡처 시 그대로 확인될 수 있습니다.
반면 SSL을 적용하면 동일한 트래픽도 암호화되어 외부에서는 내용을 해석할 수 없습니다.
데이터 유출 방지와 보안 강화를 위해 DB 통신에 SSL 적용을 권장합니다.

[테스트 환경]
Server A : Ubuntu 24.04 / Mariadb Server 10.11 / Let’s encrypt SSL (Apache 2.4)
Client B : Ubuntu 22.04 / Mariadb Client 10.6 / Tshark 3.6.2
[SSL 적용 전] Client B에서 Server A로 접근 후 쿼리문 입력 MariaDB [testdb]> SELECT 'password=MySecret123!'; +-----------------------+ | password=MySecret123! | +-----------------------+ | password=MySecret123! | +-----------------------+ 1 row in set (0.003 sec)
Client B에서 tshark -i ens3 -f "tcp port 3306" -V 명령어로 캡쳐
[SSL 미적용시 평문 노출]
MySQL Protocol
Request Command Query
Command: Query (3)
Statement: SELECT 'password=MySecret123!'
-> 쿼리 내용이 그대로 보이며 사람이 읽을 수 있음
MySQL Protocol
text
text: password=MySecret123!
-> DB 결과값까지 평문 노출됨
[Protocols in frame: eth:ethertype:ip:tcp:mysql]
-> MySQL 프로토콜 해석 가능하며 내부 구조까지 분석 가능
[DB SSL 적용 흐름]
1. Server B: 인증서 발급
2. Server B: MySQL SSL 설정
3. Client A: CA 신뢰 설정 (또는 OS trust 사용)
4. MySQL: SSL 강제 + 계정 생성
5. 네트워크: IP 직접 접근 차단
6. 클라이언트: VERIFY_IDENTITY로 접속 (mysql만 지원, mariadb 지원안됨)
[Server B]
1. Let’s Encrypt 인증서 발급
ex. /etc/letsencrypt/live/test.com/
2. DB 데몬에서 사용을 위해 인증서파일 권한 및 그룹권한 변경 필요
3. /etc/letsencrypt/archive/test.com 원본 경로 하단의 파일들을 복사
ex. # cp -arp /etc/letsencrypt/archive/test.com/fullchain1.pem /etc/mysql/ssl/
# cp -arp /etc/letsencrypt/archive/test.com/privkey1.pem /etc/mysql/ssl/
4. 인증서 파일 권한 변경
# chown mysql:mysql /etc/mysql/ssl/fullchain1.pem
# chown mysql:mysql /etc/mysql/ssl/privkey1.pem
# chmod 600 /etc/mysql/ssl/fullchain1.pem
# chmod 600 /etc/mysql/ssl/privkey1.pem
5. DB 설정파일 수정
# vi /etc/mysql/mariadb.conf.d/50-server.cnf
[mysqld]
ssl-ca=/etc/letsencrypt/live/test.com/fullchain.pem
ssl-cert=/etc/letsencrypt/live/test.com/fullchain.pem
ssl-key=/etc/letsencrypt/live/test.com/privkey.pem
require_secure_transport=ON
# systemctl restart mysqld
5. Mysql 계정 생성 및 SSL 강제
MariaDB [(none)]> CREATE USER 'appuser'@'%' IDENTIFIED BY 'Pass!1234';
MariaDB [(none)]> ALTER USER 'appuser'@'%' REQUIRE SSL;
MariaDB [(none)]> GRANT ALL PRIVILEGES ON *.* TO 'appuser'@'%';
MariaDB [(none)]> FLUSH PRIVILEGES;
6. 네트워크: IP 직접 접근 차단 (필요시)
생략해도 IP로도 접속 시도 가능 (TLS 실패하더라도 접근 시도 자체는 됨)
# iptables -A INPUT -p tcp --dport 3306 -s <WAS_IP> -j ACCEPT
# iptables -A INPUT -p tcp --dport 3306 -j DROP
[Client B]
7. DB 원격 접속 (OS 자체 ca 파일 사용, /etc/ssl/certs/ca-certificates.crt)
# mysql -h test.com -u appuser -p --ssl --ssl-ca=/etc/ssl/certs/ca-certificates.crt
# mysql -h test.com -u appuser -p --ssl-mode=VERIFY_IDENTITY
-> MySQL 5.7.11 이상 또는 MySQL 8.X 클라이언트에서만 --ssl-mode=VERIFY_IDENTITY 옵션 지원
[SSL 적용 후] Client B에서 Server A로 접근 후 쿼리문 입력 MariaDB [testdb]> SELECT 'password=MySecret123!'; +-----------------------+ | password=MySecret123! | +-----------------------+ | password=MySecret123! | +-----------------------+ 1 row in set (0.003 sec)
Client B에서 tshark -i ens3 -f "tcp port 3306" -V 명령어로 캡쳐
[SSL 적용시 암호화]
Transmission Control Protocol
TCP payload (57 bytes)
TCP segment data (57 bytes)
-> 쿼리 내용 보이지 않고, 단순 데이터 길이만 보임
TCP payload (120 bytes)
TCP segment data (120 bytes)
-> 실제 데이터 내용 확인 불가, 암호화된 바이너리 형태
[Protocols in frame: eth:ethertype:ip:tcp]
-> MySQL 프로토콜 자체가 숨겨지며 TLS 내부데이터로 숨겨짐
[SSL 적용 테스트 방법]


MariaDB [(none)]> SELECT user, host, ssl_type FROM mysql.user;
[ssl_type]
● ANY → REQUIRE SSL
● X509 → mutual TLS
● 공백 → SSL 안 써도 접속 가능

MariaDB [(none)]> SHOW VARIABLES LIKE ‘%ssl%’;

MariaDB [(none)]> SHOW STATUS LIKE ‘Ssl_cipher’;
–> 현재 세션 암호화 여부 조회
공백일경우 SSL 미사용, 평문 통신

이 글은 본인의 실제 경험과 학습을 기반으로 직접 작성하였으며, AI는 참고용으로만 활용하였습니다.





