MysqlConnector로 인증서를 통한 보안 통신 구현

개요



MySqlConnector를 이용한 WEB 어플리케이션에 SSL 통신을 구축하는 구현 방법
(이번은 증명서의 발행원을 heroku로 하고 있습니다.)

참고로 한 사이트
htps : // v. mysql. 코 m / 드 c / 콘 c와 rpy 텐 / 엔 / 콘 c와 루 py 텐 - 콘 c rgs. HTML

버전



Flask==1.1.2
파이썬 3.8.7
mysql-connector-python==8.0.23
mysql 5.5.62
(↑ ClearDB와 같은 클라우드에서 호스팅 된 DaaS 사용)

도입 절차



① 다음 파일을 준비합니다.
· SSL 인증 기관 정보를 포함하는 ssl_ca 파일
· SSL 인증서가 포함된 ssl_cert 파일
· SSL 키를 포함하는 ssl_key 파일

heroku에서 ClearDB를 사용하는 경우,
만든 애플리케이션의 대시보드에서 대상 앱을 선택합니다.
리소스 탭의 ClearDB MySQL에서 NAVISITE로 이동합니다.


점프 대상 보안 탭에서 다양한 인증서를 발급할 수 있습니다.


② 이전 순서로 취득한 디렉토리에 각 pem 파일을 배치합니다.
(디렉토리 구성은 공식에 따라 opt/mysql/ssl로 되어 있습니다.)
또한 반드시 메인 모듈과 같은 계층에 배치하도록 합니다.
app.py가 메인 모듈이면 다음과 같습니다.

├── app.py
├── opt
│   └── mysql
│   └── ssl
│   ├── ca.pem
│   ├── client-cert.pem
│   └── client-key.pem

③ mysqlconnector의 DB 연결 인수를 설정합니다.
연결 인수에 제공하는 인증서의 경로는 이전 단계에서 설정한 것을 나열합니다.

app.py
import mysql.connector
from mysql.connector.constants import ClientFlag

config = {
    'user': 'ssluser',
    'password': 'password',
    'host': '127.0.0.1',
    'client_flags': [ClientFlag.SSL],
    'ssl_ca': '/opt/mysql/ssl/ca.pem',
    'ssl_cert': '/opt/mysql/ssl/client-cert.pem',
    'ssl_key': '/opt/mysql/ssl/client-key.pem',
}

이 설정 후, 내가 주저했던 점은 파일 경로를 전달하는 방법이었습니다.
파이썬에서는 OS에 따라 슬래시 기법이 다르기 때문에 windows 환경에서 설정한 파일 경로는 heroku에 배포하면 참조되지 않고 오류를 출력했습니다.
app[web.1]: context.load_verify_locations(ca)
app[web.1]: FileNotFoundError: [Errno 2] No such file or directory
app[web.1]:"Invalid CA Certificate: {}".format(err))
app[web.1]: mysql.connector.errors.InterfaceError: Invalid CA Certificate: [Errno 2] No such file or directory

os 당 경로의 형식은 다음과 같이 다릅니다.
windows의 경우 -->\\
POSIX (mac/linux)의 경우 -->/

해결 방법은 메인 모듈의 절대 경로와 인증서 파일의 상대 경로를 연결하여 경로를 전달하는 것입니다.
그 때, 작동하는 os를 판정해, os에 따라 패스의 취득 방법을 스위치 하도록(듯이) 했습니다. (약간 중복적인 생각도 들지만...)

app.py
import os

# 証明書のディレクトリ指定
dirname = os.getcwd()
if os.name == 'nt':
    # windows
    ca_path = os.path.join(dirname, 'opt\\mysql\\ssl\\ca.pem')
    cert_path = os.path.join(dirname, 'opt\\mysql\\ssl\\client-cert.pem')
    key_path = os.path.join(dirname, 'opt\\mysql\\ssl\\client-key.pem')
elif os.name == 'posix':
    # mac or linux
    ca_path = os.path.join(dirname, 'opt/mysql/ssl/ca.pem')
    cert_path = os.path.join(dirname, 'opt/mysql/ssl/client-cert.pem')
    key_path = os.path.join(dirname, 'opt/mysql/ssl/client-key.pem')


config = {
    'user': 'ssluser',
    'password': 'password',
    'host': '127.0.0.1',
    'client_flags': [ClientFlag.SSL],
    'ssl_ca': ca_path ,
    'ssl_cert': cert_path ,
    'ssl_key': key_path ,
}

이것으로 설정이 완료되었습니다!

결론



공부의 일환으로서 개인개발을 시작하고 나서 처음에는 영어의 문서나 Stack over flow등에 기재된 프랙티스를 피해, 가능한 한 일본어로 요약된 사이트를 참고로 하고 있었습니다. 하지만 역시 본질은 오리지널 문서에 있다고 느꼈습니다.
또, Teretail에는 실려 있지 않은 사건이나 해결 플로우도, Stack over flow에는 기재되어 있는 것이 의외로 많아, 공부가 되었습니다.
해석에 따라서는 오해도 생기기 때문에, 그로 인해 되돌아가 발생하는 일도 있을 것이며, 둘레가 될지도 모릅니다만, 문제 해결을 위해 멀어진 시간이나 쏟아진 노력은 언젠가 반드시 무언가에 살아 것이라고 믿고 앞으로도 배우고 싶습니다.

좋은 웹페이지 즐겨찾기