본문 바로가기

Software Engineering/Linux

FTP 서버에 대해 배운 내용 (ubuntu, vsftpd)

사진: Unsplash 의 Hans-Peter Gauster

 

FTP 서버를 셋업하다 알게 된 내용들을 정리하였습니다. Ubuntu 20.04 / vsftpd FTP server를 사용하였습니다.

 

1. FTP 기본 개념

  • FTP는 제어 연결, 데이터 연결 2개의 연결을 사용하여 파일을 송수신한다.
  • 제어 연결은
    • 목록 보기(ls), 다운로드(get), 업로드(put)과 같은 명령을 전송하는데 사용 된다.
    • 21번 포트를 기본값으로 사용한다. (사용자 정의 포트로 변경 가능)
    • 클라이언트가 서버에 접속하는 연결이다.
    • 제어 연결은 active/passive 모드와 상관 없이 공통 연결이다.
    • 제어 연결은 FTP 세션이 끝날 때 까지 유지 된다.
  • 데이터 연결은
    • 제어 연결에서 전송된 명령을 실행하기 위해 파일 데이터나 디렉토리 목록을 전송하는데 사용된다.
    • 데이터 전송이 필요할 때 일시적으로 생성되고, 전송이 끝나면 닫힌다.
    • 데이터 연결 방식에 따라 active/passive 모드가 나뉜다.
    • active 모드가 먼저 나오고, 이후 passive 모드가 추가 되었다.
    • 현재는 passive 모드를 기본값으로 (대부분) 사용한다.
    • FTP 서버에서는 active/passive 모드 연결을 허용할 지 결정 할 수 있다. (active만 사용 / passive만 사용 / 둘 다 사용)
    • 데이터 연결에 active 모드를 사용할지 passive 모드를 사용할지는 클라이언트에서 결정한다.
  • 데이터 연결 - active 모드는
    • 서버가 클라이언트에게 연결하는 방식이다.
    • 전송 시나리오는
      • 제어 연결: 클라이언트 아웃바운드 랜덤 포트 > 서버 제어 연결 포트(21)로 연결 시작
      • 제어 연결: 클라이언트 아웃바운드 랜덤 포트 > 서버 제어 연결 포트(21)에 클라이언트가 수신을 대기할 포트를 알려줌
      • 데이터 연결: 서버 아웃바운드 데이터 전송 포트(20) > 클라이언트 수신 대기 포트 연결하여 파일 전송
    • 클라이언트가 방화벽/공유기 뒤에 있어서 외부 IP와 직접 매칭이 되지 않는 경우에는 인바운드 포트가 막혀 있는 경우가 많아서 데이터 전송에 실패하는 경우가 많음
    • 회사 사내 폐쇠망 처럼 클라이언트 IP가 별도의 공유기(NAT)로 재매핑 되지 않는 경우는 active 모드도 사용 가능
  • 데이터 연결 - passive 모드는
    • 클라이언트가 서버에 연결하는 방식이다.
    • 전송 시나리오는
      • 제어 연결: 클라이언트 아웃바운드 랜덤 포트 > 서버 제어 연결 포트(21)로 연결 시작
      • 제어 연결: 클라이언트 아웃바운드 랜덤 포트 > 서버 제어 연결 포트(21)에 PASV 모드 요청, 서버가 수신 대기할 랜덤 포트를 알려줌(pasv_min_port~pasv_max_port 중 1개)
      • 데이터 연결: 클라이언트 아웃바운드 랜덤 포트2 > 서버 데이터 연결 포트에 연결하여 파일 전송
    • 제어 연결, 데이터 연결 모두 클라이언트가 서버에 연결하는 방식이다.
    • 서버에서는 제어 포트(21)와 passive 포트 대역의 포트 방화벽을 열어주어야 한다.

2. vsftpd 설정 관련

  • 기본 설정 파일의 위치는 /etc/vsftpd.conf
  • 기본 설정
    • anonymous_enable=NO: ID 없이 익명 접속 허용 여부 결정
    • local_enable=NO: /etc/passwd에 있는 로컬 계정의 로그인을 허용할지 결정, 필수적으로 YES로 설정해야함
    • listen=YES: 데몬 모드(standalone)으로 실행할지 결정, YES로 설정해야 vsftpd가 직접 포트 리스닝을 수행함. NO로 하면 inetd나 xinetd 같은 슈퍼 데몬이 vsftpd를 관리함
    • listen_port=21: 제어 연결 포트를 설정
  • 데이터 전송 모드 설정
    • ftp_data_port=20: active 모드에서 서버가 클라이언트로 접속하는 아웃바운드 포트, passive에서는 의미 없는 설정
    • connect_from_port_20=NO: active 모드에서 서버가 20번 아웃바운드 포트로 클라이언트에 연결할지 결정, YES로 해야 표준 active 모드 동작이 됨, 대부분 YES로 사용, 서버의 아웃바운드 포트이므로 방화벽 측면에서는 의미 없는 설정
    • pasv_enable=YES: passive 모드를 지원할지 결정
    • pasv_min_port, pasv_max_port: 기본값0(랜덤), passive 모드에서 클라이언트가 서버로 접속 할 포트 범위 지정, 방화벽 설정 시 이 범위 포트를 열어 주어야 한다.
    • pasv_address: 기본값 없음. passive 모드에서 사용, 서버가 공유가나 클라우드 NAT 뒤에 있는 경우 클라이언트가 접속하는 외부 공인 IP를 입력한다.
  • 파일 권한, 디렉토리 제어
    • write_enable=NO: 쓰기(업로드, 삭제, 수정) 허용 결정
    • local_umask=077: 파일 업로드 시 생성되는 파일의 기본 권한을 결정, 077로 설정하면 chmod 600 적용, 022로 설정하면 chmod 644 적용
    • chroot_local_user=NO: 사용자가 자기 홈 디렉터리 상위로 이동하지 못하게 가두는 역할, YES로 하면 홈 상위로 이동하지 못함, 보안상 설정하면 안되는 옵션
    • allow_writeable_chroot=NO: chroot_local_user=YES로 설정했을 때, 홈 디렉터리에 쓰기 권한이 있으면 보안 에러가 발생하는데, 이 옵션을 YES로 하면 보안 에러 무시하고 접속 허용 됨. 보안상 설정하면 안되는 옵션
  • 로그인, 세션 관리
    • xferlog_enable=NO, 파일 업로드/다운로드 기록을 로그 파일에 남길지 결정
    • xferlog_file=/var/log/vsftpd.og: 로그 파일의 저장 경로 지정
    • idle_session_timeout=600: 기본값 600초=10분, 클라이언트가 명령을 보내지 않을 때 연결을 끊을 때 까지 대기하는 시간

3. vsftpd 인증 관련

  • os 계정이 아닌 vsftpd 자체 인증 사용하기
# vsfptd 설치
sudo apt update
sudo apt install vsftpd db-util -y

# 사용자 가상 계정 생성
sudo vi /etc/vsftpd/virtusers.txt

# virtusers.txt
ftpusername1
password1
ftpusername2
password2

# Berkely DB 생성
sudo db_load -T -t hash -f /etc/vsftpd/virtusers.txxt /etc/vsftpd/virtusers.db

# DB 권한 변경
sudo chmod 600 /etc/vsftpd/virtusers.db

# PAM 설정
sudo cp /etc/pam.d/vsftpd /etc/pam.d/vsftpd.virtual
sudo vi /etc/pam.d/vsftpd.virtual

# vsftpd.virtual
auth    required pam_userdb.so db=/etc/vsftpd/virtusers
account required pam_userdb.so db=/etc/vsftpd/virtusers

# 가상 사용자, 디렉토리 생성
sudo useradd -d /home/ftp_home -s /usr/sbin/nologin ftpusername1
sudo mkdir -p /home/ftp_home
sudo chown -R ftpusername1:ftpusername1 /home/ftp_home
sudo chmod -R 755 /home/ftp_home

# vsftpd.conf 수정
...
pam_service_name=vsftpd.virtual
guest_enable=YES
guest_username=ftpusername1
virtual_use_local_privs=YES
local_root=/home/ftp_home
...

# vsfptd 재시작
sudo systemctl restart vsftpd

4. vsftpd 운영 관련

  • systemd log 확인
    • sudo journalctl -u vsftpd -f
  • vsftpd log 확인
    • sudo tail -f /var/log/vsftpd.log
  • vsftpd 설정 확인
    • cat /etc/vsftpd.conf
  • port 충돌 확인
    • sudo lsof -i :21 (또는 사용자 정의 포트)