[Python3 - PyMySQL] 2. sshtunnel을 이용한 private database server 접속 테스트

2021. 2. 4. 15:58Python/Basic

반응형
  1. SSH Tunnel
  2. sshtunnel
    2.1. sshtunnel?
    2.2. Keyword Arguments
  3. sshtunnel을 활용한 간단한 조회

1. SSH Tunnel

private network 상에서만 통신하고자 하는 서비스나, 보안이 중요한 database는 방화벽을 별도로 열어두지 않아 외부 환경에서 테스트를 하는게 매우 까다롭습니다.

이러한 외부환경으로 공개되지 않은 서비스를 접속하고 싶을때에는 어떻게 해야할까?

데이터베이스를 접속해야할때마다 터미널로 ssh 접속한 후 cli환경으로 접속해야한다면 너무 까다로울 것입니다.

이럴때 이용하는 것이 바로 SSH tunneling입니다.
SSH tunneling은 원격 게이트웨이를 통해 SSH접속한 후, 내부에서 접속가능한 private service에 접근하는 서비스입니다.

이런 ssh 터널링은 MySQL Workbench IDE에서 찾아볼 수 있습니다.

SSH 터널링은 ssh hostname과 private key를 설정하고, 해당 서버내의 MySQL Server로 접속하도록 도와줍니다.

ssh 터널링을 이용하면 외부로 개방되지 않은 private database server의 값을 로컬에서 이용하여 개발을 할 수 있습니다.

2. sshtunnel

2.1. sshtunnel?

ssh 터널을 이용하여 private server로 접속할 수 있도록 하는 python용 패키지로, 쓰레드를 이용하여 백그라운드에 포트 포워딩 SSH 연결을 엽니다.

sshtunnel 패키지 내의 SSHTunnelForwarder 클래스를 통해 생성한 객체를 start()하여 SSH 터널을 생성합니다.
SSHTunnelForwarder로 생성한 객체는 반드시 stop 메서드를 통해 명시적으로 닫아줘야 합니다.

SSHTunnelForwarder 클래스 내에는 __enter__, __exit__ magic method가 정의되어있기 with 구문을 사용할 수 있습니다.

class SSHTunnelForwarder(object):
	...

	def __enter__(self):
		try:
			self.start()
			return self
		except KeyboardInterrupt:
			self.__exit__()

	def __exit__(self, *args):
		self.stop(force=True)

pip를 이용하여 sshtunnel 패키지를 설치합니다.

pip install sshtunnel

2.2. Keyword Arguments

tunnel = SSHTunnelForwarder(('jiniworld.me', 22222),
                            ssh_username='jini',
                            ssh_pkey='C:/Users/jini/.ssh/apple.pem',
                            remote_bind_address=('127.0.0.1', 3306))
  • ssh_address_or_host
    • SSHTunnelForwarder의 맨 첫번째 인자
    • tuple 형태나 string 형태로 설정할 수 있으며, 위와같이 키워드를 생략할 수 있습니다.
    • 설정
      • 튜플형식
        • (호스트주소, 포트) 함께 정의
      • 문자열 형식
        • 호스트 주소 설정 (ssh_port 키워드도 별도로 설정해줘야 합니다.)
        • ~/.ssh/config에 설정한 Host
  • ssh_port
    • ssh 서비스 포트
  • ssh_username
    • ssh 연결에 사용될 인증된 사용자
  • ssh_password
    • ssh 연결에 사용될 사용자의 접속 비밀번호
    • 보안을 위해 비밀번호를 설정하는 것보다는 private key을 사용하는 것을 권장합니다.
  • ssh_pkey
    • ssh 연결에 사용될 private key
  • remote_bind_address
    • ssh 연결을 통해 접속한 원격 서버에서 접속할 private server 접속 정보.
    • (호스트주소, 포트) 튜플 형식으로 입력받습니다.

3. sshtunnel을 활용한 간단한 조회

이전시간에 pymysql을 이용하여 로컬 데이터베이스에 접속했던 것을 응용하여 이번에는 ssh 터널링으로 ssh 접속한 서버에 설치된 MySQL 서버에 접속하여 select를 실행해보도록 합니다.

import pymysql
from sshtunnel import SSHTunnelForwarder


if __name__ == '__main__':
    with SSHTunnelForwarder('apple',
                            remote_bind_address=('127.0.0.1', 3306)) as tunnel:
        with pymysql.connect(host='127.0.0.1', user='test2', password='test2', port=tunnel.local_bind_port,
                             db='test_db', charset="utf8", cursorclass=pymysql.cursors.DictCursor) as conn:
            with conn.cursor() as cur:
                sql = '''
                SELECT * from users
                '''
                cur.execute(sql)
                print(sql)
                results = cur.fetchall()
                for result in results:
                    print(result)
    print('\nfinish!\n', '-----' * 20)

~/.ssh/config 에 정의된 ssh 접속정보의 Host를 이용하면 위와 같이 매우 간단한 형태로 SSHTunnelForwarder 객체를 정의할 수 있습니다.

Host apple
        HostName jiniworld.me
        User jini
        Port 22222
        IdentityFile ~/.ssh/apple.pem

~/.ssh/config 에 정의된 apple 접속 정보


apple 서버의 MySQL 서버에도 동일한 데이터를 넣어두고 위의 파이썬 파일을 실행해봅니다.
실행결과는 이전시간과 같습니다.

                SELECT * from users

{'id': 1, 'name': 'jini', 'age': 29, 'email': 'jini@jiniworld.me', 'status': 'Y', 'created_dt': datetime.datetime(2020, 12, 22, 15, 42, 20), 'type': '1'}
{'id': 2, 'name': 'sol', 'age': 33, 'email': 'sol@jiniworld.me', 'status': 'Y', 'created_dt': datetime.datetime(2020, 12, 22, 15, 42, 23), 'type': '2'}
{'id': 3, 'name': 'coco', 'age': 34, 'email': 'coco@c.com', 'status': 'Y', 'created_dt': datetime.datetime(2020, 12, 22, 17, 13, 21), 'type': '2'}
{'id': 4, 'name': 'lily', 'age': 22, 'email': 'lily@ll.com', 'status': 'Y', 'created_dt': datetime.datetime(2020, 12, 29, 10, 51, 17), 'type': '1'}

finish!
 ----------------------------------------------------------------------------------------------------


++

  • how to connect private MySQL Database Server using ssh tunneling
  • how to connect private MySQL via SSH Tunneling using python
728x90
반응형