Unix/Debian

간단한 FTP서버

ForceCore 2009. 2. 18. 15:14
Spec
1. 일반 사용자들은 공유된 디렉토리에 읽고 쓸 수 있다.
2. FTP는 안 되고, 암호화된 FTP인 FTPS, FTPES만 사용 가능. (파일질라를 클라이언트로 쓰는 것이 가장 좋다)
3. SFTP (secure shell이 제공하는 FTP)는 일반 사용자들이 이용할 수 없다.
4. LVM으로 여러개의 디스크를 묶어서 쓸 생각이다. 디스크 하나가 fail 나더라도, fail난 것만 없어지니까 :D


OS 설치과정
Debian Linux 5.0을 Network Install CD로 Desktop도 안 깔린 기본 base만 설치함. -_-;;

SSH 설치
# apt-get install ssh
/etc/ssh/sshd_config를 수정해서 Root login을 못 하게 하고, port 9922번을 추가로 listen하게 함.
Port 22라도 된 것 줄 아래에 Port 9922 한줄을 더 적으면 된다.
Root로 검색해서 permit root login 이런 비슷한 것은 no로 교체하면 됨.

Locale
en_US.UTF-8
ko_KR.UTF-8
C
를 지원하도록 함.
# dpkg-reconfigure locales
였던거 같음.

VSFTPD 설치
# apt-get install vsftpd
우선 대충은 올라가서, 돌아가긴 하는데 설정을 해야 한다.

위의 spec을 이루기 위해서, 아래 자료를 컨닝하였다.
http://howto.gumph.org/content/setup-virtual-users-and-directories-in-vsftpd/
# apt-get install libpam-pwdfile
으로, PAM모듈 중, 파일로 (passwd파일 말고)도 사용자를 관리할 수 있는 모듈을 받는다.
이 모듈에 대한 정보는 pam_pwdfile 로 구글링 해보면 나온다.
http://cpbotha.net/software/pam_pwdfile/

ID는 htpasswd 명령어로 추가하게 되어있는데, 안타깝게도, minimal 설치인지라, htpasswd 명령어가 없다.
# apt-get install apache2-utils
로 추가적인 패키지를 설치하면 된다.
# mkdir /etc/vsftpd
# touch /etc/vsftpd/passwd
로, 사용자 정보를 담을 파일을 만든다. 사용자를 추가하려면,
# htpasswd -m /etc/vsftpd/passwd [사용자ID]
이렇게 추가한다. -m을 안 붙이면 md5의 강력한 암호화가 안 되어서 보안이 구려진다. 라고 생각했는데... htpasswd의 md5기능은 우리가 쓰고자 하는 PAM 모듈과 호환되지 않았다.

또한 htpasswd파일의 어디를 쳐다봐도, gid나 uid가 없다. 간단한 virtual user를 위한 PAM 모듈이다보니 그런 기능은 없는 듯 하다. 말 그대로 가상 유저이지, 시스템에 실제로 로그인 할 수 있는 사용자는 아닌 것이다.

VSFTPD 설정
/etc/vsftpd.conf 을 수정해서 입맛대로 고칠 차례이다.
우선은 /etc/vsftpd.conf를 위에서 아래로 훑으면서, 감으로 설정을 해본다.
그동안 설정했던, 필자의 "표준" 설정과 다르다.
표준 설정(?)에서는 모든 사용자들이 다 real user들이었는데 여기선 virtual이니...
설정에서 포인트는, guest 와 관련된 설정들이다. anonymous와는 또 다른 개념으로 guest가 가상유저라고 생각하면 된다.

listen=YES
anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
dirmessage_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
xferlog_file=/var/log/vsftpd.log
ascii_upload_enable=NO
ascii_download_enable=YES
ftpd_banner=Welcome to blah FTP service.
secure_chroot_dir=/var/run/vsftpd
pam_service_name=vsftpd
rsa_cert_file=/etc/ssl/certs/vsftpd.pem
rsa_private_key_file=/etc/ssl/private/vsftpd.pem
ssl_enable=YES
ssl_sslv2=YES
ssl_sslv3=YES
ssl_tlsv1=YES
force_local_data_ssl=YES
force_local_logins_ssl=YES
pasv_min_port=60000
pasv_max_port=60100
virtual_use_local_privs=YES
hide_ids=YES
user_sub_token=$USER
guest_enable=YES
local_root=/home/ftproot
chroot_local_user=YES
필자의 설정은 이렇다.
/home/ftproot 를 모든 사용자가 공유하고 read/write 가능한 공용 FTP이다. ftpes 를 가능하게 하는 설정도 있다.

참고로 필자가 컨닝한 설정은 이렇다:
listen=YES
anonymous_enable=NO
local_enable=YES
virtual_use_local_privs=YES
write_enable=YES
connect_from_port_20=YES
secure_chroot_dir=/var/run/vsftpd
pam_service_name=vsftpd
guest_enable=YES
user_sub_token=$USER
local_root=/var/www/sites/$USER
chroot_local_user=YES
hide_ids=YES
더 compact하고, 비슷하지만 다르다.

OpenSSL 설치
# apt-get install openssl
으로 OpenSSL을 설치한다. 그러나, 인증서를 만들어주진 않는군!!;;
http://forcecore.tistory.com/953
위 글을 참고하기 바란다.

pam-pwdfile
htpasswd로는 PAM모듈이 인식하는 MD5 hash가 안 나와서, chpwdfile이란걸 컴파일 해 쓰기로 함.
# apt-get install build-essential
로 필요한 컴파일 도구를 설치한다.

http://cpbotha.net/files/mirror/chpwdfile-0.24.tar.gz
chpwdfile 이라는 프로그램을 컴파일 해야 한다.
이것을 받아 압축을 풀고, 그냥 make만 하면 간단히 컴파일 된다.
생성되는 chpwdfile 프로그램을 이용하면 되는데... 사용 방법이 조금 복잡하다(어디까지나 htpasswd에 비해 그렇단 말)

Usage for chpwdfile:

        chpwdfile [options] [username]

  Options:
  -a  add the user             }
  -d  delete the user          } Default is -m
  -m  modify the user's entry  }
  -c  <filename>  specify a config file [default=/etc/chpwdfile.conf]
  -f  <filename>  specify the file to modify (must already exist)
  -p  <num>       set minimum password length [default=5]
  -u  <num>       set minimum username length [default=5]
  -t  <d|m>       set hash type; 'd'==DES, 'm'=MD5 [default=d]
  -s  read password directly from stdin (useful for scripts)
  -h  show usage information
  -v  show version number
동작이 새로유저를 추가하는건지 지우는건지 수정하는건지, 알아서 판단하지 않고 사용자의 몫으로 남아있다 -_-;; -a 해서 안 되면 -m 하도록 스크립트를 짜든지 그건 알아서 하라. 또 없는 파일을 만들어주지도 않는다...

추가된 사용자가 스스로 비번을 변경하기는 안 된다는 것이군 어쨌든. 비번 바꾸는 것은 php스크립트로 chpwdfile을 invoke하게 만들든지... 알아서 하자.

사용자 비번 변경
알아서 하자... 라고 했지만, 그게... 알아서 하기엔 좀 어려운 주제인듯 -_-;;
필자는 chpwfile을 대신할 수 있는 perl 스크립트를 찾아내었고
필자가 그것을 직접 php로 번역하였다. (직접이라고 자랑했긴 한데 그다지 안 어려움...;;;)
그리고 hwpasswd를 관리할 수 있는 PHP스크립트를 찾아내어서 그 번역한 php와 합체시켰다.


사용법은...

/export/www에 index.php가 오고 있다고 가정하고 있다. 이는 필자 나름의 개인적인 "표준"설정임 -_-
1. useradd.php
사용자를 추가해주는 스크립트다.
php useradd.php 추가할ID
이렇게 하면 ID가 추가된다. 이미 ID가 존재하면 error를 알려줌.
저렇게 php를 shell-script로 쓰려면, php-cli 패키지를 설치해야지 된다. (debian/ubuntu의 경우.)

2. www/index.php
음... 실행해보면 안다. useradd.php를 제외한 나머지 파일은 index.php를 위한 파일이다.
보안을 위해 https 프로토콜을 강제하길 권한다:
http://forcecore.tistory.com/955 : 이렇게...

중요한 가정: 아파치가, /etc/vsftpd/passwd 를 건드릴 수 있다고 가정하고 있다! 이게 보안에 어떤 영향을 끼칠지는...

LVM으로 디스크 묶기:
중요한 topic이라 따로 묶어야 할 것 같다:
http://forcecore.tistory.com/956
디스크/파티션이 여러개이고, 소프트링크로 파일을 관리하다보면 관리자 입장에서도 정말 난감하다. -_-;; 깔끔하지도 않고 공간배치도 효율적이지 않고... 가장 좋은 것은 raid1+0 (미러링한 것을 여러개 묶는 것)이지만, 가난한 서버이므로 -_- 그냥 LVM으로 묶는 raid0 비슷하게 꾸려갈 것임.