MySQL/MariaDB Server SSH Over Tunneling
클라이언트에서 원격 서버 MySQL DB server 접속시 SSH turnneling 을 이용할 수 있다.
- ssh tunneling 이해
- SSHTunnelForwarder 클래스
- HeidiSQL ssh tunnel 사용
ssh tnnneling 이해
비 암호화된 통신을 지원하는 원격 프로그램이 암호화된 통신을 지원하는 ssh 를 사용해서 원격지에 접속이 가능하게 한다. 직접 TLS/SSL 구현을 하지 않더라도 SSL 로 암호화된 통신 채널을 통해 안전하게 프로그램을 사용할 수 있다.
터널링은 아래 같이 SSH 서버를 통해서 원격지에서 SSH 통신을 지원한다.
링크 참고2 의 그림
MySQL client 에서 Database server 포트 3306으로 직접 접속하지 않고 ssh 를 이용해 원격 서버에 연결하고 원격 서버 내부에서 mysql server 에 접속해 사용하게 해준다.
SSHTunnelForwarder 이용 tunneling 사용
sshtunnel 모듈이 필요하다.
1 | pip install pymysql |
시나리오
다음 2개의 시나리오는 참조 링크 3 의 공식문서에 있는 내용이다.
사례1) 사용자가 8080 웹 서비스에 연결할 필요가 있을 때 22번 포트로만 연결가능할 때
1 | ---------------------------------------------------------------------- |
사례2) SSH server 가 허용하는 경우.
1 | ---------------------------------------------------------------------- |
DB접속 정보
sshtunnel 패키지를 사용한다. DB 접속 정보를 외부 json 파일에서 얻어온다고 가정한다.
1 | import json |
SSHTunnelForwarder 사용
1 | SSHTunnelForwarder((HOST_IP, SSH_PORT), |
ssh_address_or_host:
- tuple 형태나 string 형태로 설정할 수 있으며, 위와같이 키워드를 생략할 수 있습니다.
- 튜플형식: (호스트주소, 포트) 함께 정의
- 문자열 형식: 호스트 주소 설정 (ssh_port 키워드도 별도로 설정해줘야 합니다.)
~/.ssh/config
에 설정한 Host
ssh_port: ssh 서비스 포트
ssh_username: ssh 연결에 사용될 인증된 사용자
ssh_password: ssh 연결에 사용될 사용자의 접속 비밀번호
보안을 위해 비밀번호를 설정하는 것보다는 private key을 사용하는 것을 권장합니다.ssh_pkey: ssh 연결에 사용될 private key 파일 혹은 paramiko.pkey.PKey
remote_bind_address:
(호스트주소, 포트)
튜플 형식. ssh 연결을 통해 접속한 원격 서버에서 접속할 private server 접속 정보.
with 구문과 사용
SSHTunnelForwarder
클래스에 __enter__
, __exit__
magic method가 정의되어 with 구문과 함께 사용한다.
1 | with sshtunnel.SSHTunnelForwarder( |
Windows 경우 보안 경고를 확인!
윈도우즈에서 파이썬 코드에서 SSHTunnelForwarder 를 처음 사용시 아래 같이 경고를 만난다.
사례1
사례1 로 접속하는 방법이 전형적인 터널링 구현이다. SSHTunnelForwarder을 with 구문과 함께 쓸 수 있다.
1 | import pymysql |
터널링을 통해서 SQL Query가 잘 진행된다.
사례2) ssh_pkey 사용 (실패)
기록을 위해 남긴다. 잘 안되는 코드이다.
사례2 같이 직접 서버에 접근이 안되는 경우 ssh key pair 를 사용할 수 있다.
사용자 아이디, 패스워드 형식에서 패스워드를 직접 코드 등에 입력하기 보다 private key 쌍을 사용하면 좀 더 보안에 안전하다.
ssh-keygen 으로 생성한 공개키를 DB 서버의 ssh/authorized_keys`` 파일에 id_rsa.pub 내용을
ssh-copy-id또는
scp` 명령으로 서버에 복사한다.
1 | ssh-copy-id -i ~/.ssh/id_rsa.pub username@jump_server_host -p ssh_port |
scp 를 사용해도 좋다
1 | scp -P 2020 .\.ssh\id_rsa qkboo@DBSERVER:~/auth_key |
SSHTunnelForwarder 에서 ssh_pkey 에 비밀키를 지정해 준다.
1 | with SSHTunnelForwarder(('DBSERVER', 2020), |
SQLAlchemy engine 생성하기
SQLAlchemy 의 engine 을 생성할 수 있다. with 구문과 함께 사용할 수 있지만 engine 을 여러 프로시저에서 지속해서 사용한다면 아래 같이 start(), stop() 사이에 pymysql, sqlalchemy 코드를 배치해도 좋다.
1 | # SSH Tunnel 사용1 |
with 구문과 사용
1 | # SSH Tunnel 사용2 - with 구문과 사용 |
클라이언트에서 ssh tunnel 사용
클라이언트에서 MySQL / MariaDB 접속시 보안을 위해서 SSH over 방식을 통해 3306 포트가 아닌 ssh over 방법을 사용할 수 있다.
- HeidiSQL ssh tunnel 사용하기
- MysQL Workbench 에서 ssh tunnel 사용하기
- Server 에서 bind 제외하기
1. HeidiSQL ssh tunnel 사용하기
유형을 SSH Tunnel 로 선택하고 MySQL / MariaDB 데이터베이스의 DB 사용자 계정과 비밀번호을 입력한다.
SSH tunnel 을 만들어줄 ssh client 를 선택하고 개인 키 파일을 선택한다. SSH 로 로그인하는 DB server의 사용자 계정 ID를 입력한다.
선택한 개인 키가 로그인 패스워드를 대체한다.
SSH 아이디-패스워드 방법은 잘 안된다.
2. MysQL Workbench 에서 ssh tunnel 사용하기
MySQL workbench 에서 ssh tunnel 로 접속하려면 DB 서버측에 authorized_keys 에 클라이언트 공개키가 등록되어야 한다.
DB 서버의 `ssh/authorized_keys`` 파일에 id_rsa.pub 내용을 추가한다.
1 | > scp -P 2020 .\.ssh\id_rsa qkboo@192.168.0.24:~/auth_key |
복사한 공개키를 .ssh/authorized_keys
에 추가한다.
1 | cat auth_key >> .ssh/authorized_keys |
root 계정은 잘 안된다.
3. Server 에서 bind 제외하기
서버에서 my.cnf 에 bind를 0.0.0.0
으로 해두었으면 기본 값인 127.0.0.1
로 해두고 SSH tunnel 방법으로 통해 접근하므로 좀 더 안전할 수 있다.
- DB server 로컬에서는 직접 mysql client 로 접근가능하고
- 외부 / 원격지에서는 ssh tunnel 을 통해서 작업이 가능하다.
1 | bind-address = 127.0.0.1 |
참고
MySQL/MariaDB Server SSH Over Tunneling
https://blog.thinkbee.kr/mysqlclient_SSH_Tunneling-59f215a18e7e/