FTP 클라이언트가 vsftpd 서버에 접속하려 할 때 530 Login incorrect 응답을 받는 경우, 대부분의 관리자는 즉시 비밀번호를 의심하지만, 실제 원인은 인증 체인의 훨씬 더 깊은 계층에 숨어 있습니다. 이 오류는 단순한 자격 증명 실패가 아니라, 리눅스 사용자 인증 파이프라인 전체 — 특히 셸 유효성 검사, PAM 모듈 동작, chroot 환경 구성 — 에서 발생하는 다중 조건 충족 실패를 의미합니다. 아래 절차는 시스템 로그와 구성 파일을 기반으로 한 실용적 진단 프레임워크를 제공합니다.
1. 530 오류의 진짜 원인: 인증 흐름 재구성
vsftpd는 SSH와 달리 자체 인증 루틴을 수행하며, 다음 네 가지 단계를 순차적으로 거칩니다:
- 요청 수신: vsftpd 마스터 프로세스가 사용자 ID/비밀번호 수신
- 셸 검증:
/etc/passwd의 7번째 필드(셸 경로)가/etc/shells에 등록되어 있는지 확인 - PAM 인증:
pam_shells.so,pam_unix.so등 모듈을 통해 추가 검증 - 접근 제어 적용:
userlist_enable,chroot_local_user, SELinux 컨텍스트 등 최종 필터링
다음 명령어로 핵심 정보를 한 번에 확인할 수 있습니다:
# 사용자 셸 및 홈 디렉토리 조회
getent passwd ftpuser
# 현재 등록된 셸 목록
cat /etc/shells | grep -v '^#'
# vsftpd 서비스 상태 및 포트 바인딩
systemctl is-active vsftpd && ss -tlnp | grep :21
2. 로그 기반 근본 원인 식별
실시간 로그 추적은 문제 위치를 좁히는 가장 신뢰할 수 있는 방법입니다:
# vsftpd 관련 모든 최근 이벤트 (최근 10분)
journalctl -u vsftpd --since "10 minutes ago" --no-pager
# PAM 인증 실패 기록 집중 분석
grep "vsftpd.*auth" /var/log/secure | tail -15
로그에서 주목해야 할 패턴:
pam_shells: user 'ftpuser' has invalid shell '/bin/false'→/etc/shells누락pam_unix(vsftpd:auth): authentication failure→ 비밀번호 불일치 또는pam_unix.so설정 오류refusing to run with writable root inside chroot()→ chroot 디렉토리 권한 문제
3. 셸 관련 문제 해결 전략
/etc/shells는 단순한 텍스트 파일이지만, FTP 인증에서 결정적 역할을 합니다. 다음 세 가지 접근법 중 상황에 맞는 것을 선택하세요:
옵션 A: 셸 등록 (기본 권장)
# 사용자의 셸 경로를 /etc/shells에 추가
echo "/bin/bash" | sudo tee -a /etc/shells
# 또는 특정 계정만 대상으로
user_shell=$(getent passwd ftpuser | cut -d: -f7)
[[ -n "$user_shell" ]] && echo "$user_shell" | sudo tee -a /etc/shells
옵션 B: PAM 규칙 무시 (테스트 용도)
/etc/pam.d/vsftpd 파일에서 다음 줄을 주석 처리:
# auth [success=ignore default=bad] pam_shells.so
옵션 C: FTP 전용 계정 생성
sudo useradd -r -d /srv/ftp/ftpuser -s /usr/sbin/nologin ftpuser
sudo mkdir -p /srv/ftp/ftpuser/upload
sudo chown ftpuser:ftp /srv/ftp/ftpuser/upload
sudo chmod 755 /srv/ftp/ftpuser
4. 보안 강화를 위한 핵심 설정
생산 환경에서는 다음 설정 조합이 안정성과 기능성을 동시에 확보합니다:
chroot 보안 구조
# /etc/vsftpd.conf
chroot_local_user=YES
allow_writeable_chroot=YES
seccomp_sandbox=NO # SELinux 환경에서 필요 시
※ /srv/ftp/ftpuser 디렉토리는 소유자 및 그룹이 root여야 하며, 쓰기 권한은 없어야 합니다.
사용자 허용 목록 활성화
userlist_enable=YES
userlist_file=/etc/vsftpd.allowed
userlist_deny=NO
/etc/vsftpd.allowed에는 허용할 사용자 이름만 한 줄씩 기재합니다.
TLS 암호화 필수 적용
ssl_enable=YES
rsa_cert_file=/etc/ssl/certs/vsftpd.pem
rsa_private_key_file=/etc/ssl/private/vsftpd.key
force_local_logins_ssl=YES
force_local_data_ssl=YES
ssl_ciphers=HIGH:!aNULL:!MD5:!SSLv2:!SSLv3
5. 현장 진단 체크리스트
530 오류 발생 시 다음 순서로 점검하세요:
systemctl restart vsftpd && systemctl status vsftpd→ 서비스 재시작 후 상태 확인getent passwd ftpuser→ 계정 존재 여부 및 셸 경로 확인grep "$(getent passwd ftpuser | cut -d: -f7)" /etc/shells→ 셸 등록 여부 검사ls -ldZ /srv/ftp/ftpuser→ 디렉토리 소유권, 권한, SELinux 컨텍스트 동시 점검sudo vsftpd -t -f /etc/vsftpd.conf→ 구성 문법 오류 검사
SELinux가 활성화된 환경에서는 다음과 같은 부울 값이 필수적입니다:
sudo setsebool -P ftpd_full_access on
sudo semanage fcontext -a -t public_content_t "/srv/ftp(/.*)?"
sudo restorecon -Rv /srv/ftp