Vsftpd & Proftpd
##### FTP - TFTP, FTP 접속방식 (Active Mode, Passive Mode)
### VSFTP - Tips (접속에러, 접속자 확인, SELINUX)
*** Install - 설치, 환경설정 (사용자 생성, 접속제한)
*** vsftpd.conf, 가상유저 서비스
### PproFTP - Etc, Magic Cookie, Files, Install,
/etc/proftpd.conf (기본 설정, 권한 설정, 시스템 설정),
<Anonymous>, <Directory>, <Limit>, <VirtualHost>
##############################
##############################
FTP
*** TFTP
tftp 서버는 인증 방법을 제공하지 않는다.
또한 홈 디렉토리가 없어도 tftp 서버의 홈 디렉토리를 /tftpboot 로 변경하므로 결과를 예측할 수가 없다.
tftpd 는 nobody 사용자 계정으로 실행하며 공개적으로 읽기 가능한 파일을 사용자가 읽을 수 있도록
허용할 뿐 아니라 공개적으로 쓰기 가능한 파일에 대해서도 쓸 수 있도록 허용 한다.
이 서버를 사용해야 하는 경우에는 디렉토리 변경을 강제로 수행하는 명령인
-s 플래그를 사용하여 실행하는 것을 고려해 보라.
*** 사설(내부) 아이피에서 ftp 사용시 passive mode 때문에 접속이 제대로 안되는 경우
pasv_enable=NO 를 추가후 inetd 를 재실행해 주면 다시 접속을 하면 재대로 실행이 될것이다.
# ftp 192.168.0.10
220 Welcome to FTP Server
530 Please login with USER and PASS.
...
ftp> dir
227 Entering Passive Mode (192,168,123,107,197,183)
passive 가 on 으로 되어 있을 경우 출력되는 내용이다.
vsftp 에서 따로 설정이 되지 않으면 기본적으로 on 으로 설정된다.
client 가 사설이면 server 와 Command Session 은 맺어지지만 Data Session 은 맺어지지 않는다.
server 에서 사설 client 로 Data session 연결을 시도하지만 사설 IP 이기 때문에 연결이 되지 않는다.
이런 이유로 FTP Gateway 설정을 해서 방화벽이 내부 사용자들의 FTP 접속을 대행하게 된다.
방화벽이 내부 사설 PC 의 FTP 접속 요구를 가로채서 방화벽이 대신 server 로 접속을 하게 된다.
방화벽이 server 와 client 의 중간에서 data 의 흐름을 중개하는 것이다.
### FTP 접속방식 ###
- Port Mode(Active Mode)와 Passive Mode 두 가지가 있다.
*** Port Mode (Active Mode)
처음 client 가 server 로 21 번 포트로 접속을 맺게 되는데 이 session 을 Command Session 이라고 하며
이 Command Session 을 통해 사용자는 server 에게 사용자 ID 와 Password 를 전달해서 인증을 받는다.
인증을 거친 client 는 pwd, dir, get, put 등의 원하는 작업에 해당하는 명령어를 전달한다.
FTP 를 통해 실제 파일을 주고 받을 때는 새로운 session 이 하나 더 연결되는데 이를 Data Session 이라고 한다.
Data Session 은 server 에서 자신의 출발지 포트를 20 번으로 하고 client 로 1024 이상의 포트로 접속을 맺는다.
이 Data Session 을 통해 client 는 server 로부터 파일을 다운로드 및 업로드를 하게된다.
*** Passive Mode
Port Mode(Active Mode)가 client 에서 server 로, server 에서 client 로의 접속인 반면
Passive Mode 는 client 가 server 로 Command Session 과 Data Session 을 모두 연결하는 방식이다.
내부 사설 PC 에서 server 로 Command 와 Data Session 을 모두 연결하기 때문에 내부에서 외부로
FTP 접속시 Passive Mode 로만 접속한다면 방화벽 에서는 FTP Gateway 를 설정할 필요는 없다.
####################
##### VSFTP (Very Secure FTP Daemon)
vsftp 는 보안 부분을 특히 강조한 데몬으로 Redhat, Suse, Open-BSD 에서 기본 FTP 로 채택하고 있으며
보안, 빠른 퍼모먼스, 안정성을 주요 특징으로 소개하고 있고 그 성능도 여느 ftp 서버 보다 탁월하다.
또한 config 파일의 설정 문법도 아주 간단해서 FTP 서버 관리를 쉽게 할 수 있다.
*** 주요 기능
- 가상 IP 별 별도의 환경 설정 기능 (설정 파일의 listen_address= 이용)
- 가상 사용자 설정, 강력한 사용자설정
- 전송 대역폭 지정
- PAM 지원 (버전 1.2.0부터는 PAM을 통한 wtmp에 로긴 로그를 남김)
- xferlog 표준 로그 파일보다 상세한 자체 로그 파일 형식 지원
- Standalone 방식과 inetd (xinetd)를 통한 운영 모두 지원
- IP별 다른 환경 파일 지정 기능 (tcp_wrappers와 함께 사용할 때)
### Tips ### ::: ★★★
- ssh 터널링을 사용하여 vsftp 접속시 Bad IP Deny 나오면 pasv_promiscuous=YES 을 추가하라.
*** 접속에러
- 반드시 ftp 유저의 홈디렉토리의 권한을 root.root 로 셋팅해야 익명접속이 문제없이 된다.
- /vsr/ftp/pub 폴더의 권한을 777 로 바꾸면 접속이 안된다.
vs가 Very Secure 의 약자이다. 쉽게 얘기해서 보안이 강화된 ftp 다. /var/ftp/pub 디렉토리에
모든 권한을 풀어주게 되면 보안상 위험하기 때문에 vsftpd 에서는 접속을 막도록 설정되어 있다.
500 OOPS: cannot open chroot() user list file 에러
vsftpd.chroot_list 주석제거시 해당 파일이 없으면 발생한다.
500 OOPS: cannot change directory:/var/ftp
/var/ftp 디렉토리를 생성해 주면 된다.
550 Permission denied.
write 권한이 없는 경우 발생하는 에러이다. (write_enable=YES 로 지정)
*** 접속자 확인
vsftpd v1.2.0 이상부터 PAM 을 통해 wtmp 에 로그를 남기므로 last 로 접속여부를 확인할 수 있다.
ftpwho 형태의 명령은 없으며 다음 명령어 등으로 확인할 수 있다.
# ps -ef|grep vsftpd
# fuser -v ftp/tcp
*** SELINUX
# setsebool -P ftp_home_dir 1
페도라 코어 4 까실때 SELinux 로 설정했다면 디폴트로 사용자의 home 디렉토리에 쓰기를 막아놓는다.
SELinux 설정에서 FTP 부분을 변경하자.
# service vsftpd restart
home 디렉토리의 읽고쓰기를 1(True)로 변경하시고 vsftpd 를 재시작.
# setsebool -P ftpd_disable_trans 1
FTP 에 관하여 SELinux 정책을 아예 적용하지 않는 옵션을 설정
#####
##### Install ###
http://vsftpd.beasts.org/
ftp://vsftpd.beasts.org/users/cevans/
*** 설치
# tar xvfz vsftpd-1.2.0.tar.gz
# cd vsftpd-1.2.0
# vi logging.c
/* str_replace_unprintable(p_str, '?'); */
vsftpd는 출력할 수 없다고 판단하는 ASCII 코드 31 이하, 128~159, 177 문자를 ? 로 바꿔서 저장한다.
한글 파일명을 전송할 때 로그에 ???? 로 남지않도록 str_replace_unprintable(p_str, '?'); 를 주석처리
# vi builddefs.h
tcp_wrappers 접속제어를 사용하려면
#undef VSF_BUILD_TCPWRAPPERS -> #define VSF_BUILD_TCPWRAPPERS 로 바꾼다.
# mkdir /usr/local/sbin /usr/local/man/man{5,8}
# make
# make install
생성된 vsftpd 파일이 /usr/local/sbin 에 복사된다.
man 페이지가 /usr/local/man/man5, /usr/local/man/man8 로 복사
inet 모드로 운영할 때 사용할 vsftpd 파일도 /etc/xinetd.d 디렉토리에 복사가 된다.
# cp vsftpd.conf /etc
# cp install_dir/RedHat/vsftpd.pam /etc/pam.d/ftp
local 계정 사용자들의 로그인 인증을 위해 설치 디렉토리안의 RedHat 안에 있는
vsftpd.pam 파일을 /etc/pam.d 디렉토리에 ftp 라는 이름으로 복사
### 환경설정 ###
# vi /etc/vsftpd.conf
# mkdir /usr/share/empty
VSFTP 는 empty 라는 디렉토리를 필요로 한다. 기본구성은 /usr/share/empty 다.
*** 사용자 생성
- VSFTP 를 운영하기 위해서는 nobody 사용자가 필요
# usradd -M nobody
# grep nobody /etc/passwd
nobody:x:99:99:Nobody:/:/bin/bash
- Anonymous FTP 에서 사용할 ftp 계정 생성
# mkdir /var/ftp
# useradd -d /var/ftp ftp
# chown root.root /var/ftp
반드시 ftp 유저의 홈디렉토리의 권한을 root.root 로 셋팅해야 익명접속이 문제없이 된다.
# chmod og-w /var/ftp
*** 접속제한
# vi /etc/pam.d/vsftpd
auth required /lib/security/pam_listfile.so
item=user sense=deny file=/etc/ftpusers onerr=succeed <==(1)
auth required /lib/security/pam_pwdb.so shadow nullok
auth required /lib/security/pam_shells.so
account required /lib/security/pam_pwdb.so
session required /lib/security/pam_pwdb.so
이 파일은 /etc/ftpusers에 등록된 유저명은 접근을 하지 못하게 하는 것이다. (sense=deny)
ftpusers 파일이 없다면 생성해 주면 된다. (/etc/passwd 파일을 참조해 작성하면 된다)
# vi /etc/ftpusers
FTP 접속을 허용하지 않을 ID를 등록한다. (또는 vsftpd.ftpusers)
- /var/log/messages에 다음과 같은 로그가 남는다.
Aug 16 22:21:52 truefeel vsftpd: PAM-listfile: Refused user xxxxxxxx for service vsftpd
*** etc
# vi /etc/xinetd.d/vsftp ::: disable = yes
# /etc/rc.d/init.d/xinetd restart
# /usr/local/sbin/vsftpd &
#####
##### vsftpd.conf ###
*** 기본 설정
ftpd_banner=Welcome to acsecret FTP service.
FTP 서버 접속할 때 로긴 메시지 (default=버전번호). 한글 사용 가능
dirmessage_enable=YES 새로운 디렉토리에 들어갔을 때 뿌려줄 환경 메시지를 저장한 파일명
listen=YES Standalone 으로 운영할 때 listen=YES.
connect_from_port_20=YES Standalone 일때 포트 변경을 원할 경우 설정.
listen_port=2121 기본 포트외 다른 포트를 사용한다. vsftpd 서버를 재실행한다.
*** 서버 동작
idle_session_timeout=600 (default=300초). 클라이언트에서 아무런 명령이 없을경우
세션을 끝낼 때까지의 대기시간.
data_connection_timeout=120 (default=60초). data connection 을 끊을 대기 시간.
ls_recurse_enable=YES 디렉토리 내용 출력시 캐쉬 사용여부.
(클라언트 ftp 접속 프로그램 에서도 지정 가능)
pam_service_name=vsftpd PAM 파일명을 지정 (설치할 때 /etc/pam.d/vsftpd 명으로 복사함)
*** 접속 권한
local_enable=YES (default = NO). 로컬 계정 사용자의 접속 허용 여부
anonymous_enable=YES (default = YES). anonymous 사용자의 접속 허용 여부
userlist_enable=YES /etc/vsftpd.user_list 에 있는 사용자에 대해 접근을 허가 설정.
- 익명접속
nopriv_user=ftp
no_priv_user=ftp 익명(anonymous) 로그인시, 앨리어싱될 유저명 기입.
deny_email_enable=YES 익명 접속시 패스워드에 일반 이메일 주소를 거부 여부
(vsftpd.banned_emails에 지정된 이메일 주소만 허용)
banned_email_file=/etc/vsftpd.banned_emails
- chroot
chroot_local_user=YES (default=NO). 접속시 로컬 사용자의 홈디렉토리를 /로 변경
사용자의 홈디렉토리를 벗어나지 못하도록 제한하기 위한 설정. 제한이 필요할 경우
YES 로 바꾼 후 제한할 사용자 ID 를 chroot_list_file= 에 설정한 파일에 지정한다
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd.chroot_list
접속시 사용자 홈디렉토리를 /로 변경할 사용자 목록 허용. chroot 제한(적용)이 필요할 경우
YES 로 바꾼후 제한을 적용할 사용자 ID 를 chroot_list_file= 에 설정한 파일에 지정한다.
주의할 것은 chroot_local_user=YES 와 chroot_list_enable=YES 를 함께 사용할 경우
/etc/vsftpd.chroot_list에 포함된 사용자 ID 만 제한없이 홈디렉토리를 벗어날 수 있다. (반대로 작용)
*** 화일 권한
local_umask=022 (default = 077). 로컬 계정 사용자용 umask
write_enable=YES (defualt = NO). write 명령어 허용 여부
ascii_upload_enable=YES ASCII 파일 업로드 가능.
ascii_download_enable=YES ASCII 파일 다운로드 가능
- 익명사용자
anon_upload_enable=YES (default = NO). anonymous 사용자가 파일을 업로드 할수 있는지 여부
허용시 업로드 할수있는 디렉토리를 생성해 주어야 한다.
anon_mkdir_write_enable=YES (default = NO). anonymous 사용자의 디렉토리 생성 허용 여부
chown_upload=YES 익명유저가 업로드한 파일의 소유권을 자동변경.
chwon_username=acsecret 소유권을 변경하기 원하는 유저명으로 기입
*** log
session_support=YES wtmp 에 로그 남기기 (YES 로 해야만 last 명령어로 접속 여부 확인 가능)
xferlog_file=/var/log/vsftpd.log 파일 전송 로그 파일명
xferlog_enable=YES (default=YES). 파일 전송 로그를 남길 것인지 여부
xferlog_std_format=YES (defalut=YES). xferlog 표준 포맷으로 로그를 남길지 여부
xferlog 표준 포맷은 로그인, 디렉토리 생성등의 로그를 남기지 않지만
vsftpd 스타일 로그는 이를 포함한 보다 상세한 로그를 남긴다
- vsftpd 스타일 로그 예
Sun Jul 12 01:38:32 2003 [pid 31200] CONNECT: Client "127.0.0.1"
Sun Jul 12 01:38:34 2003 [pid 31199] [truefeel] FAIL LOGIN: Client "127.0.0.1"
### 필요한 설정을 추가 ###
- pasv mode
pasv_enable=NO 사무실에서 공유기를 통해서 접속을 하는데 ls 등이 자주 먹통이 되면 설정.
pasv_promiscuous=YES
pasv_min_port=30000
pasv_max_port=30999
- 가상유저
guest_enable=YES
guest_username=virftp 가상 유저의 실제 할당 계정
user_sub_token=$USER 서로 다른 홈 디렉토리를 부여하기 위해 셋팅
local_root=/home/virftp/$USER
virftp_use_local_privs=YES 설정하지 않으면 기본 적으로 anonymous 의 권한을 가지고
화일을 생성하지 못한다.
- xinetd 를 통하지 않고 standalone으로 동작할 때만 사용 가능)
max_clients=100 최대 접속자 수
max_per_ip=3 IP 당 접속 수
*** 전송속도 제한 (0은 제한없음, 단위는 초당 bytes)
local_max_rate=200000 계정 사용자의 전송량 제한
anon_max_rate=100000 anonymous 사용자의 전송속도 제한
trans_chunk_size=0 지정한 byte 단위로 나눠서 전송 저장한다. 0은 vsftpd 가 알아서 판단한다.
v1.1.3 이상에서 trans_chunk_size 옵션이 있다.
anonymous 사용자와 일반 계정 사용자로 나눠서 bandwidth 를 설정 하도록 옵션을 제공한다.
이 설정은 전송되는 상황을 더 쉽게 파악할수 있도록 해준다.
anon_max_rate=10000, trans_chunk_size=0 로 설정하여 chunk size 를 vsftpd 가 판단하도록 한다.
vsftpd 는 chunk size 를 제한한 rate(10000) 보다 큰 50000 byte 가 적당하다고 판단했다면
1~4 초 사이에는 전송된 파일 크기는 0 으로 표시될 것이다.
5 초가 되어야 파일 크기는 50000 으로 보일 것이다. (5초 이후에도 마찬가지다)
이때 trans_chunk_size=5000 으로 했다면 전송된 파일 크기를 바로바로 확인할 수 있다.
size 는 최소 4096~65536 의 값을 설정해야 적용이 된다.
- proftpd 의 RateReadFreeBytes 와 RateReadHardBPS 같은 역할을 하는 옵션은 없다.
RateReadFreeBytes bandwidth 제한 없이 전송할 수 파일 크기
RateReadHardBPS RateReadFreeBytes 보다 파일이 클때, 위의 지정한 파일크기 까지는 제한없이 전송.
그 다음 크기부터는 제한한 bandwidth로 파일 전송
#####
##### 가상유저 서비스 ###
가상유저 FTP 란 로컬 시스템에 실제로 존재하지 않는 유저로 FTP 로그인을 허락하고 운영하는 환경이다.
로컬 시스템에 계정을 추가하지 않고도 FTP 만을 위한 사용자를 추가, 삭제할 수 있는 FTP 시스템이다.
사용자 들에게 FTP 만 제공해야 될때 아주 유용하게 사용할 수 있다.
*** 가상유저 데이터베이스 생성
FTP 가상유저를 생성하기 위해 가상유저와 패스워드가 담긴 DB 파일을 만들어야 되는데
간단히 사용자 ID 와 비밀번호가 입력된 텍스트 파일을 db_load 유틸을 이용해
DB 포맷으로 변환해 줌으로써 가상유저가 사용할 사용자 DB 파일을 만들수 있다.
홀수줄은 FTP 가상유저 ID 가 되고 짝수줄은 바로 윗줄에 명시된 FTP 가상유저의 비밀번호가 된다.
# cat vir_user.txt
myid
1234
DB 포멧으로 변환하기 위해 db_load 유틸을 사용하는데 db4-utils 이라는 RPM 패키지에 포함되어 있다.
db_load 유틸을 설치하지 않았으면 db4-utils RPM 패키지를 다운받아 설치하라.
/etc 디렉토리안에 넣고, root 이외의 사용자는 파일을 볼수없게 퍼미션을 600 으로 변경
# db_load -T -t hash -f vir_user.txt ~/vsftpd_login.db
# mv ~/vsftpd_login.db /etc/
# chmod 600 /etc/vsftpd_login.db
# ls -l
-rw------- 1 root rootl 12288 10월 27 16:39 /etc/vsftpd_login.db
*** 사용자 인증에 사용할 PAM 파일 생성
이제 가상 유저들의 ID와 비밀번호가 정확한지 체크한후 FTP 로그인을 허락하기 위한 PAM 을 만들 것이다.
# vi /etc/pam.d/vsftpd
auth required /lib/security/pam_userdb.so db=/etc/vsftpd_login account required \
/lib/security/pam_userdb.so db=/etc/vsftpd_login
*** 가상유저 계정 생성과 가상유저들이 사용할 디렉토리 생성
virftp 계정을 가상 유저들의 실제 계정으로 추가하고
/home/virftp 디렉토리를 가상 FTP의 홈디렉토리로 지정을 할 것이다.
# useradd -d /home/virftp virftp
# cp /etc/hosts /home/virftp/
# chown virftp.virftp hosts
# ls -l
drwx------ 4 virftp virftp 4096 10월 27 16:39 /home/virftp
-rw-r--r-- 1 virftp virftp 146 10월 27 16:39 /home/virftp/hosts
*** 가상 FTP 환경설정 파일 세팅
이제 마지막으로 가상 FTP 를 사용하기 위한 환경설정 파일을 작성할 것이다.
vsftpd_vitual.conf 라는 파일에 다음의 내용을 넣어 /etc 디렉토리에 생성하라.
listen=YES standalone 모드로 설정하기 위해
listen_port=2121 listen_port 를 추가하고 vsftpd 서버를 재실행한다
#connect_from_port_20=YES
local_enable=YES 가상 유저도 로컬사용자 이다.
anonymous_enable=NO 익명접속 막음
chroot_local_user=YES 홈 디렉토리 이외는 접속 불능
write_enable=YES 화일 생성 가능
local_umask=022
xferlog_enable=YES 접속 로그 생성
xferlog_file=/var/log/vsftpd.log
pam_service_name=vsftpd pam 화일 이름
pasv_min_port=30000
pasv_max_port=30999
guest_enable=YES 반드시 ok
guest_username=virftp 가상 유저의 실제 할당 계정
user_sub_token=$USER 서로 다른 홈 디렉토리를 부여하기 위해 셋팅
local_root=/home/virftp/$USER
virftp_use_local_privs=YES 설정하지 않으면 기본 적으로 anonymous 의 권한을 가지고
화일을 생성하지 못한다.
dirmessage_enable=YES
*** 위와같이 설정이 되었다면 /home/virftp 에 가상유저별 홈디렉토리를 생성해야한다.
# mkdir /home/virftp/{myid,yourid}
# chown virftp.virftp /home/virftp/*
# ls -l /home/virftp/
-rw-r--r-- 1 virftp virftp 146 10월 27 16:39 hosts
drw-r-xr-x 1 virftp virftp 4096 10월 27 16:39 myid
drw-r-xr-x 1 virftp virftp 4096 10월 27 16:39 yourid
*** vsftpd 실행
가상유저 FTP 를 운영하기 위해서는 vsftpd 를 Standalone 방식으로 작동시켜야 된다.
vsftpd 실행시에 /etc/vsftpd_virftp.conf 파일을 환경설정 파일로 지정하자.
# ftp localhost
user :
passwd :
####################
##### PproFTP
*** Etc
- 대용량 ProFTPD 운영하기
LVS(Linux Virtual Server) 모듈을 커널에 설정한 다음, Load Balancing 을 한다면
대규모의 네트워크 부하를 분산시킬 수 있는 Proftpd 서비스를 할 수 있다.
참고 사이트 http://linux.clusterkorea.org/lvs
http://kldp.org/Translations/html/Virtual_Server-KLDP/index.htm
- proftp 에서 root 접속, 익명연결 모두 연결은 되나 파일이나 디렉토리가 안보인다.
한국통신 쓰고, 공유기 연결, 텔넷접속은 잘된다.
공유기를 연결은 사설 IP 를 사용하는데 알 FTP 나 기타 FTP 보면 passive mode에 체크후 접속해라.
원인은 공유기 셋팅문제인거 같다. 인터넷 모뎀에 바로 연결 했더니 ftp 접속이 잘 되었다.
### Magic Cookie ###
%C 현재 작업하고 있는 디렉토리
%E 서버 관리자의 e-mail 주소
%f 사용가능한 hdd 공간 (giga단위)
%F 사용가능한 hdd 공간 (byte단위)
%L 로컬 host의 이름
%m 지금 접속할수있는 최대 클라이언트 수를 타타냄 ("메시지 %m")
%M 접속 가능한 최대 사용자 수
%N 현재 접속자 수
%R 원격 host의 이름
%T 시스템의 현재 시간 (접속한 시간)
%u ident protocol에 의해 알려진 사용자 이름
%U login 시 입력한 사용자 이름
%V ServerName 지시자의 내용 (서버이름)
==================== .welcome.msg ====================
환영합니다......
ProFTPd Alzza Linux 6.0 2.2.12(안정)
ftp://%L/
o 남은 용량 : %F KB
o 현 사용자 수 : %N/%M (하나의 호스트당 1명까지 접속 허가합니다)
o %R의 %u(%U)님이 접속한 현 시각은 %T년입니다.
Admin-mailto:%E
========================= END =========================
1.2.pre6 버전을 제외한 그 이상의 버전은 "%F KB" 대신 "%f"로 기입하면 Mb로 출력된다.
### Files ###
*** 실행화일
/usr/sbin/proftpd proftpd 실행화일
/usr/sbin/in.proftpd inetd 모드로 운영하기 위한 링크화일
/etc/rc.d/init.d/proftpd standalone 일때 proftpd 데몬 스크립트 화일
/usr/bin/ftpcount 현재 서버에 접속하고 있는 사람의 숫자를 세는 프로그램
/usr/bin/ftpwho 현재 서버에 접속하고 있는 사람의 아이디, process 정보를 출력 해주는 프로그램
/usr/bin/ftpls ftp 디렉토리 목록 출력
/usr/bin/ftpcopy 목적지 ftp 에서 파일 다운로드
*** 구성화일
/var/ftp anonymous 의 홈디렉토리
/var/ftp/pub anonymous ftp 파일 다운로드 디렉토리
/var/ftp/incoming anonymous ftp 파일 업로드 디렉토리
/var/log/xferlog ftp 로그 파일
*** 설정화일
/etc/proftpd.conf proftpd 설정화일
/etc/pam.d/ftp ftp 보안 관련 설정 파일
~/.ftpaccess .ftpaccess 화일을 가지고 각 디렉토리마다 접근제한을 할수있다
proftpd.conf 화일로 접근을 설정할수 있지만 코드가 복잡해지게 된다
/etc/ftpusers proftpd 의 접근을 막어놓은 리스트화일
/etc/ftphosts 외부 접근 설정
allow acsecret www.glister.co.kr
/>deny test 168.126.38.26
#####
##### Install ###
http://www.proftpd.org http://proftpd.oops.org/ http://www.proftpd.net/
*** /etc/xinetd.d/proftpd
service ftp
{
flags = REUSE
protocol = tcp
socket_type = stream
instances = 50
wait = no
user = root
server = /usr/sbin/in.proftpd
log_on_success = HOST PID
log_on_failure = HOST RECORD
}
*** rpm
- proftpd-core 파일을 먼저 설치한 후에 서버의 구동방식에 따라 알맞은 파일을 다운받아 설치하면 된다.
# rpm -Uvh proftpd-core-1.2.0rc2-1kr2.i386.rpm
# rpm -Uvh proftpd-xinetd-1.2.0.rc2-1kr2.i386.rpm
### Source ###
- 최적화하기 위해서는 아래와 같이 환경설정을 한 후에 컴파일을 하면 된다.
# CC="egcs"
CFLAGS="-O9 -funroll-loops -ffast-math -malign-double -mcpu=pentiumpro -march=pentiumpro
-fomit-frame-pointer -fno-exceptions"
# tar -xvzf proftpd-1.2.xxx.tar.gz
# mv proftpd-1.2.xxx proftpd
# ./configure --prefix=/usr/local/proftpd --sysconfir=/etc
--enable=autoshadow shadow 패스워드를 지원하는 서버의 경우 자동으로 패스워드를 인식
# cp contrib/dist/rpm/ftp.pamd /etc/pamd.ftp
# make
# make install
# cp contrib/dist/rpm/ftp.pamd /etc/pamd.ftp
# mkdir /var/ftp
# chown ftp.ftp /var/ftp
# chmod o= /var/ftp ::: drwxr-xr-x 에서 "drwxr-x--" 로 변경
*** 환경설정
- Passive 모드 이용시
# vi /etc/rc.d/rc.local
modprobe ip_nat_ftp
modprobe ip_conntrack_ftp
# vi /etc/proftpd.conf
# vi /etc/ftpusers 접속 막을 계정 등록
# vi /etc/pam.d/ftp
# vi /etc/ftphosts
# vi ~/.ftpaccess
#####
##### /etc/proftpd.conf ###
- 자세한 설명은 /usr/share/doc/proftpd-버전/Configuration.html 파일에 나와 있다
- 익명 사용자를 허용하려면 /etc/ftpusers 파일에 anonymous 계정을 삭제하고
anonymous 관련 주석을 모두 삭제하자
*** 몰라
DenyFilter 어떤 명령과도 매치가 되지 않는 정규 표현식을 지정.
proftpd로 오는 명령어 조합을 막는데 유용하다
### 기본 설정 ###
ServerAdmin acsecret@glister.co.kr
ServerName "acsecret home network"
사용자가 FTP 서버에 접속했을 때 이 FTP 서버의 이름이 무엇인지 출력해준다.
ServerIden
ServerIdention "경호 FTP 서버에 접속하신것을 환영합니다."
사용자가 접속 했을때 출력되는 문자열을 설정.
Off 로 지정 하였을 경우 Porftpd Server Ready ServerName 이 출력된다.
지시자가 <VirtualHost> 블럭안에 존재 할때는 virtual server로 접속했을때 출력되는 문자열 설정
*** 메시지
DisplayLogin Login 시 나타나는 메시지 지정. 화일은 ascii 형태의 화일이다.
상대 경로로 지정할 경우 user 가 접속 했을때 처음 디렉토리를 기준으로 찾게 된다.
file 이 없다고 하더라도 에러는 발생하지 않는다.
익명 사용자의 경우 <anonymous /var/ftp> 가 기준 디렉토리다
DefaultRoot ~ 으로 설정할 경우 접근할수 있는 루트가 자신의 홈디렉토리로 설정되므로
일반 사용자들은 환영 메시지를 볼 수가 없다. ::: ★★★
DisplayQuit logout 시 나타나는 메시지 화일 지정
DisplayFirstChdir cd 명령으로 처음으로 디렉토리를 이동하였을 때 나타나는 메시지 화일 지정
*** 서버 동작
ServerType standalone / inetd
inetd.conf 설정을 하지 않고 proftpd 를 root 권한으로 실행하면 standalone daemon 으로 작동하게 된다.
Port 21 standalone 일때만 적용된다. inetd 로 설정했을 경우 inetd 에서 지정.
User nobody
Group nobody
root 권한으로 proftpd 를 시작하고 user 지시자로 설정한 유저와 group 으로 설정한 권한을 넘긴다
DefaultServer on | off
DefaultServer 는 FTP 서버의 primary IP 또는 가상 호스트 설정 블록에서 설정된 IP 가 아닌
기타 IP address 로부터 연결이 있을때 기본으로 사용 되어질 서버 설정을 해준다.
오직 하나의 server 만이 기본으로 설정되어 질수있다
알려지지 않은 연결이 있을 때 "no server available to service your request" 내용을 보여주며
연결이 끊어지게 될 것이다. 각 primary server 설정 또는 virtual server 들에 대한 defaultserver 가
on 으로 정의되어 있으면 모든 목적지를 알수없는 접속들은 default server 에 의해 서비스가 된다.
### 권한 설정 ###
*** 인증 설정
RootLogin root 의 ftp 접속 여부 (기본 설정은 거부한다)
rootlogin 지시자의 사용여부와 관계없이 루트 사용자는 항상 log 를 남긴다.
AuthPAMAuthoritative on | off (default=off). PAM 이 인증에 있어서 최종 단계의 권한 수용 여부
on 은 ftpusers file 을 이용하여 PAM 인증한다.
RequireValidShell on | off (default=on)
/etc/shells 에 정의되지 않는 shell을 사용하는 유저에게 FTP 접속 허락및 거절에 대한 지정
/etc/shells 에 등록되어 있는 shell 이 지정되어 있는 유저들만 로그인이 가능하게 한다
ftp user 의 shell 이 보통 /bin/false 로 지정이 되어 있으므로 이 값을 off 로 해준다.
on 은 /etc/shells 에 user 들이 사용하는 shell 이 없으면 login 을 할수없다.
그러므로 anonymous user 접속을 한다면 RequireValidShell 을 off 로 해야 login 할수있다.
MaxLoginAttempts 클라이언트가 proftpd 에 접속할때 인증 시도하는 횟수
사용자가 이횟수동안 접속을 못하는 경우 접속은 끊어지고 log 에 기록이 남는다.
DeferWelcome Client가 인증에 성공할 때까지 server에 대한 정보를 전송 지연
*** 화일 권한
Umask 022 새로 생성되는 화일 퍼미션 설정
002 (directory : 775, file 664), 020 (directory : 757, file 606)
022 (directory : 755, file 644), 007 (directory : 770, file 660)
070 (directory : 707, file 606)
777 - umask = directory's permission
666 - umask = file's permission (ftp 특성상 실행권한이 없기때문에 666이 가장 큰값이다)
기본적으로 모든 ftp 는 umask 값으로 022 로 정해져 있다.
LsDefaultOptions
LsDefaultOption -a ls 명령어의 -a option 으로 hidden file 을 볼수 있게 한다
AllowOverwrite on | off 덮어쓰기 지원
AllowRetrieveRestart on | off 이어쓰기 지원
HideUser root 소유권이 root 인 file 이나 directory 들을 보여주지 않는다
HideGroup root 그룹권한이 root 인 file 이나 directory 들을 보여주지 않는다
*** 디렉토리 권한
DefaultRoot ~
ftp 서버에 일반 계정으로 접속한 사용자에게 최상위 디렉토리를 지정해주는 것이다.
<Anonymous> 지시자 안에서는 사용할수 없다
/ /로 설정하면 사용자가 FTP 서버에 접속했을 때 / 디렉토리까지 접근 가능하게 설정한다
~ 일반 계정의 홈디렉토리가 접속한 계정의 최상위 디렉토리로 접근 가능하게 설정
- ~ woori,doori,!admin
woori,doori 유저id 가아닌 그룹을 뜻하고, !는 부정인 admin 그룹을 제외하고를 뜻한다
woori,doori 그룹은 자신의 홈디렉토리가 기본루트 디렉토리가 되고,
admin 그룹은 시스템 root(/) 디렉토리까지 접근할수 있다.
HideNoAccess on | off 접근 권한이 없는 사용자가 HideNoAccess 설정되어 있는
<Anonymous> 나 <Directory> 블록에 로그인 하였을때 디렉토리 항목을 볼수 없게한다
### 시스템 설정 ###
MaxInstances 30 atandalone 일경우 클라이언트마다 자식 프로세스를 만들어 주는 최대 갯수.
inetd 모드에서는 효과가 없다. DOS 공격으로 방어하기 위해 30 지정.
*** 최대 접속 제한
MaxClients [최대접속자수] ["메시지"] anonymouse 로 접속 할수있는 최대 사용자 수를 지정.
<global>, <virtual host> 블럭에서도 사용할수 있어 일반 사용자의 수도 제한 가능하다.
기본 메시지는 530 sorry maqxium users 출력.
none 접속을 제한하지 않는다.
MaxClientsPerHost [최대접속자수] ["메시지"] 하나의 호스트에서 접속 session 을 만들수있는 갯수
MaxHostsPerUser [최대접속자수] ["메시지"] 사용자 단위 접속 session 을 만들수 있는 갯수
MaxClients 3 "Sorry,", MaxClients none ""
MaxClientsPerHost 1 "죄송합니다, %m 하나의 호스트 IP 에서 한개의 FTP 접근만 허용합니다."
MaxHostsPerUser 1 "죄송합니다, %m 현재 본계정은 접속중이며 동일한 계정으로 다중 동시 접속은 불가능 합니다."
*** 접속 유지 시간 (초 단위)
TimeoutIdle 600 접속자가 입력없이 연결을 유지할 수 있는 시간
TimeoutNoTransfer 600 접속자가 디렉토리 목록을 받는등의 연결에 대한 입력없이 유지 할수있는 시간
TimeoutLogin 300 Client가 인증을 유지할 수 있는 시간
TimeoutStalled 600
*** 전송 대역폭 지정
- 모듈: mod_xfer, 버전: 1.2.0 이후
RateReadBPS / RateWriteBPS n (byte per sec). 클라이언트가 ftp 를 이용할때 전송 대역폭을 제어
0 는 대역폭의 한계가 없음을 말한다.
RateReadFreeBytes n (Byte). 대역폭 제한 없이 전송되는 바이트 수.
큰 화일을 다운로드 하는 동안에 많은 대역폭을 설정할 수 있다.
RateReadHardBPS on | off (defaul=off). RateReadFreeBytes 에 지정된 양만큼 파일이 전송되면
RateReadBPS 에 정해진 만큼 대역폭을 사용한다.
RateReadBPS 1024 다운로드 속도가 최대 1024bps 로 제한
### 확장 기능 ###
TimesGMT on | off GMT 시각 사용 여부
Server 의 Ftpd 시간을 지역시간으로 고정한다.
on 으로 했을 경우 GMT 시간을 표시 하기 때문에 한국의 경우 9 시간의 오차가 발생한다.
HiddenStor on | off 두단계의 화일 업로드 기능을 지원해주는 역할
화일 업로드중 사용자가 이화일을 사용할수 없도록 하기위해 사용된다
on 화일 업로드중 화일 명은 .in.file.name 으로 업로드가 되고 완료된후 원래의 이름을 가진다
UpTime 10 service 시작시간
DownTime 23 service 종료시간
service를 시작하고 마칠 시간을 24시간 표기법으로 지정을 한다
오전 10 시 부터 오후 23시 까지만 서버의 접속을 가능하게 한다.
DenyFilter \*.*/ 1.2.1 이하 버젼에서의 버그를 위한 설정
PathDenyFilter "(^.ftpaccess$)|(.mp3$)" MP3 확장자를 가진 파일을 업로드 못하게 한다.
*** 접속 지연이 되는경우 설정하면 빨라진다.
UseReverseDNS off
IdentLookups off ident protocol 은 remote username 의 허용 여부
1. 서버 부하, 2. inverse domain 문제, 3. ident lookup 문제
2 번과 3 번의 경우에는 UseReverseDNS off, IdentLookups off 설정으로 해결할수 있다.
/etc/hosts 에 접속할 client 의 ip 를 등록한 후 접속이 원할해 진다면 2번의 문제인 것이다.
*** FXP
AllowForeignAddress on
PassivePorts 49152 65534
일명 서버 투 서버 라고 불리우며 서버간의 파일 전송을 가능하게 하는 서비스를 의미한다.
FXP 서비스는 보통 windows ftp 들은 기본적으로 지원을 해 왔으나 Unix 용의 ftp 의 경우는
이 기능이 도입이 된지는 얼마 되지 않는다.
ProFTPD 에서 FXP 를 사용하기 위해서는, 사용하는 ProFTPd 의 버젼이 1.2.0 rc3 이상의 버젼이어야 한다.
만약 리얼 유저들만 허락을 하고 싶다면, Global 블럭이나 VirtualHost 블럭에 설정을 하도록 한다.
익명 서비스에도 이 기능을 사용하게 하고 싶다면 Anonymous 블럭에 이 값을 지정하도록 한다.
AlloForeignAddress 는 여러번 중복 지정이 되어도 상관 없으니 원하는 블럭에 기능을 사용할 수 있게
하든지 없게 하든지 마음대로 설정을 할 수가 있다.
#####
##### <Anonymous>, <Directory>, <Limit>, <VirtualHost> ###
*** <Directory>
- ~ 문자는 사용자의 홈디렉토리를 가리킨다.
- <Anonymouse> 지시자 안에서 사용하는 경우를 제외하고 절대 경로만을 입력해야 한다
(상대경로나 심벌릭링크 안됨, ~(사용자 홈디렉토리) 문자 허용됨)
- 지시자를 사용할때 몇가지 방법이 있는데 그 한가지는 바로 wildcard(*) 의 사용이다.
wildcard 는 디렉토리 자신과 해당 레벨의 모든 디렉토리 뿐 아니라 그 하위 디렉토리 까지를 의미한다.
wildcard 를 써서 영향받은 디렉토리는 그냥 <Directory> 에 의해서 영향을 받은 디렉토리보다
우선권을 가지게 된다. ::: ★★★
*** <Anonymous dir_name>
접속시 익명의 사용자 anonymous 로 접속하여 이용할 수 있는 디렉토리에 대한 옵션을 설정
anonymous 로 접속하는 익명 서비스 요청자들에 대한 여러가지 제한과 옵션을 적는다.
- <Directory> 지시자를 이용해 지정된 디렉토리와 그 하위 디렉토리에 대해서 특정 지시자를 사용할수 있다
- "*" 를 사용해서 영향을 받은 디렉토리는 <Directory> 지시자에 의해 영향을 받은 디렉토리보다 우선권을 가진다
### <Limit> ###
usage : <Limit command | command-group> ....... </Limit>
어떤 지시그룹 내에서, 또는 일반 내용속에서 ftp 명령어 사용에 제약을 주기 위해서 사용한다.
<limit> 이 설정되면 이후 설정에 영향을 주게 되며, 뒤에 설정한 <limit> 이 나올 때까지
모든 <directory>와 <Anonymous> 에 적용된 설정들을 제한하게 된다.
- Limit 명령어 제한이 실제 파일과 디렉토리에 접근 권한을 변경시키지 않는다.
- Limit 가 명령어를 제한하도록 사용되는 동안 운영체제 fs 에 상속되는 파일의 권한은 아무런 변화가 없다.
- host 지정방법
띄어쓰기와 콤마 둘다 사용가능
192.168.0.
.glister.co.kr
- 실제로 지정한 디렉토리에 (uploads) 화일을 쓰기위해서는 아래 명령을 실행 해주어야한다
# chown ftp.ftp /var/ftp/uploads
# chmod 755 /var/ftp/uploads
*** <Limit> block 의 command 숫자는 제한이 없다.
command 는 어떤 사용 가능한 FTP 명령도 되지만 다음 중 하나를 사용한다.
CWD(Change Work Directory) 디렉토리를 변경.
CWD 에 limit를 적용하면 CDUP(Change Directory UP)에도 적용된다.
DELE(DELEte) 파일을 삭제할 경우.
MKD(Make Directory) 새로운 디렉토리를 만든다.
RNFR(ReName From), RNTO(ReName To) 디렉토리의 이름을 바꿀 경우.
RMD(ReMove Directory) 디렉토리 삭제.
RETR(RETRieve) 서버에서 클라이언트로 파일 전송.
STOR(STORe) 클라이언트에서 서버로 파일 전송.
- 개별적인 명령을 다음과 같이 명령어 그룹으로 사용할 수도 있다.
ALL 모든 FTP 명령에 대한 제한을 적용
DIRS LIST 와 NLST 과 같은 디렉토리 목록관 관련된 FTP 명령을 포함
READ RETR, STAT 같은 파일 읽기와 관련된 FTP 명령을 포함, 디렉토리 목록은 포함되지 않는다
WRITE MKD, RMD 같은 파일 또는 디렉토리 쓰기, 생성, 삭제와 관련된 FTP 명령을 포함
- 특수 명령을 사용할 수도 있다.
LOGIN 사용자가 서버에 login을 할때 login 초기화의 허용 또는 제한에 사용 하거나
의사명령에 Limit을 적용해서 문맥에 연결
*** order
- ip 에대한 제약을 가하는 방법으로서 order 지시자를 사용한 제약을 설정 할수있다.
- 128.134.57.200 glister.co.kr 128.134.70.0 을 제외하고 모든 접속에대한 모든 ftp CMD 를 거부한다
<Limit ALL>
Order Allow,Deny
Allow from 128.134.57.200 glister.co.kr,128.134.70.
Deny from all
<Limit>
### <Anonymous /var/ftp> ###
- anonymous 의 홈디렉토리인 /var/ftp 는 기본적으로 pub, upload 디렉토리가 있다.
User ftp
Group ftp
<Anonymous> 에서 사용되는 User 와 Group 은 ProFTP 서버에 사용자가 anonymous 로 접속 할때의
디렉토리에 대한 User 와 Group을 지정해준다.
디렉토리에 대한 실제적인 권한은 지정한 사용자인 ftp user 가 가지게 된다.
UserAlias anonymous ftp anonymous 접속자는 localhost 의 ftp 계정을 할당 받는다.
서버에 접속할때 anonymous 를 ftp user 로 매핑하여 접근하게 한다.
AnonRequirePassword on | off
익명 접근을 할때 특정 password 를 지정할수 있다. 단 위의 User 지시자의 name 이
passwd file 에 등록이 되어져 있어야 한다. on 일 경우 이메일 주소로 login 을 할수 없다.
ShowSymlinks on | off
HideUser root (/home) 밑에 "rwxr-xr-x" 인 디렉토리의 내용이 안보이게 한다. ?????
DisplayLogin /welcome.msg
DisplayFirstChdir .message
MaxClients 3 "Sorry,"
MaxClientsPerHost 1 "Sorry, Allow only one client for host"
RequireValidShell off
MaxClients 10
<Limit LOGIN>
Order Allow,Deny
Allow from 128.134.57.200 glister.co.kr,128.134.70. .modu.com
Deny from all
</Limit>
<Limit WRITE>
DenyAll
</Limit>
<Directory /var/ftp/uploads>
Allowoverwrite on
AllowRetrieveRestart on
Umask 0022 anonymous 만이 서브디렉토리를 생성할수 있다
RateReadBPS 2024
RateWriteBPS 2024
<Limit READ STOR MKD RNTR RNTO DIRS DWD>
AllowAll
</Limit>
<Limit RMD DELE>
DenyAll
</Limit>
anonymous 가 만든 디렉토리를 다른 anonymous 가 지우지 못하게 한다
반대기능은 위문을 주석처리하고 아래를 적용해준다
<Limit Write>
AllowAll
</Limit>
</Directory>
</Anonymous>
### <VirtualHost> ###
- 한 아이피에서 여러개의 가상 ftp를 운영하고 있으므로 보안상 log 화일을 각각 관리 하도록 한다
- 가상 호스트를 설정하기 위해서는 dns 설정이 반듯이 필요하고 inetd 과 standalone 방식으로 나뉜다.
목적지 주소와 포트를 이용해서 설정된 가상호스트 중 올바른 정보가 있다면 알맞은 서비스를 시작한다.
- 현재 가상 호스트 에서는 anonymous 접속을 지원하지 않으므로 <Anonymous> 지시자를 사용할수 없다
하지만 ip 기반의 가상호스트 에서는 <Anonymous> 지시자를 사용할수 있다.
anonymous 접속을 할려면 우선은 Ftp 서버에 각각 다른 ip 주소가 ip alias 되어 있어야 한다.
그리고 네임 서버에 각각 다른 ip 주소로 지정이 되어 있어야 한다.
cocori.glister.co.kr IN A 192.168.0.50
dodori.glister.co.kr IN A 192.168.0.51
(예제에서는 ip 기반을 위해 추가함)
- 기본적인 모든 가상 호스트의 설정이 공통적으로 적용되는 부분을 설정한다
<Global>
Umask 022
DisplayLogin welcome.msg
DisplayFirstChdir .message
DefaultRoot ~!admin
MaxLoginAttempt 3
LsDefaultOptions "-a"
</Global>
*** ftp://cocori.glister.co.kr:29213
<VirtualHost cocori.glister.co.kr>
ServerName "cocori.glister.co.kr FTP server"
ServerAdmin "acsecret@glister.co.kr"
MaxClients 10 "Sorry, Maxium users %m"
MaxClientsPerHost 1 "Sorry, Allow only one client for host"
TransferLog /var/log/xferlog-cocori.glister.co.kr
port 29213
<Limit WRITE>
DenyAll
</Limit>
- <anonymous /home/cocori/ftp> 에는 /home/cocor/ftp 를 write 명령어 제한을 둔다.
<Anonymous /home/cocori/ftp>
User ftp
Group ftp
UserAlias anonymous ftp
<Limit WRITE>
DenyAll
</Limit>
- /home/cocori/ftp/uploads 부분은 anonymous 가 쓸수 있도록 지시자를 설정한다.
<Directory /home/cocori/ftp/uploads>
AllowOverwrite on
AllowRetrieveRestart on
<Limit WRITE>
Order Deny,Allow
Deny from nuguna.com
Allow from all
</Limit>
</Directory>
</Anonymous>
</VirtualHost>
*** ftp://doridori.glister.co.kr:29213
<VirtualHost doridori.glister.co.kr>
ServerName "doridori.glister.co.kr FTP server"
ServerAdmin "acsecret@glister.co.kr"
MaxClients 3 "Sorry, Maxium users %m"
MaxClientsPerHost 1 "Sorry, Allow only one client for host"
TransferLog /var/log/xferlog-nuna.glister.co.kr
<Anonymous /home/doridori/ftp>
<Directory /home/doridori/ftp/uploads>
...
</Directory>
...
</Anonymous>
</VirtualHost>
.ftpaccess 화일을 가지고 각 디렉토리마다 사용자들의 접근을 제한할수 있다.
# useradd nobody
# mkdir /usr/share/empty/
# mkdir /var/ftp/
# useradd -d /var/ftp ftp
# chown root.root /var/ftp
# chmod og-w /var/ftp
# make install
# cp vsftpd.conf /etc
# cp RedHat/vsftpd.pam /etc/pam.d/vsftpd
# cat /etc/passwd | awk -F: '{print $1}' > /etc/vsftp.chroot_list
# vi ~/welcome.msg
사용자가 ftp 로그인시 환영 인사말 설정
%U 접속한 사용자
%E ServerAdmin 에서 지정한 email 주소
%T 현재 시간
UserAlias anonymous ftpuser ftpuser 로 anonymous login을 할수 있도록 한다
아마 PAM인증을 사용하는 proftpd를 가져오신것 같네요.
혹시 문제가 발생할까 해서 .. 컴파일 설치 테스트 결과.. 이상없습니다.
설치버전 : proftpd-1.2.10
OS : Fedora Core 4
컨피그 옵션 : ./configure --prefix=/usr/local/proftpd --enable-autoshadow --enable-shadow
make 한 다음 make install 하고
proftpd.conf 파일에
nogroup을 nobody 로 바꾸어 주었으며,
AuthPAM off
정도 설정
'Linux > Linux 일반' 카테고리의 다른 글
리눅스 글꼴 설정 (0) | 2007.03.14 |
---|---|
ln -s text.txt hello.txt 는 hello.txt를 생성하여 text.txt를 가리킨다. (0) | 2007.03.13 |
Emacs (0) | 2007.03.11 |