본문 바로가기
서버구축 (WEB,DB)

Proftpd와 MySQL 연동한 사용자 관리

by 날으는물고기 2009. 6. 22.

Proftpd와 MySQL 연동한 사용자 관리

728x90

FTP를 사용하여 데이터 저장 서버를 만들려고 한다.
도전 과제는 다양한 사용자가 존재할 수 있고, 사용자 정보 즉, 추가 삭제가 빈번히 일어난다.
중앙에서 FTP서버에 접속하는 계정을 관리, 유지 하고 싶다.

기본적으로 FTP는 리눅스의 쉘 계정을 사용한다.
FTP유저를 추가하고 싶다면 쉘에 계정을 추가해야하는데..
이거 쫌 보안에 민감하지 않을 수 없다.

그래서 선택한것이 mysql 의 데이터베이스를 사용하여 가상 계정을 만들어 FTP사용을 제어 하는것이다.

찾아본 결과로는 아주 만족스럽게 모든것이 제어가 가능하다.
원하면 쿼터도 조절가능하나, 현재 나의 서비스에서는 필요가 없기때문에 기본적으로 proftp와 mysql 을 연결하여 조절하는 작업을 설명해보겠다.

찾아보면 기본적인 설정에 대한 문서는 어느정도 공개 되어있다.
proftp의 한글 사이트까지 있으나, 단순한 매뉴얼 번역일뿐.. 예제가 없어.. 처음 사용하는데에는 많은 시행착오가 필요할듯 한다.
그래서 여기에 하나의 예제를 만들고자 한다.

그럼 연동 작업 시작합니다.

기본적으로 proftp와 mysql 을 설치 해야한다. (당연하죠?)
이때 중요한 작업이 proftp를 설치할때 mysql을 사용하여 연동할것이라는것을 알려줘야한다.

./configure 할때
다음 옵션을 추가한다.
--with-modules=mod_sql:mod_sql_mysql --with-includes=/usr/include/mysql

즉 ./configure --with-modules=mod_sql:mod_sql_mysql --with-includes=/usr/include/mysql 그밖의 자신의 옵션들...

또는

./configure --prefix=/usr/local/proftpd --with-modules=mod_sql:mod_sql_mysql --with-includes=/usr/include/mysql --with-libraries=/usr/lib --enable-autoshadow --enable-shadow

이렇게 설정하면 된다. 자세한 설치 작업에 대한것은 이곳에서 설명하지 않기로 하겠다.
mysql에서 특별히 할것이 없다. 그냥 기존에 설치 되어있으면 된다.


Step 1

이제 DB에 관리를 할 사용자와 그룹 테이블을 만들겠다.

create table users (
      userid   char(12) not null,
      uid      integer unsigned,
      gid      integer unsigned,
      passwd   char(63),
      shell    char(255),
      homedir  char(255),
      count    integer unsigned not null,
      access_time datetime NOT NULL,
      valid    integer unsigned,
      primary key (userid)
    );

create table groups (
     gname    char(12) not null,
     gid      integer unsigned,
     members  text,
     primary key(gname)
   );



proftp 매뉴얼에 있는 기본적인 테이블 스키마이다. 여기에 사용자의 최종 접속 시간을 체크하기 위해 access_time 이라는 필드를 추가했다.

Step 2

다음은 모든 가상 계정들을 대신하여 폴더 권한을 가질 계정의 실제 그룹과 유저를 생성하겠다.

> groupadd -g 3001 ftpuser
> useradd -u 3001 -s /sbin/nologin -d /bin/null -c "proftpd user" -g ftpuser ftpuser



이렇게 좀 떨어진 gid와 uid로 그룹과 유저를 생성한다. 관리의 편리를 위해서다.
중요점! 유저를 생성할때 이 유저는 실제로 사용할 유저가 아니기 때문에 홈디렉토리와 쉘이 없어야 한다.

Step 3


이제 proftp 설정화일을 수정하자.
설정화일을 각 설치 환경마다 다르겠지만, 기본적으로는 설치된 proftp 폴더아래에 etc 폴더아래에 있다.

화일의 맨 아랫부분에 다음 설정을 삽입한다.
각 설정은 설명을 할테니 자신이 원하는 환경에 맞게 수정하면 될것이다.

<Global>

# SQL Authentication
# SQL user
# Mysql 접속 정보이다. 형식은 DB이름@호스트:포트 사용자아이디 사용자패스워드 이다.
SQLConnectInfo test@localhost:3306 ftp ftppass

# 사용자 테이블에 저장될 패스워드의 형식을 결정한다.
# 많이 쓰는것이 mysql 의 PASSWORD() 함수를 사용하는것이다. 이를 위해서는
# 아래 Plaintext를 Backend 로 변경한다. Plaintext는 글자 그대로 텍스트로 저장한것이다.
SQLAuthTypes            Plaintext

# 사용자 테이블의 정보를 알려준다.
# 형식은: 테이블이름 아이디필드 패스워드필드 uid gid 홈폴더필드 쉘필드 이다.
# 자신이 만든 테이블의 필드명에 맞게 하나씩 써준다.
SQLUserInfo             users userid passwd uid gid homedir shell

# 그룹 테이블의 정보를 알려준다.
# 형식은: 테이블이름 그룹이름 gid 그룹속한사용자 이다.
# members 는 콤마로 각 그룹에 속할 실제 계정 유저를 넣어 주면 된다.
SQLGroupInfo            groups gname gid members

# 유저의 사용을 제어하는 쿼리를 만든다.
# 유저 테이블을 보면 valid라는 필드가 있는데 이것이 0인 유저는 로그인 못하고
# 1인 사용자만 로그인 할수 있게 쿼리를 날리기 위한 Where 절을 생성한다.
# 필요에 따라 쿼리를 쓰면 된다.
SQLUserWhereClause      "valid = 1"

# 만약 유저 테이블의 homedir 폴더가 없다면 기본적으로 사용한 폴더를 설정한다.
SQLDefaultHomedir       "/home/data2/storeftp"

# FTP사용자들은 모두 가상이기 때문에 실제 쉘 계정이 없다.
# 아래를 설정함으로써 쉘이 없어도 ftp에 접속 할수 있게 한다.
RequireValidShell       off

# 어떤 인증을 할지를 설정하는데
# 여기서는 유저와 그룹을 체크하는것으로 했다.
# 단순하 FTP에서는 단지 users 만 적어서 사용자 관리만 할 수 있다.
SQLAuthenticate         users* groups*

# 최소 GID와 UID로 사용할 번호이다.
# 기본적으로 999 이기 때문에 설정할 필요 없지만.. 보안적인 측면에서 설정하면 좋다.
SQLMinID        3000

# 만약에 유저의 homedir이 없으면 자동으로 생성해주는 설정이다.
# 필요없으면 주석 처리 하면 된다.
CreateHome on


# 이제 부터는 약간의 관리 로그를 작성하는 부분이다.

# 각 쿼리를 이름을 만들수 있다.
# 아래에 보면 getcount 뒤에 SELECT 가 쭉 붙는데.. 이 쿼리가 getcount 라는 이름으로 저장된것으로 보면 된다.
SQLNamedQuery           getcount SELECT "count from users where userid='%u'"
SQLNamedQuery           updatecount UPDATE "count=count+1, access_time=now() WHERE userid='%u'" users

# 로그인했을때 보여줄 메세지이다. %{getcount}이것은 위에 설정한 쿼리의 결과값을 출력한다.
# 여기서 PASS는 로그인했을때 하라는 부분이다.
SQLShowInfo             PASS "230" "%u님은 %{getcount} 번 로그인하셨네요~"
# 즉, PASS일때 위의 메세지를 보여주고 그리고 updatecount 쿼리를 한번 실행하라는것이다.
# updatecount는 위에 정의 했는데 각 유저 테이블의 로그인 횟수를 증가하고 최종 로그인 시간을 저정하는 부분이다.
SQLLog                  PASS updatecount

# 이부분은 추가적으로 각 사용자의 다운로드와 업로드 부분을 로그 기록하는 것인데,
# 테이블 스키마를 아래에 적어 주겠다.
SQLLog RETR receivefile
SQLNamedQuery receivefile INSERT "null, '%u', '%f', %b, now(), now()" file_download

SQLLog STOR sendfile
SQLNamedQuery sendfile INSERT "null, '%u', '%f', %b, now(), now()" file_upload

</Global>

# 이부분은 ftp사용의 로그를 저장할 화일을 설정하는 부분인데.. 자신의 환경에 맞게 설정하면 된다.
# 아마 기본적으로 TransferLog     /var/log/xferlog 이부분을 있을듯하다.
SQLLogFile      /var/log/ftpsql
SystemLog       /var/log/ftplog
TransferLog     /var/log/xferlog


 

------------------------- 참고--------------------
업로드, 다운로드 관리 테이블
CREATE TABLE `file_download` (
  `num` int(11) NOT NULL auto_increment,
  `user` varchar(30) NOT NULL,
  `file_name` varchar(100) NOT NULL,
  `file_size` int(11) NOT NULL,
  `file_date` date NOT NULL,
  `file_time` time NOT NULL,
  PRIMARY KEY  (`num`),
  KEY `user` (`user`,`file_date`)
) ;

CREATE TABLE `file_upload` (
  `num` int(11) NOT NULL auto_increment,
  `user` varchar(30) NOT NULL,
  `file_name` varchar(100) NOT NULL,
  `file_size` int(11) NOT NULL,
  `file_date` date NOT NULL,
  `file_time` time NOT NULL,
  PRIMARY KEY  (`num`),
  KEY `user` (`user`,`file_date`)
);



Step 4

실제 사용할 유저를 추가해보자~~
먼저 그룹정보를 추가한다.

INSERT INTO `groups` (`gname`, `gid`, `members`) VALUES ('ftpuser', 3001, 'ftpuser');

여기서 그룹 이름과 gid는 서버의 실제 정보를 입력해야한다.
memebers 에서 아까 step2 에서 생성한 실제 유저 정보를 입력한다.

이제는 가상 유저를 추가하자.

INSERT INTO `users` (`userid`, `passwd`, `uid`, `gid`, `homedir`, `shell`, `count`, `access_time`, `valid`) VALUES ('test', 'test', 3001, 3001, '/home/ftpuser/test', '/sbin/nologin', 0, '', '' '1');

이렇게 데이터를 추가하면 사용할 유저가 추가된다.
여기서 중요점은 이 가상 유저가 사용할 그룹 id 즉, gid를 위에서 설정한 그룹 정보와 맞춰야한다.
그래야 이 가상 유저가 로그인하면 실제 계정인 ftpuser 로 로기인 한것처럼 된것이기 때문이다.

이제 로그인 해보자. FTP 클라이언트 프로그램을 이용하여 설정한 서버로
유저 이름 test 비밀번호 test로 접속해보자.
접속 되면 잘된것이고 안되면.. 다시 설정을 잘 봐야 할것이다.

그리고 실제 서버의 폴더에 가면 /home/ftpuser/test 라는 폴더가 자동 생성되었을것이다.

다음과 같은 SQL 문으로 쉽게 사용자들의 데이터 전송량, 전송갯수, 전송된 화일명들을 알수 있습니다.

SELECT user, sum(file_size)as transfer from file_upload group by user;
// 사용자별 업로드 사용량을 확인 하는 것입니다.

SELECT user, count(file_name)as files, file_date from file_download group by user;
// 사용자별 다운로드 화일 갯수 확인

이상으로 Proftp 와 mysql을 연결하여 계정 관리하는 방법을 설명하였다.
DB에서 계정을 관리하기 때문에 보안적인 측면에서 좋고,
관리도 더욱 쉬워지게 될것이라 생각한다.

참고 자료:
http://www.howtoforge.com/proftpd_mysql_virtual_hosting (영문이지만 예제가 잘 나와있다.)
http://www.castaglia.org/proftpd/modules/mod_sql.html (그밖의 설정 화일에 대한 매뉴얼)
http://proftpd.oops.org/ (Proftpd 한글 사용자 모임)

728x90

댓글3

  • 소년 2010.01.20 17:25

    글 잘봤습니다.

    근데 제가 문제가 있어서 이렇게 질문드립니다.

    위와 똑같이 했습니다 .. 그런데 접속이 안되고 디렉토리도 생성이 되지 않는군요
    ... 왜그럴까요?? ㅠㅠ;; 에러메세지도 안뜨고 ....
    아 그리고 수정해야할거 알려드릴께용
    accessed_time // access_time
    디비 만들때는 access_time 인데 인서트 시킬때는 accessed_time 라고 되어있네요 ^^ ed 빼주시면 될듯하네요

    ftplog 확인해보니까!!

    /home/ftp/test 홈디렉토리가 없다고 나오더군요

    디렉토리 생성이 바로 되지 않네요 .. 만들어주니까 접속이 되더군요.... ;;;;
    답글

  • Favicon of http://windrei.tistory.com 소년 2010.01.29 14:24

    답변이 늦어서 죄송합니다 권한 문제가 맞습니다..

    777하니 잘되네요.....

    리눅스 초보라!! 많이 배워갑니다 ^^ 감사합니다...
    답글