60.Unix2008. 12. 17. 12:32
반응형

윈디하나의 솔라나라: ProFTPD

최종 갱신일: 2008-04-07, 이 문서는 윈디하나의 솔라나라, http://www.solanara.net/에서 최근에 갱신된 문서를 찾을 수 있다.

들어가기 전에

  • ProFTPD는 보안에 중심을 둔 FTP서버이다. 패치도 자주 되는데, http://www.proftpd.org를 모니터링 해 최신 버전이 나오면 패치해 준다. rc버전이라도 서비스에 문제 없다면 업데이트 해 주는 것이 좋다.
  • ProFTPD Korean User Group에서 한글 자료를 구할 수 있다.

1. 설치 전에

ftpwho, ftptop, ftpshut를 쉽게 사용하기 위해 PATH를 걸어준다.
root@wl # vi /etc/profile
# for ProFTPD located at /usr/local/proftpd
if [ -x /usr/local/proftpd/bin/ftpwho ]
then
  PATH=/usr/local/proftpd/bin:$PATH; export PATH;
fi
root@wl #

2. ProFTPD 설치

  1. TCPWrappers
    ProFTPD 1.2.9버전까지만 해도 솔라리스 9에 기본 설치되어있는 TCPWrappers를 이용해 설치할 수 있었지만, 1.2.10에 와서는 설치가 되지 않는다. 최신 버전의 TCPWrappers를 설치한다. sunfreeware.com의 tcp_wrappers-7.6-sol9-intel-local.gz 를 받아 설치한다.
    root@wl ~ # wget ftp://ftp.sunfreeware.com/pub/freeware/intel/9/tcp_wrappers-7.6-sol9-intel-local.gz
    root@wl ~ # gunzip tcp_wrappers-7.6-sol9-intel-local.gz
    root@wl ~ # pkgadd -d tcp_wrappers-7.6-sol9-intel-local
    
  2. OpenSSL의 설치는 openssl.html을 참고한다.
  3. ProFTPD
    root@wl ~ # gtar xvfz cd proftpd-1.3.1.tar.gz
    root@wl ~ # cd proftpd-1.3.1
    root@wl ~/proftpd-1.3.1 # ./configure \
    --with-includes=/usr/sfw/include:/usr/include:/usr/local/include:/usr/local/ssl/include:/usr/local/mysql/include/mysql:/usr/local/mysql/include/mysql \
    --prefix=/usr/local/proftpd \
    --enable-sendfile \
    --enable-shadow \
    --with-modules=mod_wrap:mod_tls:mod_sql:mod_sql_mysql 1)
    root@wl ~/proftpd-1.3.1 # make
    root@wl ~/proftpd-1.3.1 # make install
    
    1) 모듈설명
    mod_wrap: IP주소를 기준으로 사용자들의 접근 제어가 가능하도록 해주는 모듈. 필요없으면 이 부분을 삭제한다.
    mod_tls: ftps를 사용할 수 있도록 하는 모듈. 필요없으면 이 부분을 삭제한다.
    mod_sql: 데이터베이스를 이용해 인증해주는 모듈. 필요없으면 이 부분을 삭제한다.
    mod_sql_mysql: mod_sql의 데이터베이스로 MySQL을 사용할 수 있도록 하는 모듈. 필요없으면 이 부분을 삭제한다.
    ':'은 각각의 명령을 구분하는 구분자이다.
    오류가 나면 --with-include 라인과, --with-modules 라인을 삭제한다.

3. 설치후 기본 설정

ProFTPD는 inetd를 이용해 띄울수 있지만 여기서는 StandAlone으로 띄우는 방법에 대해 설명한다.
root@wl ~ # vi /etc/inetd.conf
#ftp ~~~
root@wl ~ # ps -ef | grep inetd
  root   150     1  0  10월 22 ?        0:00 /usr/sbin/inetd -s
root@wl ~ # kill -HUP 150
root@wl ~ # vi /usr/local/proftpd/etc/proftpd.conf
DefaultRoot ~ # 언 코멘트
root@wl ~ # /usr/local/proftpd/sbin/proftpd # 실행
root@wl ~ # pkill proftpd # 종료

4. 설정하기

root@wl ~ # vi /usr/local/proftpd/etc/proftpd.conf
# 이 내용을 복사해서 사용할 때 # 뒷 부분은 삭제해야 한다.
AllowstoreRestart on      # Upload Resume 허용. 대부분의 서버는 off로 되어있다. 익숙한 ftp사용자가 아니면 off로 해 놓는것이 좋다.
RequireValidShell off     # 익명연결 허용
ShowSymlinks      on      # 심볼릭 링크 보임
DefaultRoot       ~       # 기본 루트 설정
ServerIdent       on      "FTP server" # 서버 정보 보임
DisplayConnect    /etc/proftp.connect.msg # 로그인 이전 메시지
DisplayLogin      /etc/proftp.login.msg   # 로그인 이후 메시지
MaxClients        100	"Sorry, the maximum number(%m) of allowed users are already connected" # 최대 클라이언트 수
MaxClientsPerHost 5	"Sorry, the maximum number clients (%m) from your host are already connected" # 호스트당 최대 클라이언트 수
HideUser          root    # 사용자 숨김
HideGroup         root    # 그룹 숨김
AuthPAM           On      # PAM 인증
AuthPAMConfig     ftp     # PAM 설정
TCPAccessFiles /etc/hosts.allow /etc/hosts.deny # TCPWrapper
<Directory /export/home/*>
  AllowstoreRestart on # Upload Resume을 가능하게 한다.
</Directory>

<IfModule mod_tls.c>
  TLSEngine on
  TLSLog TLSLog  /var/log/ftps.log
  TLSProtocol TLSv1

  # Are clients required to use FTP over TLS when talking to this server?
  TLSRequired off

  # Server's certificate
  TLSRSACertificateFile /usr/local/ssl/certs/signed-req.pem
  TLSRSACertificateKeyFile /usr/local/ssl/certs/req.key

  # CA the server trusts
  TLSCACertificateFile /usr/local/ssl/certs/ca.crt

  # Authenticate clients that want to use FTP over TLS?
  TLSVerifyClient off
</IfModule>
root@wl ~ # vi /etc/pam.conf
ftp auth required /usr/lib/security/pam_unix.so
ftp account required /usr/lib/security/pam_unix.so
※ 파일 전송을 위한 암호화된 프로토콜에는 FTPS, SFTP가 있다. 이중 쉽게 사용할 수 있는 것은 SFTP로 SSH를 설치하면 자동 설치되며, Solaris 9 x86 9/04에 전체 설치를 선택했다면 이미 설치되어있다. 그러나 이는 FTP의 기능중 몇가지, 예를 들면 이어받기나 이어 보내기를 지원하지 않아 불편하다. 그래서 ProFTPD에 SSL을 이용해 FTPS를 사용하는것이며 proftpd는 mod_tls.c를 통해 구현된다.
※ CuteFTP Pro로 FTP with TLS/SSL (AUTH TLS - Explicit)과 FTP with SSL (AUTH SSL - Explicit) 프로토콜을 테스트했으며 모두 정상적으로 되었다.

5. Anonymous FTP 설정

익명 FTP는 사용자인증 과정 없이 사용할 수 있는 FTP서비스를 말한다. 서비스를 비 정상적으로 사용하는 사용자가 많기 때문에 주기적인 트래픽 모니터링은 필수다.
# 익명 FTP에 사용할 계정을 만든다. Anonymous FTP를 이 사용자의 권한으로 실행될 것이다.
root@wl ~ # /usr/sbin/groupadd -g 103 ftp
root@wl ~ # useradd -d /export/home/ftp -g ftp -u 104 -s /bin/false ftp
root@wl ~ # mkdir /export/home/ftp # Anonymous FTP의 홈 디렉토리. 소유자와 그룹 모두 root, staff로 놔둔다.
root@wl ~ # vi /usr/local/proftpd/etc/proftpd.conf # 설정은 모두 되어있다. 한번 보자.
root@wl ~ # pkill proftpd
root@wl ~ # /usr/local/proftpd/sbin/proftpd # ProFTPD는 재시작하는 것이 없다.
익명 사용자도 업로드 할 수 있도록 incomming 디렉토리 만들어 보자. 장담하지만, 특별한 접근 제한이 없다면 일주일 이내에 WAREZ에 의해 장악된다. TCPWrapper등을 이용해 접근제한을 하지 않는다면, 실제 서비스에서는 하지 않는 것이 좋다.
root@wl ~ # mkdir /export/home/ftp/incomming
root@wl ~ # chmod 777 /export/home/ftp/incomming
root@wl ~ # vi /usr/local/proftpd/etc/proftpd.conf
# 다음을 추가한다.
<Anonymous ~ftp>
  ...
  # <Anonymous ~ftp>와 </Anonymous> 사이에 아래를 추가한다.
  <Directory incoming>
  AllowOverwrite                on
  AllowStoreRestart             on
    <Limit STOR MKD>
      AllowALL
    </Limit>
  </Directory>
</Anonymous>
root@wl ~ # pkill proftpd
root@wl ~ # /usr/local/proftpd/sbin/proftpd # ProFTPD는 재시작하는 것이 없다.
※ Anonymous의 User와 Group을 모두 ftp로 하였고, AnonymousFTP로 접속한 유저는 ftp:ftp권한을 가진다는 것을 생각하면 이해하기 쉬울 것이다.

5. IP기반의 접근 제어

아래 예제는 192.168.0.3,192.168.0.2에서만 접근 가능하도록 설정한 것이다. FTP서버와 TCP/IP Connection이 이루어지나, 인증이 되지 않는다. 아예 Connection이 안되게 하려면 방하벽을 이용한다.
root@wl ~ # vi /usr/local/proftpd/etc/proftpd.conf
# TCPAccessFiles부분을 추가한다.
TCPAccessFiles /etc/hosts.allow /etc/hosts.deny
root@wl ~ # vi /etc/hosts.deny
ALL:ALL
root@wl ~ # vi /etc/hosts.allow
proftpd: 192.168.0.3,192.168.0.2
root@wl ~ # pkill proftpd
root@wl ~ # /usr/local/proftpd/sbin/proftpd

6. SQL 인증

※ 많은 사람들이 사용하는 ftp서비스를 운영함에 있어서 문제될 수 있는 부분은, 일일이 계정을 주어야 한다는 것이다. ftp만을 접속하게 하기 위해 시스템 로컬 계정을 발급하는 것은 보안상의 문제를 포함해, 여러가지 문제를 야기할 수 있다. 따라서 ftp사용자들의 계정 데이터베이스로 시스템을 이용하지 않는 방법이 나오게 되었으며, 그중 proftpd에서 유용하게 사용 할 수 있는 MySQL Database를 이용한 방법에 대해 설명한다.
root@wl ~ # vi /usr/local/proftpd/etc/proftpd.conf
# 아래부분을 추가한다.
<IfModule mod_sql.c>
SQLAuthenticate on
SQLConnectInfo ftpdb@localhost root
SQLAuthTypes Plaintext
SQLLogFile /var/log/proftpdsqllog
# SQLUserInfo users userid passwd uid gid homedir shell 
# SQLGroupInfo groups groupname gid members
</IfModule>
※ 위세팅은 localhost에 있는 MySQL의 ftpdb 데이터베이스를 사용하며, 사용자 이름은 root, 패스워드는 없다. 테이블 이름은 ftpusers, ftpgroups 이다. 만약 데이터베이스 접속에 패스워드가 필요하다면, [SQLConnectInfo ftp@localhost root]에 한칸 띄우고 패스워드를 써 주면 된다. 이제 MySQL을 세팅할 차례다.
※ SQLUserInfo, SQLGroupInfo 부분의 세팅은 테이블 이름이며 테이블의 필드 이름이다. 기본값을 그대로 사용하기에 주석처리 해 놓은 것이다.
root@wl ~ # mysql -u root
mysql> create database ftpdb;
Query OK, 1 row affected (0.00 sec)
mysql> use ftpdb
Database changed
mysql> CREATE TABLE users (
    userid VARCHAR(30) NOT NULL UNIQUE,
    passwd VARCHAR(80) NOT NULL,
    uid INTEGER UNIQUE,
    gid INTEGER,
    homedir VARCHAR(255),
    shell VARCHAR(255)
  );
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE groups (
    groupname VARCHAR(30) NOT NULL,
    gid INTEGER NOT NULL,
    members VARCHAR(255)
  );
Query OK, 0 rows affected (0.00 sec)
mysql> insert into users (userid, passwd, uid, gid, homedir, shell) values ('dbtest', 'test', 101, 10, '/export/home/windy', '/bin/bash');
Query OK, 1 row affected (0.00 sec)
mysql> insert into groups (groupname, gid, members) values ('staff', 10, 'dbtest');
Query OK, 1 row affected (0.00 sec)
mysql> exit
Bye
root@wl ~ # pkill proftpd
root@wl ~ # /usr/local/proftpd/sbin/proftpd
- 뭔가 이상하다면 /var/log/proftpdsqllog 파일을 확인해본다. 테이블이름의 기본값이 ProFTPD 버전마다 다른듯 하다.

7. xferlog

ProFTPD는 전송 로그를 /var/log/xferlog에 저장한다. 아래는 로그 파일의 형식에 대한 예이다.
root@wl ~ # tail /var/log/xferlog
Fri Nov 11 11:56:28 2005 0 xxx.xxx.xxx.xxx zzzz /sample.txt a _ i r webmaster ftp  1  *  c
-----------------------1 2 --------------3 ---4 ----------5 6 7 8 9 -------10 -11 12 13 14
로그시간 전송시간 원격호스트이름 파일크기 파일이름 전송종류 특별전송플래그 방향 접근모드 유저이름 서비스이름 인증방법 인증된유저ID 완료여부
1 로그시간. 로그가 저장된 로컬 호스트의 현재 시간
2 전송시간. 전송에 소요된 시간. 초
3 원격호스트이름. 없는 경우 IP로 저장됨
4 파일크기. 바이트
5 파일이름.
6 전송종류. a: 아스키 전송, b: 바이너리 전송
7 특별전송플래그. C: 파일 압축됨, U: 파일 압축풀림, _: 해당없음
8 방향. o: 외부(Outgoing), i:내부(Incoming), d:삭제(Deleted)
9 접근모드. a: 익명유저(Anonymous), g: 손님유저(Guest), r: 로컬 인증된 유저(Real)
10 유저이름. 로컬 유저이름. 손님인 경우 주어진 ID.
11 서비스이름. 수행될때의 서비스 이름. 일반적으로 ftp.
12 인증방법. 0: 없음, 1: RFC931
13 인증된유저ID. 인증 메쏘드에 의해 얻은 유저ID. *의 경우 존재하지 않음
14 완료여부. c: 전송이 완료됨, i: 전송이 완료되지 않음
Posted by 1010