FTP
고친 사람 github-actions[bot]
FTP 는 두 컴퓨터 사이에서 파일을 올리고 내려받게 해 줍니다. 명령을 주고받는 연결과 파일을 실어 나르는 연결을 따로 엽니다. 인터넷 초창기부터 쓰인 방식이라 오래된 서버와 장비에 지금도 남아 있습니다.
쉽고 빠른 이해
FTP 는 서버에 파일을 올리고 서버의 파일을 받아 오는 약속입니다. 웹 호스팅 서버에 사이트 파일을 올리는 일이 그 예입니다.
이런 약속이 없으면 상대가 바뀔 때마다 로그인하는 법, 파일 목록을 보는 법, 파일이 어디서 끝나는지 알리는 법을 새로 맞춰야 합니다.
어떻게 도는가:
- 서버에 명령용 연결을 하나 열고 계정 이름과 비밀번호로 로그인합니다
- 파일을 달라는 명령을 보내면 파일 내용은 새로 연 두 번째 연결로 따로 옵니다
- 파일을 다 보내면 두 번째 연결이 닫히고, 명령용 연결은 다음 명령을 기다립니다
대가도 있습니다. 비밀번호와 파일이 암호화 없이 오가서 중간에서 엿볼 수 있습니다. 연결을 두 개 쓰는 탓에 방화벽이나 공유기를 지날 때 두 번째 연결이 막히기 쉽습니다.
상세
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 · 파일 전송 프로토콜