[출처] http://blog.sdnkorea.com/blog/675
이 테크팁은 안전한 ftp 서버를 생성하는 방법에 대해서 설명 합니다. ftp 데몬은 비-root 유저에 의해 실행되고, 유저가 정의한 포트를 리스닝하며, chroot 를 이용한 고립된 환경에서 동작합니다. 이 구현은 표준 ftp 포트를 이용해서 root 유저가 ftpd 를 실행하도록 변경하실 수도 있습니다. 이 환경은 설정이 가능한 접근제어 권한을 통해서 미리 지정된 사용자만이 로그인 할 수 있도록 합니다. 물론 여러분이 이러한 고립된 환경을 생성하려면 root 유저 권한이 필요 합니다.
참고: 이 방법은 솔라리스9 에서만 테스트 되었지만 기타 다른 솔라리스 버전에서도 잘 동작할 것입니다.
고립된 ftp 환경을 위치할 장소를 지정합니다, 필자는 이 글에서 /ftpjail 을 사용할 것입니다.
이 디렉토리는 설정파일과 ftp 서버 바이너리를 담기에 충분한 공간,즉 약 8메가 정도 와 ftp 를 통해 전송될 파일들의 용량을 더한 만큼의 공간을 가진 마운트된 파일시스템이어야 합니다.
이 테크팁에서 설명하고 있는 고립된 FTP 환경을 위한 전체 파일 리스트를 보여주고 있는 보조자료는 다음 링크에서 찾으실 수 있습니다: http://wikis.sun.com/display/BigAdmin/Building+a+Secure+FTP+Server+-+File+List
<ftp jail root> (/ftpjail) 환경 만들기
<ftp jail root> (/ftpjail) 디렉토리 아래에 심볼릭 링크와 디렉토리들을 생성합니다.
mkdir -p /ftpjail
cd /ftpjail
mkdir -p dev etc etc/ftpd etc/default usr/bin usr/sbin usr/lib/security usr/lib/locale usr/lib/security/sparcv9 usr/lib usr/share/lib/zoneinfo upload
chmod 100 usr/sbin
chmod 444 dev etc/default usr/share usr/share/lib usr/share/lib/zoneinfo
chmod 555 etc etc/ftpd usr usr/bin usr/lib usr/lib/locale usr/lib/security
chmod 777 upload
Create ln -s usr/bin bin
고립 환경에 필요한 특수 디바이스 파일들을 생성하기
디바이스 심볼링 링크의 목록을 통해서 현재 사용하고 있는 특수 디바이스 파일들과 메이저, 마이너 넘버를 찾습니다.
cd /dev
ls -l conslog null tcp ticlts ticotsord udp zero
lrwxrwxrwx 1 root other 31 Aug 8 12:36 conslog -> ../devices/pseudo/log@0:conslog
lrwxrwxrwx 1 root other 27 Aug 8 12:36 null -> ../devices/pseudo/mm@0:null
lrwxrwxrwx 1 root other 27 Aug 8 12:36 tcp -> ../devices/pseudo/tcp@0:tcp
lrwxrwxrwx 1 root other 29 Aug 8 12:36 ticlts -> ../devices/pseudo/tl@0:ticlts
lrwxrwxrwx 1 root other 32 Aug 8 12:36 ticotsord -> ../devices/pseudo/tl@0:ticotsord
lrwxrwxrwx 1 root other 27 Aug 8 12:36 udp -> ../devices/pseudo/udp@0:udp
lrwxrwxrwx 1 root other 27 Aug 8 12:36 zero -> ../devices/pseudo/mm@0:zero
이제 실제 디바이스 파일을 찾습니다.
cd ../devices/pseudo
ls -l log@0:conslog mm@0:null tcp@0:tcp tl@0:ticlts tl@0:ticotsord udp@0:udp mm@0:zero
crw-rw-rw- 1 root sys 21, 0 Aug 8 12:36 log@0:conslog
crw-rw-rw- 1 root sys 13, 2 Sep 25 11:47 mm@0:null
crw-rw-rw- 1 root sys 13, 12 Aug 8 12:36 mm@0:zero
crw-rw-rw- 1 root sys 42, 0 Aug 8 12:36 tcp@0:tcp
crw-rw-rw- 1 root sys 105, 2 Aug 8 12:36 tl@0:ticlts
crw-rw-rw- 1 root sys 105, 1 Aug 8 12:36 tl@0:ticotsord
crw-rw-rw- 1 root sys 41, 0 Aug 8 12:36 udp@0:udp
위에서 찾은 메이저, 마이너 넘버를 이용하여 새로운 디바이스 파일들을 고립된 환경에 생성합니다.
cd /dev
ls -l conslog null tcp ticlts ticotsord udp zero
lrwxrwxrwx 1 root other 31 Aug 8 12:36 conslog -> ../devices/pseudo/log@0:conslog
lrwxrwxrwx 1 root other 27 Aug 8 12:36 null -> ../devices/pseudo/mm@0:null
lrwxrwxrwx 1 root other 27 Aug 8 12:36 tcp -> ../devices/pseudo/tcp@0:tcp
lrwxrwxrwx 1 root other 29 Aug 8 12:36 ticlts -> ../devices/pseudo/tl@0:ticlts
lrwxrwxrwx 1 root other 32 Aug 8 12:36 ticotsord -> ../devices/pseudo/tl@0:ticotsord
lrwxrwxrwx 1 root other 27 Aug 8 12:36 udp -> ../devices/pseudo/udp@0:udp
lrwxrwxrwx 1 root other 27 Aug 8 12:36 zero -> ../devices/pseudo/mm@0:zero
그 다음으로 실제 디바이스 파일들의 목록을 살펴 봅니다.
cd ../devices/pseudo
ls -l log@0:conslog mm@0:null tcp@0:tcp tl@0:ticlts tl@0:ticotsord udp@0:udp mm@0:zero
crw-rw-rw- 1 root sys 21, 0 Aug 8 12:36 log@0:conslog
crw-rw-rw- 1 root sys 13, 2 Sep 25 11:47 mm@0:null
crw-rw-rw- 1 root sys 13, 12 Aug 8 12:36 mm@0:zero
crw-rw-rw- 1 root sys 42, 0 Aug 8 12:36 tcp@0:tcp
crw-rw-rw- 1 root sys 105, 2 Aug 8 12:36 tl@0:ticlts
crw-rw-rw- 1 root sys 105, 1 Aug 8 12:36 tl@0:ticotsord
crw-rw-rw- 1 root sys 41, 0 Aug 8 12:36 udp@0:udp
위에서 찾은 메이저, 마이너 넘버를 이용하여 새로운 디바이스 파일들을 생성합니다.
cd /ftpjail/dev
mknod conslog c 21 0
mknod null c 13 2
mknod zero c 13 12
mknod tcp c 42 0
mknod ticlts c 105 2
mknod ticotsord c 105 1
mknod udp c 41 0
chmod 666 conslog null tcp ticlts ticotsord udp zero
작업한 결과를 확인 합니다.
ls -l
crw-rw-rw- 1 root other 21, 0 Sep 25 11:57 conslog
crw-rw-rw- 1 root other 13, 2 Sep 25 11:57 null
crw-rw-rw- 1 root other 42, 0 Sep 25 11:57 tcp
crw-rw-rw- 1 root other 105, 2 Sep 25 11:57 ticlts
crw-rw-rw- 1 root other 105, 1 Sep 25 11:57 ticotsord
crw-rw-rw- 1 root other 41, 0 Sep 25 11:57 udp
crw-rw-rw- 1 root other 13, 12 Sep 25 11:57 zero
고립된 ftp 환경에서 설정 파일들을 생성합니다
vi 같은 에디터를 사용해서 다음의 파일들을 생성합니다.
/ftpjail/etc/groupother::1:root
ftp::30000:
/ftpjail/etc/pam.conf
ftp auth required /usr/lib/security/pam_unix.so.1
ftp account required /usr/lib/security/pam_unix.so.1
ftp session required /usr/lib/security/pam_unix.so.1
/ftpjail/etc/passwd
참고: 아래의 gftp 를 ftp 서버를 이용해 로그인할 유저 이름으로 변경합니다. 여러분은 ftp 서버를 로그인할때 사용할 다른 유저들을 이 파일에 추가하실 수 있습니다.
root:x:0:1:::
ftp:x:30000:30000::/upload:/bin/false
gftp:x:30000:30000::/upload:/bin/sh
/ftpjail/etc/shadow
참고: 아래의 gftp 를 ftp 서버를 이용해 로그인할 유저 이름으로 변경하고, $$ 를 유저가 사용할 패스워드로 변경 합니다.
암호화된 패스워드 생성을 위해서, 패스워드 설비를 이용해서 여러분이 패스워드를 알고 있는 호스트 유저의 패스워드를 변경 합니다. 그다음에 암호화된 패스워드를 /etc/shadow 에서 복사해 옵니다. passwd 유틸리티를 이용해서 패스워드를 다시 변경해야 함을 기억하시기 바랍니다. 이 파일에 있는 유저들은 반드시 var/ftpjail/etc/passwd 에 있는 유저들과 매치 되어야 합니다.root:*LK*:6445::::::
ftp:*LK*:13651::::::
gftp:$$:13651::::::
/ftpjail/etc/shells
/bin/sh
/ftpjail/etc/ftpd/ftpaccess
hostname ftpserver
defaultserver private
class all real,guest,anonymous *
# all the following default to "yes" for everybody
delete no real,guest,anonymous
overwrite no real,guest,anonymous
rename no real,guest,anonymous
chmod no real,guest,anonymous
umask no real,guest,anonymous
# specify the upload directory information
upload / * no
upload / /upload yes
greeting terse
noretrieve *
#allow-retrieve /upload/*
defumask 777
/ftpjail/usr/bin/runme
/usr/sbin/in.ftpd -P 2020 -p 2021 -S -u 022 -W -a -Q
새롭게 생성된 파일의 퍼미션 정정하기
cd /ftpjail/etc
chmod 444 group pam.conf passwd shadow shells /ftpjail/etc/ftpd/ftpaccess
chmod 100 /ftpjail/usr/bin/runme
고립된 ftp 환경으로 현재 파일들을 복사하고, 퍼미션 정정하기
cp -p /etc/default/init /ftpjail/etc/default/init
cp /usr/bin/sh /ftpjail/usr/bin/sh; chmod 111 /ftpjail/usr/bin/sh
cp /usr/sbin/in.ftpd /ftpjail/usr/sbin/in.ftpd; chmod 6100 /ftpjail/usr/sbin/in.ftpd; chown 30000:30000 /ftpjail/usr/sbin/in.ftpd
cp -rp /usr/lib/locale/* /ftpjail/usr/lib/locale
cp -rp /usr/share/lib/zoneinfo/* /ftpjail/usr/share/lib/zoneinfo
cd /ftpjail/usr/lib
cp -p /usr/lib/libbsm.so.1 .
cp -p /usr/lib/libc.so.1 .
cp -p /usr/lib/libcmd.so.1 .
cp -p /usr/lib/libdl.so.1 .
cp -p /usr/lib/libgen.so.1 .
cp -p /usr/lib/libmd5.so.1 .
cp -p /usr/lib/libmp.so.2 .
cp -p /usr/lib/libnsl.so.1 .
cp -p /usr/lib/libpam.so.1 .
cp -p /usr/lib/libresolv.so.2 .
cp -p /usr/lib/libsecdb.so.1 .
cp -p /usr/lib/libsocket.so.1 .
cp -p /usr/lib/ld.so.1 .
cp -p /usr/lib/nss_user.so.1 .
cp -p /usr/lib/nss_files.so.1 .
chmod 555 *
cd /ftpjail/usr/lib/security
cp -p /usr/lib/security/crypt_bsdbf.so.1 .
cp -p /usr/lib/security/crypt_bsdmd5.so.1 .
cp -p /usr/lib/security/crypt_sunmd5.so.1 .
cp -p /usr/lib/security/pam* .
cd /ftpjail/usr/lib/security/sparcv9
cp -p /usr/lib/security/sparcv9/* .
새로운 환경을 살펴 보기 위한 초기 테스트
한가지 빼먹은것이 있는데 만약 유저가 ls 커맨드를 사용할 수 있도록 하길 원한다면 해당 파일을 환경으로 복사해야 합니다. 필자는 파일을 테스트 후에 지울 것을 추천합니다.
cp /usr/bin/ls /ftpjail/usr/bin/ls; chmod 111 /ftpjail/usr/bin/ls
고립 환경에서 sh 쉘 스크립트를 실행합니다.
참고: 환경안에서는 오직 제한된 커맨드들만이 존재 합니다. 그러나 ls 와 cd 같은 명령은 사용이 가능합니다.
chroot /ftpjail /usr/bin/sh
ftp 서버 시작하기
참고: ftpd 프로세스가 고립된 환경에서 생성되고 실행될 것이고 런타임 커맨드에서 지정된 포트를 리스닝하게 될 것입니다.
chroot /ftpjail /usr/bin/sh -c runme
서버가 시작되었는지 확인합니다.
참고: 필자의 /etc/password 파일에는 UID 30000 에 대한 항목이 없으므로 아래의 결과는 오직 숫자로 출력 됩니다.
ps -ef|grep ftpd
0030000 26704 1 0 09:04:30 ? 0:00 /usr/sbin/in.ftpd -P 2020 -p 2021 -S -u 022 -W -a -Q
ftp 서버 테스트하기
참고:/ftpjail/etc/ftpd/ftpaccess 에 설정된대로 여러분은 오직 파일의 업로드만 가능합니다.
ftp 127.0.0.1 2021
login gftp/<as set in /ftpjail/etc/shadow>
저자에 관하여
Ross Moffatt 은 유닉스 시스템 관리자로 10년 이상 일해 왔고 ross.stuff@telstra.com 로 연락하실 수 있습니다.
이 글의 영문 원본은
Building a Secure FTP Server
에서 보실 수 있습니다