지식

[Linux] scp vs sftp — 뭐가 다르고, 이제 뭘 써야 하나

서버에 파일 하나 올릴 일이 생기면 손가락이 먼저 scp를 친다. 그런데 어디선가 "scp는 deprecated됐다, sftp를 써라"는 말을 듣고 나면 애매해진다. 잘만 되는데 왜? 바꿔야 하나? 이 글은 그 고민에 대한 정리다. 결론을 미리 말하면 — 퇴역한 것은 scp '프로토콜'이지 scp '명령'이 아니고, 최신 시스템에서 여러분이 치는 scp는 이미 속으로 SFTP로 동작하고 있을 가능성이 높다.

용어부터: 명령과 프로토콜은 다르다

혼란의 절반은 이름에서 온다.

  • scp는 두 가지를 가리킨다. ① 커맨드라인 명령 scp, ② 그 명령이 전통적으로 쓰던 전송 프로토콜(1980년대 BSD rcp의 프로토콜을 SSH 위에 그대로 얹은 것).
  • SFTP는 SSH 위에서 동작하도록 설계된 별도의 파일 전송 프로토콜(SSH File Transfer Protocol)이다. 이름 때문에 자주 오해받는데, FTP와는 아무 관련이 없다. FTP에 TLS를 씌운 FTPS와도 완전히 다른 물건이다. sftp라는 대화형 명령이 이 프로토콜의 기본 클라이언트다.

둘 다 SSH 연결 위에서 돌아가므로 인증(키·패스워드), 암호화, 포트(22)는 동일하다. 차이는 그 터널 안에서 파일을 주고받는 방식이다.

scp 프로토콜은 왜 퇴역했나

scp 프로토콜의 구조적 문제는 "원격 셸에 문자열을 던져서 처리한다"는 설계 자체에 있다.

1) 원격 경로가 셸을 통과한다. scp server:'*.log' .이 동작하는 이유는 그 글롭을 원격 셸이 풀기 때문이다. 편해 보이지만, 파일명이 셸에게 문자열로 전달된다는 뜻이고, 이는 곧 인젝션 표면이다. 실제로 백틱이 든 파일명이 원격에서 명령으로 실행되는 취약점(CVE-2020-15778)이 보고됐다.

# scp 프로토콜에서 이 글롭은 '원격 셸'이 해석한다
scp user@server:'/var/log/app-*.log' ./logs/
# 파일명에 셸 메타문자가 섞이면? — 그게 문제였다

2) 클라이언트가 서버를 믿는다. 구식 scp 클라이언트는 서버가 보내주는 파일명을 그대로 받아 썼다. 악의적인(혹은 침해된) 서버가 요청한 것과 다른 파일명을 보내 클라이언트 쪽 파일을 덮어쓸 수 있었다(CVE-2019-6111 계열).

3) 고칠 수가 없다. 프로토콜에 버전 협상도 확장 메커니즘도 없어서, 위 문제들을 프로토콜 수준에서 수리할 방법이 없었다. OpenSSH 팀이 8.0 릴리스 노트에서 scp 프로토콜을 "outdated, inflexible and not readily fixed"라고 못 박고 sftp·rsync 사용을 권고한 배경이다.

반면 SFTP는 처음부터 프로토콜로 설계됐다. 요청과 응답이 구조화된 패킷이라 셸이 끼어들 자리가 없고, 파일명은 데이터로만 취급되며, 부분 읽기/쓰기·디렉토리 조회·rename·stat 같은 파일시스템 연산이 프로토콜 차원에서 정의돼 있다.

OpenSSH의 해법: 명령은 남기고 속만 바꿨다

사람들의 scp 습관은 버릴 수 없으니, OpenSSH는 명령의 겉은 유지하고 밑단 프로토콜을 교체했다.

OpenSSH 버전 scp 명령의 동작
8.0 (2019) scp 프로토콜 퇴역 권고, 클라이언트 방어 패치
8.7 (2021) scp -s로 SFTP 프로토콜 모드 실험 도입
9.0 (2022) scp가 기본으로 SFTP 프로토콜 사용. 구 프로토콜은 -O 플래그로만

즉 OpenSSH 9.0 이상이라면, 여러분이 치는 scp src user@server:dst는 문법만 옛날 것이고 전송은 SFTP로 이뤄진다. "scp를 버려라"는 조언은 이 시점부로 사실상 자동 이행된 셈이다.

# 내 시스템이 어느 쪽인지 확인
ssh -V
# OpenSSH_9.x 이상이면 scp는 기본 SFTP 모드

scp -v somefile user@server: 2>&1 | grep -i sftp
# SFTP 모드면 subsystem 요청 로그가 보인다

scp -O somefile user@server:   # 굳이 구 프로토콜로 보내야 할 때 (구형 장비 등)

주의할 부수 효과 하나: SFTP 모드에서는 원격 글롭을 셸이 아니라 클라이언트·서버가 처리하므로, 구 프로토콜에서 되던 server:'$(command)' 같은 셸 확장 트릭은 (다행히) 더 이상 통하지 않는다. 원격 셸 확장에 기대던 스크립트가 있다면 이 지점에서 깨진다.

실사용 비교: 명령 대 명령

프로토콜 문제가 정리됐으니, 남는 고민은 "어떤 명령이 내 작업에 맞나"다.

scp 명령 sftp 명령
사용 모델 한 줄 복사 (cp 감각) 대화형 세션 (ls/cd/get/put) + 배치
전송 재개 불가 — 처음부터 다시 reget / reput으로 이어받기
원격 탐색 불가 (경로를 알아야 함) ls, cd로 둘러보며 결정
원격 파일 조작 복사만 rename, rm, mkdir, chmod
스크립팅 한 줄이라 자연스러움 -b batchfile로 명령 묶음 실행
재귀 복사 -r get -r / put -r

속도는 어떨까. 둘 다 같은 SSH 터널을 쓰므로 병목은 대개 암호화와 네트워크이고, 요즘 OpenSSH의 sftp는 버퍼링이 개선되어 실사용 차이는 미미하다. 속도가 정말 문제라면 답은 둘 다 아니고 rsync다(델타 전송·재개·동기화).

그래서 뭘 쓰나 — 상황별 결론

  • "이 파일 하나 저기로" 한 줄 복사scp 명령 그대로 쓴다. OpenSSH 9.0+면 이미 SFTP 프로토콜이라 보안 우려도 해소된 상태다. 습관을 바꿀 이유가 없다.
  • 수 GB짜리 전송, 끊기면 곤란sftp로 열고, 끊기면 reget/reput으로 잇는다. scp는 이어받기가 없어서 대용량에 근본적으로 불리하다.
  • 원격에 뭐가 있는지 보면서 골라 받아야 함sftp 대화형. 경로를 외워서 scp 한 줄을 조립하는 것보다 빠르다.
  • 주기적 동기화·백업·대량 트리 복사rsync -avz. scp/sftp의 영역이 아니다.
  • 한쪽이 OpenSSH 9.0 미만인 구형 시스템 → scp가 구 프로토콜로 동작할 수 있다. 신뢰할 수 없는 서버에서 파일을 받을 때는 이 조합을 피하고 sftp를 명시하는 게 안전하다.

정리

"scp vs sftp"는 이제 프로토콜 싸움이 아니다 — 그 싸움은 SFTP의 승리로 끝났고, scp 명령조차 SFTP 위로 이사했다. 남은 것은 인터페이스 취향의 문제다. 한 줄이면 scp, 세션이면 sftp, 동기화면 rsync. 단, 내 ssh -V가 9.0을 넘는지 한 번은 확인해 두자. 그 한 줄이 "습관을 그대로 둬도 되는가"의 답이다.

조회 0댓글 0

댓글

아직 댓글이 없습니다. 첫 댓글을 남겨보세요.