SFTP protocol을 이용하여 파일공유 시스템 구축

강정우·2024년 1월 7일
0

Dev_Ops

목록 보기
6/15
post-thumbnail

SFTP란?

SFTP(Secure File Transfer Protocol)는 파일 전송에 사용되는 프로토콜 중 하나로, 네트워크를 통해 데이터를 안전하게 전송할 수 있도록 설계되어있다.
이 프로토콜은 SSH(Secure Shell) 프로토콜을 기반으로 하여 통신하는 도중에 데이터가 암호화되어 전송되므로, 전송 중인 데이터의 기밀성과 무결성을 보장한다.

SFTP 특징

1. 암호화

SFTP는 데이터를 암호화하여 전송하기 때문에, 네트워크를 통한 데이터 도청이나 중간자 공격에 대해 안전하다.

2. 인증

사용자는 보통 암호나 SSH 키를 통해 인증을 받아야 서버에 접근할 수 있다. 이는 무단 접근을 방지하는 데 도움된다.

3. 명령어 지원

파일 전송뿐만 아니라, 파일 삭제, 디렉토리 리스트 조회, 파일 이름 변경 등 파일 시스템 관련 다양한 명령어를 지원한다.

4. 포트

SFTP는 SSH와 같은 포트(일반적으로 22번 포트)를 사용한다.
이는 포트 관리를 단순화하고, 추가적인 보안 포트를 열 필요가 없게 만든다.

5. 플랫폼 독립성

다양한 운영 체제에서 SFTP 클라이언트와 서버 소프트웨어를 사용할 수 있다.

SFTP 프로토콜 동작 과정

1. 클라이언트 준비

클라이언트(Windows)는 먼저 SFTP 클라이언트 프로그램이 필요하다.
가장 대표적인 예로 'WinSCP', 'FileZilla', 'putty' 등이 있으며, cmd로 명령어를 통해 접속할 수 있다. 이땐 당연 GUI는 제공되지 않는다.

2. 연결 요청

SFTP 클라이언트를 열고, 서버의 IP 주소나 도메인명과 함께 포트 번호(default = 22), 사용자 이름을 입력한다.
이후 연결 요청을 시작한다.

3. 서버 인증

클라이언트는 서버에 연결 요청을 보내고, 서버는 자신의 신원을 증명하기 위해 공개 키를 클라이언트에게 전송한다.
클라이언트는 이전에 연결했던 기록이 있다면 서버의 공개 키를 신뢰하고,
처음 연결하는 경우 사용자에게 서버의 공개 키를 신뢰할지 확인한.

4. 클라이언트 인증

클라이언트는 사용자가 입력한 로그인 정보(비밀번호나 SSH 키)를 이용하여 서버에 자신을 인증한다.
이때, SSH 키를 이용하는 경우, 클라이언트는 개인 키를 사용해 인증 요청에 서명하고 이 서명은 서버에서 공개 키를 이용하여 검증된다.

5. 암호화된 세션 설정

인증이 성공적으로 이루어지면, 클라이언트와 서버 사이에 암호화된 SSH 세션이 구축된다.
이 세션을 통해 모든 통신 데이터는 암호화되어 전송된다.

6. 파일 전송 및 관리

암호화된 세션을 통해 클라이언트는 파일을 업로드하거나 다운로드하고, 서버 상의 파일 관리 명령어(삭제, 이름 변경, 디렉토리 생성 등)를 실행할 수 있다. 이 모든 데이터 전송은 암호화되어 처리된다.

7. 세션 종료

사용자가 작업을 완료하면, 클라이언트는 서버에게 세션 종료를 요청하고, 연결을 안전하게 종료한다.

SFTP의 핵심은 데이터의 암호화와 서버 및 클라이언트의 상호 인증이다.
이를 통해 데이터의 기밀성, 무결성 및 인증성이 확보된다.

SFTP를 사용할 때 SSH가 필요한 이유.

SFTP(Server File Transfer Protocol)SSH(Secure Shell) 프로토콜의 일부분으로, SSH를 통해 암호화된 네트워크 연결 상에서 파일을 전송하는 기능을 제공한다.
SFTPFTP(File Transfer Protocol)의 보안 버전으로, 모든 데이터 전송이 SSH 세션 내에서 이루어지며 이로 인해 데이터가 암호화되어 전송된다.

SSH 서버가 설치되어 있을 때 SSH 프로토콜을 통해 안전하게 원격 서버에 접속할 수 있으며,
SFTP 서비스 역시 이러한 안전한 채널을 통해 파일 전송 기능을 제공한다.

따라서 SFTP 서버를 구축하기 위해서는 SSH 서버가 설치되어 있어야 하며, SSH 서비스가 활성화되어 있어야 한다.

즉, SFTP는 SSH의 서브시스템으로 작동하기 때문에 SFTP 서버 구축과 운영에는 SSH가 필수적이다.

ubuntu에서 SFTP 서버 실행시키기

앞서 설명했듯 SFTP 서버를 실행시키기 위해선 기본적으로 SSH 프로토콜를 통해 통신하기 때문에 OpenSSH 서버가 필요하다.

1. OpenSSH 서버 설치

sudo apt-get update
sudo apt-get install openssh-server

2. SSH 서비스 확인

sudo systemctl status ssh

2-1. 서비스가 활성화되어 있지 않다면, 활성화

sudo systemctl enable ssh
sudo systemctl start ssh

3. 방화벽 설정

SSH 프로토콜(default 22번 포트)를 통해 외부에서 접속을 허용하려면, Ubuntu 시스템의 방화벽을 구성하여 해당 포트를 열어야 한다.

sudo ufw allow ssh
sudo ufw enable
sudo ufw status

4. 사용자 계정 확인

SFTP를 사용하기 위해선 서버의 시스템 계정에 사용자가 등록되어있는 상태여야한다.
만약 필요하다면 새로운 사용자를 추가하면 된다.

sudo adduser [새사용자명]

5. 디렉토리 권한 설정

공유할 폴더 경로를 생성하고 사용자가 SFTP를 통해 접근할 수 있는 디렉토리의 권한을 적절하게 설정한다.
사용자가 해당 디렉토리에 파일을 읽고, 쓰고, 실행할 수 있는 권한을 설정하면 된다.

sudo mkdir -p <공유할 폴더 경로>
sudo chown 사용자Id:사용자Id <공유할 폴더 경로>
sudo ls -ld

6. SSH 구성 파일 수정

필요한 경우, /etc/ssh/sshd_config 파일을 수정하여 SFTP 설정을 조정할 수 있다.
예를 들어, 특정 사용자에게만 SFTP 접근을 허용하거나, Chroot 환경을 구성하여 사용자를 특정 디렉토리에 제한하는 설정을 할 수 있다.

sudo nano /etc/ssh/sshd_config
  • 가장 밑에 아래과 같이 SFTP 사용을 허용할 사용자 계정을 등록하고
Match User <사용자Id>
    ChrootDirectory <공유할 폴더 경로>
    ForceCommand internal-sftp
    AllowTcpForwarding no
    X11Forwarding no
    PermitTunnel no
    AllowAgentForwarding no

Match User: sshd_config에서 특정 조건에 맞는 사용자에 대한 설정을 시작할 때 사용된다.
ChrootDirectory: <사용자Id>가 SFTP를 통해 접속할 때, 이 디렉토리를 사용자의 루트 디렉토리로 제한한다.
ForceCommand: 사용자가 SSH를 통해 서버에 접속할 때 실행할 명령을 강제한다. 여기서 internal-sftp를 강제함으로써, 사용자가 SSH를 통해 로그인하더라도 오직 SFTP 인터페이스만 사용할 수 있게 된다. 즉, 일반적인 쉘 접근은 불가능합니다.
AllowTcpForwarding: TCP 포워딩 기능을 사용할 수 있는지 여부를 설정한다. no로 설정하면 사용자가 SSH 포트 포워딩을 사용하지 못하게 하여, 터널링을 통한 네트워크 서비스 접근을 방지한다.
X11Forwarding: X11 포워딩 기능을 사용할 수 있는지 여부를 설정한다. no로 설정하면 사용자가 그래픽 사용자 인터페이스(GUI) 애플리케이션을 원격으로 실행하는 것을 방지한다.
PermitTunnel: 포인트-투-포인트 네트워크 터널을 허용할지 여부를 결정한다. no로 설정하면 사용자가 SSH VPN 터널을 설정하는 것을 방지한다.
AllowAgentForwarding: SSH 에이전트 포워딩을 허용할지 여부를 설정한다. no로 설정하면 사용자가 SSH 키 인증을 다른 서버로 포워딩하는 것을 방지한.
PermitTTY: SSH를 통해 원격 터미널 세션(TTY)을 할당할 수 있는지 여부를 결정한다. no로 설정하면 사용자는 SSH를 통해 원격 쉘에 로그인하고 터미널 세션을 시작할 수 없다.

바로 그 위에 SFTP 서브시스템을 아래와 같이 수정해주면 된다.

Subsystem sftp internal-sftp
  • 참고
    Subsystem: SSH 서버에 서브시스템을 선언하는 키워드이다. 서브시스템은 SSH 연결을 통해 원격으로 실행할 수 있는 외부 서비스를 의미한다.
    sftp: 이것은 구성된 서브시스템의 이름을 가리키며, SSH를 통해 접근할 수 있는 SFTP 서비스를 의미한다.
    internal-sftp: 이것은 SSH 서버가 사용할 SFTP 서버의 구현을 지정한다. internal-sftp는 SSH 서버에 내장된 SFTP 서버를 사용하라는 의미로, 별도의 SFTP 서버 데몬 없이 SFTP 세션을 처리할 수 있게 한다.

이 설정으로 인해 SSH 서버는 SFTP 요청을 받을 때 internal-sftp를 사용하여 처리하게 된다. 이 내장 SFTP 서버는 보안성이 높은 파일 전송을 위해 설계되었으며, 별도의 SFTP 소프트웨어를 설치할 필요가 없다.
이 방식은 시스템의 보안을 강화하고 구성을 단순화하는 장점이 있다.

요즘은 보안상의 이유로 22번 포트를 사용하지 않는다. 따라서 상단부에 원하는 포트 번호를 설정하고

# What ports, IPs and protocols we listen for
Port 2222

SSH 서비스를 재시작한다.

sudo systemctl restart ssh

그리고 수정한 포트 번호를 방화벽에 등록해주고

sudo systemctl restart ssh

기존에 등록한 포트를 삭제하고 새로운 포트를 등록해주면 된다.

sudo ufw allow 2222/tcp
sudo ufw delete allow 22/tcp

7. SSH 서비스 재시작

sudo systemctl restart ssh

중요. sshd_config 파일에서 외부에서 마운트 된 폴더경로를 설정하면 안 된다.

사실 안 되는 것은 아니다. 무조껀 root 계정만 가능하다.
그 외 계정을 등록하면 권한이 r-x 즉, 읽기, 실행만 되지 수정, 생성, 삭제는 안 된다.

이러한 설정은 흔히 네트워크 파일 시스템(NFS)이나 외부 스토리지를 마운트하여 사용할 때 에러가 발생할 수 있다.

즉, ChrootDirectory 지시어를 사용하여 SFTP 사용자를 특정 디렉토리로 제한할 때, 그 디렉토리가 외부에서 마운트된 저장 공간인 경우 에러가 발생할 수 있다.

ChrootDirectory 설정은 다음과 같은 요구 사항을 충족해야 정상적으로 작동한다.

1. 소유권 및 권한

ChrootDirectory <공유할 폴더 경로>로 지정된 디렉토리는 root 사용자에게 소유되어야 하며, 그룹이나 다른 사용자에게는 쓰기 권한이 없어야 한다.
이는 보안상의 이유로, chroot 환경 내에서의 권한 상승을 방지하기 위함이다.

2. 파일 시스템

일부 외부 파일 시스템은 chroot 작업과 호환되지 않을 수 있다.
예를 들어, 특정 네트워크 파일 시스템은 chroot 환경에서의 사용에 제한을 둘 수 있다.

3. 마운트 옵션

외부 저장소가 시스템에 마운트될 때, nosuid, nodev, noexec와 같은 옵션이 설정되어 있다면, 이는 chroot 환경 내에서의 실행을 제한할 수 있다.

체크목록

만약 외부에서 마운트된 저장 공간을 ChrootDirectory로 사용하려고 할 때 에러가 발생한다면, 다음과 같은 단계체크해보자.

1. 마운트 확인

외부 저장 공간이 올바르게 마운트되었는지 확인한다. 마운트 상태는 mount 또는 df -h 명령어로 확인할 수 있다.

2. 소유권 및 권한

ChrootDirectory로 지정된 디렉토리의 소유권과 권한을 확인한.
root 소유이며, 다른 사용자나 그룹에게는 쓰기 권한이 없어야 한다.

3. 로그 파일 검토

SSH 서버의 로그 파일(/var/log/auth.log 또는 /var/log/secure)을 확인하여 구체적인 에러 메시지를 찾아보면 된다.

4. 마운트 옵션 조정

필요하다면 /etc/fstab 파일을 수정하여 외부 저장 공간의 마운트 옵션을 조정하면 된다.

5. SELinux 또는 AppArmor 설정

SELinux 또는 AppArmor와 같은 추가적인 보안 모듈 설정이 문제를 일으킬 수 있으니, 해당 설정을 확인하고 필요에 따라 조정하면 된다.

해결법 ( 격리 디렉토리 )

ChrootDirectory를 사용하여 SFTP 사용자를 격리시키는 경우, 보안상의 이유로 chroot 된 디렉토리는 root 사용자의 소유여야 하며, root 외의 다른 사용자에게는 쓰기 권한이 없어야 한다고 하였다.

그러나, 격리된 환경 내부에서 다른 사용자에게 쓰기 권한을 부여하고 싶은 경우, 격리된 디렉토리 내부에 서브 디렉토리를 만들고, 해당 서브 디렉토리에 쓰기 권한을 부여하여 이 문제를 해결할 수 있다.

1. 루트 소유의 격리 디렉토리 생성

루트 사용자 소유의 격리 디렉토리를 생성한다. 이 디렉토리는 root만 쓸 수 있어야 한다.

sudo mkdir /home/sftpuser
sudo chown root:root /home/sftpuser
sudo chmod 755 /home/sftpuser

2. 사용자의 홈 디렉토리 생성

격리 디렉토리 내부에 사용자가 접근할 수 있는 서브 디렉토리를 생성하고, 해당 사용자에게 쓰기 권한을 부여한다.

sudo mkdir /home/sftpuser/writeable
sudo chown sftpuser:sftpuser /home/sftpuser/writeable
sudo chmod 755 /home/sftpuser/writeable

3. SSH 구성 파일 수정

/etc/ssh/sshd_config 파일에서 ChrootDirectory를 설정할 때, 사용자가 접근할 수 있는 디렉토리로 경로를 지정한다.

Match User sftpuser
ChrootDirectory /home/sftpuser
ForceCommand internal-sftp

이 설정은 sftpuser가 SFTP를 통해 로그인할 때 /home/sftpuser 디렉토리를 루트(/)로 인식하게 하며, /writeable 디렉토리 내에서는 파일 생성 및 수정이 가능하게 한다.

4. SSH 서비스 재시작:

sudo systemctl restart sshd

외부에서 SFTP 접근하는 방법

SFTP 클라이언트 사용

FileZilla, WinSCP, putty 등을 사용하면 된다.

FileZilla

putty

CMD 접근

window, MacOS

sftp 사용자명@호스트주소

명령어

ls: 서버의 디렉토리 목록
get 파일명: 서버에서 파일을 다운로드
put 파일명: 로컬에서 서버로 파일을 업로드
cd 디렉토리명: 서버 내의 디렉토리를 변경
mkdir 디렉토리명: 서버에 새 디렉토리를 만듦
rmdir 디렉토리명: 서버에서 디렉토리를 삭제
rm 파일명: 서버에서 파일을 삭제
chmod 권한 파일명: 서버에서 파일의 권한을 변경
exit: SFTP 세션을 종료

profile
智(지)! 德(덕)! 體(체)!

0개의 댓글