사전 FTP
프로토콜

FTP

gabury1고친 사람 github-actions[bot]

FTP 는 두 컴퓨터 사이에서 파일을 올리고 내려받게 해 줍니다. 명령을 주고받는 연결과 파일을 실어 나르는 연결을 따로 엽니다. 인터넷 초창기부터 쓰인 방식이라 오래된 서버와 장비에 지금도 남아 있습니다.

쉽고 빠른 이해

FTP 는 서버에 파일을 올리고 서버의 파일을 받아 오는 약속입니다. 웹 호스팅 서버에 사이트 파일을 올리는 일이 그 예입니다.

이런 약속이 없으면 상대가 바뀔 때마다 로그인하는 법, 파일 목록을 보는 법, 파일이 어디서 끝나는지 알리는 법을 새로 맞춰야 합니다.

어떻게 도는가:

  1. 서버에 명령용 연결을 하나 열고 계정 이름과 비밀번호로 로그인합니다
  2. 파일을 달라는 명령을 보내면 파일 내용은 새로 연 두 번째 연결로 따로 옵니다
  3. 파일을 다 보내면 두 번째 연결이 닫히고, 명령용 연결은 다음 명령을 기다립니다

대가도 있습니다. 비밀번호와 파일이 암호화 없이 오가서 중간에서 엿볼 수 있습니다. 연결을 두 개 쓰는 탓에 방화벽이나 공유기를 지날 때 두 번째 연결이 막히기 쉽습니다.

상세

FTP(File Transfer Protocol, 파일 전송 프로토콜)는 클라이언트가 서버에 접속해 파일을 올리고 받는 규칙입니다. 이 절은 FTP 가 연결을 왜 둘로 나누는지부터 봅니다. 그다음 로그인과 파일 한 개 받기를 실제 메시지로 따라갑니다. 마지막으로 방화벽 앞에서 생기는 문제와 보안의 빈틈을 봅니다.

FTP 가 두 연결을 쓰는 모양은 단골 가게에 전화를 걸어 둔 채 물건을 주문하는 장면과 비슷합니다. 주문과 대답은 전화로 오갑니다. 물건은 주문할 때마다 택배 트럭이 따로 와서 내려놓고 떠납니다.

파일을 주고받는 데 약속이 필요한 이유

파일 하나를 남의 컴퓨터로 옮기려 해도 정할 것이 여럿입니다. 누가 들어올 수 있는지 확인해야 합니다. 저쪽에 어떤 파일이 있는지 볼 수 있어야 합니다. 받는 쪽은 파일이 어디서 끝나는지 알아야 합니다.

FTP 는 이것들을 명령 몇 개로 정해 두었습니다. 운영체제가 달라도 이 명령만 맞추면 어느 클라이언트든 어느 서버와 파일을 주고받습니다. 약속이 없으면 상대가 바뀔 때마다 이 셋을 새로 맞춰야 합니다.

명령 연결과 데이터 연결

FTP 는 TCP(Transmission Control Protocol, 전송 제어 프로토콜) 위에서 돕니다. TCP 는 두 컴퓨터 사이에 연결을 맺고, 보낸 바이트를 빠짐없이 순서대로 건네 주는 프로토콜입니다.

접속해서 로그인하고 끝낼 때까지의 한 차례 이용을 세션이라고 부릅니다. FTP 는 한 세션에서 TCP 연결을 두 종류로 씁니다. 세션 내내 열어 두는 명령 연결 하나와, 실어 나를 것이 생길 때마다 새로 여는 데이터 연결입니다.

첫째는 명령 연결입니다. 로그인부터 끝인사까지 한 세션 내내 열려 있습니다. 명령과 그 대답은 전부 이 연결로 오갑니다. 제어 연결이라고도 부릅니다.

한 컴퓨터 안에서 어느 프로그램에 닿을지는 포트라는 번호로 가립니다. FTP 서버는 명령 연결을 21번 포트에서 기다립니다.

둘째는 데이터 연결입니다. 파일 내용이나 파일 목록처럼 실어 나를 것이 생길 때마다 새로 열고, 다 보내면 닫습니다. 파일 열 개를 받으면 데이터 연결도 열 번 열리고 닫힙니다.

이렇게 나누면 파일이 어디서 끝나는지 따로 알릴 필요가 없습니다. 보내는 쪽이 데이터 연결을 닫으면 그것이 파일의 끝입니다. 큰 파일이 오가는 동안에도 명령 연결은 비어 있어서 전송을 멈추라는 명령을 보낼 수 있습니다.

앞의 비유로 보면 명령 연결이 전화이고 데이터 연결이 택배 트럭입니다.

명령과 응답 코드

명령 연결로 오가는 것은 사람이 읽을 수 있는 글자 한 줄입니다. 클라이언트는 네 글자 안팎의 영어 명령어 뒤에 인자를 붙여 보냅니다. 자주 보는 명령은 아래와 같습니다.

명령 하는 일
USER 계정 이름을 보낸다
PASS 비밀번호를 보낸다
LIST 폴더 안의 파일 목록을 달라고 한다
RETR 파일을 내려받는다. retrieve(가져오기)의 줄임이다
STOR 파일을 올린다. store(저장하기)의 줄임이다
TYPE 텍스트로 보낼지, 바이트를 바꾸지 않고 보낼지 정한다
PORT 데이터 연결을 서버가 걸게 한다. 뒤의 「액티브 모드와 패시브 모드」에서 다룬다
PASV 데이터 연결을 클라이언트가 걸게 한다. passive(수동)의 줄임이다. 같은 절에서 다룬다
QUIT 세션을 끝낸다

서버는 명령마다 한 줄로 대답합니다. 대답은 세 자릿수 응답 코드와 그 뒤의 설명 문장으로 이루어집니다. 숫자는 프로그램이 읽고 다음 동작을 정하는 데 씁니다. 문장은 사람이 읽으라고 붙인 것이라 서버마다 조금씩 다릅니다.

응답 코드의 맨 앞 숫자가 대답의 성격을 정합니다. 프로그램은 맨 앞 숫자만 보고도 기다릴지, 다음 명령으로 갈지, 포기할지 고를 수 있습니다.

맨 앞 숫자 뜻 예
1 받았다. 곧 시작하고 끝나면 한 번 더 대답한다 150 곧 데이터 연결을 연다
2 끝났다 226 전송을 마치고 데이터 연결을 닫는다
3 받았다. 다음 정보가 더 필요하다 331 계정은 확인했다. 비밀번호를 달라
4 이번엔 실패했다. 다시 해 볼 만하다 425 데이터 연결을 못 열었다
5 실패했다. 같은 요청은 또 실패한다 550 파일이 없거나 권한이 없다

HTTP(HyperText Transfer Protocol, 웹 문서를 주고받는 프로토콜)가 세 자릿수 코드의 맨 앞 숫자로 대답의 성격을 가르는 것도 같은 방식입니다.

로그인까지 오가는 메시지

접속해서 로그인을 마칠 때까지 명령 연결에 오가는 줄을 옮기면 아래와 같습니다. C: 는 클라이언트가 보낸 줄이고 S: 는 서버가 보낸 줄입니다.

S: 220 Service ready    // 서버가 먼저 인사
C: USER alice           // 계정 이름
S: 331 Need password    // 비밀번호를 달라
C: PASS s3cret          // 암호화 없이 간다
S: 230 Logged in        // 로그인 끝

접속하자마자 먼저 말을 꺼내는 쪽은 서버입니다. 클라이언트는 220 을 받고 나서야 계정 이름을 보냅니다. 비밀번호 줄은 적힌 글자 그대로 네트워크를 지나갑니다.

공개 파일을 나눠 주는 서버는 계정 이름으로 anonymous 를 받아 누구나 들어오게 하기도 합니다. 이것을 익명 FTP라고 부릅니다.

파일 하나를 받는 순서

로그인한 뒤 파일 하나를 받을 때는 두 연결이 함께 움직입니다. 아래 그림은 서버의 두 포트를 따로 세워, 어느 메시지가 어느 연결로 가는지 보입니다.

sequenceDiagram
    participant 클라이언트
    participant 명령 as 서버 명령 포트
    participant 데이터 as 서버 데이터 포트
    클라이언트->>명령: PASV
    명령-->>클라이언트: 227 이 주소와 포트로 붙어라
    클라이언트->>데이터: 데이터 연결을 연다
    클라이언트->>명령: RETR report.csv
    명령-->>클라이언트: 150 곧 보낸다
    데이터-->>클라이언트: 파일 내용 · 다 보내면 연결을 닫는다
    명령-->>클라이언트: 226 전송을 마쳤다

클라이언트는 먼저 PASV 로 데이터 연결을 어디로 열지 묻습니다. 서버가 227 로 주소와 포트를 알려 주면 클라이언트가 그리로 새 연결을 엽니다. 그다음 RETR 로 report.csv 라는 파일을 달라고 합니다.

파일 내용은 데이터 연결로만 흐릅니다. 명령 연결에는 시작을 알리는 150 과 끝을 알리는 226 만 지나갑니다. 데이터 연결이 닫히는 것이 파일의 끝입니다. 226 은 그 전송이 탈 없이 끝났다는 확인입니다.

227 응답에서 포트를 읽는 법

227 응답은 주소와 포트를 쉼표로 이은 숫자 여섯 개로 알려 줍니다. 앞의 넷은 IP 주소(Internet Protocol address, 인터넷에서 컴퓨터를 가리키는 번호)입니다. 뒤의 둘은 포트 번호를 두 조각으로 나눈 것입니다.

여섯 숫자는 하나씩 0부터 255 까지, 곧 한 바이트에 담기는 값입니다. IP 주소는 네 조각이 각각 이 범위라서 그대로 네 숫자로 적습니다.

포트 번호는 0부터 65535 까지라서 한 바이트에 안 들어갑니다. 그래서 256 으로 나눈 몫과 나머지로 쪼개 보냅니다. 받은 쪽은 몫에 256 을 곱하고 나머지를 더해 되돌립니다.

S: 227 Entering Passive Mode (192,168,0,10,195,80)

주소 = 192.168.0.10      // 앞의 네 수
포트 = 195 × 256 + 80    // 50000

이 대답을 받은 클라이언트는 192.168.0.10 의 50000번 포트로 데이터 연결을 엽니다.

액티브 모드와 패시브 모드

데이터 연결을 누가 여느냐에 따라 FTP 의 동작이 두 가지로 나뉩니다. 둘은 액티브 모드와 패시브 모드입니다. 능동 모드와 수동 모드라고도 부릅니다.

액티브 모드 패시브 모드
클라이언트가 보내는 명령 PORT 와 자기 주소·포트 PASV
연결을 기다리는 쪽 클라이언트 서버
연결을 거는 쪽 서버. 자기 20번 포트에서 건다 클라이언트

액티브 모드가 원래 방식입니다. 클라이언트가 PORT 로 「여기로 걸어 달라」며 자기 주소를 알려 주면 서버가 거기로 연결을 겁니다. 패시브 모드는 방향을 뒤집어서, 연결을 거는 쪽을 늘 클라이언트로 둡니다. 앞 절에서 따라간 순서가 패시브 모드입니다.

방화벽과 NAT 앞에서 생기는 문제

방화벽은 밖에서 안으로 들어오는 연결을 기본으로 막는 장비나 프로그램입니다. 액티브 모드에서는 서버가 클라이언트 쪽으로 연결을 겁니다. 그러면 클라이언트 앞의 방화벽이 이 연결을 막습니다. 로그인은 되는데 파일 목록만 안 뜨는 증상이 대개 이것입니다.

NAT(Network Address Translation, 네트워크 주소 변환)는 집이나 회사 안에서만 쓰는 주소를 바깥에서 통하는 주소로 바꿔 주는 기능입니다. 집집마다 있는 공유기가 이 일을 합니다. 안쪽 컴퓨터 여러 대가 바깥 주소 하나를 나눠 쓰게 됩니다.

NAT 는 오가는 데이터 조각의 머리에 적힌 주소만 고칩니다. PORT 명령 안에 글자로 적힌 안쪽 주소는 손대지 않고 넘깁니다. 서버는 그 주소를 받아 연결을 걸지만 바깥에서는 닿지 않는 주소라 실패합니다.

패시브 모드는 클라이언트 쪽 문제를 풀어 줍니다. 대신 이번엔 서버 쪽 방화벽이 데이터용 포트를 열어 두어야 합니다. 어느 포트가 쓰일지 미리 모르니, 서버는 보통 쓸 포트 범위를 정해 두고 방화벽에서 그 범위를 엽니다.

방화벽 가운데는 명령 연결을 엿보는 것도 있습니다. PORT 나 227 속의 포트 번호를 읽고 그 포트만 잠깐 열어 줍니다.

텍스트 전송과 바이너리 전송

운영체제마다 텍스트 파일에서 줄 끝을 적는 방식이 다릅니다. 유닉스 계열은 줄 바꿈 글자 하나를 씁니다. 윈도우는 두 글자를 씁니다. FTP 는 전송 중에 이 차이를 메워 줍니다.

TYPE A 로 두면 텍스트 전송입니다. A 는 ASCII(American Standard Code for Information Interchange, 미국 정보 교환 표준 부호)에서 왔습니다. 보내는 쪽은 줄 끝을 네트워크용 표준 두 글자로 바꿔 보냅니다. 받는 쪽은 그것을 자기 운영체제 방식으로 다시 바꿉니다.

TYPE I 로 두면 바이너리 전송입니다. I 는 image 에서 왔습니다. 이 방식은 바이트를 하나도 바꾸지 않고 보냅니다. 이미지나 압축 파일을 텍스트 전송으로 보내면 줄 바꿈처럼 보이는 바이트가 바뀌어 파일이 깨집니다.

암호화 없이 오가는 비밀번호와 파일

FTP 는 명령도 파일도 암호화하지 않습니다. 같은 네트워크에서 오가는 데이터를 엿볼 수 있는 사람은 PASS 줄에서 비밀번호를 읽어 냅니다. 파일 내용도 마찬가지로 드러납니다.

FTPS(FTP Secure)는 FTP 의 두 연결을 TLS(Transport Layer Security, 이미 맺은 연결 위에 암호화를 씌우는 프로토콜)로 감싼 것입니다. 명령과 응답은 FTP 와 같습니다. 오가는 바이트만 암호화됩니다.

연결이 둘인 구조도 같아서 방화벽 문제가 함께 따라옵니다. 게다가 명령 연결까지 암호화되어서, 앞에서 본 명령 연결을 엿보는 방화벽도 그 안의 포트 번호를 읽지 못합니다.

SFTP(SSH File Transfer Protocol)는 SSH(Secure Shell, 원격 서버에 암호화된 연결로 접속하는 프로토콜) 연결 하나 안에서 파일 명령과 파일 내용을 함께 주고받습니다. 이름이 비슷할 뿐 FTP 와는 다른 프로토콜입니다. 연결이 하나라서 방화벽에서 포트 하나만 열면 됩니다.

FTP 를 쓰는 곳과 피하는 곳

지금 FTP 를 만나는 곳은 주로 오래전에 만들어진 시스템입니다. 웹 호스팅 서버에 사이트 파일을 올리는 경우가 있습니다. 회사끼리 밤마다 정산 파일을 주고받는 배치 작업도 있고, 펌웨어나 설정 파일을 FTP 로 주고받는 네트워크 장비도 있습니다. 상대가 FTP 만 말할 줄 알면 이쪽도 FTP 를 쓸 수밖에 없습니다.

부하 테스트 도구도 FTP 요청을 보낼 수 있습니다. 파일 서버가 동시에 몇 건의 내려받기를 견디는지 잴 때 씁니다.

새로 만드는 시스템은 대개 다른 수단을 고릅니다. 암호화가 필요하면 SFTP 나 FTPS 를 씁니다. 웹 애플리케이션과 붙어야 하면 HTTP 로 파일을 올리고 받습니다. 믿을 수 없는 네트워크를 지나면서 암호화 없는 FTP 를 쓰면 계정과 파일이 함께 드러납니다.

관련 항목

FTP 를 실어 나르는 전송·네트워크 프로토콜

TCP · IP · IP 주소 · IPv6 · 포트 번호 · 전송 계층

FTP 세션을 이루는 연결과 전송 모드

명령 연결 · 데이터 연결 · 액티브 모드 · 패시브 모드 · 세션 · 스트림 모드

FTP 명령 연결에 오가는 명령과 대답 형식

PASV · EPSV · EPRT · 상태 코드 · Telnet

FTP 연결을 가로막는 네트워크 장비

방화벽 · NAT · 공유기 · 사설 IP 주소 · 상태 기반 방화벽 · 애플리케이션 계층 게이트웨이

FTP 에 암호화를 더하거나 대신하는 전송 프로토콜

FTPS · SFTP · SSH · TLS · SCP · rsync

FTP 대신 파일을 올리고 받는 다른 수단

HTTP · WebDAV · Amazon S3 · 객체 스토리지 · TFTP

FTP 전송 방식이 다루는 파일 표현

ASCII · 줄바꿈 문자 · 텍스트 파일 · 바이너리 파일 · 문자 인코딩

FTP 의 보안 약점과 그것을 노리거나 막는 수단

평문 전송 · 패킷 스니핑 · 중간자 공격 · 익명 FTP · FTP 바운스 공격 · 암호화

FTP 를 구현하거나 호출하는 프로그램

JMeter · FileZilla · vsftpd · ProFTPD · curl · wget

FTP 가 속하는 상위 분류

프로토콜 · 응용 계층 · 네트워크 · 클라이언트-서버 모델 · 파일 전송

다른 이름: File Transfer Protocol · 파일 전송 프로토콜