Python에서 SFTP 기능 만들기

Olorunfemi Akinlua 2024년2월16일
  1. pysftp를 사용하여 Python에서 SFTP 기능 생성
  2. paramiko를 사용하여 Python에서 SFTP 기능 생성
Python에서 SFTP 기능 만들기

SSH(Secure Socket Shell)는 다른 컴퓨터에 액세스하고 SHA 및 암호화를 통해 암호 및 공개 키 인증을 사용하는 더 나은 보안 네트워크 프로토콜입니다.

SFTP(SSH File Transfer Protocol)는 SSH를 사용하는 파일 전송 프로토콜로 기존에 사람들이 사용하던 일반적인 FTP보다 낫습니다.

Python에서 애플리케이션을 개발하려면 파일 전송 프로토콜이 필요할 수 있습니다. 암호 스니핑 및 중간자 공격과 같은 공격을 극복하고 데이터 무결성을 유지할 수 있는 기본 기능을 제공하는 SFTP를 사용해야 합니다.

이 문서에서는 Python 내에서 SFTP를 사용하여 데이터와 파일을 이동하는 방법을 보여줍니다.

pysftp를 사용하여 Python에서 SFTP 기능 생성

Python에는 안전하지 않은 FTP 프로토콜 서비스를 제공하는 도우미 기능이 있는 FTP 클라이언트 클래스인 ftplib가 함께 제공됩니다. SFTP를 사용하려면 타사 라이브러리를 설치해야 하는데 그 중 하나가 pysftp 라이브러리입니다.

pysftp를 사용하면 SFTP에 액세스하고 보안 프로토콜로 작업하여 애플리케이션 요구 사항을 충족할 수 있습니다. pysftp를 설치하려면 pip를 사용해야 합니다.

pip install pysftp

또한 SFTP 서버가 필요합니다. Windows의 경우 WinSCP 소프트웨어를 사용하고 Windows PC에서 SFTP 서버 클라이언트를 설정하는 방법을 배우려면 이 설치 가이드를 참조하십시오. 그러나 SFTP 서버가 있는 경우 시작하겠습니다.

코드를 작성하기 전에 개인 키사용자 이름(akinl) 및 호스트 이름(localhost)을 사용하여 SFTP 서버에 로그인합니다.

python에서 sftp 기능 만들기 - 고급 사이트 설정

이제 root 폴더에 로그인했습니다. 우리의 목표는 root 디렉토리에 있는 파일과 디렉토리를 나열하고 파일을 SFTP 서버, 특히 store 디렉토리에 복사하는 것입니다.

python에서 sftp 기능 생성 - sftp 서버에 로그인됨

pysftp 라이브러리에 지정된 미리 정의된 코드 템플릿을 사용하여 코딩을 시작하겠습니다. 코드 내에서 호스트 이름, 포트, 사용자 이름개인 키 경로를 할당했습니다.

이러한 값은 SFTP 서버 세부 정보에서 알 수 있으며 개인 키는 Python 파일의 디렉터리에 복사됩니다.

import pysftp

sftpHostName = "localhost"
sftpPort = 22
userName = "akinl"
privateKeyPath = "./id_rsa"

with pysftp.Connection(
    host=sftpHostName,
    port=sftpPort,
    username=userName,
    private_key=privateKeyPath,
    cnopts=cnOptions,
) as sftp:
    print("Connected to SFTP server!")

위의 코드는 지정된 매개변수와 함께 SFTP 연결 객체(pysftp.Connection())를 사용하여 SFTP 서버에 연결합니다. with 블록 내부에는 sftp라는 개체 내에 SFTP 연결이 설정되어 있습니다.

다음은 코드의 출력입니다.

C:\\Python310\\lib\\site-packages\\pysftp\\__init__.py:61: UserWarning: Failed to load HostKeys from C:\\Users\\akinl\\.ssh\\known_hosts. You will need to explicitly load HostKeys (cnopts.hostkeys.load(filename)) or disableHostKey checking (cnopts.hostkeys = None).
  warnings.warn(wmsg, UserWarning)
Traceback (most recent call last):
  File "c:\\Users\\akinl\\Documents\\Python\\SFTP\\index.py", line 8, in <module>
    with pysftp.Connection(host=sftpHostName, port=sftpPort, username=userName, private_key=privateKeyPath) as sftp:
  File "C:\\Python310\\lib\\site-packages\\pysftp\\__init__.py", line 132, in __init__
    self._tconnect['hostkey'] = self._cnopts.get_hostkey(host)
  File "C:\\Python310\\lib\\site-packages\\pysftp\\__init__.py", line 71, in get_hostkey
    raise SSHException("No hostkey for host %s found." % host)
paramiko.ssh_exception.SSHException: No hostkey for host localhost found.
Exception ignored in: <function Connection.__del__ at 0x000001F0E9656320>
Traceback (most recent call last):
  File "C:\\Python310\\lib\\site-packages\\pysftp\\__init__.py", line 1013, in __del__
    self.close()
  File "C:\\Python310\\lib\\site-packages\\pysftp\\__init__.py", line 784, in close
    if self._sftp_live:
AttributeError: 'Connection' object has no attribute '_sftp_live'

No hostkey for host %s foundpysftp를 사용하여 SFTP 연결 객체로 작업할 때 발생하는 일반적인 오류로, 호스트 파일이 없을 때 발생합니다.

이 문제를 처리하기 위해 연결 옵션(pysftp.CnOpts())을 생성하고 호스트 키를 없음으로 지정하고 알려진 호스트 검사를 무시할 수 있습니다.

import pysftp

sftpHostName = "localhost"
sftpPort = 22
userName = "akinl"
privateKeyPath = "./id_rsa"

cnOptions = pysftp.CnOpts()
cnOptions.hostkeys = None

with pysftp.Connection(
    host=sftpHostName,
    port=sftpPort,
    username=userName,
    private_key=privateKeyPath,
    cnopts=cnOptions,
) as sftp:
    print("SFTP server connection successful")

코드의 출력은 다음과 같습니다.

C:\Python310\lib\site-packages\pysftp\__init__.py:61: UserWarning: Failed to load HostKeys from C:\Users\akinl\.ssh\known_hosts. You will need to explicitly load HostKeys (cnopts.hostkeys.load(filename)) or disableHostKey checking (cnopts.hostkeys = None).
  warnings.warn(wmsg, UserWarning)
SFTP server connection successful

유일한 오류는 비활성화된 호스트 키 확인에 대한 낮은 수준의 경고입니다. 먼저 SFTP 서버 내에 있음을 표시하기 위해 작업 디렉토리를 변경해 보겠습니다.

import pysftp

sftpHostName = "localhost"
sftpPort = 22
userName = "akinl"
privateKeyPath = "./id_rsa"

cnOptions = pysftp.CnOpts()
cnOptions.hostkeys = None

with pysftp.Connection(
    host=sftpHostName,
    port=sftpPort,
    username=userName,
    private_key=privateKeyPath,
    cnopts=cnOptions,
) as sftp:
    print("SFTP server connection successful")
    print("The current working directory is ", sftp.pwd)
    sftp.cwd("./store")
    print("After the cwd operation, the current working directory is ", sftp.pwd)

위 코드의 출력은 다음과 같습니다.

SFTP server connection successful
The current working directory is /
After the cwd operation, the current working directory is /store.

cwd는 현재 작업 디렉토리를 인수로 지정된 것으로 변경합니다. 또한 listdir() 메서드를 사용하여 rootstore 디렉토리 내의 파일을 나열하고

import pysftp

sftpHostName = "localhost"
sftpPort = 22
userName = "akinl"
privateKeyPath = "./id_rsa"

cnOptions = pysftp.CnOpts()
cnOptions.hostkeys = None

with pysftp.Connection(
    host=sftpHostName,
    port=sftpPort,
    username=userName,
    private_key=privateKeyPath,
    cnopts=cnOptions,
) as sftp:
    rootFiles = sftp.listdir()
    storeFiles = sftp.listdir("./store")
    print(rootFiles, storeFiles)

코드의 출력은 다음과 같습니다.

['index.txt', 'main.py', 'store'] []

listdir() 메서드는 인수가 전달되지 않으면 현재 작업 디렉토리 내의 모든 파일과 디렉토리를 나열하지만 인수를 제공하면 전달한 인수 내의 파일을 확인합니다. 그 결과 파일이 존재하지 않기 때문에 root 디렉토리에 대한 두 개의 파일과 하나의 디렉토리가 있었고 store 디렉토리에 대한 파일이 없었습니다.

이제 put(), put_d()put_r() 메서드를 사용하여 일부 파일을 SFTP 서버로 이동해 보겠습니다. put()을 사용하여 파일만 이동합니다.

다음으로 python 파일과 동일한 디렉터리에 test.txt라는 텍스트 파일을 만들고 파일을 SFTP 서버에 복사합니다.

import pysftp

sftpHostName = "localhost"
sftpPort = 22
userName = "akinl"
privateKeyPath = "./id_rsa"

cnOptions = pysftp.CnOpts()
cnOptions.hostkeys = None

with pysftp.Connection(
    host=sftpHostName,
    port=sftpPort,
    username=userName,
    private_key=privateKeyPath,
    cnopts=cnOptions,
) as sftp:
    sftp.put("test.txt", preserve_mtime=True)

코드 출력:

python에서 sftp 기능 생성 - 출력

test.txt 파일은 이제 SFTP 서버 루트 디렉토리에 있습니다. 이제 동일한 test.txtstore 디렉토리로 이동하고 복사하기 전과 후의 파일 내용을 나열해 보겠습니다.

import pysftp

sftpHostName = "localhost"
sftpPort = 22
userName = "akinl"
privateKeyPath = "./id_rsa"

cnOptions = pysftp.CnOpts()
cnOptions.hostkeys = None

with pysftp.Connection(
    host=sftpHostName,
    port=sftpPort,
    username=userName,
    private_key=privateKeyPath,
    cnopts=cnOptions,
) as sftp:
    print(sftp.listdir("./store"))
    sftp.put("test.txt", preserve_mtime=True, remotepath="./store/upload.txt")
    print(sftp.listdir("./store"))

위 코드의 출력은 test.txt 파일이 upload.txt로 서버에 업로드되었고 이미지 내에서 볼 수 있음을 보여줍니다.

[]
['upload.txt']

python에서 sftp 기능 생성 - 출력 업로드

put_d() 메소드를 사용하여 디렉토리의 내용을 복사할 수 있습니다. 예를 들어 세 개의 텍스트 파일(one.txt, two.txtthree.txt)이 포함된 SeptData 디렉터리를 생성하고 디렉터리 내용을 root 폴더에 복사합니다.

그러나 복사할 경로에는 이전에 사용한 상대 경로가 아닌 전체 경로가 필요합니다.

import pysftp

sftpHostName = "localhost"
sftpPort = 22
userName = "akinl"
privateKeyPath = "./id_rsa"

cnOptions = pysftp.CnOpts()
cnOptions.hostkeys = None

with pysftp.Connection(
    host=sftpHostName,
    port=sftpPort,
    username=userName,
    private_key=privateKeyPath,
    cnopts=cnOptions,
) as sftp:
    print(sftp.listdir("./"))
    sftp.put_d(
        r"C:\Users\akinl\Documents\Python\SFTP\SeptData", "./", preserve_mtime=True
    )
    print(sftp.listdir("./"))

코드 출력:

['index.txt', 'main.py', 'store', 'test.txt']
['index.txt', 'main.py', 'one.txt', 'store', 'test.txt', 'three.txt', 'two.txt']

세 개의 파일은 이제 디렉토리 내의 파일 및 디렉토리 목록으로 표시되는 root 디렉토리 내에 있습니다. 따라서 get() 메서드를 사용하여 SFTP 서버에서 파일을 다운로드할 수 있습니다.

import pysftp

sftpHostName = "localhost"
sftpPort = 22
userName = "akinl"
privateKeyPath = "./id_rsa"

cnOptions = pysftp.CnOpts()
cnOptions.hostkeys = None

with pysftp.Connection(
    host=sftpHostName,
    port=sftpPort,
    username=userName,
    private_key=privateKeyPath,
    cnopts=cnOptions,
) as sftp:
    sftp.get("./store/upload.txt", preserve_mtime=True)

코드를 성공적으로 실행한 후 upload.txt 파일이 파이썬 파일의 디렉토리에 나타납니다. get_d()get_r() 메소드를 사용하여 원격 디렉토리를 가져올 수 있습니다.

paramiko를 사용하여 Python에서 SFTP 기능 생성

Paramiko는 클래스와 메서드를 통해 Python용 SSHv2의 간단한 구현을 제공하는 훌륭한 라이브러리입니다. 이러한 방법 중 일부를 사용하여 SFTP 서버에 대한 연결을 시작하고 공개 키 인증을 통해 해당 서버와 작업할 수 있습니다.

paramiko를 설치하려면 다음과 같이 pip 명령을 사용할 수 있습니다.

pip install paramiko

마지막 섹션의 연결 세부 정보를 사용하여 작업 디렉터리 변경에서 원격 SFTP 서버에서 파일 가져오기에 이르기까지 동일한 작업을 수행할 수 있습니다.

SSHClient()는 SFTP 서버에 연결할 새 SSH를 생성하고 set_missing_host_key_policy()는 알려진 호스트 키 없이 서버에 연결하기 위한 정책을 설정할 수 있도록 하며 connect() 메서드를 사용합니다. SFTP 서버에 대한 실제 연결을 만듭니다.

디렉토리를 store 디렉토리로 변경하고 각각 chdir, getcwdlistdir을 사용하여 현재 작업 디렉토리와 해당 디렉토리의 내용을 인쇄합니다.

import paramiko

sftpHostName = "localhost"
sftpPort = 22
userName = "akinl"
privateKeyPath = "./id_rsa"

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(
    hostname=sftpHostName, port=sftpPort, username=userName, key_filename=privateKeyPath
)

sftp_client = ssh.open_sftp()
sftp_client.chdir("./store")
print(sftp_client.getcwd())
print(sftp_client.listdir())

sftp_client.close()
ssh.close()

코드 출력:

/store
['one.txt', 'three.txt', 'two.txt', 'upload.txt']

첫 번째 줄에는 chdir() 메서드에 의해 설정된 현재 작업 디렉토리가 포함되고 두 번째 줄에는 store 디렉토리 내의 파일 및 디렉토리 목록이 포함됩니다.

Olorunfemi Akinlua avatar Olorunfemi Akinlua avatar

Olorunfemi is a lover of technology and computers. In addition, I write technology and coding content for developers and hobbyists. When not working, I learn to design, among other things.

LinkedIn