반응형
250x250
Notice
Recent Posts
Recent Comments
Link
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
Archives
Today
Total
관리 메뉴

가끔 보자, 하늘.

MySQL/MariaDB에 TLS 적용하기 본문

개발 이야기/DB, 데이터분석, AI

MySQL/MariaDB에 TLS 적용하기

가온아 2023. 12. 8. 10:41

일반적으로 DB는 안전한 보안망에 구축하기도 하고, 외부에서 DB에 직접 연결을 지원하지 않아 SSL을 적용할 일 자체가 없도록 하는게 더 좋습니다. 그럼에도 필요한 경우가 생기네요. ^^a 

여기서는 Ubuntu/MariaDB를 기준으로 정리해 보았습니다. 

우선 해당 시스템에 Openssl이 적용되어 있는지 확인합니다.

# DB에 쿼리
SHOW VARIABLES LIKE '%ssl%'

# 터미널에서 openssl 설치 여부 확인
$ openssl version      # 버전확인
$ ldd /usr/bin/openssl # 현재 사용하는 라이브러리와 경로 확인

만약 이미 설정이 완료되어 있다면 아래와 같은 결과를 확인하실 수 있습니다. DB에 설정이 되어있지 않을 경우 have_openssl은 yes로, have_ssl은 No로 출력됩니다. 설정이 완료되어 있다면 이곳으로!

이미 필요한 인증서를 가지고 있다면 이곳으로! 아니면 사설 인증서를 생성해 보겠습니다. (MariaDB TDE link)

$ cd ~     # 우선 별도 권한이 필요없는 자신의 home 디렉토리로 이동합니다.

# 사설 인증서 생성
$ openssl genrsa 2048 > ca-key.pem
$ openssl req -new -x509 -nodes -days 36500 -key ca-key.pem -out ca.pem
  # 설정 시 Common Name 은 mariadb-ca로 기록하고, 나머지는 적절히 입력 혹은 기본값으로 둡니다.

# 서버 인증서 생성
$ openssl req -newkey rsa:2048 -days 36500 -nodes -keyout server-key.pem -out server-req.pem
  # 설정 시 Common Name 은 mariadb-srv로 기록하고, 나머지는 적절히 입력 혹은 기본값으로 둡니다.
$ openssl rsa -in server-key.pem -out server-key.pem
$ openssl x509 -req -in server-req.pem -days 36500 -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem
$ openssl verify -CAfile ca.pem server-cert.pem # 이상 유무 확인

# 서버 인증서를 ssl 폴더에 임의의 폴더를 생성하여 모두 이동
$ sudo mkdir /etc/ssl/mariadb
$ cd /etc/ssl/mariadb
$ sudo cp *.pem /etc/ssl/mariadb/
$ sudo chown mysql:mysql /etc/ssl/mariadb/*


# 클라이언트 인증서 생성. 클라이언트 인증서는 maria db에 접속할 클라이언트에서 사용합니다.
$ openssl req -newkey rsa:2048 -days 365000 -nodes -keyout client-key.pem -out client-req.pem
  # 설정 시 Common Name 은 mariadb-client로 기록하고, 나머지는 적절히 입력 혹은 기본값으로 둡니다.
$ openssl rsa -in client-key.pem -out client-key.pem
$ openssl x509 -req -in client-req.pem -days 365000 -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem
$ openssl verify -CAfile ca.pem client-cert.pem # 이상 유무 확인

my.cnf에 ssl 관련 옵션을 설정합니다.

$ sudo vi /etc/mysql/my.cnf

[mysqld]
ssl_cert = /etc/ssl/mariadb/server-cert.pem
ssl_key = /etc/ssl/mariadb/server-key.pem
ssl_ca = /etc/ssl/mariadb/ca.pem
require_secure_transport = ON # ssl만 접속 가능하도록 설정합니다.

이제 mariadb를 재시작해 보세요. 정상적으로 실행되었으면 짝짝짝!!!

이제 외부에서 접속해 보겠습니다. HeidiSQL로 접속할 때 기존 설정에서 SSL로 접속하겠다는 체크하는 것 이외에 더 필요한 내용은 없습니다.

nodejs 앱에서 접속한다면 위에서 생성했던 인증서 중 아래 코드에 있는 파일들을 복사해 설정하면 됩니다.

  const mysql = require('mysql');
  const fs = require('fs');

  const mysqlcfg = {
    host :'db_ip',
    port : 3306,
    user : 'user_name',
    password : 'password',
    database:'db_name',
    multipleStatements: true,
    ssl : {
        ca: fs.readFileSync('server-cert.pem'),
        key: fs.readFileSync('client-key.pem'),
        cert: fs.readFileSync('client-cert.pem')
    }
  };
  .
  .
  .

python에서는 아래와 같이 설정해 사용할 수 있습니다.

import pymysql.cursors
import ssl

ssl_settings = {
    'ca': 'server-cert.pem',
    'key': 'client-key.pem',
    'cert': 'client-cert.pem'
}

# SSL 컨텍스트 생성
ssl_context = ssl.create_default_context()
ssl_context.load_verify_locations('server-cert.pem')
ssl_context.load_cert_chain('client-cert.pem', 'client-key.pem')
ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_NONE  # 서버 인증서 검증을 하지 않음   

conn = pymysql.connect(
    host='db_ip',
    port=3306,
    user='user_name',
    password='user_password',
    db='db_name',
    charset='utf8',
    ssl = ssl_context
)

연말이네요. 다들 즐거...  끝!!

반응형