C#

SFTP 파일 전송

SFTP (SSH FTP)

SFTP는 SSH File Transfer Protocol을 일컫는 것으로, SSH를 사용하여 서버에 파일을 전송하거나 다운받는데 사용한다. SFTP는 파일 송수신을 기존의 FTP 보다 더 안전한 방식으로 처리하는데, 실제 내부적으로 SSH 세션을 열고 파일 송수신을 진행한다. FTP는 디폴트로 포트 21을 사용하고, SFTP는 SSH 포트(디폴트로 22)를 기본적으로 사용한다. 일반적으로 보안상 FTP 보다는 SFTP를 사용할 것을 권장한다.

SFTP 라이브러리

SFTP를 C#에서 사용하기 위해서는 SFTP를 지원하는 SSH.NET, WinSCP .NET Assembly 등과 같은 3rd Party 라이브러리를 사용해야 한다. 아래는 nuget을 통해 SSH.NET과 WinSCP .NET Assembly를 설치하는 명령이다.

PM> Install-Package SSH.NET
PM> Install-Package WinSCP

SSH.NET을 이용한 SFTP 클라이언트

SSH.NET을 사용하여 SFTP 클라이언트 프로그램을 작성하기 위해서는 SftpClient 클래스를 사용한다. SftpClient 클래스는 다양한 메서드들을 제공하는데, 예를 들어 기본적으로 다운로드, 업로드, 디렉토리 리스트 등의 기능을 사용할 수 있다.

아래 예제는 SSH.NET을 사용하여 SFTP 서버에 접속한 후, 해당 계정의 홈디렉토리에 있는 파일/디렉토리를 표시하고, 하나의 파일을 다운로드한 후, 다시 그 파일을 다른 디렉토리에 업로드하는 샘플이다.

// using System;
// using System.IO;
// using Renci.SshNet;
// using Renci.SshNet.Sftp;

var ci = new ConnectionInfo("test.com",
    "user",
    new PasswordAuthenticationMethod("user", "pwd"));

using (var sftp = new SftpClient(ci))
{
    // SFTP 서버 연결
    sftp.Connect();

    // 현재 디렉토리 내용 표시
    foreach(SftpFile f in sftp.ListDirectory("."))
    {
        Console.WriteLine(f.Name);
    }

    // SFTP 다운로드
    using (var outfile = File.Create("ftptest.txt"))
    {
        sftp.DownloadFile("./ftptest.txt", outfile);
    }

    // SFTP 업로드
    using (var infile = File.Open("ftptest.txt", FileMode.Open))
    {
        sftp.UploadFile(infile, "./myftp/ftptest.txt");
    }

    sftp.Disconnect();
}

WinSCP .NET Assembly를 이용한 SFTP 클라이언트

WinSCP는 대표적인 윈도우즈용 FTP/SFTP/SCP/WebDav/S3 유틸러티 프로그램으로, 주로 로컬 컴퓨터와 원격 컴퓨터 간의 파일 전송에 사용된다. WinSCP는 파일 전송 Task들을 실행하기 위해 (마치 telnet 명령들과 같은) 명령어 처리 콘솔 인터페이스를 제공하는데, 이를 WinSCP Scripting Interface라 한다. 이러한 Scripting Interface에 기반한 .NET Wrapper를 WinSCP .NET Assembly라 부르며, 이를 통해 C#, VB.NET 등의 .NET 프로그램에서 WinSCP의 기능을 사용할 수 있게 되었다. WinSCP .NET Assembly의 원래 목적은 기존 Scripting Interface에서 처리하지 못하는 복잡한 프로그래밍 Task들을 쉽게 처리하도록 하는데 있기 때문에, 이는 제한된 기능만을 제공하는 라이브러리라 볼 수 있다.

WinSCP .NET Assembly를 사용하기 위해서는 아래와 같은 nuget 명령을 사용하여 라이브러리를 설치한다. WinSCP .NET Assembly는 WinSCPnet.dll 파일을 가리키며, nuget에서 기본적으로 WinSCP.exe 를 함께 설치하기 때문에, 별도로 WinSCP 유틸러티를 설치할 필요는 없다.

PM> Install-Package WinSCP

비록 제한적이긴 하나, WinSCP .NET Assembly를 이용하여 FTP/SFTP/SCP 기능을 쉽게 사용할 수 있다. WinSCP .NET Assembly를 사용하는 기본적인 절차는 다음과 같다.

  • WinSCP.SessionOptions 클래스의 객체를 생성하여, 서버 컴퓨터의 연결 정보를 지정한다
  • WinSCP.Session 클래스의 객체를 생성하고, Open(SessionOptions객체) 메서드를 호출하여 서버에 연결한다
  • 파일을 다운로드 하기위해 Session.GetFiles() 메서드를 사용한다
  • 파일을 업로드 하기위해 Session.PutFiles() 메서드를 사용한다
  • 디렉토리를 동기화(sync) 하기위해 Session.SynchronizeDirectorie() 메서드를 사용한다

아래 예제는 로컬 컴퓨터의 C:\src\* 파일들을 서버의 myftp 폴더로 업로드 하는 코드이다. SFTP 서버에 연결할 때, 접속하고자 하는 서버의 SshHostKeyFingerprint를 지정하거나, 서버를 신뢰한다면 GiveUpSecurityAndAcceptAnySshHostKey를 true로 설정한다. 또한, 한가지 주의할 것은 복수 파일들을 전송하고 할 때는, 서버 폴더명 뒤에 / 를 넣어야 한다는 점이다. 즉, "./myftp" 대신 "./myftp/" 를 사용해야 한다.

// using WinSCP;

using (Session session = new Session())
{
    // 세션 옵션 지정
    var sessionOptions = new SessionOptions
    {
        Protocol = Protocol.Sftp,
        HostName = "test.com",
        UserName = "user",
        Password = "pwd",
        //SshHostKeyFingerprint = "ssh-rsa 2048 xxxxxxxxxxx...="
        GiveUpSecurityAndAcceptAnySshHostKey = true
    };

    // 세션 연결
    session.Open(sessionOptions);

    // 파일 업로드
    var txOptions = new TransferOptions();
    txOptions.TransferMode = TransferMode.Binary;

    TransferOperationResult txResult;
    txResult = session.PutFiles(@"C:\src\*", "./myftp/", false, txOptions);

    // 에러 있으면 throw
    txResult.Check();

    // 결과 출력
    foreach (TransferEventArgs tx in txResult.Transfers)
    {
        Console.WriteLine($"{tx.FileName}: 업로드 성공");
    }
}

본 웹사이트는 광고를 포함하고 있습니다. 광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.

Previous Next Print