Search Results for '프로그래밍/리눅스 & MY-SQL'


206 posts related to '프로그래밍/리눅스 & MY-SQL'

  1. 2010/06/01 리눅스 명령어 (역시나 필요한 사람이 있을까 해서..)
  2. 2010/06/01 끊김없이 네임서버 이전(교체)하기
  3. 2010/06/01 MySQL 백업용 쉘스크립트입니다.
  4. 2010/06/01 vi 에디터에서 창 나누기
  5. 2010/06/01 메일서버에서의 스펨메일 운영 방안(고급) 3
  6. 2010/04/14 인터넷슈퍼데몬(xinetd)
  7. 2010/04/14 JSP CENT OS 5 세팅법 |
  8. 2010/04/14 qmail 설치 |
  9. 2010/04/14 리눅스 iptables 사용법 1
  10. 2010/04/14 리눅스 iptables 중지하고자 할때
  11. 2010/03/29 아파치 설정팁들 이것저것
  12. 2010/03/29 아파치 최적화 httpd.conf 성능
  13. 2010/03/29 아파치 응답속도를 측정 ab -명령
  14. 2010/03/29 .htaccess를 이용한 특정 디렉토리 접근 관리하기
  15. 2010/03/29 /home에 있는 계정을 계정별로 따로 백업하는 스크립트 1
  16. 2010/03/29 리눅스에서 휴지통 (safedelete)
  17. 2010/03/29 리눅스 실시간 트래픽 모니터링 하기
  18. 2010/03/29 특정 확장자만 찾아서 복사
  19. 2010/03/29 여러가지 리눅스 팁들
  20. 2010/03/29 웹호스팅 사용자를 위한 계정관리 스크립트
  21. 2010/03/29 ncftp 를 이용한 백업 스크립트 1
  22. 2010/03/29 24시간 이내에 수정된 php 파일만 찾기
  23. 2010/03/29 현재 웹호스팅중이면 같은 서버에 호스팅 수
  24. 2010/03/29 vsftpd passive mode 사용
  25. 2010/03/29 useradd 및 userdel 사용방법
  26. 2010/03/18 MY - SQL 인젝션 복구쿼리
  27. 2010/03/14 지정한 두 기간 사이의 날짜 랜덤 생성
  28. 2010/03/12 [MySQL] root 비밀번호 분실시 해결법
  29. 2010/03/12 국가별 아이피 차단 스크립
  30. 2010/03/12 IPTABLES 를 이용한 파이어 월 구축..
addbib - 도서목록 형식의 데이터베이스를 만들거나, 확장
apropos - 사용설명서의 키워드 검색
ar - 라이브러리 만들기, 관리
at, batch - 원하는 시간에 원하는 명령을 실해하게 하는 명령
awk - 패턴 검색과 언어 처리
banner - 큰 글자(배너) 만들기
basename - 경로 이름에서 마지막에 있는 이름만 출력
biff - 자신에게 편지가 배달되면 알려주는 명령
bin-mail, binmail - 예전에 사용한 전자우편 프로그램
cal - 달력보기
calendar - 간단한 일정표
cat - 파일 병합과 내용 보기
cb - 간단한 C 프로그램 beautifier(?)
cc - C 컴파일러
cd - 작업 디렉토리 바꾸기
checknr - nroff 또는 troff 입력 파일 검사; 오류를 보여준다
chgrp - 파일의 사용자 그룹 바꾸기
chmod - 파일의 접근 권한 바꾸기
clear - 터미날 화면 깨끗이 하기
cmp - 두 파일을 바이트 단위로 비교
colcrt - troff 파일의 밑줄 속성 문자 처리
comm - 지정 두파일의 줄 단위 비교와 그 처리
compress, uncompress, zcat - 파일 압축관련 유틸리티들
cp - 파일 복사
cpio - copy file archives in and out
cpp - C 언어 전처리기
csh - C 문법과 비슷한 쉘 스크립트 문법과 기타 여러 기능이 내장된 쉘
ctags - ex 나 vi 편집기에서 사용될 tag 파일을 만드는 명령
date - 시스템 시간 보기나 지정하기
dbx - 소스 수준의 디버거
deroff - nroff, troff, tbl, eqn 관련 내용 지움
df - disk free: 디스크의 남은 용량 보기
diff - 두 파일의 차이점 비교
du - disk used : 디스크 사용량 보기
echo - 인자를 표준 출력으로 출력
ed, red - 기본 줄 편집기
eqn, neqn, checkeq - 수식 표현 포멧 도구
error - 컴파일러 오류 메시지 목록
ex, edit, e - 줄 편집기
expand, unexpand - TAB 문자를 공백문자로 바꿈, 또는 그 반대로
expr - 인자를 수식으로 처리
file - 파일 형식 알아보기
find - 파일 찾기
finger - 사용자 정보 알아보기
fmt, fmt_mail - 간단한 문서나, 편지 포멧 도구
fold - 긴 줄 출력 방법 지정
ftp - 파일 전송 프로그램
gcore - 실행 중인 프로세스의 core 이미지를 구한다.
gprof - call-graph profile data(?)를 보여줌
grep - 문자열 찾기
groups - 사용자의 그룹을 보여줌
history - 이전 명령 보기
hostname - 현재 시스템 이름을 보여줌
imake - makefile 만드는 프로그램
indent - C 프로그램 소스 파일을 들여쓰기 하는 포멧 도구
install - 파일 설치
join - 관계형 데이터베이스 연산자
kill - 프로세스 죽이기 - "마누라 죽이기"와 상관없음 :-)
last - 사용자가 마지막 접속 상태를 보여줌
ld, ld.so - 링크 편집기, 동적 링크 편집기
leave - 자신의 접속 종료 시간을 알려줌
less - more 명령의 확장
lex - 어휘 분석 프로그램 생성기
lint - C 프로그램 verifier
ln - 파일의 하드, 심벌릭 링크 명령
login - 시스템 접속 명령
look - 시스템 디렉토리나, 정열된 목록에서 단어 찾기
lookbib - 도서목록형 데이타베이스에서 찾기
lorder - 오브젝트 라이브러리의 관계 찾기
lp, cancel - 인쇄 시작, 취소
lpq - 인쇄 작업 상황 보기
lpr - 인쇄
lprm - 인쇄 작업 지우기
ls - 디렉토리 내용 보기
mail, Mail - 전자 우편 프로그램
make - 실행 파일을 만들거나, 특정 작업 파일을 만들 때 사용하는 도구
man - 온라인 사용자 설명서를 보는 명령
mesg - 메시지 수신 상태를 보거나 지정
mkdir - 디렉토리 만들기
mkstr - C 소스 파일을 참조로 오류 메시지 파일을 만듬.
more, page - 텍스트 파일 보기 명령
mv - 파일 이동이나, 이름 바꾸기
nawk - 패턴 검색과 언어 처리
nice - 낮은 우선권에서 명령 실행
nm - 심블 이름 목록 보기
nroff - 문서 포멧 도구
od - 8진수, 10진수, 16진수, ascii 덤프
passwd, chfn, chsh - 비밀번호, 핑거정보, 쉘 바꾸기
paste - 여러파일의 서로 관련 있는 줄 연결시키기
pr - 문서 파일 양식화 도구
printenv - 현재 환경 변수들의 내용과 그 값 알아보기
prof - profile 자료 보기
ps - 현재 프로세스 정보 보기
ptx - permuted(순열화된?, 교환된?) 색인 만들기
pwd - 현재 작업 디렉토리 보기
quota - 한 사용자에게 지정된 디스크 할당량보기
ranlib - archive를 random 라이브러리로 변화
rcp - 리모트 카피
rcs - RCS 파일 속성 바꾸기
rcsdiff - RCS revisions 비교
rev - 한 줄의 문자열 꺼꾸로
rlogin - 리모트 로그인
rm, rmdir - 파일, 디렉토리 지우기
roffbib - 도서목록형 데이터베이스 보기 또는 양식화
rsh - 리모트 쉘
rup - 로칼 머쉰의 호스트 상태 보기(RPC version)
ruptime - 로칼 머쉰의 호스트 상태 보기
rusers - 현재 접속자 보기 (RPC version)
rwall - 모든 사용자에게 알림(RPC)
rwho - 현재 접속자 보기
sccs - Source Code Control System (SCCS)
sccs-admin, admin - SCCS 사용 내역 파일을 만들고, 관리
sccs-cdc, cdc - SCCS 델타의 델파 주석을 바꿈
sccs-comb, comb - SCCS 델타 조합
sccs-delta, delta - SCCS 파일에 데해 델타를 만듬
sccs-get, get - SCCS 파일 버전확인
sccs-help, help - SCCS 오류나 경고 메시지 검색
sccs-prs, prs - SCCS 사용내역의 선택된 부분 보기
sccs-prt, prt - SCCS 파일에서 델타 테이블 정보를 봄
sccs-rmdel, rmdel - SCCS 파일에서 델타를 지움
sccs-sact, sact - SCCS 파일의 편집 상태를 봄
sccs-sccsdiff, sccsdiff - SCCS 파일들의 버전 비교
sccs-unget, unget - SCCS 파일의 미리 얻은 것(?)을 취소한다.
sccs-val, val - SCCS 파일 유요화
script - 화면 갈무리
sed - stream editor
sh - 유닉스 표준 쉘
size - 오브젝트 파일의 크기들을 보여줌
sleep - 지정한 시간 만큼 실행 보류
sort - 줄 정열과 검색
sortbib - 도서목록형 데이터베이스 정열
spell, hashmake, spellin, hashcheck - 맞춤범 검사(물론 영어겠지요)
split - 파일 나누기
strings - 오브젝트 파일이나, 실행 파일에서 문자열 찾기
strip - 오브젝트 파일에서 심벌 테이블과 중복된 비트 삭제
stty - 터미날 설정
su - super-user, 임시적으로 새 ID로 바꿈
symorder - 심벌 순서 바꿈
tabs - 터미날 tab 크기 지정
tail - 파일의 끝 부분 보기
talk - 다른 사용자와 이야기하기
tar - 여러 파일 묶기 또는 묶긴 파일 풀기
tbl - nroff 또는 troff의 도표 작성 도구
tee - 표준 출력으로 방향 전환
telnet - TELNET 프로토콜을 이용한 원격 리모트 호스트 접속
test - 주워진 환경이 참인지, 거짓인지를 돌려줌
tftp - 간단한 ftp.
time - 명령 실행 시간 계산
touch - 파일 날짜 관련 부분을 바꿈
troff - 문서 양식화 도구
true, false - 쉘 스크립트에서 사용되는 참/거짓을 리턴하는 명령
tsort - topological sort
tty - 현재 터미날 이름 보기
ue - MICROemacs
ul - 밑줄 속성 문자 표현
unifdef - cpp 입력 줄에서 ifdef 부분 바꾸거나 지움
uniq - 중복되는 빈줄 지우기
units - 프로그램 변환도구
uptime - 시스템 부팅 기간 보기
users - 현재 접속 사용자 보기
uucp, uulog, uuname - 시스템 간의 복사
uuencode, uudecode - 이진 파일을 아스키파일로 인코딩, 반대로 디코딩
uusend - 리모트 호스트에 파일 보내기
uux - 리모트 시스템 명령 실행
vacation - 자동으로 편지 답장하기
vgrind - grind nice program listings
vi, view, vedit - ex 바탕의 편집기
vtroff - 문서 양식화 도구
w - 현재 누가 접속해 있으며, 무엇을 하고있는지
wait - 프로세스가 마치기를 기다림
wall - 모든 사용자에게 알림
wc - 단어, 줄, 바이트 계산
what - 파일에서 SCCS 버전 정보 알아냄
whatis - 명령의 간단한 설명 보여줌
whereis - 찾는 명령의 실행파일, 소스, 맨페이지가 어디 있는지 경로를 보여

which - 명령만 찾음.
who - 시스템에 접속되어 있는 사람만 보여줌
whoami - 현재 사용하고 있는 자신이 누군지 보여줌
write - 다른 사용자의 화면에 특정 내용을 알림
xargs - 명령행 인자 처리 명령
xstr - extract strings from C programs to implement shared strings
yacc - yet another compiler-compiler: 파싱(형태소분석) 프로그램 생성기
yes - 항상 yes만 응답하는 명령
zcat - 압축 파일 내용보기
2010/06/01 10:06 2010/06/01 10:06
1. 서버이전 하루전에 전체 도메인 TTL값을 3600 정도로 맞춰줍니다. (아마도 86400로 되어있을듯)
-> zone파일 일괄변경 : 해당 디렉토리에서 ls | xargs perl -pi -e 's/86400/3600/'

2. 이전할 서버에 zone파일을 모두 백업하고. 위와 같이 IP정보를 일괄 변경해줍니다.

3. 이전할 서버의 IP가 정상적으로 질의응답하는지 테스트합니다.
->nslookup
->server 신규서버IP
->test.com

4. ns.domain.com ns2.domain.com의 호스트 정보를 변경하여 줍니다.

5. domain.com의 네임서버를 변경하여 줍니다.

6. 하루이상 모니터링하시고... 여러 도메인 질의해보시고 기존 서버를 내리시면 됩니다

TTL값 조정후 하루지난 후 TTL값이 동일하게 적용됬는지.. 질의해보시고.. 이전하시기 바랍니다. 호스트정보 변경도 잊지마시구요..
2010/06/01 10:00 2010/06/01 10:00
/etc/cron.daily 에 파일을 만들어 두거나

crond 에 등록해서 사용하시면 됩니다.

[기능요약]

1.root 계정으로 전체 디비를 디비별로 백업 가능함
2.옵션으로 테이블 별 백업 가능함.
3.보존 설정 기간 이후 자동 삭제

--------------------------------------------source----------------------------------------------------------

#!/bin/sh

############################################################################
#
# By 질주본능 2009/06/03
#
#    V 2.0
#
# 데이터 베이스별 혹은 테이블 별로 백업 받을 수 있도록 변경했으며
# 30 LINE 에 명기된 배열에 속하는 디비들만 테이블 별로 백업 받는다.
#
# 데이터베이스 단위로 받은 파일은 DB. 으로 시작하고
# 테이블 단위는 TB. 으로 시작하는 파일명을 갖는다.
#
# 백업 파일은 dump.gz 로 형성 되며 설정된 보존 기간이 지나면 자동 삭제 된다.
#
#############################################################################

##### SET VARIABLES ############ 전체를 백업 받으려면 여기에 root 계정을 입력한다.
DBHOST="yourhost"
DBUSER="yourid"
DBPWD="yourpassword"

#백업 경로
BACKUPDIR="/home/your_backup_dir/"
#로그 작성 경로
LOGDIR="/home/your_backup_log_dir/"
#로그 파일 앞에 붙을 특정 텍스트
LOGNAME="log_"

###### SET DB NAMES which BACKUP by TABLES ###### 여기 표시된 DB 들은 테이블 별로 백업된다.
DB_TBARR=(dbname1 dbname2 dbname3)

#백업 옵션을 원하는 대로 설정
#routine 옵션은 5버전 이상에서만 사용(function 등을 백업함)
OPTIONS="--skip-comments --default-character-set=euckr --routines"

##### SET CHARGE LIMIT ########## 백업 파일 저장 기간(일단위)
CHARGE_LMT=3

##### DELETE OLD_BACKUP FILES #######
find ${BACKUPDIR} -name "*.gz" -mtime +${CHARGE_LMT} -exec rm -rf {} \;

##### START LOG CREATE ##########
YMD_S=`date +%Y%m%d%H%M%S`
touch ${LOGDIR}${LOGNAME}${YMD_S}.start

##### DB LIST GET ###############
#IF YOU WANT TO EXCEPT SOME DATABASE ADD THIS
#grep -v Database | grep -v somename | grep -v somename`
#

#grep -v dbname 하면 백업 시 제외 된다.

RESULT=`mysql -u$DBUSER -p$DBPWD -h$DBHOST -e "show databases" | grep -v Database`

for DB in $RESULT; do

    sw=0
    ##### compare DB to TBARR #####
    for i in ${DB_TBARR[@]}; do
        if [ $i = $DB ]; then
            let "sw=sw+1"
        fi
        done

    if [ $sw = 0 ]; then
        # BACKUP by DB
        FNAME=${BACKUPDIR}DB.${DB}_${YMD_S}.dump
        #echo $FNAME
        touch $FNAME
        echo "set foreign_key_checks=0;" >> $FNAME
        mysqldump -u$DBUSER -p$DBPWD -h$DBHOST $OPTIONS $DB >> $FNAME
        echo "set foreign_key_checks=1;" >> $FNAME
        gzip --rsyncable $FNAME

    else
        # BACKUP by TABLES
                RESULT_TB=`mysql -u$DBUSER -p$DBPWD -h$DBHOST $DB -e"show tables" | grep -v heap | grep -v Tables_in `
                for TB in $RESULT_TB; do

                        FNAME=${BACKUPDIR}TB.${DB}.${TB}_${YMD_S}.dump
            #echo $FNAME
            touch $FNAME
            echo "set foreign_key_checks=0;" >> $FNAME
            mysqldump -u$DBUSER -p$DBPWD -h$DBHOST $OPTIONS $DB $TB >> $FNAME
            echo "set foreign_key_checks=1;" >> $FNAME
            gzip --rsyncable $FNAME

                done        
    fi

done

##### END LOG CREATE ###########
YMD_E=`date +%Y%m%d%H%M%S`

touch ${LOGDIR}${LOGNAME}${YMD_E}.end
2010/06/01 09:58 2010/06/01 09:58
모니터가 16:9 길죽한 거니까
창을 세로로 나누어서 쓰니까 편하군요..
..
vi 에디터에서

ctrl + w  v  하면 수직 창이 나누어진다.
ctrl + w  s 는 수평나누기이다.(별로 쓸일이 없다)
..
나누어서
ctrl + w  w 하면 나누어진 창으로 커서가 이동한다.
..
창 크기 조절은..
수평.. 나누기 했으면..

ctrl + w  N+  하면 N 만큼 커진다..
예를 들면 ctrl+w 를 한뒤에 숫자 3 과 플러스를 누르면 3 만큼 창이 커진다.
마이너스 하면 작아지고..
..
만약 수직 나누기에서 창크기 조절은..
N>.. N< 와 같다.. 즉 ctlr+w 누른후 숫자 3 과 꺽은 괄호 < 나 > 를
누르면 크기가 조절이 된다
..
창 연 후에  다른 파일 열려면..
창 명령모드
:e  aaa.txt  하고 하든가..

파일명을 몰라서 파일목록 보이게 하려면..
:e [디렉토리] 와 같이 한다.
만약 현재 디렉토리의 파일 목록 보려면..
:e .
와 같이 점을 찍으면 된다.
2010/06/01 09:58 2010/06/01 09:58
스펨메일 차단을 위해 HOWTO문서가 아니라, 전체적인 로직을 설명한 문서입니다.

스펨메일때문에, 스펨어쎄신, PROCMAIL, rcpthosts, tcp.smtp 화일등을 다 동원해서 스펨메일을 차단해 보려고 해도 결론적으로는 tcp.smtp 차단으로 답이 나올 것입니다.

스펨어쎄신과 procmail 등은 pop에 관련된 항목이라, 메일을 이용하는 User에게나 유용한 내용이지, 서버에서 메일로 인해 부하가 걸리는 것에는 아무런 효과를 주지 못합니다.

기본적인 사용법으로 tcp.smtp. rcpthosts를 이용해서 기본적으로 메일 발송에 관련해서 차단할 수는 있습니다. 즉, 메일서버를 통해 허용되지 않은 IP에 대해서는 특정 호스트로만 메일 발송이 가능하게 할 수 있습니다.

문제는 일반 사용자들은 이렇게 해서 별 문제가 없습니다만, 어떻게든 뚫고 들어와서 내 메일서버를 통해 타 사이트로 메일을 보내려고 시도하는 스펨메일이 있다는 것입니다. 물론 메일은 날아가지 않을 것입니다. rcpthosts에서 허용한 호스트외에는 말이죠.

문제는 queue에 mess가 계속 쌓인다는 것입니다.
mess가 계속 늘어 난다는 것은 스펨메일이 계속 들어오고 있다는 것입니다. 즉, 메일 서버가 감당하지 못하는 양이 계속해서 들어오고 있다는 것입니다.

이것을 막기 위한 방법에 대해 지금 부터 간략하게 설명하려 합니다.

=================== ===========================
tcp.smtp 화일은 다음과 같은 용도로 사용합니다.
(1) 인증된 IP에 대해서는 어떤 호스트로도 메일발송이 가능하게 합니다.
      방법 : 고정IP에서만 사용된다면 간단하지만, 유동 IP도 고려 하려면, 약간의 트릭이 필요합니다. 저희 같은 경우는 Intranet에 로그인을 하게 되면, 해당 사용자의 IP가 Database에 허용IP로 등록이 됩니다. Crontab을 이용하여 1분 단위로 새로 추가된 IP가 있으면 tcm.smtp에 등록하는 형태로 만들어 두었습니다.  즉, 유동IP에서 메일을 보내려면, 인트라넷 로그인후 1분후에 메일을 보낼 수 있는 것이죠.

(2) Deny된 IP에 대해서는 메일 송/수신 자체가 불가하게 만듭니다.
    사이트를 검색해보면 spamiplist 같은 화일이 있습니다.  일차적으로 이 아이피 리스트를 구해 전부 등록합니다. 물론 Database에 DenyIP로 등록합니다.  추가될때마다 Database에 등록하면 crontab이 1분단위로 tcp.smtp 화일을 생성할 것입니다.
   

(3) 그외 IP는 허용된 호스트로만 메일을 발송할 수 있도록 합니다.
    rcpthots에 허용된 호스트를 등록합니다.


========= 기타 Util ===============

제 경우에는 1분단위로 위의 작업을 하는 crontab 실행 화일과 매일 1회 crontab 실행하는 화일을 만들었습니다.

1분단위는 IP에 대한 block, allow 검사만 합니다.
매일단위는 queue에 쌓여 있는 mess를 삭제하는데 사용합니다.

1분 단위로 잔존해있는 mess를 검색하여, 해당 mess화일을 열어 파싱하여 어떤 IP에서 발송한 메일인지 확인하여 동일 IP에 대해 counting합니다. 몇회 이상이 발생하면 deny로 IP를 추가합니다.

뭐, 기타 웹페이지에서 mess를 읽을 수 있는 곳으로 복사하였다가, 메시지 확인후 ip deny 여부를 판단하는 것을 구현하기도 하였습니다.


==================================

결론은 이렇습니다.
(1) tcp.smtp 화일에 allow, deny IP를 수작업으로 일일이 등록하지 않고, crontab을 이용하여 IP를 등록한다.

(2) crontab으로 실행되는 프로그램이 쉽게 IP리스트를 관리하기 위한 database를 구축한다. 또한, 주기적으로 queue에 쌓여 있는 mess를 삭제하는 루틴을 만든다. 아무거나 삭제하면 안되겠죠? 이건 재량것..

(3) 등록된 database와 메일서버내에 잔존해 있는 queue에 쌓인 mess를 함께 관리할 수 있는 웹페이지를 구성한다.

이런 환경을 만들어 두니, 이젠 메일서버가 말썽을 일으키지 않네요.

============ 서비스 도중 발생한 추가항목 ===============

tcp.smtp에 IP를 Deny해 두어도, qmail-remote 데몬을 이용해서 계속해서 deny한 IP가 접속을 하는군요. ㅡ.ㅡ 도대체 tcp.smtp는 정상적인 메일인 경우에만 적용되는것 같습니다.

예를 들어
From xxx@메일서버IP 형태로 발신자가 잡히면 그냥 통과해 버린다는게 문제입니다.
물론, 다양한 qmail patch를 이용하면 relay되긴 하겠지만... 자신없습니다.ㅡ.ㅡ
그래서 iptables를 사용할수 밖에 없다는 결론에 이르렇습니다.

결론은 tcp.smtp도 하고, iptables를 이용하여 해당 IP를 25, 110 포트 자체를 막아버렸더니, 더이상 들어오지 않네요.  물론, 간혹 특정IP에서 스팸메일을 보내긴 하나, 1,2통 정도는 애교로 봐주고 있습니다. 다 막아 버릴수도 있지만, 거래처 메일이 스팸으로 잡힐지 몰라서.. 3일에 20통의 메일이 걸리면 차단입니다. ^^

iptables 잘못 사용하면 곤란한 일이 생길수도 있으니, 잘 학습해 보고 사용하세요.
2010/06/01 09:56 2010/06/01 09:56

# 리눅스 시스템의 서비스관리 방식

 - 리눅스 서버에서 서비스를 관리하는 방식에는 여러가지가 있으며 대부분 서비스들은 init
   이라는 프로세스에 의해 생성 및 제거 된다

 - 특정 스크립트에 의해 시작/종료/재시작되는 것이 있으며 또한 리눅스명령어에 의해
   직접 시작/종료되는 것들도 있다

 - init 프로세스에 의한 관리

  -> 시스템 부팅에서부터 종료할 때까지의 모든 서비스들에 관여하고 있다

  -> 모든 독립데몬 서비스들이 init 프로세스로부터 실행됨

  -> init 프로세스 설정 파일 : /etc/inittab

 - 리눅스 명령어(command)에 의한 관리방식

  -> 가장 직접적인 방식으로서 사용자의 명령어 사용에 의해 실행된다

  -> 시스템에 존재하는 명령어 또는 사용자가 만든 쉘스크립트(또는 실행파일)

 - SYSTEM V 스크립트 방식

  -> /etc/rc.d/init.d 디렉토리에 존재하는 각 서비스 제어파일에 의한 관리방식

 - xinetd에 의한 관리방식

  -> /etc/xinetd.d 디렉토리내의 각 서비스파일들에 의한 관리방식

 - chkconfig에 의한 관리방식

  -> 부팅시에 자동실행할 서비스들을 설정한다

  -> 설정결과는 /etc/rc.d/rcN.d 디렉토리내의 링크파일의 생성과 파일명으로 존재

  -> xinetd 서비스는 /etc/xinetd.d 디렉토리내에 있는 파일내의 설정으로 존재

  -> ntsysv와 상호 보완적인 관리방식이다

  -> ntsysv 방식과 결과는 같지만 command 형식을 이용한 설정방식이다

 - ntsysv에 의한 관리방식

  -> 부팅시에 자동실행할 서비스들을 설정한다

  -> 설정결과는 /etc/rc.d/rcN.d 디렉토리내의 링크파일의 생성과 파일명으로 존재

  -> chkconfig와 상호 보완적인 관리방식이다

  -> chkconfig 방식과 결과는 같지만 툴을 이용한 설정방식이다


 - 서비스명 규칙

  -> /etc/hosts.allow 파일과 /etc/hosts.deny 파일내에서 사용하는 서비스이름은
     실제 데몬파일명을 지정해야 하며 "sshd : ALL" 에서 sshd 라는 이름은
     /usr/sbin/sshd 라는 파일명에서 가져온 것이다

  -> chkconfig 와 ntsysv 는 설정하면 자동으로 이름이 명명되어 나타나며 그 이름을
     그대로 사용하면 된다

  -> /etc/xinetd.d 디렉토리의 파일 내에서 사용하는 services 항목이름은 chkconfig
     설정시 사용되는 이름 또는 서비스 데몬명을 그대로 사용한다


# 슈퍼데몬방식과 독립데몬방식의 서비스 차이점

 - 독립방식서비스는 자체적으로 항상 메모리에 상주하여 서비스 요청시 실시간으로 응답한다

 - xinetd라는 슈퍼데몬에 의해 실행되고 제어된다

 - xinetd 서비스와 standalone 서비스의 비교

  XINETD 환경 서비스

   -> 의미 : xinetd에 의해 제어되는 서비스들의 데몬
   -> 실행방법 : 필요할 때에 xinetd에 수행됨
   -> 데몬상주여부 : xinetd에 의해 불리워진 후에 서비스완료후에 자동 종료
   -> 실행속도 : 독립방식에 비해 느림
   -> 자원사용 : 시스템자원사용이 효율적(자원사용 적음) 
   -> 기타 : /etc/xinetd/서비스명으로 xinetd 제어파일이 존재
   -> 접근제어 : tcp_wrapper에 의해 접근제어
        /etc/hosts.allow, /etc/hosts.deny 파일로 접근제어 설정을 할수 있다


  독립 서비스

   -> 의미 : 독립적으로 실행되는 서비들의 데몬
   -> 실행방법 : 독립적인 서비스를 위하여 항상 독립적으로 수행된다
   -> 데몬상주여부 : 독립적인 서비스를 위하여 메모리에 독립데몬으로 상주한다
   -> 실행속도 : xinetd 방식에 비해 빠름
   -> 자원사용 : xinetd방식에 비해 자원사용이 비효율적이다(자원사용 많음) 
   -> 기타 : /etc/xinetd/서비스명으로 xinetd 제어파일이 존재
   -> 접근제어 : tcp_wrapper와는 무관하지만 자체
        설정파일에 의해 접근제어 할 수 있다  
 
  공통 사항

   -> 로깅 : /etc/syslog.conf 파일의 설정에 따름, 대부분 /var/log파일에 로깅
   -> 참고
    1) 독립적으로 실행되는 데몬들도 xinetd 환경으로 변경할 수 있으며
        반대로 xinetd 환경에서 서비스되는 데몬들도 독립적인 실행모드로
        변경할 수 있다                                               
    2) sshd 서비스의 경우 standalone이지만 /etc/hosts.aloow,        
        /etc/hosts.deny의 접근제어를 받는다 따라서 독립데몬이라도    
         tcp_wrapper의 영향을 받을 수 있다                           
 

  -> standalone 모드로 실행이 되는 데몬은 독립적으로 실행되며 항상 메모리에
     상주하여 서비스요청이 있을 때 언제든 바로 응답하며 응답속도를 요하는 경우에
     이 모드를 이용한다 단점으로는 메모리에 항상 상주해있으므로 메모리점유로
     인하여 서버부하를 준다

  -> xinetd 모드로 실행이 되는 데몬은 xinetd라는 특별한 데몬(인터넷슈퍼데몬)에
     의해 관리되며, 필요한 경우에만 메모리로 적재되어 실행이 되어 응답을 한다
     빠른 응답속도를 요하지 않는 경우에 이 모드를 이용한다 단점으로는 응답속도가
     standalone 보다는 상대적으로 느리다는 것이고 장점으로는 메모리에 항상 상주해
     있는 것이 아니므로 standalone 모드보다는 서버부하를 상대적으로 줄일수 있다


# 인터넷 슈퍼데몬의 특징

 - xinetd는 인터넷슈퍼데몬(Internet Super Daemon)을 의미한다

 - xinetd는 그 자체적으로는 하나의 독립데몬이지만 xinetd가 하는 역할이 여러가지 다른
   서비스들을 관리하는 역할이기 때문이다
 
 - xinetd는 서비스되는 여러가지 데몬들을 제어하면서 각각의 서비스들의 연결을 담당한다

 - xinetd의 특징

  -> 각 서비스별로 별도의 파일에 설정이 가능하다(/etc/xinetd.d/* 파일들)

  -> xinetd에서 가지고 있던 접근제어 기능을 가지고 있다

  -> tcp_wrapper를 내장하고 있기 때문에 접근제어를 할 수 있다

  -> timeout 설정으로 서비스 접근제어를 할 수 있다

  -> 접속시도 횟수로 접근제어를 할 수 있으므로 무차별 서비스거부공격(DoS)을
     방지할 수 있다

  -> 동일한 IP를 가진 호스트에서 동시 접속수를 제어하여 접근제어를 할 수 있다

  -> 로그파일의 크기를 제한 할 수 있다

  -> xinetd에서 제어되는 각 서비스들에 대한 syslog 로깅 레벨 설정이 가능하다

  -> 서비스를 거부하거나 서비스 접근제어가 되었을 경우에 상세로그를 기록한다

 - xinetd는 외부에서 서비스요청이 있을 때 /etc/xinetd.d/ 디렉토리내의 각 서비스파일들에
   정의되어 있는 내부 프로그램(데몬)을 실행시켜주는 역할을 한다


# 슈퍼데몬 xinetd방식의 서비스 흐름

 - 외부에서 telnet 연결요청(서비스의 요청)이 들어온다

 - xinetd 데몬은 외부에서 요청된 서비스를 tcp_wrapper에게 넘겨준다

 - tcp_wrapper는 /etc/hosts.allow와 /etc/hosts.deny 파일의 설정을 확인하여 해당 요청자의
   접근을 허용할지 허용하지 않을지 결정한다

 - 허가된 요청일 경우에는 /etc/syslog.conf에 설정되어 있는 /var/log/secure 파일에
   해당 접속에 대한 정보를 기록하고 /etc/xinetd.d/telnet 파일을 불러들여서 서비스를
   연결한다 이때 /etc/xinetd.d/telnet 파일내의 server 지시자행에 설정되어 있는 telnet
   데몬의 위치를 찾아서 요청을 처리하게된다

 - 허가되지 않은 요청일 경우에는 /etc/syslog.conf 파일에 설정되어 있는 /var/log/secure
   파일에 허가되지 않은 접속이 있었다는 로그를 남기고 접속요청을 거부하게 된다


# xinetd 서비스 관련 파일

 - xinetd 서비스 관련 파일들


  -> /etc/xinetd.conf : xinetd 서비스에 공통적으로 적용되는 주된 설정 파일
  -> /etc/xinetd.d/파일들 :  xinetd 기반 서비스들의 개별 설정 파일들          
  -> /usr/sbin/xinetd : xinetd 데몬파일                                  
  -> /usr/sbin/tcpd : tcp_wrapper 데몬 파일                            
  -> /etc/rc.d/init.d/xinetd : xinetd 시작/종료 스크립트 파일                   
  -> /etc/hosts.allow : 서비스별 허용할 호스트 또는 IP 리스트(tcp_wrapper)
  -> /etc/hosts.deny : 서비스별 거부할 호스트 또는 IP 리스트(tcp_wrapper)
  -> /etc/syslog.conf : 시스템로그 설정 파일                             
  -> /var/log/secure : tcp_wrapper 로그파일 (접근기록 파일)             
  -> /etc/services : 서비스포트 설정 파일                             
  -> /etc/protocols : 프로토콜 설정 파일                               

 - /etc/xinetd.conf 파일은 xinetd의 최상위 설정파일로서 "Tcp_Level Configuration File"
   라고 한다

 - /etc/xinetd.d 디렉토리내의 각 서비스 설정파일들에 대하여 글로벌하게 영향을 주게된다
   개별 설정파일에 개별적으로 존재하지않는 설정항목들에 대해서는 기본적으로 적용될
   항목들이 설정되어 있는 파일이다


# xinetd 주설정 파일과 /etc/xinetd.d 내의 개별 서비스 설정파일

 - xinetd의 메인 설정파일로서 xinetd 데몬이 실행될 때에 설정 내용을 불러와서 적용한다

  # cat /etc/xinetd.conf

  #
  # This is the master xinetd configuration file. Settings in the
  # default section will be inherited by all service configurations
  # unless explicitly overridden in the service configuration. See
  # xinetd.conf in the man pages for a more detailed explanation of
  # these attributes.

  defaults
  {
  # The next two items are intended to be a quick access place to
  # temporarily enable or disable services.
  #
  # enabled  =
  # disabled =

  # Define general logging characteristics.
   log_type = SYSLOG daemon info
   log_on_failure = HOST
   log_on_success = PID HOST DURATION EXIT

  # Define access restriction defaults
  #
  # no_access =
  # only_from =
  # max_load = 0
   cps  = 50 10
   instances = 50
   per_source = 10

  # Address and networking defaults
  #
  # bind  =
  # mdns  = yes
   v6only  = no

  # setup environmental attributes
  #
  # passenv  =
   groups  = yes
   umask  = 002

  # Generally, banners are not used. This sets up their global defaults
  #
  # banner  =
  # banner_fail =
  # banner_success =
  }

  includedir /etc/xinetd.d

  -> /etc/xinetd.conf 파일의 구성

   => defaults 설정은 /etc/xinetd.d 디렉토리내에 존재하는 xientd 서비스들에
            공통적으로 적용하는 설정내용이다
      xinetd 기반의 서비스들에 대하여 기본값으로 적용하는 설정으로 개별
      설정항목이 별도로 존재할 때에는 이 기본 설정값은 무시되고 개별
      설정값이 적용된다

   => includedir /etc/xinetd.d 설정은 xinetd 서비스의 적용을 받는 개별
      서비스 설정파일들을 /etc/xinetd.d 디렉토리에서 불러오는 것이다


 - xinetd 기반의 개별 서비스 설정파일들은 /etc/xinetd.d 디렉토리 내에 개별 서비스이름과
   같은 파일명으로 존재한다

  # ls -l /etc/xinetd.d/
  total 52
  -rw-r--r-- 1 root root 1157 2008-09-18 17:36 chargen-dgram
  -rw-r--r-- 1 root root 1159 2008-09-18 17:36 chargen-stream
  -rw-r--r-- 1 root root 1157 2008-09-18 17:36 daytime-dgram
  -rw-r--r-- 1 root root 1159 2008-09-18 17:36 daytime-stream
  -rw-r--r-- 1 root root 1157 2008-09-18 17:36 discard-dgram
  -rw-r--r-- 1 root root 1159 2008-09-18 17:36 discard-stream
  -rw-r--r-- 1 root root 1148 2008-09-18 17:36 echo-dgram
  -rw-r--r-- 1 root root 1150 2008-09-18 17:36 echo-stream
  -rw-r--r-- 1 root root  332 2008-09-08 23:11 rsync
  -rw-r--r-- 1 root root 1212 2008-09-18 17:36 tcpmux-server
  -rw-r--r-- 1 root root  304 2009-07-29 19:17 telnet
  -rw-r--r-- 1 root root 1149 2008-09-18 17:36 time-dgram
  -rw-r--r-- 1 root root 1150 2008-09-18 17:36 time-stream


 - xinetd 기반의 서비스에 대한 개별 설정 파일

  # cat /etc/xinetd.d/rsync

  # default: off
  # description: The rsync server is a good addition to an ftp server, as it \
  # allows crc checksumming etc.
  service rsync
  {
   disable = yes
   flags  = IPv6
   socket_type     = stream
   wait            = no
   user            = root
   server          = /usr/bin/rsync
   server_args     = --daemon
   log_on_failure  += USERID
  }


 - /etc/xinetd.conf 파일에 다음 항목이 설정되어 있다면 Global 하게 적용되는 것을
     의미하고 /etc/xinetd.d/ 디렉토리 내에 존재한다면 개별서비스 설정이 된다

  -> service   : 서비스이름으로 /etc/services 파일에 등록된 서비스이름과 동일해야한다

  -> disable : 해당 서비스를 서비스할 것인가(no) 아닌가(yes)를 결정한다
             서비스를 하도록 설정하려면 no로 설정하고 서비스를 하지 않으려면
             yes 로 설정한다

  -> socket_type : TCP일 경우에는 stream으로 설정하고 UDP일 경우에는 dgram으로
      설정하며 서비스의 성격에 따라 raw, rdm, seqpacket 등이 올수
      있다

  -> wait  : xinetd가 서비스 요청을 받은 경우, 이후에 즉시 또는 다른 요청을
      처리할 것인지(no) 아닌지(yes)의 여부를 결정하는 지시자이다
      stream일 경우에는 반드시 no 이여야하며 no는 현재 요청외에의
      다른 접속요청을 새로운 것으로 시작하여 처리하게 된다

  -> user  : 서비스를 어떤 사용자 권한으로 서비스할 것인가를 결정한다

  -> server : 해당 서비스 요청이 들어왔을 경우에 해당 서비스를 담당하게될
      데몬파일의 위치를 절대경로로 지정하는 항목이다

  -> log_on_failure : 서버접속에 성공하지 못하였을 때 로그파일에 기록하는 내용을
        설정할 수 있다 HOST, USERID 그리고 ATTEMPT, RECORD 등이
        추가로 설정될 수 있다.

        HOST란 접속을 시도한 클라이언트의 IP 주소를 의미한다

        USERID란 접속한 사용자의 ID를 각각 의미한다

        +=은 /etc/xinetd.conf 파일의 기본설정항목에 추가할 항목을
        지정할 때 사용한다

        -=는 /etc/xinetd.conf 파일의 기본설정항목에서 뺄 항목을
        지정할 때 사용한다

  -> log_on_success : 서버 접속에 성공하였을 경우에 기록할 내용을 설정할 수 있다
        PID, HOST, USERID, EXIT, DURATION 등을 기록할 수 있다

        PID란 프로세스의 ID를 의미한다

        HOSTID란 클라이언트의 IP 주소를 의미한다

        USERID란 접속한 사용자의 ID를 의미한다

        EXIT란 프로세스의 종료상태를 의미한다

        DURATION이란 연결지속시간을 의미한다

  -> only_from : 'only_from = 192.168.1.0/24' 와 같은 설정이 가능하며 서버로
      해당 서비스 접속이 가능한 네트워크를 지정한다

  -> no_access  : 'no_access = 192.168.1.100'와 같은 설정이 가능하며 특정
      호스트를 접속을 제한 한다

  -> instances  : 'instances = 60'과 같은 설정이 가능하며 해당 서비스로 접속
      가능한 최대 접속자수를 제한한다

  -> access_times : 'access_times = 08:00~18:00'와 같은 설정이 가능하며 해당
      서비스의 이용가능 시간을 지정할 수 있다

  -> per_source : 'per_source = 5'와 같은 설정이 가능하며 동일한 호스트에서
      해당 서비스로의 접속시 동시에 접속할 수 있는 횟수를 지정한다

      서비스거부공격 (DoS)을 차단하기 위해 사용될 수 있다


# xinetd의 시작과 종료

 - xinetd 서비스를 위해서는 xinetd 데몬이 실행되어있어야한다

 - xinetd 데몬을 실행하려면 /etc/rc.d/init.d/xinetd 스크립트파일을 이용하면 된다

 - xinetd 의 시작

  -> xinetd 스크립트에 'start' 옵션을 함께 사용하면 된다

   # /etc/rc.d/init.d/xinetd start
   Starting xinetd:                                           [  OK  ]


 - xinetd 의 종료

  -> xinetd 스크립트에 'stop' 옵션을 함께 사용하면 된다

   # /etc/rc.d/init.d/xinetd stop
   Stopping xinetd:                                           [  OK  ]
 
 - xinetd의 재시작

  -> xinetd 스크립트에 'restart' 옵션을 함께 사용하면 된다

   # /etc/rc.d/init.d/xinetd restart
   Stopping xinetd:                                           [  OK  ]
   Starting xinetd:                                           [  OK  ]


# xinetd 서비스의 접근제어 담당 tcp_wrapper

 - 특정 IP나 도메인으로부터 서비스의 접속을 차단할 수 있다

 - 접속기록이나 접속시도기록을 특정한 파일에 로그로 기록한다

 - xinetd는 tcp_wrapper를 내장하고 있기 때문에 xinetd 모드에서 실행되는 서비스들(ftp,
   telnet, ssh 등)은 거의 대부분 tcpd라는 tcp_wrapper의 데몬에 의해 접속제어를 받게 된다

 - 개별서비스들의 접근 허용을 설정하는 파일은 /etc/hosts.allow이며 접근허용이 되지 않도록
   설정하는 파일이 /etc/hosts.deny 이다

 - tcp_wapper에 제어파일인 /etc/hosts.allow 파일과 /etc/hosts.deny 파일에 의해 제어되는
   서비스가 xinetd 기반 서비스에 한정되어있지 않다는 점이다
 
 - xinetd 기반 서비스뿐아니라 독립데몬들에 대한 서비스들도 tcp_wrapper의 제어파일인
   /etc/hosts.allow 파일과 /etc/hosts.deny 파일의 접근제어를 설정할 수 있다는 의미이다

 - /etc/hosts.allow와 /etc/hosts.deny 파일의 설정

  왼쪽부분 설정 항목

   대상서비스 : tcpd에 의해 제어되는 모든 서비스명
       xinetd 기반의 서비스들 뿐 아니라 독립데몬들의
       서비스들도 설정 가능

  오른쪽부분 설정 항목

   접근제어 대상 (host, IP주소, 네트워크주소등)
    : 특정 도메인명, 특정 호스트명, 특정 IP주소, 특정네트워크


  -> 왼쪽 항목과 오른쪽 항목은 콜론(:)으로 구분하며 세번째 항목을 계속 설정할
         때에도 콜론으로 구분하여 설정한다

  -> /etc/hosts.allow 설정과 /etc/hosts.deny 설정이 중복되었을 경우에는
       /etc/shots.allow 파일의 내용이 우선 적용된다

  -> '#'으로 시작하면 주석문으로 인식한다

  -> 대상 리스트들의 나열은 스페이스나 콤마(,)로 구분한다

 - tcp_wrapper에 의해 접근제어(허용 또는 차단)가 된 후에는 그 기록을 /var/log/secure
   파일에 남기게 된다


# ntsysv

 - ntsysv와 chkconfig는 방법이 조금 다를 뿐 목적하는바가 같다

 - 사용법과 실행결과에 조금씩의 차이는 있으나 부팅시에 자동실행할 서비스들을 관리하는
   점에서는 같은 목적을 가진 도구이다

 - GUI 환경에서 사용하고 있다면 "system-config-services"를 실행하면 동일하게 사용할 수
   있다

 - ntsysv는 리눅스의 부팅시 각 부팅레벨에 따라서 실행시키거나 실행시키지 않을 서비스들을
   설정하는 유틸리티이다

 - 0번부터 6번까지의 시스템부팅레벨에 따라서 부팅시에 자동실행 할 여러가지 서비스들에
   대한 실행 여부를 설정할 수 있다

 - /usr/sbin/ntsysv를 실행하면 실행이 되지만 setup 유틸리티를 실행하여 "System services"
   항목을 선택하여 실행할 수도 있다

 - ntsysv를 실행하면 "Services" 설정창이 뜨게 되며 시스템 부팅시에 자동실행할 여러가지
   서비스들에 대해 설정하는 것이 목적이다

  -> ntsysv를 실행한 후에 각 서비스의 앞에 있느 [ ]탭을 빈공간으로 두면 해당
     서비스를 부팅시 시작하지 않으며 [*]와 같이 해당서비스를 선택해두면 부팅시에
     그 서비스를 자동실행한다


 - 개별 서비스들에 간략한 도움말을 ntsysv 실행창에서 확인할 수 있으며 도움말을 보기위해선
   'F1' 키를 누르면 된다  


 - ntsysv를 실행하였을 경우에 현재부팅레벨로 다시 부팅할 경우에 자동 실행할 서비스들을
   설정하지만 '--level' 옵션을 이용하여 특정 런레벨로 부팅시 자동으로 실행할 서비스를
   설정할 수 있다

  형식 : ntsysv --level 3

  -> 여러개의 런레벨을 설정할시에 '35' 처럼 런레벨을 설정한다


# chkconfig

 - ntsysv와 chkconfig는 부팅시에 자동으로 실행할 각종 서비스들을 설정하는 유틸리티이다

 - chkconfig는 /etc/rc.d/rcN.d의 각 디렉토리에 있는 S로 시작하는 링크파일과 K로 시작하는
   링크파일을 생성/삭제함으로써 부팅시에 자동 실행할 서비스들을 결정할 수 있다

 - '--list' 옵션을 이용하여 ckhconfig로 관리되는 자동실행 서비스 리스트들을 확인한다

  # chkconfig --list | more
  NetworkManager  0:off 1:off 2:on 3:off 4:on 5:off 6:off
  acpid           0:off 1:off 2:on 3:on 4:on 5:on 6:off
  anacron         0:off 1:off 2:on 3:off 4:on 5:on 6:off
  atd             0:off 1:off 2:off 3:on 4:on 5:on 6:off

  -> on은 활성화를 의미하는 것으로 해당 런레벨로 부팅시 자동실행 시키며
     off는 비활성화를 의미하는 것으로 해당 런레벨로 부팅시 자동실행하지 않는다


 - '--add'로 지정한 서비스를 chkconfig 관리항목에 추가한다

  # chkconfig --add httpd

  # chkconfig --list | grep httpd
  httpd           0:off 1:off 2:off 3:off 4:off 5:off 6:off

  -> '--add'로 서비스를 추가하면 /etc/rc.d/rcN.d 디렉토리에 httpd 링크 파일이
     생성된다


 - '--del'로 지정한 서비스를 chkconfig 관리항목에서 제거한다

  # chkconfig --del httpd

  # chkconfig --list | grep httpd

  -> '--del'로 서비스를 제거하면 /etc/rc.d/rcN.d 디렉토리에 httpd 링크 파일이
     삭제된다


 - 'on'으로 서비스를 2, 3, 4, 5 런레벨에서 자동실행 설정을 한다

  # chkconfig --list | grep httpd
  httpd           0:off 1:off 2:off 3:off 4:off 5:off 6:off

  # chkconfig httpd on

  # chkconfig --list | grep httpd
  httpd           0:off 1:off 2:on 3:on 4:on 5:on 6:off

  -> 런레벨을 지정하지 않으면 기본적으로 2,3,4,5 런레벨을 의미한다


 - 'off'로 서비스를 2, 3, 4, 5 런레벨에서 자동실행을 해제할 수 있다

  # chkconfig --list | grep httpd
  httpd           0:off 1:off 2:on 3:on 4:on 5:on 6:off

  # chkconfig httpd off

  # chkconfig --list | grep httpd
  httpd           0:off 1:off 2:off 3:off 4:off 5:off 6:off


 - '--level'로 해당 런레벨에서 자동실행을 설정 해제 할 수 있다

  # chkconfig --list | grep httpd
  httpd           0:off 1:off 2:off 3:off 4:off 5:off 6:off

  # chkconfig --level 3 httpd on

  # chkconfig --list | grep httpd
  httpd           0:off 1:off 2:off 3:on 4:off 5:off 6:off

  # chkconfig --level 45 httpd on

  # chkconfig --list | grep httpd
  httpd           0:off 1:off 2:off 3:on 4:on 5:on 6:off


# chkconfig 와 ntsysv, xinetd, /etc/rc.d/rcN.d 파일의 상관 관계

 - chkconfig에서 특정 서비스의 ON 의미
 
  -> ntsysv에서 *설정이 되어 부팅시 자동 실행되도록 설정된다

  -> /etc/rc.d/rcN.d에서 S로 시작하는 파일이 생성된다

  -> xinetd에 속한 서비스라면 해당파일내의 disable 항목이 no로 설정된다


 - chkconfig에서 특정 서비스의 OFF 의미

  -> ntsysv에서 *설정이 제거되어 부팅시 자동실행되지 않게된다

  -> /etc/rc.d/rcN.d 에서 K로 시작하는 파일이 생성된다

  -> xinetd에 속한 서비스라면 해당파일내의 disable 항목이 yes로 설정된다


 - chkconfig에서 특정 서비스의 add 의미

  -> /etc/rc.d/rcN.d에서 해당 서비스의 링크파일이 생성된다
     (S로 시작하는 링크파일)

  -> ntsysv의 리스트 항목에 해당 서비스 항목이 생성된다


 - chkconfig에서 특정 서비스의 del 의미

  -> /etc/rc.d/rcN.d에서 해당 서비스의 링크파일이 삭제된다

  -> ntsysv의 리스트 항목에 해당 서비스 항목이 삭제된다


# /etc/services 파일

 - 리눅스 서버에서 사용하는 모든 포트들에 대한 정의가 설정되어 있다

 - 파일에 설정되는 서비스 포트들의 형식

  서비스이름  포트/사용프로토콜유형  별칭

  -> 서비스이름

   => 설정되는 포트에 대한 서비스의 이름


  -> 포트/프로토콜

   => 지정된 서비스에서 사용될 포트번호와 사용할 프로토콜유형

   => 사용되는 포트들은 /etc/protocols란 파일에 정의되어
      있으며 프로토콜유형은 일반적으로 tcp와 udp등이 사용된다

   => 사용될 포트번호는 1024번까지는 시스템에서 이미 사용예약이 되어
      있으므로 관리자가 만들어 사용할 포트가 있다면 이 번호 이상되는
      포트번호를 지정하여 사용해야한다


  -> 별칭

   => 지정된 "서비스이름" 외에 다른 이름을 사용할 수 있도록 한다


  # cat /etc/services | more

  # /etc/services:
  # $Id: services,v 1.44 2008/04/07 21:30:33 pknirsch Exp $
  #
  # Network services, Internet style
  #
  # Note that it is presently the policy of IANA to assign a single well-known
  # port number for both TCP and UDP; hence, most entries here have two entries
  # even if the protocol doesn't support UDP operations.
  # Updated from RFC 1700, ``Assigned Numbers'' (October 1994).  Not all ports
  # are included, only the more common ones.
  #
  # The latest IANA port assignments can be gotten from
  # http://www.iana.org/assignments/port-numbers
  # The Well Known Ports are those from 0 through 1023.
  # The Registered Ports are those from 1024 through 49151
  # The Dynamic and/or Private Ports are those from 49152 through 65535
  #
  # Each line describes one service, and is of the form:
  #
  # service-name  port/protocol  [aliases ...]   [# comment]
 
  tcpmux        1/tcp                   # TCP port service multiplexer
  tcpmux        1/udp                  # TCP port service multiplexer
  rje              5/tcp                   # Remote Job Entry
  rje              5/udp                  # Remote Job Entry
  echo           7/tcp

2010/04/14 09:40 2010/04/14 09:40

JSP CENT OS 5 세팅법

#########################################################
tomcat + apache + java + php + mysql + zendoptimizer 설치
#########################################################
http://jakarta.apache.org/site/downloads/
http://archive.apache.org/dist/tomcat/
#########################################################

mysql-4.0.27.tar.gz
httpd-2.0.53.tar.gz
php-4.4.2.tar.gz
jdk-1_5_0_04-linux-i586.bin
jakarta-tomcat-5.0.28.tar.gz
jakarta-tomcat-connectors-jk-1.2.6-src.zip
mysql-connector-java-5.0.6.tar.gz

######################################################
1. mysql 설치
######################################################

tar xvfpz mysql-4.0.27.tar.gz

groupadd mysql
useradd -g mysql -M mysql -s /sbin/nologin
-4.1미만
 ./configure \
 --prefix=/usr/local/mysql --localstatedir=/db \
 --enable-assembler \
 --with-thread-safe-client --with-mysqld-user="mysql" \
 --with-client-ldflags=-all-static \
 --with-mysqld-ldflags=-all-static \
 --with-readline --without-debug \
 --without-docs --without-bench \
 --with-charset=euc_kr \
 --without-innodb # innodb를 비활성화려면 추가.

-4.1이상
 ./configure \
 --prefix=/usr/local/mysql --localstatedir=/db \
 --enable-assembler \
 --with-thread-safe-client --with-mysqld-user="mysql" \
 --with-client-ldflags=-all-static \
 --with-mysqld-ldflags=-all-static \
 --with-readline --without-debug \
 --without-docs --without-bench \
 --with-charset=euckr

make && make install

환경설정을 다시해야할 경우 make distclean 실행

ln -s /usr/local/mysql/bin/mysql /usr/bin/
ln -s /usr/local/mysql/bin/mysqldump /usr/bin/
ln -s /usr/local/mysql/share/mysql/mysql.server /etc/init.d/mysqld
cp /usr/local/mysql/share/mysql/my-medium.cnf /etc/my.cnf

vi /root/.bash_profile
PATH=$PATH:$HOME/bin:/usr/local/mysql/bin
BASH_ENV=$HOME/.bashrc
USERNAME="root"

vi /etc/profile
pathmunge /usr/local/mysql/bin

패스워드 지정
/usr/local/mysql/bin/mysqladmin -u root password "암호"

####################################################
apache 설치
####################################################

export CFLAGS="${CFLAGS} -DEAPI -DHARD_SERVER_LIMIT=1024 -DDEFAULT_SERVER_LIMIT=1024"

tar xvfpz httpd-2.0.53.tar.gz
./configure --prefix=/usr/local/apache --enable-rewrite=shared --enable-info=static --enable-so --enable-ssl --with-ssl=/usr --enable-mods-shared=ssl

make && make install

-----------------------------------------------------------------
#ServerName www.example.com:80 ==> #제거후 domain name으로 수정하거나 localhost로 수정
ex) ServerName localhost:80
AddDefaultCharset ISO-8859-1   ==> AddDefaultCharset utf8또는 euc_kr로 수정
ex)
AddDefaultCharset euc_kr
-----------------------------------------------------------------
cp /usr/local/apache2/bin/apachectl /etc/rc.d/init.d/httpd
ln -s /etc/rc.d/init.d/httpd /etc/rc.d/rc3.d/S85httpd
ln -s /etc/rc.d/init.d/httpd /etc/rc.d/rc5.d/S85httpd 
/etc/rc.d/init.d/httpd start


########################################################
php설치
########################################################

./configure \
--with-apxs2=/usr/local/apache/bin/apxs \
--with-mysql=/usr/local/mysql \
--with-freetype-dir \
--with-png-dir \
--with-gdbm \
--with-db \
--with-gd \
--with-zlib \
--with-iconv \
--with-mbstring \
--enable-track-vars=yes \
--with-mod-charset \
--with-language=korean \
--with-charset=euc_kr \
--disable-debug \
--with-xml \
--enable-inline-optimization \
--enable-memory-limit # 사용자 개별 limit 적용하려면 추가.

make && make install

cp php.ini-dist /usr/local/lib/php.ini

vi /usr/local/apache2/conf/httpd.conf
-------------------------------------------------------
LoadModule php4_module lib/apache/libphp4.so 확인(php4)
LoadModule php5_module        modules/libphp5.so 확인(php5)

DirectoryIndex 에 다음사항을 추가
DirectoryIndex index.html index.htm index.shtml index.php index.php4 index.php3 index.phtml index.cgi index.jsp

PHP 확장 타입 추가
AddType application/x-httpd-php .php .php3 .htm .html .phtml .inc .ph .jsp
AddType application/x-httpd-php-source .phps

cgi 실행 주석제거, pl추가
AddHandler cgi-script .cgi .pl

<directory /home/> 정책추가
<Directory /home/>
   AllowOverride FileInfo AuthConfig Limit
   Options MultiViews  
   <Limit GET POST OPTIONS PROPFIND>
       Order allow,deny
       Allow from all
       Deny from env=go_out
   </Limit>
   <LimitExcept GET POST OPTIONS PROPFIND>
       Order deny,allow
       Deny from all
   </LimitExcept>
</Directory>

로그파일 설정(정책 : error_log만 설정)
ErrorLog /usr/local/apache/logs/error_log
-->
ErrorLog /log/httpd/error_log
로 경로변경
CustomLog /log/httpd/access_log common

디렉토리 뷰 삭제(index)
<Directory "/usr/local/apache/htdocs">
Options FollowSymLinks MultiViews
모든 디렉토리에 index를 지워준다.
------------------------------------------------------

php.ini 설정
------------------------------------------------------
vi /usr/local/lib/php.ini
register_globals = Off -> On
allow_url_fopen = Off
upload_max_filesize = 20M
------------------------------------------------------
/usr/local/apache2/bin/apachectl configtest
아파치 문법 테스트

[참고] 아파치 가동시 아래와 같은 에러가 발생할 경우

Syntax error on line 232 of /usr/local/apache/conf/httpd.conf:
Cannot load /usr/local/apache/modules/libphp5.so into server: cal/apache/modules/libphp5.so: cannot restore segment prot after reloc: Permission
 
오류에 대한 해결 방법
vi /etc/sysconfig/selinux
SELINUX=disable
하고 재부팅한다


######################################################
Zend Optimizer 설치
https://www.zend.com에서 Zend 최신버전을 다운
php 5.x대는 Zend 3.2이상에서만 지원된다.
######################################################
cd /usr/local/src
tar zxvf ZendOptimizer-2[1].1.0b-linux_glibc21-i386.tar.gz
cd ZendOptimizer-2.1.0b-linux_glibc21-i386
./install.sh
계속 Enter

########################################################
java설치
########################################################

jdk-1_5_0_04-linux-i586.bin을 다운 받는다.

chmod 755 jdk-1_5_0_04-linux-i586.bin
./jdk-1_5_0_04-linux-i586.bin
ln -s /usr/local/src/jdk1.5.0_04 /usr/local/java

vi /etc/profile
설정
---------------------------------
APACHE2_HOME=/usr/local/apache
JAVA_HOME=/usr/local/java
PATH=$PATH:$JAVA_HOME/bin:$APACHE2_HOME/bin
export PATH

를 맨위에 추가시켜 준다.
---------------------------------
source /etc/profile
변경된 설정을 시스템에 적용

java를 실행
옵션들이 보이면 설치가 성공한것임

##################################################
tomcat설치
##################################################

jakarta-tomcat-5.0.28.tar.gz

tar xvfpz jakarta-tomcat-5.0.28.tar.gz
ln -s /usr/local/src/jakarta-tomcat-5.0.28 /usr/local/tomcat
cd /usr/local/tomcat/bin
./catalina.sh start  or  ./startup.sh

http://localhost:8080또는 http://설치한주소:8080
정상적으로 tomcat이 작동되고 있다면 브라우저에 tomcat관련 문서가 나온다.

----------------------------
tomcat shutdown
./catalina.sh stop
./shutdown.sh
----------------------------
vi /etc/profile
----------------------------
CATALINA_HOME=/usr/local/tomcat
PATH=$PATH:$JAVA_HOME/bin:$CATALINA_HOME/bin:$APACHE2_HOME/bin
export PATH
----------------------------
----------------------------
APACHE2_HOME=/usr/local/apache
JAVA_HOME=/usr/local/java
CATALINA_HOME=/usr/local/tomcat
PATH=$PATH:$JAVA_HOME/bin:$CATALINA_HOME/bin:$APACHE2_HOME/bin
export JAVA_HOME
export CATALINA_HOME
export APACHE2_HOME
export PATH

JAVA_HOME이 정의되지 않았다고 나오고 실행이 안되면
위와 같이 전부 export해주면 해결됨
실행이 되면 상관없음
----------------------------
source /etc/profile
현재 tomcat이 운영중이라면 shutdown하고 다시 실행하자
catalina.sh stop
catalina.sh start
----------------------------

vi /etc/rc.d/init.d/tomcat 실행 스크립트
--------------------------------------------------------------------
#!/bin/sh

TOMCAT_PROG=tomcat

# if TOMCAT_USER is not set, use tomcat like Apache HTTP server
if [ -z "$TOMCAT_USER" ]; then
 TOMCAT_USER="root"
fi

RETVAL=0

# start and stop functions
start() {
 echo -n "Starting tomcat: "
 su -l $TOMCAT_USER -c '/usr/local/tomcat/bin/startup.sh'
 RETVAL=$?
 echo
 [ $RETVAL = 0 ] && touch /var/lock/subsys/tomcat
 return $RETVAL
}

stop() {
 echo -n "Stopping tomcat: "
 su -l $TOMCAT_USER -c '/usr/local/tomcat/bin/shutdown.sh'
 RETVAL=$?
 echo
 [ $RETVAL = 0 ] && rm -f /var/lock/subsys/tomcat /var/run/tomcat.pid
 rm -rf /usr/local/jakarta-tomcat/work/*
}

# See how we were called.
case "$1" in
start)
 start
;;
stop)
 stop
;;
restart)
 stop
 # Ugly hack
 # We should really make sure tomcat is stopped before leaving stop
 sleep 2
 start
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
esac

exit $RETVAL
--------------------------------------------------------------------
이렇게 스크립트를 만들어 놓으면 다음부터는
톰캣을 시작할때 명령어 하나면 쳐주면 된다.

시작
service tomcat start
중지
service tomcat stop

참고)데몬 실행순서
톰캣이 기동된후 아파치가 실행되어야 한다.


########################################################
mod_jk 설치하기

mod_jk2는 2004년부터 공식적으로 지원을 중단해서
최신버전 톰캣에서는 적용되지 않는다.
따라서 현재 최신 버전까지 모두 지원되고 있는
mod_jk를 이용해서 톰캣과 아파치를 연결한다.
mod_jk는 가능한 최신버전을 깔아준다.

최신버전 다운
http://tomcat.apache.org/download-connectors.cgi

########################################################

unzip jakarta-tomcat-connectors-jk-1.2.6-src.zip

./buildconf.sh
./configure --with-apxs2=/usr/local/apache/bin/apxs

make && make install

--------------------------------------------------------------------
mod_jk.so 가 /usr/local/apache2/modules 디렉토리 안에 있고, 권한은 755로 설정되어있는지 확인한다.
--------------------------------------------------------------------

☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★
아파치를 톰캣에 연결하기
(최중요 부분)
★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆

--------------------------------------------------------------------
아파치와 톰캣을 연결해 주기 위해 설정해야 하는 파일은
세가지이다.

workers.properties
mod_jk.conf
httpd.conf
--------------------------------------------------------------------

1. workers.properties

/usr/local/apache2/conf 디렉토리에 workers.properties
라는 이름의 파일을 만들고 아래의 내용을 입력한 후 저장한다.

--------------------------------------------------------------------

workers.tomcat_home=/usr/local/tomcat
workers.java_home=/usr/local/java
ps=/

worker.list=ajp13

worker.ajp13.port=8009
worker.ajp13.host=localhost
worker.ajp13.type=ajp13
worker.ajp13.lbfactor=1

--------------------------------------------------------------------
참고
cp /usr/local/src/tomcat-connectors-1.2.23-src/conf/workers.properties /usr/local/apache2/conf/
처럼 복사해서 설정만 바꿔줘도 된다.

2. mod_jk.conf

/usr/local/apache2/conf 디렉토리에 mod_jk.conf
라는 이름의 파일을 만들고 아래의 내용을 입력한 후 저장한다.

--------------------------------------------------------------------

JkWorkersFile /usr/local/apache/conf/workers.properties
JkLogFile /log/jk/mod_jk.log
JkLogLevel warn
JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"
JkRequestLogFormat "%w %V %T"
JkMount /*.jsp ajp13
JkMount /servlet/* ajp13
JkMount /servlet ajp13
JkMount /WEB-INF/* ajp13
JkMount /WEB-INF ajp13
JkMount /jsp-examples/* ajp13
JkMount /jsp-examples ajp13

--------------------------------------------------------------------

3. httpd.conf
vi /usr/local/apache2/conf/httpd.conf
제일 밑에
include "/usr/local/apache2/conf/mod_jk.conf"
추가해주고, 아파치 재 시작.

http://Web_server_name_or_IP에 접속해서 성공하면 연결성공.
http://Web_server_name_or_IP/jsp-examples
http://Web_server_name_or_IP/servlets-examples
도 확인해 본다.

########################################################
가상도메인 설정하기
httpd.conf, virtualhost.conf server.xml
이 3파일이 필요하다.
########################################################

1.httpd.conf 편집

NameVirtualHost 222.239.223.109

vi /usr/local/apache2/conf/httpd.conf
제일 아래에
include "/usr/local/apache/conf/virtualhost.conf"
추가해 준다.

2.virtualhost.conf 편집

vi /usr/local/apache/conf/virtualhost.conf

<VirtualHost 222.239.223.109>
ServerAdmin webmaster@aaa.com
DocumentRoot /home/aaa.com
ServerName aaa.com
ServerAlias www.aaa.com
ErrorLog /log/httpd/aaa-error_log
CustomLog /log/httpd/aaa-access_log common
JkLogFile /log/jk/aaa-jk.log
JkLogLevel warn
JkMount /*.jsp ajp13
</VirtualHost>


※주의
/log/httpd/
/log/jk
폴더는 만들어 주어야 한다.

3. server.xml 편집

cd /usr/local/tomcat/conf


vi server.xml

제일 아래로 이동
--------------------------------------------------------------------
 <Host name="aaa.com" debug="0" appBase="/home/aaa.com/public_html">
 <Alias>www.aaa.com</Alias>
 </Host>
--------------------------------------------------------------------

cd /usr/local/tomcat/conf/Catalina
추가할 도메인 이름으로 폴더를 하나를 만든다.


mkdir aaa.com
cd aaa.com
vi ROOT.xml
-----------------------------------
<?xml version="1.0" encoding="UTF-8"?>
 <Context docBase="/home/aaa.com" privileged="true" reloadable="true">
 </Context>
------------------------------------
docBase에 서비스 받고자 할 디렉토리를 써준다.

<?xml version='1.0' encoding='utf-8'?>
<Context workDir="work/Catalina/jy.com/_" path="/" displayName="ShoppingShop" docBase="" useNaming="false" reloadable="true">
  <Resource type="javax.sql.DataSource" description="Oracle DB Connection" auth="Container" name="jdbc/myoracle"/>
</Context>


#######################################################
 Mysql-Connector-Java(JDBC셋업)
#######################################################

tar xvfpz mysql-connector-java-5.0.6.tar.gz
chown -R root.root mysql-connector-java-5.0.6


1) java에 class file 등록하기
cp mysql-connector-java-5.0.6-bin.jar /usr/local/java/jre/lib/ext/.
(물론 /usr/local/java는 $JAVA_HOME로 등록이 되어 있어야 한다.)

2) tomcat에 class file 등록
cp mysql-connector-java-5.0.6-bin.jar /usr/local/tomcat/common/lib/.
(물론 /usr/local/tomcat은 $CATALINA_HOME에 등록되어 있어야 한다.)

------------------------------------
vi /etc/profile

아랫부분을 추가한다

CLASSPATH=$CLASSPATH:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/jre/lib/ext/mysql-connector-java-3.1.13-bin.jar:/usr/local/tomcat/common/lib:servlet-api.jar
export CLASSPATH
------------------------------------
source /etc/profile


cd $JAVA_HOME/bin 으로 가서,

./javap com.mysql.jdbc.Driver 실행후
------------------------------------------------------------------------
Compiled from "Driver.java"

public class com.mysql.jdbc.Driver extends com.mysql.jdbc.NonRegisteringDriver implements java.sql.Driver{

    public com.mysql.jdbc.Driver()       throws java.sql.SQLException;

    static {};

}
------------------------------------------------------------------------
라는 메시지가 뜨면 정상


------------------------------------------------
jdbc드라이버를 이용한 java와 mysql의 연동 테스트
------------------------------------------------

아래 내용을 저장
vi jdbc.java
------------------------------------------------------------------------
import java.sql.*;
      class jdbc {
        public static void main(String argv[]) {
             try {
                Class.forName("org.gjt.mm.mysql.Driver");
                System.out.println("jdbc driver load success");
             } catch (ClassNotFoundException e) {
                System.out.println(e.getMessage());
             }
             try {
                String url = "jdbc:mysql://127.0.0.1:3306/mysql";
        Connection con = DriverManager.getConnection(url,"root","패스워드");
                System.out.println("mysql sucess");
                Statement stmt = con.createStatement();
                ResultSet rs = stmt.executeQuery("select user from user where user='root'");
                System.out.println("Got result:");
                while(rs.next()) {
                     String no= rs.getString(1);
                     String tblname  = rs.getString(1);
                     System.out.println(" no = " + no);
                     System.out.println(" tblname= "+ tblname);
                }
             stmt.close();
             con.close();
             } catch(java.lang.Exception ex) {
                ex.printStackTrace();
             }
        }
      }
------------------------------------------------------------------------
저장하고 나온다.

javac jdbc.java 컴파일해주고
java jdbc 실행시켜주면

아래 메세지가 나오면 성공
jdbc driver load success
mysql sucess
Got result:
 no = root
 tblname= root
 no = root
 tblname= root


---------------
jsp 연동 테스트
---------------

/usr/local/tomcat/webapps/ROOT 으로 가서,

vi mysql.jsp
------------------------------------------------
<%@ page import="java.sql.*"
contentType="text/html;charset=euc-kr"%>
<%
String DB_URL = "jdbc:mysql://localhost:3306/mysql";
String DB_USER = "root";
String DB_PASSWORD= "패스워드";
Connection conn;
Statement stmt;
try {
Class.forName("org.gjt.mm.mysql.Driver");
conn = DriverManager.getConnection(DB_URL, DB_USER,
DB_PASSWORD);
stmt = conn.createStatement();
conn.close();
out.println("MySQL 연결 성공");
} catch(Exception e)
{out.println(e);}
%>
------------------------------------------------
Mysql 연결 성공
이라는 글자가 나오면 성공


마지막으로

vi /usr/local/tomcat/conf/server.xml
이부분으로 찾아서
<!-- Define a non-SSL HTTP/1.1 Connector on port 8080 -->
    <Connector port="8080" maxHttpHeaderSize="8192"


Connector port="8080" ---> Connector port=""
로 해주어서 8080포트로의 접속을 막아준다.

--------------------------------------------------
/etc/profile 최종
--------------------------------------------------
APACHE2_HOME=/usr/local/apache
JAVA_HOME=/usr/local/java
CATALINA_HOME=/usr/local/tomcat
PATH=$PATH:$JAVA_HOME/bin:$CATALINA_HOME/bin:$APACHE2_HOME/bin
CLASSPATH=.:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/jre/lib/ext/mysql-connector-java-5.1.7-bin.jar:/usr/local/tomcat/common/lib:$CATALINA_HOME/common/lib/servlet-api.jar
export JAVA_HOME=/usr/local/java
export CATALINA_HOME="/usr/local/tomcat"
export APACHE2_HOME
export PATH
export CLASSPATH
export LANG="ko_KR.euc-KR"

2010/04/14 09:36 2010/04/14 09:36
===========================
Qmail 설치
Test 환경
CentOS 5.4 +
===========================

Qmail 관련 소스 다운로드

mkdir /usr/local/src/qmail
wget http://www.lug.or.kr/files/centos_book/qmail/netqmail-1.05.tar.gz
wget http://www.lug.or.kr/files/centos_book/qmail/ucspi-tcp-0.88.tar.gz
wget http://www.lug.or.kr/files/centos_book/qmail/daemontools-0.76.tar.gz
wget http://www.lug.or.kr/files/centos_book/qmail/qmail-date-localtime.patch => 표준GMT 시간 +9 한국시간 인식 패치
wget http://www.lug.or.kr/files/centos_book/qmail/netqmail-1.05-tls-smtpauth-20070417.patch => smtp 인증관련 패치

tar -xzf netqmail-1.05.tar.gz

===ucspi-tcp 패치, 컴파일, 설치====

=sendmail 관련 스크립트 제거

/etc/init.d/saslauthd stop
chkconfig --del saslauthd

/etc/init.d/dovecot stop
chkconfig --del dovecot

/etc/init.d/sendmail stop
chkconfig --del sendmail

tar -xzf ucspi-tcp-0.88.tar.gz

cd ucspi-tcp-0.88

patch -p1 < /usr/local/src/qmail/netqmail-1.05/other-patches/ucspi-tcp-0.88.errno.patch
patch -p1 < /usr/local/src/qmail/netqmail-1.05/other-patches/ucspi-tcp-0.88.a_record.patch
patch -p1 < /usr/local/src/qmail/netqmail-1.05/other-patches/ucspi-tcp-0.88.nodefaultrbl.patch

make
make setup check

===daemontools 패치, 컴파일, 설치

cd ..

mkdir -p /package
chmod 1755 /package/
tar -xzf daemontools-0.76.tar.gz -C /package/

cd /package/admin/daemontools-0.76/

patch -p1 < /usr/local/src/qmail/netqmail-1.05/other-patches/daemontools-0.76.errno.patch
package/install


qmail 컴파일 설치

cd /usr/local/src/qmail/netqmail-1.05
mkdir /var/qmail
./collate.sh

cd netqmail-1.05

# groupadd nofiles
# useradd -g nofiles -d /var/qmail/alias alias
# useradd -M -g nofiles -d /var/qmail qmaild
# useradd -M -g nofiles -d /var/qmail qmaill
# useradd -M -g nofiles -d /var/qmail qmailp
# groupadd qmail
# useradd -M -g qmail -d /var/qmail qmailq
# useradd -M -g qmail -d /var/qmail qmailr
# useradd -M -g qmail -d /var/qmail qmails

patch -p1 < /usr/local/src/qmail/qmail-date-localtime.patch
patch -p0 < /usr/local/src/qmail/netqmail-1.05-tls-smtpauth-20070417.patch

make
make setup check

make cert

make tmprsadh

./config-fast mail.parksunho.pe.kr

스크립트 작성

vi /var/qmail/rc
==================================================================
#!/bin/sh

# Using splogger to send the log through syslog.
# Using qmail-local to deliver messages to ~/Maildir/ by default.

exec env - PATH="/var/qmail/bin:$PATH" \
qmail-start ./Maildir/ splogger qmail
===================================================================

chmod 755 /var/qmail/rc

mkdir -p /var/qmail/supervise/qmail-send/log
mkdir -p /var/qmail/supervise/qmail-smtpd/log
chmod +t /var/qmail/supervise/qmail-send
chmod +t /var/qmail/supervise/qmail-smtpd

vi /var/qmail/supervise/qmail-send/run
==================
#!/bin/sh
exec /var/qmail/rc
==================

vi /var/qmail/supervise/qmail-send/log/run
=============================================
#!/bin/sh
exec /usr/local/bin/setuidgid qmaill \
     /usr/local/bin/multilog t /var/log/qmail
=============================================

vi /var/qmail/supervise/qmail-smtpd/run
=============================================================
#!/bin/sh
Q_UID=`id -u qmaild`
Q_GID=`id -g qmaild`

exec /usr/local/bin/softlimit -m 20000000 \
     /usr/local/bin/tcpserver -vRHl 0 -x /etc/tcp.smtp.cdb \
     -u $Q_UID -g $Q_GID 0 25 /var/qmail/bin/qmail-smtpd 2>&1
=============================================================

vi /var/qmail/supervise/qmail-smtpd/log/run
===================================================
#!/bin/sh
exec /usr/local/bin/setuidgid qmaill \
     /usr/local/bin/multilog t /var/log/qmail/smtpd
===================================================

chmod 755 /var/qmail/supervise/qmail-send/run
chmod 755 /var/qmail/supervise/qmail-send/log/run
chmod 755 /var/qmail/supervise/qmail-smtpd/run
chmod 755 /var/qmail/supervise/qmail-smtpd/log/run

mkdir -p /var/log/qmail/smtpd
chown qmaill /var/log/qmail /var/log/qmail/smtpd

vi /etc/tcp.smtp
==================================
127.0.0.1:allow,RELAYCLIENT=""
222.239.223.200:allow,RELAYCLIENT=""
==================================

tcprules /etc/tcp.smtp.cdb /etc/tcp.smtp.tmp < /etc/tcp.smtp

qmail 시작 스크립트
vi /etc/rc.d/init.d/qmail
============================================================================================
#!/bin/sh

# For RedHat chkconfig
# chkconfig: - 80 30
# description: the qmail MTA

PATH=/var/qmail/bin:/bin:/usr/bin:/usr/local/bin:/usr/local/sbin
export PATH

case "$1" in
  start)
    echo "Starting qmail"
if [ -e /service/qmail-send ] ; then
if svok /service/qmail-send ; then
svc -u /service/qmail-send
else
echo qmail-send supervise not running
fi
else
ln -s /var/qmail/supervise/qmail-send /service/
fi

if [ -e /service/qmail-smtpd ] ; then
if svok /service/qmail-smtpd ; then
svc -u /service/qmail-smtpd
else
echo qmail-smtpd supervise not running
fi
else
ln -s /var/qmail/supervise/qmail-smtpd /service/
fi
    if [ -d /var/lock/subsys ]; then
      touch /var/lock/subsys/qmail
    fi
    ;;
  stop)
    echo "Stopping qmail..."
    echo "  qmail-smtpd"
    svc -dx /service/qmail-smtpd /service/qmail-smtpd/log
rm -f /service/qmail-smtpd
    echo "  qmail-send"
    svc -dx /service/qmail-send /service/qmail-send/log
rm -f /service/qmail-send
    if [ -f /var/lock/subsys/qmail ]; then
      rm /var/lock/subsys/qmail
    fi
    ;;
  stat)
    svstat /service/qmail-send
    svstat /service/qmail-send/log
    svstat /service/qmail-smtpd
    svstat /service/qmail-smtpd/log
    qmail-qstat
    ;;
  doqueue|alrm|flush)
    echo "Flushing timeout table and sending ALRM signal to qmail-send."
    /var/qmail/bin/qmail-tcpok
    svc -a /service/qmail-send
    ;;
  queue)
    qmail-qstat
    qmail-qread
    ;;
  reload|hup)
    echo "Sending HUP signal to qmail-send."
    svc -h /service/qmail-send
    ;;
  pause)
    echo "Pausing qmail-send"
    svc -p /service/qmail-send
    echo "Pausing qmail-smtpd"
    svc -p /service/qmail-smtpd
    ;;
  cont)
    echo "Continuing qmail-send"
    svc -c /service/qmail-send
    echo "Continuing qmail-smtpd"
    svc -c /service/qmail-smtpd
    ;;
  restart)
    echo "Restarting qmail:"
    echo "* Stopping qmail-smtpd."
    svc -d /service/qmail-smtpd
    echo "* Sending qmail-send SIGTERM and restarting."
    svc -t /service/qmail-send
    echo "* Restarting qmail-smtpd."
    svc -u /service/qmail-smtpd
    ;;
  cdb)
    tcprules /etc/tcp.smtp.cdb /etc/tcp.smtp.tmp < /etc/tcp.smtp
    chmod 644 /etc/tcp.smtp.cdb
    echo "Reloaded /etc/tcp.smtp."
    ;;
  help)
    cat <<HELP
   stop -- stops mail service (smtp connections refused, nothing goes out)
  start -- starts mail service (smtp connection accepted, mail can go out)
  pause -- temporarily stops mail service (connections accepted, nothing leaves)
   cont -- continues paused mail service
   stat -- displays status of mail service
    cdb -- rebuild the tcpserver cdb file for smtp
restart -- stops and restarts smtp, sends qmail-send a TERM & restarts it
doqueue -- schedules queued messages for immediate delivery
 reload -- sends qmail-send HUP, rereading locals and virtualdomains
  queue -- shows status of queue
   alrm -- same as doqueue
  flush -- same as doqueue
    hup -- same as reload
HELP
    ;;
  *)
    echo "Usage: $0 {start|stop|restart|doqueue|flush|reload|stat|pause|cont|cdb|queue|help}"
    exit 1
    ;;
esac

exit 0
==============================================================================================

chmod 755 /etc/rc.d/init.d/qmail
chkconfig --add qmail
chkconfig --level 35 qmail on
chkconfig --list|grep qmail

mv /usr/lib/sendmail /usr/lib/sendmail.org
mv /usr/sbin/sendmail /usr/sbin/sendmail.org
ln -s /var/qmail/bin/sendmail /usr/lib
ln -s /var/qmail/bin/sendmail /usr/sbin
echo master > /var/qmail/alias/.qmail-root
echo master > /var/qmail/alias/.qmail-postmaster
echo master > /var/qmail/alias/.qmail-mailer-daemon
chmod 644 /var/qmail/alias/.qmail*

/var/qmail/bin/maildirmake /etc/skel/Maildir

메일 테스트
telnet localhost 25
2010/04/14 07:25 2010/04/14 07:25

리눅스 iptables 사용법:
iptables는 리눅스를 설치하면 보통 기본적으로 설치되므로
설치방법은 따로 설명하지 않으며 예제 위주로 간단히 사용법을 알아 보겠습니다.
아래 명령어는 모두 root권한으로 실행해야 됨을 미리 알려 드립니다.

1. 리눅스에서 부팅시 자동으로 iptables 서비스 시작하기:
  아래 2가지 방법 중에 하나로 보통 서비스를 자동실행하도록 등록한다.
1) 쉘창에서 3, 5 모드에서 재부팅시 자동으로 iptables 서비스가 시작되도록 하는 명령어
# chkconfig --level 35 iptables on
--> 3: multi console 모드 , 5: X윈도우즈 모드
2) ntsysv 에서 iptalbes 서비스 체크
# ntsysv

2. 먼저 iptables 의 옵션은 아래와 같다.
iptables 에는 3가지 chain 이 존재: INPUT, OUTPUT, FORWARD
1) 필터링 사슬 전체 조작 옵션
-N : 새로운 사슬 만들기
-L : 사슬의 규칙을 보여주기
-X : 비어 있는 사슬을 없애기
-P : 사슬의 규칙을 바꾸기
-F : 사슬에 있는 모든규칙을 지우기

2) 사슬의 규칙을 조작하는 옵션
-A : 사슬에 새로운 규칙을 추가하기(맨아래에 추가됨)
-I : 사슬에 규칙을 삽입하기(맨앞쪽에 삽입됨)
-R : 사슬에 있는 규칙을 다른 규칙과 교환하기
-D : 사슬에 있는 규칙을 없애기

3) 규칙을 정의하는데 필요한 하위옵션
-s : 출발지 주소
-d : 목적지 주소
--sport : 출발지(source) 포트번호
--dport : 목적지 포트번호
-p : 프로토콜(tcp, udp, icmp ..)
-i : 패킷이 들어오는 네트워크 인터페이스(inbound interface)
-o : 패킷이 나가는
-f : 분절된(fragment) packet
-j : 규칙을 지정(jump)

3. 기본정책을 ACCEPT로 설정하는 법:
# iptables -P INPUT ACCEPT
# iptables -P OUTPUT ACCEPT
# iptables -P FORWARD ACCEPT

4. 현재 자신의 방화벽 규칙을 볼 수 있는 명령:
# iptables --list 또는 iptables -L
처음으로 명령을 실행하면 아래와 같이 아무 정책도 설정되어 있지 않는 것을 볼 수 있다.
# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination        

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination        

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination        

Chain RH-Firewall-1-INPUT (0 references)

5. 규칙 추가 후에 저장하기 :
현재 규칙을 저장하는 명령어는 아래와 같다.
# /etc/rc.d/init.d/iptables save 
-> /etc/sysconfig/iptables 에 저장됨
위 명령어로 저장후에 실제 저장된 파일을 확인해 보면 아래와 같이 아무 설정이 안된것을 알 수 있다.
# vi /etc/sysconfig/iptables
# Generated by iptables-save v1.3.5 on Thu Jun 25 18:25:02 2009
*filter
:INPUT ACCEPT [11:764]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [320:65885]
:RH-Firewall-1-INPUT - [0:0]
COMMIT
# Completed on Thu Jun 25 18:25:02 2009

이제 간단한 규칙을 추가해 보자.
예를 들어 ip= 192.168.0.111 를 입력단에서 패킷을 drop하는 규칙을 추가하고 현재 정책을 확인한다.
# iptables -A INPUT -s 192.168.0.111 -j DROP
# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination        
DROP       all  --  192.168.0.111       anywhere           

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination        

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination        

Chain RH-Firewall-1-INPUT (0 references)

이제 저장을 한 후에 저장된 파일을 확인해 보면 아래와 같이 규칙이 저장되어 있는것을
볼 수 있다.
# /etc/rc.d/init.d/iptables save
# vi /etc/sysconfig/iptables
# Generated by iptables-save v1.3.5 on Mon Dec  7 14:55:45 2009
*filter
:INPUT ACCEPT [6561:820283]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [5984:1470873]
:RH-Firewall-1-INPUT - [0:0]
-A INPUT -s 192.168.0.111 -j DROP  <--- 이부분이 새로 추가한 규칙
COMMIT
# Completed on Mon Dec  7 14:55:45 2009

6. 현재 iptables 규칙을 초기화 하기:
# iptables -F
위 명령어를 실행하고 정책을 보면 아래와 같이 초기화 되어 있는 것을 알 수 있다
# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination        

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination        

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination        

Chain RH-Firewall-1-INPUT (0 references)

그러나 실제 저장되어 있는 내용을 보면 아래와 같이 초기화가 되어 있지 않는 것을 볼 수 있다.
# vi /etc/sysconfig/iptables
# Generated by iptables-save v1.3.5 on Mon Dec  7 14:55:45 2009
*filter
:INPUT ACCEPT [6561:820283]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [5984:1470873]
:RH-Firewall-1-INPUT - [0:0]
-A INPUT -s 192.168.0.111 -j DROP  <--- 이부분이 새로 추가한 규칙
COMMIT
# Completed on Mon Dec  7 14:55:45 2009

즉, 초기화 명령어는 현재상태에만 적용되며,
iptables 서비스가 재시작되거나 서버가 리부팅되면 /etc/sysconfig/iptables 에 저장되었던
규칙이 다시 적용된다는 것을 알 수 있다.

7. 정책을 빠르게 수정하여 적용하는 법 :
 6 에서와 같이 정책을 초기화 하고 서비스를 재시작해야 하는 방법은 상당히 비효율적인것을 알 수 있다.
따라서 현재 적용되는 정책을 특정파일(날짜별)로 저장해서 수정사항이 있다면
바로 그 저장된 파일을 수정한후 바로 정책에 적용하는 방법은 아래와 같다.

1) 현재 적용되고 있는 정책을 읽기 가능한 텍스트파일 형태로 저장하는 명령어는 아래와 같다.
# iptables-save > /root/iptable_091207.save

확인해 보면 똑같이 저장되어 있는것을 볼 수 있다.
# cat  /root/iptable_091207.save
# Generated by iptables-save v1.3.5 on Mon Dec  7 14:55:45 2009
*filter
:INPUT ACCEPT [6561:820283]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [5984:1470873]
:RH-Firewall-1-INPUT - [0:0]
-A INPUT -s 192.168.0.111 -j DROP  <--- 이부분이 새로 추가한 규칙
COMMIT
# Completed on Mon Dec  7 14:55:45 2009

2) 이제 저장되어 있는 iptables 파일을 바로 편집기로 수정 한후 저장한다.
# vi /root/iptable_091207.save
# Generated by iptables-save v1.3.5 on Mon Dec  7 14:55:45 2009
*filter
:INPUT ACCEPT [6561:820283]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [5984:1470873]
:RH-Firewall-1-INPUT - [0:0]
-A INPUT -s 192.168.0.199 -j DROP  <--- 편집기에서 111 -> 199 로 변경
-A INPUT -s 222.222.222.222 -j DROP <--- 편집기에서 새로 정책 추가
COMMIT
# Completed on Mon Dec  7 14:55:45 2009

3) 저장된 정책을 바로 적용하는 명령어는 다음과 같다.
# cat /root/iptable_091207.save | iptables-restore

확인해 보면 편집기로 수정했던 부분이 아래와 같이 바로 iptables 정책이 적용되어 있는 것을 알 수 있다
# iptables -L
# Generated by iptables-save v1.3.5 on Mon Dec  7 14:55:45 2009
*filter
:INPUT ACCEPT [6561:820283]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [5984:1470873]
:RH-Firewall-1-INPUT - [0:0]
-A INPUT -s 192.168.0.199 -j DROP  <--- 편집기에서 111 -> 199 로 변경했던 부분
-A INPUT -s 222.222.222.222 -j DROP <--- 편집기에서 새로 정책 추가했던 부분
COMMIT
# Completed on Mon Dec  7 14:55:45 2009

8. iptables 사용예 :
마지막으로 사용예를 몇개 알아보면 아래와 같다.

예1) 소스 ip가 192.168.0.111 인 접속의 모든 접속 포트를 막아라.
# iptables -A INPUT -s 192.168.0.111 -j DROP

예2) INPUT 사슬에 출발지 주소가 127.0.0.1(-s 127.0.0.1) 인 icmp 프로토콜(-p icmp) 패킷을 거부(-j DROP)하는
정책을 추가(-A)하라
# iptables -A INPUT -p icmp -s 127.0.0.1 -j DROP

예3) INPUT 사슬에 목적지 포트가 23번(--dport23)인 tcp 프로토콜(-p tcp) 패킷을 거부하는(-j DROP)규칙을
추가(-A) 하라.
# iptables -A INPUT -p tcp --dport 23 -j DROP

예4) INPUT 사슬에 목적지 포트 번호가 80번(--dport 80)인 tcp 프로토콜(-p tcp)패킷을 받아들이는(-j ACCEPT)
규칙을 추가(-A) 하라
# iptables -A INPUT -p tcp --dport 80 -j ACCEPT

예5) INPUT 사슬에 목적지 포트번호가 1023번 보다 작은 모든 포트(--dport :1023)인 tcp프로토콜(-p tcp)패킷을
거부하는(-j DROP)규칙을 추가(-A)하라
# iptables -A INPUT -p tcp --dport :1023 -j DROP

예6) ftp포트를 열어라
# iptables -I INPUT -p tcp --dport 21 -j ACCEPT

예7) imap 서비스를 방화벽에서 열어라
# iptables -I INPUT -s 192.168.0.0/255.255.255.0 -p udp --dport 143 -j ACCEPT

예8) 웹서버 방화벽 열어라
# iptables -I INPUT -p tcp --dport 80 -j ACCEPT

예9) 웹서버 포트 80 -> 8880으로 교체하라( 웹서비스 포트 변경시 /etc/services 에서도 변경 해줘야 함)
# iptables -R INPUT 2 -p tcp --dport 8880 -j ACCEPT

예10) domain-access_log 파일에 있는 모든 ip의 모든 접속 포트를 막아라(DOS공격 방어시 사용)
# cat domain-access_log |awk '{print $1}'|sort |uniq |awk '{print "iptables -A INPUT -s "$1" -j DROP"}'|/bin/bash

2010/04/14 07:15 2010/04/14 07:15

기동

/etc/init.d/iptables start


중지
/etc/init.d/iptables stop

2010/04/14 06:47 2010/04/14 06:47
브라우징 제거

아파치의 디폴트세팅은 브라우징이 enable되어 있다.
브라우징이란 웹브라우저에서 URL입력시 index.html과 같은 정확한 파일명을
생략하고 디렉토리만 적었을 경우, 디렉토리내 파일목록이 출력되는 현상을 말한다.
http.conf의 디렉토리 디렉티브내 다음줄 추가

Options -Indexes


아파치 인증창 사용

http.conf에서 인증을 걸 디렉토리 디렉티브내 다음줄 추가

    AllowOverride AuthConfig

해당 디렉토리에 다음과 같이 .htaccess파일(텍스트파일) 생성
[root@ns mrtg]# cat .htaccess 
AuthName "MRTG를 위한 인증"
AuthType Basic
AuthUserFile /webhosting/mrtg/.auth
require valid-user

AuthName: 인증창 타이틀
AuthType: 인증형태
AuthUserFile: 인증자들의 리스트를 가진 파일(htpasswd명령어로 생성)

-c(create)는 처음 파일을 생성할때 필요하다.
[root@ns mrtg]# htpasswd -c .auth kang 
New password: 
Re-type new password: 
Adding password for user kang
[root@ns mrtg]# ls -l .auth
-rw-r--r--    1 root     root           19 May  3 16:54 .auth


외부 IP접근제어

http.conf의 디렉토리 디렉티브내 다음줄 추가

	AllowOverride AuthConfig
    Order Allow,Deny
    Deny from 211.43.134.128/24 xxx.xxx.xxx.xxx/24
    Allow from all
    
Deny from 에 접근차단할 ip대를 입력.
슬래쉬(/)뒤의 숫자들은 net mask지정(생략하면 single ip에 대한 차단)


위의 내용을 종합한 예는 다음과 같다.    


    Options -Indexes FollowSymLinks MultiViews

    AllowOverride AuthConfig

    Order allow,deny
    Allow from all
    Deny from 211.43.134.128/24 xxx.xxx.xxx.xxx/24




가상호스트/Redirect

아래의 예는 dbakorea.pe.kr로 오면, www.dbakorea.pe.kr로 redirect시킨다.
본인은 아파치말고, packet filtering으로 처리하려했으나 실력부족과 게으름으로 인해
그만두었다.

    ServerName          dbakorea.pe.kr
    Redirect    /       http://www.dbakorea.pe.kr


가상호스트의 전형적인예

    ServerAdmin         kang@dbakorea.pe.kr
    DocumentRoot        /webhosting/dbakorea-mobile
    ServerName          mobile.dbakorea.pe.kr
    ErrorLog            /usr/local/apache/logs/mobile.dbakorea.pe.kr-error_log
    CustomLog           /usr/local/apache/logs/mobile.dbakorea.pe.kr-access_log common
    scriptAlias /cgi-bin/ /webhosting/dbakorea-mobile/cgi-bin/
	DirectoryIndex      login.html


아파치 정보출력제어
80포트로 telnet후 get / http/1.0하면 나오는 정보제어

ServerTokens Prod[uctOnly] 
: Apache 만 보여줌 
ServerTokens Min[imal] 
: Apache 버젼만 보여줌 
ServerTokens OS 
: 아파치 버젼과 운영체제를 보여줌 
ServerTokens Full (또는 지시하지 않았을때) 
: 모두 보여줌


Offline Browser서비스 거부(출처: http://www.apache.kr.net)
WebZip만 테스트해봤지만 %{User-agent} 라는 변수에 'MSIE 6.0b'와 같이 찍힌다.
한마디로 안된다. 다른 용도로 사용될 지 몰라도,..

<Directory />
    Options FollowSymLinks
    AllowOverride None
    Order allow,deny
    Allow from all
    Deny from env=go_out
</Directory>

#CustomLog /usr/local/apache/logs/access_log common
#CustomLog /usr/local/apache/logs/referer_log referer
#CustomLog /usr/local/apache/logs/agent_log agent
CustomLog /usr/local/apache/logs/access_log combined

<IfModule mod_setenvif.c>
    BrowserMatch "Mozilla/2" nokeepalive
    BrowserMatch "MSIE 4.0b2;" nokeepalive downgrade-1.0 force-response-1.0
    BrowserMatch "RealPlayer 4.0" force-response-1.0
    BrowserMatch "Java/1.0" force-response-1.0
    BrowserMatch "JDK/1.0" force-response-1.0
    BrowserMatch "WebZIP" go_out
    BrowserMatch "Teleport" go_out
    BrowserMatch "GetRight" go_out
    BrowserMatch "WebCopier" go_out
</IfModule>

<VirtualHost *>
     ServerAdmin         kang@dbakorea.pe.kr
     DocumentRoot        /webhosting/dbakorea
     ServerName          www.dbakorea.pe.kr
     ServerAlias        dbakorea.pe.kr
     ErrorLog            /usr/local/apache/logs/www.dbakorea.pe.kr-error_log
     CustomLog           /usr/local/apache/logs/www.dbakorea.pe.kr-access_log combined
</VirtualHost>


아파치 로그 rotate
디폴트로 아파치로그는 wtmp, lastlog등과 같이 일정 시간, 크기..등등에 따라 로그의 순환이 
이루어지지 않는다. logrotate로 3개의 로그를 1달단위로 순환하려면 /etc/logrotate.conf파일의 마지막에 다음과 같이 추가한다. # system-specific logs may be configured here /usr/local/apache/log/www.dbakorea.pe.kr-access_log { monthly rotate 2 } 바이러스등에 대한 아파치로그 제거 # CodeRed Worm등의 로그제거 SetEnvIf Request_URI default.ida CodeRed SetEnvIf Referer .ida CodeRed SetEnvIf Request_URI cmd.exe CodeRed SetEnvIf Referer cmd.exe CodeRed SetEnvIf Request_URI root.exe CodeRed SetEnvIf Referer root.exe CodeRed ServerAdmin kang@dbakorea.pe.kr DocumentRoot /webhosting/dbakorea ServerName www.dbakorea.pe.kr ServerAlias dbakorea.pe.kr ErrorLog /usr/local/apache/logs/www.dbakorea.pe.kr-error_log CustomLog /usr/local/apache/logs/www.dbakorea.pe.kr-access_log combined env=!CodeRed 출처 : linux.co.kr
2010/03/29 13:57 2010/03/29 13:57

테스트 환경

OS  : Red Hat Enterprise Linux AS release 4 (Nahant)

Kernel Version : 2.6.9-5.ELsmp

CPU & Cache : 2 Xeon(TM) CPU 3.06GHz 3057MHz, 512 KB Cache

Memory :  2G

Swap : 4G

Web server : Apache Http Server 2.0.52

Web test tool : ab, Httperf, flood


테스트 계획

rpm 설치후 기본 상태에서 설치된 웹서버에 동시 접속자 1000 명이 1000 번의 요청을 하는 경우를 테스트하여 웹서버의 성능을 측정한다.

다양한 환경설정을 변경해서 웹서버를 튜닝한 이후 다시 동일한 환경으로 테스트해서 실제적인 성능향상이 있는지를 점검한다.


테스트 케이스

1) ab -n 1000 -c 1000 -t 10 http://210.183.235.95/

2) httperf --server 210.183.235.95 --port 80 --rate 1000 --num-conns 20000 --hog

3) flood floodconf..xml > result.out (floodconf.xml 파일에 환경설정)

기본설치후 아파치 성능 테스트


웹사이트가 느리면 고객은 바로 다른 사이트로 이동하기 마련이다.

따라서 기업은 고객을 확보, 유지하기 위해 웹사이트의 성능을 최상의 상태로 유지해야하며 이로 인해 웹사이트의 성능을 진단하고 분석하는 도구들에 대해서 많은 관심을 가지고 있으며 현재 기업들마다 다양한 방법들로 성능을 관리하고 있다.

상용 SW

공개 SW

WEBest

SiteAngel

sitemonitor

WatchPro/TestPro

WEBest

ab

Flood

Httperf

Hammerhead

Web Performance Tool (WPT)

표 1. <웹서버 성능테스트 프로그램 비교>


웹서버의 성능을 측정하기 위해서 먼저 공개SW 벤치마크 프로그램 ab, Flood, Httperf 에 대해서 알아보기로 하자.


ab

ab는 "Apache HTTP server Benchmarking tool" 의 약어로서 아파치서버의 응답속도를 측정하는 밴치마킹툴이다. 이 툴은 현재 설치된 아파치서버의 실행속도 및 성능테스트를 위해서 제우스테크널리지(Zeus Technology Ltd, http://www.zeustech.net/)의 Adam Twiss가 개발한 툴이며. 아파치를 설치하고 나면 기본적으로 설치되므로 별도의 설치 과정 없이 바로 사용할 수 있다.

명령어위치: /usr/local/apache/bin/ab            

(RPM설치시 : /usr/bin/ab)


아래는 ab를 이용해서 -c(한번에수행할 다중요구수) 값을 1000으로하고, -n(페이지요청수) 값을 1000 으로 하였으며 -t(테스트허용 최대시간)값을 10으로 주는 예이다.


[root@www ~]# ab -c 1000 -n 1000 -t 10 http://210.183.235.95/

This is ApacheBench, Version 2.0.41-dev <$Revision: 1.141 $> apache-2.0

Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/

Copyright (c) 1998-2002 The Apache Software Foundation, http://www.apache.org/


Server Software:        Apache/2.0.52

Server Hostname:        210.183.235.95

Server Port:            80


Document Path:          /

Document Length:        440 bytes


Concurrency Level:      1000

Time taken for tests:   10.6038 seconds

Complete requests:      13416

Failed requests:        0

Write errors:           0

Total transferred:      8176434 bytes

HTML transferred:       5907440 bytes

Requests per second:    1340.79 [#/sec] (mean)

Time per request:       745.829 [ms] (mean)

Time per request:       0.746 [ms] (mean, across all concurrent requests)

Transfer rate:          797.92 [Kbytes/sec] received


Connection Times (ms)

              min  mean[+/-sd] median   max

Connect:        1  286 1301.0      4    9005

Processing:    21  148 467.1     95    6437

Waiting:       17  135 424.3     87    6434

Total:         57  434 1457.6    108    9703


Percentage of the requests served within a certain time (ms)

  50%    108

  66%    120

  75%    127

  80%    135

  90%    179

  95%   3076

  98%   9068

  99%   9076

 100%   9703 (longest request)


ab 의 측정결과에서 다음과 같은 내용을 분석할수 있다.

Server Software

아파치버전을 표시

Server Hostname

특정사이트의 이름(도메인명)

Server Port

웹서비스 사용포트번호

Document Path

초기 문서가 준재하는 웹문서 root위치

Time take for tests

응답시간(매우 중요한 결과 값임)

Document Length

초기문서(대부분 index.html, index.htm)의 용량크기

Complete requests

요구에 응답완료한 세션수

Failed requests

요구에 응답실패한 세션수

Broken pipe errors

실패한 에러수

Total transferred

총 전송바이트수

HTTP transferred

총 전송한 HTML바이트수

Requests per second

초당응답요구수

Time per request

요구에 응답한 시간(단위 micro second, 중요한 결과값)

Time per request

요구에 응답한 시간

Transfer rate

초당전송가능한 용량

표 2. <ab 의 결과분석>



Httperf


Httperf 툴은 요청이 발생하는 비율, 총 연결 수, 타임아웃 한계 등을 제어할 수 있다.

다운로드는 http://www.hpl.hp.com/research/linux/httperf/ 에서 가능하며 설치는 일반적인 소스설치법과 동일하게 ./configure ; make; make install 로 진행할수 있다.

사용할 수 있는 옵션은 아래와 같다

--server 서버주소

여기에 적어 준 서버로 접속을 시도한다

--port 숫자

여기에 적어 준 포트로 접속을 시도한다

--num-conns 숫자

총 몇개의 접속을 만들 것인지를 결정한다.

--rate 숫자

초당 몇개의 접속을 만들 것인지를 결정한다.

--timeout 숫자

숫자만큼의 초 이후 응답이 없는 연결은 timeout 에러로 처리한다.

--think-timeout 숫자

CGI등 서버쪽에서 처리해야 하는 일들이 있는 페이지의 경우 서버측에 이를 처리할 시간을 준다. timeout에서 이곳에 주어진 숫자만큼을 더한 값이 진짜 timeout값이 된다.

--hog

가능한 모든 포트를 사용한다. 이 옵션을 주지 않으면 기본적으로 1024부터 5000까지의 포트만 사용한다.

표 3.<httperf 의 주요옵션>


아래 예제는 210.183.235.95 웹서버의 80번 포트로 1초에 1000개씩 총 20000개의 접속을 만들게 된다.

[root@www ~]# httperf --server 210.183.235.95 --port 80 --rate 1000 --num-conns 20000 --hog

httperf --hog --client=0/1 --server=210.183.235.95 --port=80 --uri=/ --rate=1000 --send-buffer=4096 --recv-buffer=16384 --num-conns=20000 --num-calls=1

Maximum connect burst length: 8


Total: connections 20000 requests 20000 replies 20000 test-duration 20.000 s


Connection rate: 1000.0 conn/s (1.0 ms/conn, <=540 concurrent connections)

Connection time [ms]: min 0.3 avg 70.5 max 3006.4 median 1.5 stddev 422.3

Connection time [ms]: connect 60.8

Connection length [replies/conn]: 1.000


Request rate: 1000.0 req/s (1.0 ms/req)

Request size [B]: 65.0


Reply rate [replies/s]: min 978.7 avg 1000.0 max 1021.5 stddev 17.5 (4 samples)

Reply time [ms]: response 9.6 transfer 0.0

Reply size [B]: header 169.0 content 440.0 footer 0.0 (total 609.0)

Reply status: 1xx=0 2xx=20000 3xx=0 4xx=0 5xx=0


CPU time [s]: user 3.83 system 14.57 (user 19.2% system 72.9% total 92.0%)

Net I/O: 658.2 KB/s (5.4*10^6 bps)


Errors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0

Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0


Flood - a profile-driven HTTP load tester

Flood 는 아파치 프로젝트 하위의 프로젝트이다

XML 설정파일을 필요로 하며, URL 과 POST data 를 여러 서버들에 테스트할수 있다.


현재 Flood 는 Subversion 으로 관리되고 있으며 설치시에 자동으로 소스 디렉토리 하위에서 apr 과 apr-util 패키지를 찾으므로 아래처럼 체크아웃해서 설치하면 된다.

만일 apr 과 apr-util을 이미 받아온 상태라면  configure 할때 --with-apr and --with-apr-util 옵션을 사용해서 경로를 지정해주면 된다


 % svn co http://svn.apache.org/repos/asf/httpd/test/trunk/flood

 % cd flood

 % svn co http://svn.apache.org/repos/asf/apr/apr/trunk apr

 % svn co http://svn.apache.org/repos/asf/apr/apr-util/trunk apr-util


 % ./buildconf

 % ./configure --disable-shared

 % make all

설치가 정상적으로 진행되었으면 설치한 디렉토리에서 아래처럼 확인할수 있다

 % ./flood examples/round-robin.xml > foo.out


결과 파일을 다른프로그램에서 활용하고 싶은 경우는 

% ./examples/analyze-relative foo.out 를 실행해보면 참고할수 있다.

analyze-relative 파일은 테스트 결과값을 가공하는 간단한 스크립트이다.


Flood 에 대해서 보다 상세한 정보를 원한다면 http://httpd.apache.org/test/flood/faq.html 를 방문하자.

아래는 floodconf.xml 파일을 이용해서 테스트 하는 부분이다. xml형식의 환경설정 파일을 설정하는 방법은 http://httpd.apache.org/test/flood/ 를 방문해서 참고하기 바란다.


[root@www ~]# flood floodconf.xml > result.out

[root@www ~]# ./analyze-relative result.out

Slowest pages on average (worst 5):

   Average times (sec)

connect write   read    close   hits    URL

0.0018  0.0019  0.0081  0.0082  29126   http://210.183.235.95/

Requests: 29127 Time: 0.80 Req/Sec: 41776.74




설정변경을 통한 아파치 성능 최적화

아파치는 httpd.conf 파일을 이용해서 성능과 안정성 그리고 보안을 각각 구현할수 있다. 이제부터 리눅스에서 아파치 웹서버를 최상의 상태로 운용하기 위하여 성능을 향상시킬수 있는 아파치의 설정 지시자들을 살펴보기로 하자.


Timeout

접속된 클라이언트가 서버에 아무런 요청이 없을 때 어느정도 시간이 지나면 연결을 끊을지를 초단위로 설정한다. 네트웍의 성능이 낮을수록 이 수치를 높게 설정하는 것이 좋다.


MaxClients

웹서버 성능에 가장 큰 영향을 주는 것은 메모리다. 방문자의 요청에 응답하기 위해서 프로세스가 생성되는되 이 지시자의 개수만큼만 생성가능하다. 여기서 지정한 개수 이상의 요청이 들어오면 아파치는 요청을 무시한다.

MaxClients 지시어를 조절하여 웹서버가 스왑을 할 정도로 많은 프로세스를 만들지 않도록 해야 한다. 스왑은 요청당 지연시간을 늘리기 때문에 웹서버는 스왑을 하면 안된다. top으로 프로세스 목록을 보고 아파치 프로세스의 평균 메모리 사용량을 알아낸후, 사용가능한 메모리의 양만큼 조절해준다


KeepAlive

아파치의 한 프로세스가 접속한 클라이언트의 지속적인 요청작업을 계속해서 처리하게 할 것인지를 결정하는 지시자. 이 지시자의 값을 On으로 되어 있어야 MaxKeepAliveRequests , KeepAliveTimeout 지시자가 유효하게 된다


MaxKeepAliveRequests

이전의 KeepAlive 지시어가 On 일때만 유효하다. KeepAlive 를 이용해서  한 프로세스가 접속한 클라인언트의 이어지는 요청을 모두 처리하도록 설정했는데, 이때 무한정 계속 처리하는것이 아니라 이 지시자를 이용해서 처리할 횟수를 지정해준다. MaxKeepAliveRequests 100 처럼 설정해두면 프로세스가 100번의 요청을 처리한후 자신은 죽고 그다음 프로세스가 다시 클라인언트의 요청을 이어서 처리하도록 하는것이다. 방문자가 많은 홈페이지라면 이 값을 좀 올려두는것이 좋다


KeepAliveTimeout

이전의 KeepAlive 지시어가 On 일때만 유효하다. KeepAlive 를 사용한다면 프로세스들은 이미 열린 연결에서 추가 요청을 기다리며 대기중이다.

KeepAliveTimeout 15 처럼 설정해두면 클라이언트가 15초동안 아무요청이 없으면 프로세스의 연결을 끊는다. 이 값을 60 초 이상으로 올리면 사용자의 요청을 기다리며 아무일을 하지않는 프로세스가 60초동안 떠있게 되는것이다. 자신의 네트웍대역과 부하에 따라 적절히 조절하자. 기본값 15 로도 무방하다


StartServers

아파치 시작시에 실행시킬 프로세스의 개수. 뒤에나오는 MinSpareServers, MaxSpareServers 등의 지시자에 의해서 프로세스는 생성되기도 하고 죽기도 하므로 큰 의미를 가지는것은 아니다.


MinSpareServers

항상 대기하고 있을 프로세스의 최소개수. 여기서 지정한 숫자보다 적은 프로세스가 대기되어 있다면 아파치는 가능한 이 숫자를 유지하기위해 노력한다.


MaxSpareServers

항상 대기하고 있을 프로세스의 최대개수. 여기서 지정한 숫자보다 많은 프로세스가 대기되어 있다면 아파치는 가능한 이 숫자를 유지하기위해 노력한다.


MaxRequestsPerChild

하나의 프로세스당 최대 처리할 수 있는 방문자의 요청횟수

서버사양이 좋다면 이 값을 높여 두는것이 시스템의 부하조절과 자원낭비를 방지하는데 좋다.


HostnameLookups

웹서버의 로그(access_log)에 보면 클라이언트의 IP가 기록되어있는데 이 지시자를 On으로 설정하면 IP주소를 도메인명으로 기록하기위해서 노력을 하게된다.

아파치 1.3 이전에 HostnameLookups의 기본값은 On이였다.

이말은 접속을 요청하면 DNS를 검색해서 접속자의 호스트명을 알아내어야 한다는것이다,. 아파치 1.3에서 이 설정의 기본값이 Off로 변경되었다.

아파치의 성능을 생각한다면 반드시 Off 로 설정하기 바란다.

만일 로그파일의 주소를 호스트명으로 변환할 필요가 있다면 아파치에 포함된 logresolve 프로그램을 사용해서 나중에 할수있으니 실제 사용하는 웹서버가 아닌 다른 컴퓨터에서 로그파일을 후처리하길 바란다.


다른 설정에서 DNS 질의 고려

Allow from domain이나 Deny from domain 지시어를 사용한다면 (즉, IP 주소가 아닌 호스트명이나 도메인명을 사용한다면) 부득이 중복-역 DNS 검색을 (역검색을 한후 악의로 변경되었는지 확인하기위해 다시 검색) 해야 한다. 그러므로 성능을 높이기 위해 이런 지시어에는 가능하면 이름대신 IP 주소를 사용하자


FollowSymLinks와 SymLinksIfOwnerMatch

가능하면 심볼릭링크를 허용하지 않는것이 보안상 좋다. 하지만 꼭 써야한다면 Options SymLinksIfOwnerMatch 보다는 Options FollowSymLinks를 사용하라

Options SymLinksIfOwnerMatch 일 경우 아파치는 심볼릭 링크를 검사하기위해 시스템호출을 한번 더 해야 한다. 좋은 성능을 얻으려면 SymLinksIfOwnerMatch는 피하자


AllowOverride

AllowOverride 는 이전에 설정된 아파치 환경설정을 무시하고 새로운 설정을 적용하는 방법에 대한 설정이다. AccessFileName 을 별도로 설정하지 않았다면 아파치는 .htaccess 파일을 디렉토리 접근인증에 사용한다.

설정할수 있는 지시자는 다음과 같다.


AuthConfig 

AuthDBMGroupFile, AuthDBMUserFile, AuthGroupFile, AuthName, AuthType, AuthUserFile, require 등과 같은 클라이언트 인증지시자의 사용을 허용.

FileInfo

AccessFileName 으로 지정한 파일에 대하여 AddEncoding, AddLanguage, AddType, DefaultType, ErrorDocument, LanguagePriority 등과같은 문서유형을 제어하는 지시자 사용을 허용

Indexes

AccessFileName 으로 지정한 파일에 대하여 AddDescription, AddIcon, AddIconByEncoding, DirectoryIndex, FancyIndexing 등과같은 디렉토리 인덱싱을 제어하는 지시자 사용을 허용

Limit

AccessFileName 으로 지정한 파일에 대하여 allow, deny, order 같은 호스트접근을 제어하는 지시자사용을 허용

Options

AccessFileName 으로 지정한 파일에 대하여 Options 지시자를 이용한 재설정을 허용

All

위에서 이야기한 모든 것을 허용

None

AccessFileName 으로 지정한 파일을 무시. 어떠한 설정도 재설정 할수 없다.


만일 overrides를 허용한다면 아파치는 파일명의 각 부분마다 AccessFileName 으로 지정한 파일(대부분 .htaccess)을 열길 시도한다. 예를 들어 설정은 아래와 같고,


DocumentRoot /www/htdocs

<Directory />

AllowOverride all

</Directory>


/index.html URI에 대한 요청이 있다고 가정하자.

아파치는 /.htaccess, /www/.htaccess, /www/htdocs/.htaccess를 매번 열려고 시도한다. 최고의 성능을 얻으려면 항상 AllowOverride None을 사용하자.


EnableMMAP

커널에서 메모리매핑(mmap)을 지원한다면 아파치가 웹문서를 로딩하기 위하여 내부문서를 읽을때에 파일을 메모리 매핑하여 처리한다. 따라서 아파치의 성능이 크게 향상될수 있다.

그러나 메모리대응이 서버의 성능을 떨어트리고 심지어 안정성을 해치는 경우가 있고 smp Solaris 서버에서 아파치 2.0은 종종 mmap을 사용하지 않을때가 더 빠르다. 또한 NFS 마운트한 파일시스템에 있는 파일을 메모리 대응하는 도중에 다른 NFS 클라이언트에 있는 프로세스가 파일을 지우거나 파일크기를 줄이면, 웹서버 프로세스가 다음 번에 메모리대응한 파일내용을 읽을때 bus error가 발생할 수 있다.

위의 조건에 해당하면 전송하는 파일을 메모리대응하지 않도록 EnableMMAP off를 사용해야 한다.


EnableSendfile

아파치는 운영체제가 sendfile을 지원하면 커널 sendfile을 사용하여 정적 파일을 서비스하는 경우 전송할 파일을 직접 읽지않을 수 있다. sendfile을 사용하면 read와 send를 따로 할 필요가 없어서 매우 빨라진다.

그러나 sendfile을 사용하면 웹서버의 안정성을 해치게되는 경우가 있고, 커널은 자신의 캐쉬를 사용하여 NFS로 마운트한 파일을 안정적으로 서비스할 수 없는 경우가 있으므로

EnableSendfile off를 사용해서 파일을 sendfile 전송하지 않도록 할수 있다.



설정변경후 아파치 성능 테스트


이제까지 설명한 부분들을 자신의 환경에 맞게 각각 수정한 후 아파치 웹서버를 재시작하고 실제로 성능이 향상되었는지를 다시 테스트하기로 하자. 필자는 아래의 부분들을 수정해서 테스트했다.

변경이전

변경이후

Timeout 120

KeepAlive Off

MaxKeepAliveRequests 100

KeepAliveTimeout 15

HostnameLookups On

#EnableMMAP off

#EnableSendfile off

StartServers       8

MinSpareServers    5

MaxSpareServers   20

ServerLimit      256

MaxClients       256

Timeout 300

KeepAlive On

MaxKeepAliveRequests 10000

KeepAliveTimeout 25

HostnameLookups Off

EnableMMAP On

EnableSendfile On

StartServers       20

MinSpareServers    15

MaxSpareServers   45

ServerLimit      512

MaxClients       512

표 4. <httpd.conf 변경부분>


ab

[root@www ~]# ab -c 1000 -n 1000 -t 10 http://210.183.235.95/

This is ApacheBench, Version 2.0.41-dev <$Revision: 1.141 $> apache-2.0

Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/

Copyright (c) 1998-2002 The Apache Software Foundation, http://www.apache.org/


Benchmarking 210.183.235.95 (be patient)

Completed 5000 requests

Completed 10000 requests

Finished 14033 requests


Server Software:        Apache/2.0.52

Server Hostname:        210.183.235.95

Server Port:            80


Document Path:          /

Document Length:        440 bytes


Concurrency Level:      1000

Time taken for tests:   10.61616 seconds

Complete requests:      14033

Failed requests:        0

Write errors:           0

Total transferred:      8608215 bytes

HTML transferred:       6219400 bytes

Requests per second:    1394.71 [#/sec] (mean)

Time per request:       716.997 [ms] (mean)

Time per request:       0.717 [ms] (mean, across all concurrent requests)

Transfer rate:          835.45 [Kbytes/sec] received


Connection Times (ms)

              min  mean[+/-sd] median   max

Connect:        2  162 961.7     18    9049

Processing:    16  126 385.1     94    6459

Waiting:       13  114 383.5     81    6439

Total:         52  288 1147.4    118    9890


Percentage of the requests served within a certain time (ms)

  50%    118

  66%    123

  75%    128

  80%    132

  90%    153

  95%    175

  98%   3139

  99%   9188

 100%   9890 (longest request)


httperf

[root@www ~]# httperf --server 210.183.235.95 --port 80 --rate 1000 --num-conns 20000 --hog

httperf --hog --client=0/1 --server=210.183.235.95 --port=80 --uri=/ --rate=1000 --send-buffer=4096 --recv-buffer=16384 --num-conns=20000 --num-calls=1

Maximum connect burst length: 14


Total: connections 20000 requests 20000 replies 20000 test-duration 19.999 s


Connection rate: 1000.0 conn/s (1.0 ms/conn, <=37 concurrent connections)

Connection time [ms]: min 0.5 avg 3.1 max 47.3 median 1.5 stddev 4.6

Connection time [ms]: connect 1.0

Connection length [replies/conn]: 1.000


Request rate: 1000.0 req/s (1.0 ms/req)

Request size [B]: 65.0


Reply rate [replies/s]: min 996.2 avg 1000.0 max 1004.0 stddev 3.4 (4 samples)

Reply time [ms]: response 2.1 transfer 0.0

Reply size [B]: header 150.0 content 440.0 footer 0.0 (total 590.0)

Reply status: 1xx=0 2xx=20000 3xx=0 4xx=0 5xx=0


CPU time [s]: user 2.95 system 10.76 (user 14.8% system 53.8% total 68.6%)

Net I/O: 639.7 KB/s (5.2*10^6 bps)


Errors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0

Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0


flood

[root@www ~]# flood floodconf.xml > result.out

[root@www ~]# ./analyze-relative result.out

Slowest pages on average (worst 5):

   Average times (sec)

connect write   read    close   hits    URL

0.0019  0.0020  0.0045  0.0046  28999   http://210.183.235.95/

Requests: 28999 Time: 0.45 Req/Sec: 65931.82


최종 테스트 결과

벤치마크라는 것이 다양한 환경요인에 영향을 받으므로 항상 동일한 값을 기대하기는 어려운 관계로 3가지 벤치마크 프로그램들의 결과값이 모두 동일하게 나타나지는 않지만 설정을 변경하기 이전보다 전부 향상된 것을 확인할 수 있다.

 

ab

httperf

flood

기본상태

Time per request:       745.829 [ms]

Reply time [ms]: response 9.6

Time: 0.80 sec

튜닝이후

Time per request:       716.997 [ms]

Reply time [ms]: response 2.1

Time: 0.45 sec


출처 : linux.co.kr

2010/03/29 13:55 2010/03/29 13:55

ab는 “Apache HTTP server Benchmarking tool”의 약어로서  아파치서버의 응답속도를 측정하는 밴치마킹툴입니다.

ab라는 툴을 이용하여 아파치의 응답속도를 테스트하고 그 결과를 다양한 방면으로 확인할 수 있습니다. 


사용형식

ab [ -k ] [ -i ] [ -n 요청수 ] [ -t 시간제한 ] [ -c 동시접속 ] [ -p POST file ] [ -A 인증 유저이름:패스워드 ] [ -P 프락시인증 유저이름:패스워드 ] [ -H Custom header ] [ -C Cookie name=value ] [ -T content-type ] [ -v verbosity ] ] [ -w HTML 출력 ] ] [ -x 속성 ] ] [ -y  속성 ] ] [ -z  속성 ] [http://]서버이름[:port]/path

ab [ -V ] [ -h ]


사용예 #1

–V를 사용하시면 설치되어 있는 ab의 버전을 확인하실 수있습니다. 아래 결과는 현재 필자가 사용하고 있는 ab의 버전이 2.0.40이라는 것을 표시하고 있습니다. 

[root@host3 bin]# ab -V
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.116 $> apache-2.0
Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright (c) 1998-2002 The Apache Software Foundation, http://www.apache.org/

[root@host3 bin]#


사용예 #2

youngsam.net의 응답속도를 측정한 것입니다. 참고로 사이트URL의 마지막에는 반드시 "/"가 들어가야함에 주의하시기 바랍니다.  여기서 사용한 옵션 -n은 측정을 위한 웹페이지 요청수를 의미합니다. 즉 "-n 1"이라고 한 것은 지정한 URL을 한번의 요청만으로 결과를 표시한다는 의미입니다.

[root@host3 bin]# ab -n 1 http://www.youngsam.net
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.116 $> apache-2.0
Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright (c) 1998-2002 The Apache Software Foundation, http://www.apache.org/

Benchmarking www.superuser.co.kr (be patient).....done


Server Software:        Apache/2.0
Server Hostname:        www.youngsam.net
Server Port:            80

Document Path:          /
Document Length:        458 bytes

Concurrency Level:      1
Time taken for tests:   1.499567 seconds
Complete requests:      1
Failed requests:        0
Write errors:           0
Total transferred:      700 bytes
HTML transferred:       458 bytes
Requests per second:    0.67 [#/sec] (mean)
Time per request:       1499.567 [ms] (mean)
Time per request:       1499.567 [ms] (mean, across all concurrent requests)
Transfer rate:          0.00 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       17   17   0.0     17      17
Processing:  1482 1482   0.0   1482    1482
Waiting:     1481 1481   0.0   1481    1481
Total:       1499 1499   0.0   1499    1499
[root@host3 bin]#


사용예 #3

다음과 같이 -c옵션을 사용하면 한번에 수행할 다중 요구수를 지정할 수 있습니다.  지정하지 않는다면 기본값은 1이 됩니다.  테스트시에 –c 30이라고 주었으며, 결과를 보시면 “concurrency Level  30”이라는 것을 보실 수 있을 것입니다. 즉, 동시에 다중세션을 테스트한 것이며 그 결과를 확인 할 수 있습니다. 결과값의 분석은 앞에 설명된 내용과 비교하면서 보시기 바랍니다.

[root@host3 bin]# ab -c 30 http://www.yahoo.com/
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.116 $> apache-2.0
Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright (c) 1998-2002 The Apache Software Foundation, http://www.apache.org/

Benchmarking www.yahoo.com (be patient).....done


Server Software:       
Server Hostname:        www.yahoo.com
Server Port:            80

Document Path:          /
Document Length:        32247 bytes

Concurrency Level:      30
Time taken for tests:   1.75287 seconds
Complete requests:      1
Failed requests:        0
Write errors:           0
Total transferred:      32600 bytes
HTML transferred:       32247 bytes
Requests per second:    0.93 [#/sec] (mean)
Time per request:       32258.610 [ms] (mean)
Time per request:       1075.287 [ms] (mean, across all concurrent requests)
Transfer rate:          28.83 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:      208  208   0.0    208     208
Processing:   866  866   0.0    866     866
Waiting:      219  219   0.0    219     219
Total:       1074 1074   0.0   1074    1074
root@host3 bin]#

2010/03/29 13:48 2010/03/29 13:48
서버안에
.htpasswd 파일을 만들어주고

디렉토리 안에
.htaccess 파일을 만들면 끝...



1. 먼저 인증할 user와 password를 설정합니다.

/usr/local/apache/bin/htpasswd -c /지정할경로/.htpasswd 등록할ID

-> 패스워드를 입력합니다.

그럼 해당 경로에 .htpasswd 파일이 생성됩니다.

일반적으로 사용하는 경로입니다.
/usr/local/apache/htdocs/.htpasswd

2번째 패스워드부터는 -c 를 빼고 합니다. (주의)
/usr/local/apache/bin/htpasswd /지정할경로/.htpasswd 등록할ID

이렇게 하면 패스워드가 계속 추가됩니다.

하지만, 조금 귀찮더라도
.htpasswd
.htaccess
이 2개의 파일을 각 계정 안에 있는 임의의 하나의 디렉토리 안에 만들고
개별 경로를 따로 지정해 주는 쪽이 보안에 유리합니다... ;;
참... 디렉토리 권한은 701로 파일 권한은 644로 해 주세요... ^^*




2. 그리고 vi나 기타 에디터를 이용하여 .htaccess 파일을 생성합니다.

--------------------------------------------------------------------
AuthUserFile /지정한 경로/.htpasswd
AuthName "인증시 나타날 제목"
AuthType Basic

<Limit GET POST>
require valid-user
</Limit>
--------------------------------------------------------------------



여기서 부터 아래쪽은 트래픽 확인을 위한 관리를 위한 응용입니다.

아파치 설정파일 httpd.conf 파일
마지막 부분에 다음과 같이 입력합니다.

--------------------------------------------------------------------
# 사용자 트래픽 제한
<IfModule mod_throttle.c>
ThrottlePolicy None

<Location /throttle-status>
SetHandler throttle-status

# 여기서 부터 --

AuthName "인증시 나타날 제목"
AuthType Basic
AuthUserFile /지정한경로/.htpasswd
require valid-user

# 여기까지 ---

</Location>


<Location /throttle-me>
SetHandler throttle-me
</Location>

</IfModule>
--------------------------------------------------------------------
2010/03/29 07:41 2010/03/29 07:41
백업 할때 /home 을 전체로 백업하면 너무커서 관리하기 힘이들죠.
그리고 계정이 100개 이상이면 일일이 하기에는 일이 너무 많구요.
그때 이것을 쓰면 한번에 계정별로 백업이 되고 작은크기이니 cd로 백업도 가능하구요.
cron에 등록해주시면 편하겠네요..
유용하게 쓰이기를.......

======================================================================================

#!/bin/sh

# 디렉토리 설정하실때 끝에 꼭 / 넣어주세요.
home_root="/home/"
backup_home_root="/backup/"

cd $home_root

echo "백업 중입니다"
for home_name in $(ls)
do
if [ -d "$home_root/$home_name" ] ; then
echo "tar -cvzf $backup_home_root$home_name.tar.gz $home_name"
tar -czf "$backup_home_root$home_name.tar.gz" "$home_name"
fi
done

======================================================================================
2010/03/29 07:39 2010/03/29 07:39
 

리눅스에서 휴지통 (safedelete)

safedelete 를 통하여 리눅스 박스에 휴지통 만들기

http://rpmfind.net/linux/rpm2html/search.php?query=safedelete 에서
safedelete-1.3-6.src.rpm 을 다운받는다

root]#rpm -Uvh safedelete-1.3-6.src.rpm
root]#cd /usr/src/redhat/SOURCES
root]#mkdir -p /root/temp/safedelete
root]# mv * /root/temp/safedelete/
root]#cd /root/temp/safedelete
root]# tar xvfz safedelete-1.3.tar.gz
root]#tar xvfz safedel-1.3-patch.tar.gz

root]#cp safedelchk.c safedelete-1.3
root]#cp *.patch safedelete-1.3

root]# cd safedelete-1.3
root]# cp Makefile.LINUX Makefile

root]#patch -p1 < ./safedelete-1.3-glibc.patch
root]#patch -p1 < ./safedelete-1.3-y2k.patch
root]#patch undelete.c safedelete-1.3-redhat.patch
root]#patch Makefile safedelete-1.3-config.patch
root]#patch Makefile safedelete-1.3-makefile.patch
root]#make
root]#make install

.bashrc 에 다음 삽입
alias rm='/usr/bin/safedelete'
alias purge='/bin/rm'
export SAFEDAYS=7 # 7일간 보관하라
safedelchk

.safedelete.log 에 지운파일 정보를 보관
따라서, .safedelete.log를 보고 파일을 복원시키고자 할때
undelete 파일명 의 형식으로 복원함

2010/03/29 07:37 2010/03/29 07:37
# 개요
리눅스 서버를 운여하다 보면 서버내의 Traffic을 실시간으로 보고 싶을때가 있습니다. 이때 간단하게 ssh 에서 모니터링 할 수 있는 iftop을 소개합니다.

# 설치 OS
설치 OS는 SuperTuxs 5.0 혹 CentOS 5.0 에 기준하여 아래 내용을 참고 바랍니다. 다른 배포판의 경우 의존성등 기타 별도 설치가 필요 할 수 있습니다.

# 다운받기
ssh로 접속후에 첨부 파일을  /root  로 올립니다.

# 설치하기
- 아래처럼 실행하여 설치를 합니다.

[root@mbkang ~]# rpm -Uvh iftop-0.17-1.el5.rf.i386.rpm
warning: iftop-0.17-1.el5.rf.i386.rpm: Header V3 DSA signature: NOKEY, key ID 6b8d79e6
Preparing... ########################################### [100%]
1:iftop ########################################### [100%]
[root@mbkang ~]#

# 모니터링하기
- 다음에 ssh 로 로그인하여 아래처럼 하여 모니터링 합니다.
[root@mbkang ~]# iftop -p -B -P

# 모티터링 화면 (예)
그러면 아래그림과 같은 내용이 보입니다. 실시간으로 보여줍니다.

└──────────────┴───────────────┴───────────────┴───────────────┴───────────────
mbkang.hostsmb.com:pop3 => 218.55.101.14:62131 0B 2.51KB 642B
<= 0B 100B 25B
mbkang.hostsmb.com:http => 218.55.101.14:62129 0B 2.03KB 520B
<= 0B 144B 36B
mbkang.hostsmb.com:http => 218.55.101.14:62124 0B 1.77KB 453B
<= 0B 138B 34B
mbkang.hostsmb.com:http => 218.55.101.14:62128 0B 72B 18B
<= 0B 427B 107B
mbkang.hostsmb.com:ssh => 218.55.101.14:62068 502B 347B 250B
<= 20B 20B 23B
mbkang.hostsm:filenet-tms => ns3.apnic.net:domain 0B 8B 2B
<= 0B 18B 5B
mbkang.hostsm:filenet-tms => ns6.cninet.co.kr:domain 0B 8B 4B
<= 0B 15B 7B
mbkang.hostsmb.com:domain => cns101.hananet.net:39581 0B 16B 4B
<= 0B 7B 2B
mbkang.hostsm:filenet-tms => ins1.hananet.net:domain 0B 8B 2B
<= 0B 15B 4B
mbkang.hostsm:filenet-tms => 218.38.181.90:domain 0B 8B 2B
<= 0B 13B 3B
mbkang.hostsmb.com:ftp => 211.239.136.1:2208 0B 8B 3B
<= 0B 9B 4B
210.109.103.25:netbios-ns => 210.109.103.18:netbios-ns 0B 0B 0B
<= 0B 8B 2B
───────────────────────────────────────────────────────────────────────────────
TX: cumm: 161KB peak: 23.3KB rates: 502B 6.77KB 3.60KB
RX: 97.3KB 38.0KB 20B 913B 2.19KB
TOTAL: 258KB 61.3KB 522B 7.66KB 5.79KB


2010/03/29 06:52 2010/03/29 06:52
find -name *.psd | cpio -pdmv psd

psd 라는 폴더로 모든 psd 파일만 찾아서 복사
2010/03/29 06:50 2010/03/29 06:50
VNC 사용

virtual network computing의 약자로 www.uk.research.att.com에서 구할 수 있다. 개발자가 여러 컴퓨터에서 쉽게 개발 환경을 접근할 수 있어서 편리하다. 아직 한글 입력 서버가 되지 않지만 한텀 같은 자체입력 프로그램은 한글이 지원된다. download는 ftp://ftp.uk.research.att.com/pub/vnc/dist에서 받으면 된다.

리눅스 명령 소스 구하기

리눅스 설치시 전부를 선택해도 리눅스 커널 소스만 설치되고 나머지 명령어의 프로그램 소스는 설치되지 않는다.
예를 들어 bc명령어의 소스를 구해보도록 하자.
bc의 파일 위치를 알아낸다.

% which bc
/usr/bin/bc
어떤 rpm파일에서 속한 것인지 알아낸다.
% rpm -qf /usr/bin/bc
bc-1.05a-4
그 rpm파일에 대응하는 source rpm 파일을 download 받는다.
% ftp ftp.bora.net
Connected to ftp.bora.net.
220 ProFTPD 1.2.0pre10 Server (ftp5.bora.net) [ftp5.bora.net]
Name (ftp.bora.net:nso): ftp
331 Anonymous login ok, send your complete e-mail address as password.
Password: nso@
230 Anonymous access granted, restrictions apply.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> cd pub/linux/redhat/redhat/redhat-6.2/SRPMS/SRPMS
250 CWD command successful.
ftp> mget bc*
mget bc-1.05a-5.src.rpm? y
200 PORT command successful.
150 Opening BINARY mode data connection for bc-1.05a-5.src.rpm (227311 bytes).
226 Transfer complete.
227311 bytes received in 0.52 secs (4.3e+02 Kbytes/sec)
ftp> quit
221 Goodbye.
rpm파일을 홈디렉토리에 푼다. 그러기 위해서는 usr/src/redhat/SOURCES라는 하위 디렉토리가 존재해야 한다.
% mkdir -p usr/src/redhat/SOURCES
% rpm -ihv --root=`pwd` bc*
bc ##################################################

프로그램 소스가 풀린 디렉토리로 가서 tar로 묶여진 파일인 경우 tar명령으로 풀면 프로그램 소스를 볼 수가 있다.
% cd usr/src/redhat/SOURCES
% ls
bc-1.05a.tar.gz
% tar xvfz bc*
% cd bc-1.05
프로세스 죽이기

awk와 ps를 이용해서 특정 프로그램을 kill할 수 있다. kill -9 `ps aux | grep hanterm | awk '{print $2}'`

online 메뉴얼 인쇄

man -t man하면 메뉴얼이 postscript로 출력되므로 파이프로 받아서 lpr명령으로 프린터로 출력하면 된다.
man -t test | lpr
또는 man test | groff -Tps -mandoc | lpr해도 되고요.
한글 메뉴얼은 안 되는 것 같고요.
LANG 환경변수를 바꾸어서 영문 메뉴얼을 인쇄하도록

netscape에서 한글 인쇄

ghostscript를 이용해서 한글을 출력할 수 있도록 해줄 수 있는데 Postscript프린터면 프린터를 PCL 프린터를 하나 더 추가해서 ghostscript filter로 통과하도록 만들면 된다.

text 파일 인쇄

nh2ps를 이용해서 위의 방법으로 인쇄를 한다.

한텀 타이틀 바꾸기

echo -n "^[]2;test^G"
여기서 ^[는 ctrl+v를 누르고 ctrl-[를 누르고 ^G는 ctrl+v를 누르고 ctrl-G를 누른다.

삼성 센스820에 리눅스 설치

설치가 거의 끝나는 무렵에 PS/2마우스 포트를 검색하는 부분에서 시스템이 멈추어버린다. 그러므로 알짜리눅스 6.0을 설치할 때는 꼭 전문가 모드에서 설치를 해주어야 한다. 그리고 lilo설정시에 Use linear mode를 부분을 선택해야한다.
참고 : samsungelectronics.com/kr/computer/technical/software/linux/linux_setup01.html
알짜리눅스 6.1에서는 문제없이 설치되었던 것 같다

Redhat 6.0에서 smbmount

5.x와 달리 smbmount의 명령형식이 달라진 것 같다. smbmount //garden/mp3 /mnt/mp3 -U nso형식에서 smbmount //garden/mp3 -U nso -c 'mount /mnt/mp3'로 바뀐 것 같다.
6.1에서는 문제점이 사라진 것 같다.

core 파일이 생기는 것 방지

프로그램 버그로 에러가 발생하면 메모리 이미지를 core라는 파일로 만드는데 현재 디렉토리가 nfs로 연결되어 있는 상태이고 메모리를 많이 사용하는 프로세스라면 거의 시스템이 먹통이 된다. 그것을 사전에 방지하려면 .cshrc에다 limit coredumpsize 0를 넣어두면 좋다. 어차피 core파일을 분석할 일은 드물테니까.


프로세스 죽이기

awk와 ps를 이용해서 특정 프로그램을 kill할 수 있다. kill -9 `ps -ef | grep hanterm | awk '{print $2}'`

한텀 타이틀 바꾸기

echo -n "^[]2;test^G"
여기서 ^[는 ctrl+v를 누르고 ctrl-[를 누르고 ^G는 ctrl+v를 누르고 ctrl-G를 누른다.

netscape XmTextField font error

netscape를 사용하면서 URL창에 글자가 나오지 않고 XmTextField font error가 나오는 경우 xrdb를 이용해서 *XmTextField.fontList: -*-helvetica-medium-r-*-120*-iso8859-* 를 입력하면 해결된다.

한영 전환 키

CDE환경에서는 openwin환경과는 달리 한/영키를 쓰지 않고 ctrl+space로 한영전환을 합니다. 화면에 htt를 클릭해서 일반을 보면 설정값을 알 수 있습니다.


man page를 postscript로 출력

/usr/share/man/* 아래에 있는 파일을 troff -man으로 출력포맷을 만들어서 /usr/lib/lp/postscript/dpost를 써서 postscript로 변환할 수 있다. 예를 들어 sh에 대한 manual을 인쇄하고 싶다면


troff -man /usr/share/man/man1/sh.1 | /usr/lib/lp/postscript/dpost | lp

를 하면 된다.
2.7부터는 troff대신 sgml을 사용해서 online manual을 생성한 것이 많아서 위의 명령으로 되지 않을 수 있다.
PS파일 인쇄시 종이크기를 선택하지 못한다고 출력

Can't select requested paper size for Frame print job!라고 출력이 되면 대부분 FrameMaker 4에서 만들어진 PS파일이다. 문제를 제거하려면 그 vi로 그 파일을 수정하는데 /\/PageSize가 있는 라인을 찾아 A를 해서 끝에 pop false를 덧붙이고 저장하고 출력하면 된다.

웹브라우저를 netscape로

만약 웹브라우저가 netscape대신 hotjava가 실행되면 profile파일에서 설정해준 PATH에서 netscape를 찾을 수 없어서 hotjava가 실행된 것입니다. 홈디렉토리의 .cshrc나 .profile파일에서 PATH를 잘 설정해주십시오. 만약 /usr/dt/appconfig/types/ko/user-prefs.dt의 WebBrowser부분에 MAP_ACTION SDtHotJava라고 되어있으면 hotjava가 수행되므로 그런 경우 홈디렉토리 밑에 .dt/types디렉토리로 파일을 복사해서 SDtHotJava부분을 SDtNetscape로 변경하면 된다.

2장을 한장에다 프린트

postscript 파일의 경우 ftp://ftp.dcs.ed.ac.uk/pub/ajcd/psutils.tar.gz을 가져다가 gcc가 있는 환경에서 ln -s Makefile.unix Makefile을 하고 make를 하면 perl이 없으면 에러를 내고 중지된다. 그래도 psnup이 생성되므로 psnup을 이용해서 -2 옵션을 주고 input ps file이름과 output ps file이름을 주면 한장에 2장씩으로 postcript 파일을 생성해준다.

core 파일이 생기는 것 방지

프로그램 버그로 에러가 발생하면 메모리 이미지를 core라는 파일로 만드는데 현재 디렉토리가 nfs로 연결되어 있는 상태이고 메모리를 많이 사용하는 프로세스라면 거의 시스템이 먹통이 된다. 그것을 사전에 방지하려면 .cshrc에다 limit coredumpsize 0를 넣어두면 좋다. 어차피 core파일을 분석할 일은 드물테니까.

CDE에서 패널의 파일편집기보다 터미널을 default로

우선 개인용 응용프로그램 서랍에서 파일편집기를 삭제한다. 그리고 데스크탑 응용프로그램 폴더에서 파일편집기를 drag&drop으로 아이콘 설치에다 가져 놓으면 터미널이랑 파일편집기의 순서를 바꾸어 줄 수 있다.

2010/03/29 06:50 2010/03/29 06:50
 

웹호스팅 사용자를 위한 계정관리 스크립트

#!/bin/bash
##############################################################################
#
# 프로그램명 : RGRO Shell Manager
# 버전 : 1.1
# 최종수정일 : 2004년 6월 24일
#
# 제작자 : 윤범석 (알지보드)
# 홈페이지 : http://rgboard.com , http://rgro.net
# 본 프로그램은 비상업적인 목적으로 사용 가능합니다.
#
##############################################################################

##############################################################################
# 각종변수 설정
##############################################################################
# 버전
VERSION="1.1"
# mysql 경로
MYSQL_EXEC="mysql"
# mysqldump 경로
MYSQLDUMP_EXEC="mysqldump"
# 알지보드파일
RGBOARD_FILE=""
# 제로보드파일
ZEROBOARD_FILE=""
# 테터툴즈파일
TATTER_FILE=""
# 웹절대경로
WEB_ROOT=""

# 계정명
USER=`whoami`
# 절대경로
PWD=`cd ~;pwd`

if [ "$USER" = "" ]; then
  echo "계정명을 알수없습니다.
서버관리자에게 문의하세요."
  exit 1
fi

##############################################################################
# 웹절대경로를 찾는다 우선순위 www , public_html , 계정루트
##############################################################################
WEB_ROOT=$PWD
# public_html 디렉토리가 있다면
if [ -d "$PWD/public_html" ]; then
  WEB_ROOT="$PWD/public_html"
fi

# www 디렉토리가 있다면
if [ -d "$PWD/www" ]; then
  WEB_ROOT="$PWD/www"
fi
##############################################################################

##############################################################################
# 계정암호를 변경
##############################################################################
PASSWORD_CHANG() {
  clear
  echo "===================================================================
                          계정 암호변경
===================================================================
1. Telnet/SSH/FTP 암호가 동시에 변경됩니다.
2. 데이타베이스(Mysql) 암호는 변경되지 않습니다.

3. 암호변경방법
  (current) UNIX password: [현재암호입력]
  New password: [변경할암호 입력]
  Retype new password: [변경암호 재입력]

4. 입력한 암호는 표시되지 않습니다.
5. 영문자와 숫자로 6자 이상 연속된문자 제외하고 입력하세요.
";
  passwd
  if [ "$?" = "0" ]; then
  echo "정상적으로 변경되었습니다."
  else
  echo "암호변경시 에러가 발생했습니다."
  fi
}

##############################################################################
# 계정 사용량 조회
##############################################################################
HDD_QUOTA() {
  clear
  echo "===================================================================
                        계정(HDD) 사용량 조회
===================================================================
"
  quota -s
  echo "
1. blocks : 현재 사용중인 용량
2. 첫번째 quota : 현재 사용자가 사용할수 있는 용량
3. 첫번째 limit : 현재 사용자가 사용할수 있는 한계치
4. 용량표시가 없는경우 Kbyte 단위입니다.";
}

##############################################################################
# 계정 백업
##############################################################################
HDD_BACKUP() {
  clear
  echo -n "===================================================================
                         계정(HDD) 백업
===================================================================
1. 새로 만들어질 백업파일의 크기가 남은 HDD사용량을 초과 할 경우
  에러가 발생할수 있습니다. 사용하지않는 파일을 삭제후 백업하세요.

2. 일부 업로드된 파일은 에러가 발생할 수 있습니다.

3. 기존 backup- 으로 시작하는 파일은 삭제가 됩니다.

백업하시겠습니까 [yes]/no : "
  read key

  if [ "$key" == "" ]; then
  key="yes"
  fi

  if [ "$key" != "yes" ]; then
  echo "취소하셨습니다."
  return 1
  fi

  BACKUP_FILE_NAME="backup-"`date +%Y%m%d`".tar.gz"
  BACKUP_FILE="$WEB_ROOT/$BACKUP_FILE_NAME"
  echo "백업파일명 : $BACKUP_FILE_NAME"
  echo "백업중 ... (백업이 끝날때까지 기다려주세요)"
  cd ~
  if [ -f "$BACKUP_FILE_NAME" ]; then
  rm $BACKUP_FILE_NAME
  fi

  for file in $WEB_ROOT/backup-*
  do
  if [ -f "$file" ]; then
     rm $file
  fi
  done

  tar zcf $BACKUP_FILE_NAME *
  echo "백업종료 ..."
  mv $BACKUP_FILE_NAME $BACKUP_FILE
  echo "$BACKUP_FILE 으로 백업되었습니다."
  echo "다운로드 위치 : http://도메인명/$BACKUP_FILE_NAME"
}

##############################################################################
# 데이타베이스(MYSQL) 암호변경
##############################################################################
MYSQL_PASSWORD_CHANG() {
  clear
  echo "===================================================================
                   데이타베이스(MYSQL) 암호변경
===================================================================
1. 암호는 공백없이 영문자, 숫자로 입력하세요

2. 암호를 변경시 MYSQL을 사용하는 프로그램의 설정도 변경해야 합니다.

3. 암호는 화면에 표시되지 않습니다.
"
  echo -n "데이타베이스 유저아이디 [$USER] : "; read DBUSER
  echo -n "데이타베이스 기존암호 : "; read -s DBPASSWORD; echo
  echo -n "데이타베이스 새암호 : "; read -s DBNEWPASSWORD1; echo
  echo -n "데이타베이스 암호확인 : "; read -s DBNEWPASSWORD2; echo

  if [ "$DBUSER" == "" ]; then
  DBUSER="$USER"
  fi

  if [ "$DBPASSWORD" == "" ]; then
  echo "기존암호를 입력하세요."
  return 1
  fi

  if [ "$DBNEWPASSWORD1" == "" ]; then
  echo "새암호를 입력하세요."
  return 1
  fi

  if [ "$DBNEWPASSWORD1" != "$DBNEWPASSWORD2" ]; then
  echo "새암호가 동일하지 않습니다."
  return 1
  fi

  $MYSQL_EXEC -u$DBUSER -p$DBPASSWORD -e "set password=password('$DBNEWPASSWORD1');"

  if [ "$?" = "0" ]; then
  echo "정상적으로 변경되었습니다."
  else
  echo "암호변경시 에러가 발생했습니다."
  fi
}

##############################################################################
# 데이타베이스(MYSQL) 백업
##############################################################################
MYSQL_BACKUP() {
  clear
  echo "===================================================================
                   데이타베이스(MYSQL) 백업
===================================================================
1. 새로 만들어질 백업파일의 크기가 남은 HDD사용량을 초과 할 경우
  에러가 발생할수 있습니다. 사용하지않는 파일을 삭제후 백업하세요.

2. 기존 mysql- 으로 시작하는 파일은 삭제가 됩니다.

3. 암호는 화면에 표시되지 않습니다.

백업하시겠습니까 [yes]/no : "
  read key

  if [ "$key" == "" ]; then
  key="yes"
  fi

  if [ "$key" != "yes" ]; then
  echo "취소하셨습니다."
  return 1
  fi

  echo -n "데이타베이스 유저아이디 [$USER] : "; read DBUSER
  echo -n "데이타베이스 암호 : "; read -s DBPASSWORD; echo

  if [ "$DBUSER" == "" ]; then
  DBUSER="$USER"
  fi

  if [ "$DBPASSWORD" == "" ]; then
  echo "기존암호를 입력하세요."
  return 1
  fi

  BACKUP_FILE_NAME="mysql-"`date +%Y%m%d`".sql"
  BACKUP_FILE="$WEB_ROOT/$BACKUP_FILE_NAME"
  echo "백업파일명 : $BACKUP_FILE_NAME"
  echo "백업중 ... (백업이 끝날때까지 기다려주세요)"
  cd ~
  if [ -f "$BACKUP_FILE_NAME" ]; then
  rm $BACKUP_FILE_NAME
  fi

  for file in $WEB_ROOT/mysql-*
  do
  if [ -f "$file" ]; then
     rm $file
  fi
  done

  $MYSQLDUMP_EXEC -u$DBUSER -p$DBPASSWORD $DBUSER > $BACKUP_FILE_NAME

  if [ "$?" != "0" ]; then
  echo "에러가 발생했습니다."
  return 1
  fi

  echo "백업종료 ..."
  mv $BACKUP_FILE_NAME $BACKUP_FILE
  echo "$BACKUP_FILE 으로 백업되었습니다."
  echo "다운로드 위치 : http://도메인명/$BACKUP_FILE_NAME"
}

##############################################################################
# 데이타베이스(MYSQL) 복구
##############################################################################
MYSQL_RESTORE() {
  clear
  echo "===================================================================
                   데이타베이스(MYSQL) 복구
===================================================================
1. 백업파일은 계정의 루트 또는 웹디렉토리에 올려주세요.

2. 복구할 데이타베이스 백업파일을 입력하세요.

3. 중복된 테이블이 있을경우 에러가 발생하므로 데이타베이스를
  초기화 하신후 복구 하십시요.

4. 암호는 화면에 표시되지 않습니다.
"
  echo -n "데이타베이스 유저아이디 [$USER] : "; read DBUSER
  echo -n "데이타베이스 암호 : "; read -s DBPASSWORD; echo
  echo -n "데이타베이스 백업파일명 : "; read SQL_FILE;

  if [ "$DBUSER" == "" ]; then
  DBUSER="$USER"
  fi

  if [ "$DBPASSWORD" == "" ]; then
  echo "기존암호를 입력하세요."
  return 1
  fi
 
  BACKUP_FILE=""

  if [ -f "$WEB_ROOT/$SQL_FILE" ]; then
  BACKUP_FILE="$WEB_ROOT/$SQL_FILE"
  fi

  if [ -f "$PWD/$SQL_FILE" ]; then
  BACKUP_FILE="$PWD/$SQL_FILE"
  fi

  if [ "$BACKUP_FILE" == "" ]; then
  echo "백업파일을 찾을수 없습니다. 파일명을 확인하세요."
  return 1
  fi

  echo "복구 파일명 : $BACKUP_FILE"
  echo -n "복구하시겠습니까 [yes]/no : "
  read key

  if [ "$key" == "" ]; then
  key="yes"
  fi

  if [ "$key" != "yes" ]; then
  echo "취소하셨습니다."
  return 1
  fi

  echo "복구중 ... (끝날때까지 기다려주세요)"

  $MYSQL_EXEC -u$DBUSER -p$DBPASSWORD $DBUSER < $BACKUP_FILE

  if [ "$?" != "0" ]; then
  echo "에러가 발생했습니다."
  return 1
  fi

  echo "복구성공 ..."
}

##############################################################################
# 데이타베이스(MYSQL) 초기화
##############################################################################
MYSQL_ALL_TABLE_DELETE() {
  clear
  echo "===================================================================
                   데이타베이스(MYSQL) 초기화
===================================================================
1. 데이타베이스내의 모든 테이블을 삭제하오니 신중히 실행 하십시요

2. 암호는 화면에 표시되지 않습니다.
"
  echo -n "데이타베이스 유저아이디 [$USER] : "; read DBUSER
  echo -n "데이타베이스 암호 : "; read -s DBPASSWORD; echo

  if [ "$DBUSER" == "" ]; then
  DBUSER="$USER"
  fi

  if [ "$DBPASSWORD" == "" ]; then
  echo "기존암호를 입력하세요."
  return 1
  fi
 
  TABLE_LIST=`$MYSQL_EXEC -u$DBUSER -p$DBPASSWORD $DBUSER -e "show tables" | grep -v "Tables_in_"`

  if [ "$?" != "0" ]; then
  echo "이미 초기화된 상태이거나 에러가 발생했습니다."
  return 1
  fi

  if [ "$TABLE_LIST" == "" ]; then
  echo "이미 초기화된 상태입니다."
  return 1
  fi

  echo -n "모든 테이블을 삭제하시겠습니까 yes/[no] : "
  read key

  if [ "$key" != "yes" ]; then
  echo "취소하셨습니다."
  return 1
  fi
 
  echo "삭제중 ... (끝날때까지 기다려주세요)"

  for TABLE in $TABLE_LIST
  do
#    echo "테이블 삭제 => $TABLE"
  $MYSQL_EXEC -u$DBUSER -p$DBPASSWORD $DBUSER $dbname -e "drop table $TABLE"
  done
 
  if [ "$?" != "0" ]; then
  echo "에러가 발생했습니다."
  return 1
  fi

  echo "$DBUSER 이 성공적으로 초기화 되었습니다"
}

##############################################################################
# 알지보드설치
##############################################################################
RGBOARD_INSTALL() {
  clear
  echo -n "===================================================================
                         알지보드설치
===================================================================
1. 알지보드를 설치합니다.
2. 이미 설치 되어있다면 덮어쓰게 됩니다.

설치하시겠습니까 [yes]/no : "
  read key

  if [ "$key" == "" ]; then
  key="yes"
  fi

  if [ "$key" != "yes" ]; then
  echo "취소하셨습니다."
  return 1
  fi

  if [ ! -f "$RGBOARD_FILE" ]; then
  echo "알지보드 설치파일을 찾을수 없습니다."
  return 1
  fi

  cd $WEB_ROOT
  tar zxf $RGBOARD_FILE
  chmod 707 rgboard/data

  echo "성공적으로 설치되었습니다.
http://도메인명/rgboard/admin/install.php 으로 접속하세요.
관리자 페이지 : http://도메인명/rgboard/admin

자세한 사용법은 홈페이지(http://rgboard.com) 를 참고하십시요."
}

##############################################################################
# 제로보드설치
##############################################################################
ZEROBOARD_INSTALL() {
  clear
  echo -n "===================================================================
                         제로보드설치
===================================================================
1. 제로보드를 설치합니다.
2. 이미 설치 되어있다면 덮어쓰게 됩니다.

설치하시겠습니까 [yes]/no : "
  read key

  if [ "$key" == "" ]; then
  key="yes"
  fi

  if [ "$key" != "yes" ]; then
  echo "취소하셨습니다."
  return 1
  fi

  if [ ! -f "$ZEROBOARD_FILE" ]; then
  echo "제로보드 설치파일을 찾을수 없습니다."
  return 1
  fi

  cd $WEB_ROOT
  tar zxf $ZEROBOARD_FILE
  chmod 707 bbs

  echo "성공적으로 설치되었습니다.
http://도메인명/bbs/install.php 으로 접속하세요.
관리자 페이지 : http://도메인명/bbs/admin.php

자세한 사용법은 홈페이지(http://nzeo.com) 를 참고하십시요."
}

##############################################################################
# 블로그(테터툴즈)설치
##############################################################################
TATTER_INSTALL() {
  clear
  echo -n "===================================================================
                        블로그(테터툴즈)설치
===================================================================
1. 블로그(테터툴즈)를 설치합니다.
2. 이미 설치 되어있다면 덮어쓰게 됩니다.

설치하시겠습니까 [yes]/no : "
  read key

  if [ "$key" == "" ]; then
  key="yes"
  fi

  if [ "$key" != "yes" ]; then
  echo "취소하셨습니다."
  return 1
  fi

  if [ ! -f "$TATTER_FILE" ]; then
  echo "테터툴즈 설치파일을 찾을수 없습니다."
  return 1
  fi

  cd $WEB_ROOT
  tar zxf $TATTER_FILE
  chmod 707 tt

  echo "성공적으로 설치되었습니다.
http://도메인명/tt/install.php 으로 접속하세요.
관리자 페이지 : http://도메인명/tt/admin/article.php

자세한 사용萱?홈페이지(http://tattertools.com) 를 참고하십시요."
}

##############################################################################
# 웹절대경로변경
##############################################################################
WEB_ROOT_CHANGE() {
  clear
  echo -n "===================================================================
                        웹절대경로설정변경
===================================================================
1. 홈페이지 절대경로를 수정합니다.
2. 홈페이지를 올리시는 실제경로를 입력하세요.
3. 실제 홈페이지 경로가 변경되는 것은 아닙니다.
4. 현재 $WEB_ROOT 로 설정되어 있습니다.

경로변경 : $PWD/"
  read WEB_PATH

  if [ ! -d "$PWD/$WEB_PATH" ]; then
  echo "$PWD/$WEB_PATH 를 찾지 못했습니다."
  echo "경로가 수정되지 않았습니다."
  return 1
  fi

  if [ "$WEB_PATH" != "" ]; then
  WEB_PATH="$PWD/$WEB_PATH"
  else
  WEB_PATH="$PWD"
  fi

  echo -n "$WEB_PATH 로 수정하시겠습니까 [yes]/no:"
  read key

  if [ "$key" == "" ]; then
  key="yes"
  fi

  if [ "$key" == "yes" ]; then
  WEB_ROOT="$WEB_PATH"
  echo "$WEB_ROOT 로 변경되었습니다."
  else
  echo "변경되지 않았습니다."
  fi
}

while [ : ]
do
  clear
  echo -n "===================================================================
  RGRO Shell Manager V$VERSION (번호를 선택하세요)
===================================================================
  계정명 : $USER, 웹절대경로 : $WEB_ROOT
===================================================================
  1. 계정(SSH/Telnet) 암호 변경 |  4. 데이타베이스(MySQL) 암호변경
  2. 계정(HDD) 사용량 조회      |  5. 데이타베이스(MySQL) 백업
  3. 계정(HDD) 백업             |  6. 데이타베이스(MySQL) 복구
                               |  7. 데이타베이스(MySQL) 초기화
  8. 알지보드설치
  9. 제로보드설치

11. 웹절대경로 설정변경            쉘매니저 강제 종료 : Ctrl + C
99. 쉘매니저종료                   글수정 : Ctrl+Backspace
===================================================================
  번호를 입력하세요 : "
  read menu

  case "$menu" in
  "1") PASSWORD_CHANG;;
  "2") HDD_QUOTA;;
  "3") HDD_BACKUP;;
  "4") MYSQL_PASSWORD_CHANG;;
  "5") MYSQL_BACKUP;;
  "6") MYSQL_RESTORE;;
  "7") MYSQL_ALL_TABLE_DELETE;;
  "8") RGBOARD_INSTALL;;
  "9") ZEROBOARD_INSTALL;;
  "10") TATTER_INSTALL;;
  "11") WEB_ROOT_CHANGE;;
  "99") break;;
  *) echo "다시 선택해주세요.";;
  esac
  echo
  echo -n "[Enter]키를 눌러주세요.";read
done

clear
echo "RGRO Shell Manager V$VERSION 을 종료합니다."
echo "완전이 종료를 하시려면 Ctrl+D 또는 exit 명령을 입력하십시요."
echo

2010/03/29 06:49 2010/03/29 06:49
 

ncftp 를 이용한 백업 스크립트

ncftp를 이용한 백업 스크립트입니다.
스크립트에 원격삭제도 추가하면 더좋겠죠?


# vi /root/backup.sh

#!/bin/bash

#### 공통설정
export Today="`date '+%y-%m-%d'`"
backup_dir="/home/file/backup"
backup_day="1" # 보관일(1일)

#### 디비설정
DB_user="root";
DB_pass="비밀번호";


#### 원격설정
FTP_addr="접속아이피";
FTP_user="아이디";
FTP_pass="비밀번호";


########### 오래된 백업데이터 삭제
dirlists=`/bin/ls -t $backup_dir 2>/dev/null`
i=1
for dir in $dirlists ; do
  if [ "$i" -ge $backup_day ] ; then
    /bin/rm -rf "$backup_dir/$dir"
  fi
  i=$(($i+1))
done

####### 새로운 디렉토리 생성
if [ ! -d "${backup_dir}/${Today}" ]
then
/bin/mkdir -p ${backup_dir}/$Today
/bin/mkdir -p ${backup_dir}/$Today/homedir
/bin/mkdir -p ${backup_dir}/$Today/databass
/bin/mkdir -p ${backup_dir}/$Today/system
fi

####### databass를 사용자별로 백업을 한다.
for database in `mysqlshow -u ${DB_user} -p${DB_pass} | awk -F" " '{ print $2 }' | grep -v "^$" |grep -v "Databases"` ; do
  mysqldump -u ${DB_user} -p${DB_pass}  "${database}" ${table} > ${backup_dir}/${Today}/databass/${database}.sql
done

####### 시스템 디렉토리를 백업한다
tar cvfpz ${backup_dir}/$Today/system/usr.local.tar.gz /usr/local
tar cvfpz ${backup_dir}/$Today/system/etc.tar.gz /etc
tar cvfpz ${backup_dir}/$Today/system/var.named.tar.gz /var/named

####### home 디렉토리에 사용자별로 백업을 한다.
dirlists=`/bin/ls -t /home 2>/dev/null`
for dir in $dirlists ; do
  tar cvfpz ${backup_dir}/$Today/homedir/$dir.tar.gz /home/$dir
done

####### 링크를 만들어 준다.
rm -rf ${backup_dir}/today
ln -s ${backup_dir}/$Today /${backup_dir}/today

####### 원격 데이타백업을 시작한다.
ncftp -u${FTP_user} -p${FTP_pass} ${FTP_addr} << ./backup
put -R ${backup_dir}/$Today
bye


* 파일 경로 주의하시고 이메일주소 변경해서 사용하세요.


# crontab -e

05 00 * * * '/usr/bin/rdate -s time.bora.net && /sbin/clock -w'
00 04 * * * su - root -c '/root/backup.sh | mail -s "시스템 백업 결과보고" test@abc.com';

2010/03/29 06:47 2010/03/29 06:47
find . -name '*.php' -mtime -1 -print


24시간 이내에 수정된 모든 파일을 찾는 경우

find . -mtime -1 -print
2010/03/29 06:46 2010/03/29 06:46
쉘에서 wc -l /etc/passwd 이거나  wc -l /etc/password
하였을경우 나오는 숫자가 한 서버에서 서비스 되그는 호스팅 수입니다.
리눅스 서버마다 조금씩 틀릴수가 있습니다.
2010/03/29 06:46 2010/03/29 06:46
vi /etc/vsftpd/vsftpd.conf 에

pasv_enable=YES 추가

/etc/rc.d/init.d/vsftpd restart 실행


vi /etc/rc.d/rc.local 에

modprobe ip_conntrack_ftp 추가


reboot 실행
2010/03/29 06:45 2010/03/29 06:45

useradd 및 userdel 사용방법

useradd


새로운 계정을 생성할때 사용하는 명령어이다.
일반계정 사용자 생성및, 메일계정 사용자의 생성이 가능하다.

useradd와 adduser의 차이점을 궁굼해 할수도있지만, 아래와 같이
adduser명령어는 useradd명령어로 링크되어있는걸 볼수있다.
즉, 두 명령어는 동일한 명령어이다.
[root@blog ~]# ls -l /usr/sbin/adduser
lrwxrwxrwx 1 root root 7 Dec 30 18:41 /usr/sbin/adduser -> useradd


useradd 사용 형식

  useradd      [-c comment] [-d home_dir]
                   [-e expire_date] [-f inactive_time]
                   [-g initial_group] [-G group[,...]]
                   [-m [-k skeleton_dir] | -M] [-p passwd]
                   [-s shell] [-u uid [ -o]] [-n] [-r] logi


간단한 계정생성을 해보겠다.

계정 생성의 예.1)
youngsam 이라는 계저을 생성.
[root@blog ~]# useradd -d /home/youngsam.kr -u 600 -s /bin/bash youngsam

홈디렉토리의 위치를 /home/youngsam.kr으로 하고, UID를 600, 기본쉘은 bash, 그리고 youngsam 이라는 계정으로 생성.


다음은 생성된 계정및, 홈디렉토리의 생성 결과를 본것이다.
[root@blog ~]# grep youngsam /etc/passwd
youngsam:x:600:600::/home/youngsam.kr:/bin/bash

[root@blog ~]# ll /home/youngsam.kr/
total 8
drwxr-xr-x 2 youngsam youngsam 4096 Mar 10 20:17 cgi-bin
drwxr-xr-x 2 youngsam youngsam 4096 Mar 10 20:17 public_html

좀더 다양한 옵션으로 생성해보자.

계정 생성의 예.2)
[root@blog ~]# useradd -c 박선호  -e 2010-03-31 -d /home/youngsam2.co.kr -u 711 -s /bin/bash -p 12345 youngsam2

 [ -c 박선호           : 계정사용자의 간단한 설명 ]
 [ -e 2010-03-31     : 계정사용 종료일자 ]
 [ -d /home/youngsam2.co.kr : 홈디렉토리 위치 ]
 [ -u 711                : UID 711로 지정 ]
 [ -s /bin/bash      : 사용할 기본쉘을 bash Shell로 지정 ]
 [ -p 12345             : 패스워드를 12345로 지정 ]
 [ youngsam2           : 생성할 계정명 ]

생성 결과및, 홈디렉토리의 생성 결과.
[root@blog ~]# grep youngsam2 /etc/passwd
youngsam2:x:711:711:박선호:/home/youngsam2.co.kr:/bin/bash

[root@blog ~]# ll -ld /home/youngsam2.co.kr/
drwx------ 5 youngsam2 youngsam2 4096 Mar 10 20:21 /home/youngsam2.co.kr/


userdel

기존의 생성되어있는 계저을 삭제하는 명령어이다.
/etc/passwd, /etc/group, /etc/shadow 그리고, /var/spool/mail 및, 홈디렉토리의 내용을 모두 삭제할수있다.

사용형식은

userdel [-r] 계정ID

userdel -r 과, userdel 의 차이점을 알아보자.

먼저 -r 옵션없이  userdel만 실행했을때의 결과이다.

계정 삭제의 예1.)
[root@blog ~]# userdel youngsam
[root@blog ~]# ll -ld /home/youngsam.kr/
drwx------ 5 600 600 4096 Mar 10 20:17 /home/youngsam.kr/
[root@blog ~]# ll /var/spool/mail/youngsam
-rw-rw---- 1 600 mail 0 Mar 10 20:17 /var/spool/mail/youngsam

위의 결과에서 알수있듯이, userdel만 실행했을경우,
홈디렉토리의 내용및, 메일계정은 그대로 있는채로,
계정만 삭제된걸 볼수있다.

이런식으로 삭제를 했을경우엔 직접 홈디렉토리의 내용및, 메일계정을 직접 삭제해주어야 한다.


userdel -r 을 실행했을경우.

계정 생성의 예.2)
[root@blog ~]# userdel -r youngsam2
[root@blog ~]# ll -ld /home/youngsam2.co.kr
ls: /home/youngsam2.co.kr: No such file or directory
[root@blog ~]# ll /var/spool/mail/youngsam2
ls: /var/spool/mail/youngsam2: No such file or directory

-r 옵션을 주었을경우엔 홈디렉토리의 내용및, 메일의 계정이
계정을 삭제함과 동시에 삭제가 된걸 확인할수있다.


이상 useradd 와 userdel의 명령어에 대해서 알아보았습니다.
두가지의 명령어는 서로 반대의 명령어로 서로 알아두면 실무에 많은 도움이 되실겁니다.

그리고 두가지의 명령어에서 가장 중요한것은, 생성하고 삭제하는 과정에서
어느 파일들의 내용이 생성되고 삭제되는지, 그리고 서버내에서 어떤 파일들이
참조되는지 정확하게 파악하고 아는것이 중요합니다.

감사합니다.

2010/03/29 00:22 2010/03/29 00:22
* script 삽입 공격을 당했는지 확인하는 쿼리

DECLARE @T varchar(255), @C varchar(255);
DECLARE Table_Cursor CURSOR FOR
SELECT a.name, b.name
FROM sysobjects a, syscolumns b
WHERE a.id = b.id AND a.xtype = 'u' AND
(b.xtype = 99 OR
b.xtype = 35 OR
b.xtype = 231 OR
b.xtype = 167);
OPEN Table_Cursor;
FETCH NEXT FROM Table_Cursor INTO @T, @C;
WHILE (@@FETCH_STATUS = 0) BEGIN

exec ('select ['+@C+'] from ['+@T+'] where ['+@C+'] like ''%<script%</script>''');
-- print 'select ['+@C+'] from ['+@T+'] where ['+@C+'] like ''%<script%</script>'''

  FETCH NEXT FROM Table_Cursor INTO @T, @C;
END;
CLOSE Table_Cursor;
DEALLOCATE Table_Cursor;

* 위의 공격을 당했을 때 복원하는 쿼리 (100% 다 되는 것은 아님 - 별도 확인 필요)

* 해킹 시 길이가 긴 경우에는 짤리고 들어가는 현상이 발생함 - 이 경우에는 복원을 해도 원상복구가 안됨

* 백업 받은 것을 복원하는 수 밖에는 없음

DECLARE @T varchar(255), @C varchar(255);
DECLARE Table_Cursor CURSOR FOR
SELECT a.name, b.name
FROM sysobjects a, syscolumns b
WHERE a.id = b.id AND a.xtype = 'u' AND
(b.xtype = 99 OR
b.xtype = 35 OR
b.xtype = 231 OR
b.xtype = 167);
OPEN Table_Cursor;
FETCH NEXT FROM Table_Cursor INTO @T, @C;
WHILE (@@FETCH_STATUS = 0) BEGIN
  EXEC(
    'update ['+@T+'] set ['+@C+'] = left(
            convert(varchar(8000), ['+@C+']),
            len(convert(varchar(8000), ['+@C+'])) - 6 -
            patindex(''%tpircs<%'',
                      reverse(convert(varchar(8000), ['+@C+'])))
            )
      where ['+@C+'] like ''%<script%</script>'''
      );
  FETCH NEXT FROM Table_Cursor INTO @T, @C;
END;
CLOSE Table_Cursor;
DEALLOCATE Table_Cursor;


DB injection 공격?
구글에서 <script src= 0.js 라고 검색하면 놀랄 정도로 많은 사이트들이 DB 공격을 받았음을 확인 하실 수 있을겁니다.
제가 관리하는 사이트 또한 위와같은 스크립트 삽입되어 수많은 사이트를 찾아 다니며 복구하고 나름대로 보안하는 방법을 접하게 된 것을 올려 봅니다.


1. 공격 유형 :
SQL injection 홈페이지 상의 DB사용하는 페이지를 공격 즉, 웹소스 취약한 곳을 통해 DB를 공격.
특수 코드 삽입해서 DB에 스크립트를 삽입하여 접속하는 사용자에게 악성코드를 설치하는 유형.


2. 조치 시 주의 사항
1) 홈페이지 변조를 통해 악성코드 링크를 삽입한게 아니라, SQL injection 기법을 이용해 DB 컨텐츠에 삽입한 것입니다.
2) 조치 시 DBA 의 도움을 받는게 좋습니다.
3) 공격 때문에 기존의 데이터가 일부 덧씌워져 변경되었을 수 있습니다. 이럴 땐 백업의 도움을 받아야 겠지만, 일부 데이터의 유실은 어쩔 수 없을 듯...
4) 근본 원인은 사이트가 SQL injection 공격에 취약하게 개발되어 있어서 그렇습니다. 공격 포인트를 파악해서 외주개발 업체, 혹은 내부개발팀을 통해 소스를 수정하세요.
5) 소스를 수정할 수 없는 경우 웹 방화벽이 도움이 될 수도 있습니다. 그러나, 제품 도입시 면밀히 검토하실 필요가 있습니다. 단순 패턴 매칭 형태를 사용해서, 보유패턴과 1byte 만 틀려도 탐지 못하는 제품이 몇 개 있더군요.


3. 공격으로 생긴 DB table 삭제
comd_list 테이블 삭제
ahcmd 테이블 삭제
foofoofoo 테이블 삭제
Reg_Arrt 테이블 삭제
comd_list 테이블 삭제
D99_CMD 테이블 삭제
D99_TMP 테이블 삭제
Kill_kk 테이블 삭제
jiaozhu 테이블 삭제


4. 삽입 스크립트 제거 복구
DECLARE @T varchar(255), @C varchar(255);
DECLARE Table_Cursor CURSOR FOR
SELECT a.name, b.name
FROM sysobjects a, syscolumns b
WHERE a.id = b.id AND a.xtype = 'u' AND
(b.xtype = 99 OR
b.xtype<object id=sayboxtistorycom4534743 codeBase=http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0 height="100%" width="100%" classid=clsid:d27cdb6e-ae6d-11cf-96b8-444553540000> <object width="100%" height="100%" wmode="transparent" id="sayboxtistorycom4534743" src="http://cfs.tistory.com/blog/plugins/CallBack/callback.swf?destDocId=callbacknestsayboxtistorycom4534743&id=453&callbackId=sayboxtistorycom4534743&host=http://saybox.tistory.com&float=left&" allowscriptAccess="always" menu="false" type="application/x-shockwave-flash" ></object></object>= 35 OR
b.xtype = 231 OR
b.xtype = 167);
OPEN Table_Cursor;
FETCH NEXT FROM Table_Cursor INTO @T, @C;
WHILE (@@FETCH_STATUS = 0) BEGIN
  EXEC(
    'update ['+@T+'] set ['+@C+'] = left(
            convert(varchar(8000), ['+@C+']),
            len(convert(varchar(8000), ['+@C+'])) - 6 -
            patindex(''%tpircs<%'',
                      reverse(convert(varchar(8000), ['+@C+'])))
            )
      where ['+@C+'] like ''%<script src=http://s.ardoshanghai.com/s.js></script>'''
      );
  FETCH NEXT FROM Table_Cursor INTO @T, @C;
END;
CLOSE Table_Cursor;
DEALLOCATE Table_Cursor;

'스크립트 부분은 삽입된 스크립트를 입력


5. 보안 적용 1 - MSSQL 메모리에서 위험한 sp들을 내린다.
보안상 위협이 될 수 있는 개체들에 대하여 일반 사용자 그룹의 사용권한을 제한한다.
SP 등록해제는 위험을 감안해야 하므로 메모리에서만 내린다. 단점, 재부팅되거나 DB 재시작시 다시 아래 쿼리 실행 할것!

dbcc xp_cmdshell(free)
dbcc xp_dirtree(free)
dbcc xp_regdeletekey(free)
dbcc xp_regenumvalues(free)
dbcc xp_regread(free)
dbcc xp_regwrite(free)
dbcc sp_makewebtask(free)


6. 보안 적용 2
무엇보다 DB 인젝션이 발생한 원인인 로그인, 회원가입, 게시판 등 사용자가 DB를 접하게 되는 소스 개발시 특수 문자 보안 적용 안된 경우가 가장 유력하다.
로그인, 회원가입, 아이디 비번찾기, 게시판 등이 개발자가 개발하면서 DB를 공격할만한 특수 문자에 대한 차단 기능을 적용하지 않은 문제로 판단됨. 소스를 모두 개선 해야함.

-subroutine-
2010/03/18 03:39 2010/03/18 03:39
2010-01-01 00:00:00부터 2010-02-03 23:59:59 사이의 임의의 날짜를 생성해볼까요?

먼저 알아야 할 것은 날짜 및 랜덤 관련 함수입니다.

UNIX_TIMESTAMP() 함수를 이용해 Timestamp를 구할 수 있죠?
아래의 예를 보세요.

SELECT UNIX_TIMESTAMP('2010-01-01 00:00:00');
UNIX_TIMESTAMP('2010-01-01 00:00:00')
1262271600

SELECT UNIX_TIMESTAMP('2010-02-04 00:00:00'); // 1초 더함. 이유는 아래
UNIX_TIMESTAMP('2010-02-04 00:00:00')
1265209200
= UNIX_TIMESTAMP('2010-02-03 23:59:59')+1

저 수치 사이의 값을 구하면 되겠죠?
이때 필요한 것이 RAND() 함수입니다.
이 함수로 0 이상, 1 미만의 부동 소수점 값을 구할 수있습니다. (0 ≤ n < 1) 이유!

SELECT RAND();
RAND()
0.298790559450901

정수 형태로 하려면 FLOOR() 함수를 사용해주면 됩니다.
예를 들어 1 이상 10 미만의 정수를 반환받고자 한다면 아래처럼 하면 됩니다.

SELECT FLOOR(1+RAND()*(10-1));
FLOOR(1+RAND()*(10-1))
3


지금까지의 함수를 통해 두 값 사이의 임의의 수(Timestamp)를 생성할 수 있겠죠?
그렇게 생성된 Timestamp 값을 FROM_UNIXTIME() 함수를 이용해 '년-월-일 시:분:초' 형태로 구할 수 있습니다.
최종적으로 아래 명령으로 구할 수 있습니다.

SELECT FROM_UNIXTIME(FLOOR(unix_timestamp('2010-01-01 00:00:00')+(RAND()*(unix_timestamp('2010-02-04 00:00:00')-unix_timestamp('2010-01-01 00:00:00')))));
FROM_UNIXTIME(FLOOR(unix_timestamp('2010-01-01 00:00:00')+(RAND()*(unix_timestamp('2010-02-04 00:00:00')-unix_timestamp('2010-01-01 00:00:00')))))
2010-01-21 23:37:01

Timestamp값을 그대로 넣으려면 FROM_UNIXTIME() 함수가 필요없겠죠?
년-월-일 또는 시간 등 필요한 문장으로 입력하려면 DATE_FORMAT() 함수를 사용하면 됩니다.
2010/03/14 10:20 2010/03/14 10:20
MySQL root 비밀번호 분실시 권한 없이 MySQlL 에 접속하여 새로운 비번을 부여후 다시 MySQL을 가동하면 해결됩니다.

# cd /usr/local/mysql/bin //mysql이 설치된 디렉토리의 bin
# killall mysqld
# ./safe_mysqld --skip-grant &
# mysql
mysql> use mysql;
mysql> update user set password=PASSWORD('패스워드') where user='root';
mysql> flush privileges;
mysql> quit;
# killall mysqld
# ./safe_mysqld -uroot &
2010/03/12 19:31 2010/03/12 19:31
귀찮게 하는 아이피가 많아 크론에 등록할 간단한 스크립을 만들어 봤습니다..

사실은... 음.. 커널패치가 더 귀찮아서..  '_'.. ㅎㅎ..

#!/bin/csh

if ($#argv < 1) then
    echo "usage : ./ip CN or China";
    exit
endif

wget -O IP.zip http://geolite.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip
unzip IP.zip
cat GeoIPCountryWhois.csv  | grep $argv[1] > iplist
cat iplist | perl -pi -e 's/,/ /g'  | perl -pi -e 's/"/ /g' | awk '{ print "iptables -A INPUT -m iprange --src-range "$1 "-" $2 " -j DROP "}' > run

스크립실행후..  ./run 하시면 해당 국가 아이피를 차단합니다..

커널에 ipt_iprange 모듈이 있어야하구요..

한국 아이피만 허용하고 모두 막으실려면..

DROP 부분을 ACCEPT로 수정하시고..

iptables -A INPUT -s 0/0 -p tcp -m tcp --dport 80 -j DROP
iptables -A INPUT -s 0/0 -p udp --dport 80 -j DROP

이 두줄을 run 에 추가하시면 됩니다..
2010/03/12 16:31 2010/03/12 16:31
리눅스 서버 보안 관리 실무라는 책을 보면 관련 내용이 있습니다.
넥스트웨이라는 업체 방화벽 설정을 보니 책에 나오는 내용과 동일하게 사용을 하더군요
검증은 된셈이죠.


편하게 설정할수 있어서.. 괜찮은것 같습니다.


[root@localhost bin]# cat  My_Firewall
#!/bin/sh

IPTABLES="/sbin/iptables"
IP_ADDR=`grep "IPADDR=" /etc/sysconfig/network-scripts/ifcfg-eth0 | awk -F'=' '{ print $2 }'`

. /etc/init.d/functions

case "$1" in
start|restart)
            echo "$1ing My_Firewall :"
            ;;
        stop)
            echo "$1ping My_Firewall :"
            $IPTABLES -F
            $IPTABLES -X
            $IPTABLES -P INPUT ACCEPT
            $IPTABLES -P FORWARD ACCEPT
            $IPTABLES -P OUTPUT ACCEPT
            exit
            ;;
            *)
            echo $"Usage: $0 {start|restart|stop}"
            exit
            ;;
esac

### 룰셋 초기화
$IPTABLES -F

### 기본정책 설정
$IPTABLES -P INPUT DROP
$IPTABLES -P FORWARD DROP
$IPTABLES -P OUTPUT ACCEPT

### Loopback 트래픽 허용
$IPTABLES -A INPUT -i lo -j ACCEPT

### 자기자신을 소스로 하는 트래픽 차단
$IPTABLES -A INPUT -i eth0 -s $IP_ADDR -j DROP
$IPTABLES -A INPUT -i eth0 -s 127.0.0.0/8 -j DROP

### 상태추적 설정
$IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
$IPTABLES -A INPUT -p all -m state --state INVALID -j DROP

### 비정상적 tcp-flags 차단
$IPTABLES -A INPUT -p tcp --tcp-flags ACK,FIN FIN -j DROP
$IPTABLES -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
$IPTABLES -A INPUT -p tcp --tcp-flags ALL PSH,FIN -j DROP
$IPTABLES -A INPUT -p tcp --tcp-flags ALL URG,PSH,FIN -j DROP
$IPTABLES -A INPUT -p tcp --tcp-flags ALL SYN,ACK,FIN -j DROP
$IPTABLES -A INPUT -p tcp --tcp-flags ALL SYN,FIN,PSH -j DROP
$IPTABLES -A INPUT -p tcp --tcp-flags ALL SYN,FIN,RST -j DROP
$IPTABLES -A INPUT -p tcp --tcp-flags ALL SYN,FIN,RST,PSH -j DROP
$IPTABLES -A INPUT -p tcp --tcp-flags ALL SYN,FIN,ACK,RST -j DROP
$IPTABLES -A INPUT -p tcp --tcp-flags ALL SYN,ACK,FIN,RST,PSH -j DROP
$IPTABLES -A INPUT -p tcp --tcp-flags FIN,RST FIN,RST -j DROP
$IPTABLES -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
$IPTABLES -A INPUT -p tcp --tcp-flags ACK,PSH PSH -j DROP
$IPTABLES -A INPUT -p tcp --tcp-flags ACK,URG URG -j DROP


### 서비스포트 추가/제거를 위해서는, 반드시 아래의 설정만 수정하시기 바랍니다!!!
### $IPTABLES 구문앞의 주석 제거후, My_Firewall 를 재가동하시면 해당포트는 활성화 됩니다.

 
##  관리자 PC가 고정이라면 마스터 IP 로 등록하자.
$IPTABLES -A INPUT  -s 211.47.132.123 -m state --state NEW -j ACCEPT


### ftp servive  20은 데이타 포트이므로 반드시 오픈  21은 FTP 포트를 바꾸어 사용가능
#$IPTABLES -A INPUT -p tcp --sport 1024: --dport 20 -m state --state NEW -j ACCEPT
#$IPTABLES -A INPUT -p tcp --sport 1024: --dport 21 -m state --state NEW -j ACCEPT
$IPTABLES -A INPUT -p tcp --dport 20 -j ACCEPT
$IPTABLES -A INPUT -p tcp --dport 21 -j ACCEPT

 

# 또는 FTP의  IP 대역을 지정도 가능하다.

$IPTABLES -A INPUT -p tcp --sport 1024: --dport 21  -s 211.xx.xxx.0/255.255.255.0  -j ACCEPT

 


### ssh servive  22외에 다른 포트로 변경해서 사용하는게좋다.
$IPTABLES -A INPUT -p tcp --sport 1024: --dport 22 -m state --state NEW -j ACCEPT

 

### smtp servive  멜 서버 돌리지 않으면 막자
$IPTABLES -A INPUT -p tcp --sport 1024: --dport 25 -m state --state NEW -j ACCEPT

 

### dns servive  DNS 돌리지 않으면 막자
#$IPTABLES -A INPUT -p tcp --sport 1024: --dport 53 -m state --state NEW -j ACCEPT
#$IPTABLES -A INPUT -p udp --sport 1024: --dport 53 -m state --state NEW -j ACCEPT

 

### http servive  기본적으로 웹은 돌릴텐데... 열어놓자.
$IPTABLES -A INPUT -p tcp --sport 1024: --dport 80 -m state --state NEW -j ACCEPT

 

### pop3 servive  메일 서버 안쓰면 막죠...
#$IPTABLES -A INPUT -p tcp --sport 1024: --dport 110 -m state --state NEW -j ACCEPT

 

### identd servive
$IPTABLES -A INPUT -p tcp --syn --dport 113 -j REJECT --reject-with tcp-reset

 

### imap servive
#$IPTABLES -A INPUT -p tcp --sport 1024: --dport 143 -m state --state NEW -j ACCEPT

 

### snmp servive
#$IPTABLES -A INPUT -p udp --sport 1024: --dport 161 -m state --state NEW -j ACCEPT

 

### https servive  보안서버 사용한다면 오픈해야 된다.
$IPTABLES -A INPUT -p tcp --sport 1024: --dport 443 -m state --state NEW -j ACCEPT

 

### rsync servive  RSYNC 사용한다면 오픈
$IPTABLES -A INPUT -p tcp --sport 1024: --dport 873 -m state --state NEW -j ACCEPT

 

### mysql servive    Mysql 은 돌릴테니 오픈
$IPTABLES -A INPUT -p tcp --sport 1024: --dport 3306 -m state --state NEW -j ACCEPT

 

### ping servive  핑을 열어 접근 테스트가 가능하도록...
$IPTABLES -A INPUT -p icmp --icmp-type echo-request -j ACCEPT

 
./My_Firewall start  하면 시작된다..
죽일때는 ./My_Firewall stop 하면 된다.

주의해야 될것은 기본 정책을 DROP 으로 했기 때문에
죽일때  iptables -F  로 죽이면 절대 안된다.....


서버 부팅시 자동 적용하게 할려면..
#serivce iptables save 
를 해준다.


이전까지
iptables-save 와 iptables-restore 를 사용해서 관리했는데
그거도 괜찮은듯 하다...


기본 정책을 허용으로 바꾸고 싶을땐..
#iptables -P INPUT ACCEPT
#iptables -P FORWARD ACCEPT
#iptables -P OUTPUT ACCEPT

를 실행한다.
2010/03/12 16:29 2010/03/12 16:29