SFTP 장애는 “파일이 안 올라간다”로 시작하지만, 실제로는 SSH 세션 끊김, DNS/네트워크 품질, 디스크 부족, sshd 설정 변경, chroot 권한 문제 등 원인이 섞여 있는 경우가 많습니다. 여기서는 빠른 복구(임시) → 근본 해결 → 재발 방지 순서로, 그리고 마지막에 롤백/복구 경로(안전장치)까지 같이 정리합니다.

SFTP 안전 복구와 롤백을 상징하는 자물쇠와 폴더

먼저 ‘지금 당장 전송을 다시 되게 만들기’부터 시작해도 괜찮습니다.

1) 빠른 복구(임시): 영향 최소화 우선순위

아래는 “원인 분석 전”에 운영 영향만 줄이는 임시 조치들입니다. 단, 임시 조치는 반드시 기록해두고(언제/누가/무엇을), 근본 해결 후 되돌리는 것을 권장합니다.

  • 접속 경로 우회: 가능하면 동일 서버의 다른 계정/다른 디렉터리로 임시 업로드 경로를 열어 배포를 이어갑니다(예: /var/tmp/upload-staging).
  • 전송 분할: 대용량 1개 파일이 끊긴다면 작은 단위로 나눠 업로드해 업무를 진행합니다(클라이언트의 분할 업로드 기능 활용).
  • 동시 접속 낮추기: CI/CD, 배포 스크립트, 운영자 도구에서 동시 업로드 수를 줄여 SSH 세션 부담을 낮춥니다.
  • 디스크/인오드 즉시 확인: 공간 부족이면 SFTP는 ‘느림/끊김/쓰기 실패’처럼 보일 수 있습니다.

서버에서 빠르게 확인할 것(명령은 읽기 전용 위주): 디스크는 df -h, 인오드는 df -i, 최근 로그는 아래 2)에서 바로 확인합니다.

2) 증상 분류와 로그 확인: 어디서 끊기는지 먼저 잡기

Debian에서는 보통 SSH/SFTP 로그가 /var/log/auth.log에 쌓입니다. 끊김/재시도/권한 문제는 대부분 여기서 단서가 나옵니다.

SFTP 장애 분석을 위한 로그 점검 일러스트

  • 인증/세션: “Accepted password/publickey”, “session opened/closed” 패턴이 반복되는지 확인
  • 강제 종료: “Connection reset”, “Broken pipe”, “timeout” 등 네트워크/유휴 시간 관련 문구 확인
  • 권한/경로: chroot 사용 시 “bad ownership or modes for chroot directory” 같은 문구가 자주 원인
  • SFTP 서브시스템: internal-sftp 사용 여부와 에러 메시지 확인

또 하나는 서버 자원입니다. SFTP가 느릴 때는 CPU보다 디스크 I/O 대기가 범인인 경우가 많습니다. 동시에 PHP 앱이 로그 폭주/캐시 미스 등으로 디스크를 두드리면 SFTP 전송도 같이 느려집니다.

즉, “SFTP 문제”가 아니라 “서버 디스크가 바빠서 SFTP가 피해를 보는 문제”일 수 있습니다.

3) 근본 해결 ①: sshd 설정(SFTP/세션/타임아웃) 점검

운영 중 변경 이력이 있다면 /etc/ssh/sshd_config 또는 include 파일(/etc/ssh/sshd_config.d/*)에서 SFTP 관련 설정을 먼저 봅니다. 특히 아래는 끊김/느림과 연관이 잦습니다.

  • Subsystem sftp: internal-sftp 사용 여부(외부 sftp-server 경로 문제를 줄이려면 internal-sftp가 안정적인 편)
  • ClientAliveInterval / ClientAliveCountMax: 유휴 연결이 중간 장비(NAT/방화벽)에서 끊기는 상황 완화
  • Match User / Match Group: 특정 사용자만 chroot, internal-sftp 적용하는 규칙이 충돌하지 않는지

설정 파일을 바꿨다면 바로 재시작하기 전에 sshd -t로 문법 검증을 먼저 하고, 가능하면 새 SSH 세션을 하나 더 열어 둔 상태에서 reload/restart를 진행합니다(실수로 접속이 끊겨서 복구가 어려워지는 상황을 피하기 위함).

4) 근본 해결 ②: chroot/권한/디렉터리 구조 문제(가장 흔한 실수)

SFTP만 허용하려고 chroot를 걸었을 때, 접속은 되는데 업로드가 안 되거나 바로 끊기는 케이스가 많습니다. 핵심 규칙은 단순합니다.

  • chroot로 지정한 최상위 디렉터리(ChrootDirectory)는 보통 root:root 소유, 그리고 쓰기 권한이 없어야 합니다.
  • 사용자가 실제로 업로드할 디렉터리는 chroot 내부에 별도로 만들고(예: /home/sftpuser/upload), 그곳에만 쓰기 권한을 줍니다.
  • 심볼릭 링크로 바깥을 가리키게 만들면 정책/보안상 막히거나 예기치 않은 오류가 날 수 있습니다.

권한이 꼬여 있을 때 auth.log에 경고가 꽤 친절하게 나옵니다. 로그 문구를 기준으로 해당 디렉터리의 소유자/권한을 다시 맞추는 것이 정공법입니다.

5) 근본 해결 ③: 디스크/파일시스템/I/O 병목(PHP 앱과 함께 보는 관점)

SFTP 전송이 “갑자기” 느려졌다면, 같은 시점에 서버의 쓰기 작업이 폭증했는지 확인하는 게 좋습니다. 특히 PHP 앱이 아래 상황이면 디스크 I/O가 크게 튈 수 있습니다.

  • 에러 로그가 폭주(권한 문제, DB 연결 실패 반복 등)해서 로그 파일이 급성장
  • 세션 저장이 파일 기반인데 트래픽 증가로 /var/lib/php/sessions I/O 증가
  • 배포 시점에 캐시/컴파일 파일이 대량 생성(프레임워크 캐시, opcode cache warmup 등)

이 경우 SFTP 자체 설정만 손봐서는 체감이 안 좋아질 수 있습니다. “SFTP 서버 성능”이 아니라 “서버 저장장치가 바쁨”이 원인이기 때문입니다. 로그 폭주를 막고, 세션/로그 경로를 분리하거나, 로테이션 정책을 점검하는 쪽이 더 빨리 좋아지는 경우가 많습니다.

6) 재발 방지: 롤백/복구 경로(안전장치) 설계 체크리스트

sshd 설정 변경 시 롤백 경로 체크리스트

  • sshd_config 변경 전 백업: 날짜를 붙여 원본을 보관(예: sshd_config.YYYYMMDD.bak)
  • 적용 전 검증 절차: sshd -t로 문법 확인 → 가능하면 reload 우선 → 문제 시 즉시 원복
  • 세션 안전장치: 설정 적용 중에는 기존 SSH 세션을 최소 1개 유지(잠금 방지)
  • 임시 업로드 경로 준비: 장애 시 사용할 staging 디렉터리와 권한을 미리 만들어 문서화
  • 로그/디스크 모니터링: /var/log/auth.log, 디스크 사용률(df -h), 인오드(df -i) 알림 임계치 설정
  • 변경 이력 남기기: “왜 바꿨는지”가 남아야 다음 장애에서 시간을 줄일 수 있음

추가로, 배포/업로드가 SFTP에만 의존한다면, 장기적으로는 업로드 경로를 분리(별도 볼륨/스토리지)하거나 배포 파이프라인에서 SFTP 의존도를 낮추는 것도 재발 방지에 도움이 됩니다.

마무리

SFTP 끊김/지연은 원인이 다양해서, “임시로 살리고(업무 지속) → 로그로 분류 → sshd/chroot/디스크 순서로 원인 제거” 흐름이 가장 안전합니다.

특히 sshd 설정 변경은 작은 실수로도 원격 접속 자체가 막힐 수 있으니, 백업·검증·세션 유지 같은 롤백 경로를 먼저 만들어 둔 뒤에 손대는 습관이 큰 사고를 줄여줍니다.