Search Results for '프로그래밍'


1208 posts related to '프로그래밍'

  1. 2010/03/30 몇몇 CSS3 테크닉
  2. 2010/03/30 jQuery를 이용한 드롭다운 메뉴
  3. 2010/03/29 아파치 설정팁들 이것저것
  4. 2010/03/29 아파치 최적화 httpd.conf 성능
  5. 2010/03/29 아파치 응답속도를 측정 ab -명령
  6. 2010/03/29 .htaccess를 이용한 특정 디렉토리 접근 관리하기
  7. 2010/03/29 /home에 있는 계정을 계정별로 따로 백업하는 스크립트 1
  8. 2010/03/29 리눅스에서 휴지통 (safedelete)
  9. 2010/03/29 리눅스 실시간 트래픽 모니터링 하기
  10. 2010/03/29 특정 확장자만 찾아서 복사
  11. 2010/03/29 여러가지 리눅스 팁들
  12. 2010/03/29 웹호스팅 사용자를 위한 계정관리 스크립트
  13. 2010/03/29 ncftp 를 이용한 백업 스크립트 1
  14. 2010/03/29 24시간 이내에 수정된 php 파일만 찾기
  15. 2010/03/29 현재 웹호스팅중이면 같은 서버에 호스팅 수
  16. 2010/03/29 vsftpd passive mode 사용
  17. 2010/03/29 [프로그래밍] 아이폰 어플 개발자 SDK V3.0 스노우 레오파드용
  18. 2010/03/29 useradd 및 userdel 사용방법
  19. 2010/03/22 ASP용 로그 기록 클래스 2
  20. 2010/03/22 jQuery plugin, Pager 입니다
  21. 2010/03/22 SQL 쉽게 쉽게 코딩하기 - 날쿼리 -
  22. 2010/03/22 썸네일 생성 dll (codeproject에서 다운받은놈)
  23. 2010/03/22 실시간 스팸차단리스트(RBL) 이용방법
  24. 2010/03/18 구글 트랜드 검색
  25. 2010/03/18 로딩 이미지 만들어주는 사이트
  26. 2010/03/18 싸이트로딩속도 + 파일별로딩속도 알려주는 사이트
  27. 2010/03/18 MY - SQL 인젝션 복구쿼리
  28. 2010/03/18 상태표시줄 링크 없애기
  29. 2010/03/18 google의 java script hosting
  30. 2010/03/18 jquery hosting을 로컬에서 구글로 변경하기
많은 브라우져에서 CSS를 지원하고 있으나 아직 몇몇 완전히 지원되지 않는 브라우져가 있기 때문에 특정 CSS들은 브라우져에 따라 적용할 수 있도록 머리 단어가 붙는데 그 머리 단어는 다음과 같다.
  • 모질라/파이어폭스/게코(Gekko) : -moz-
  • Webkit(사파리/크롬) : -webkit- (주: 몇몇 기능들은 사파리에서만 작동하는 것도 있다. 크롬은 사파리보다 더 완전하게 지원하지 않는다)

 인터넷 익스플로러는 CSS3를 제대로 지원하지 않는다.

- 그림자 표시하기

box-shadow : #333 3px 3px 4px;
-moz-box-shadow : #333 3px 3px 4px;
-webkit-box-shadow : #333 3px 3px 4px;

2010/03/30 01:13 2010/03/30 01:13

많은 드롭다운 메뉴에 대한 예제가 보이지만, 그중에서 가장 간단해보이고 활용하기 쉬운 예제를 찾아 간단히 연습해보고 방법론을 올린다. 아마 숙지하는 것보다는 활용하는게 더 빠를 것 같다는 생각.

먼저 메뉴의 구조는 다음과 같이 HTML로 만들어진다.

<ul class="topnav">
 
  <li><a href="#"></a></li>
  <li> <a href="#">메뉴1</a>
    <ul class="subnav">
      <li><a href="#">서브메뉴</a></li>
      <li><a href="#">서브메뉴</a></li>
    </ul>
    </li>
  <li> <a href="#">메뉴2</a>
    <ul class="subnav">
      <li><a href="#">서브메뉴</a></li>
      <li><a href="#">서브메뉴</a></li>
    </ul>
    </li>
  <li><a href="#">메뉴2</a></li>
  <li><a href="#">메뉴3</a></li>
  <li><a href="#">메뉴4</a></li>
  <li><a href="#">메뉴5</a></li>
</ul>

상위 메뉴가 있고 그 드롭다운으로 하위 메뉴들이 나열되는 방식으로 표현된다.

2010/03/30 01:13 2010/03/30 01:13
브라우징 제거

아파치의 디폴트세팅은 브라우징이 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
아이폰 어플 개발에 관심있으신 분들에게...
 
 
당연하지만 맥 OSX 스노우 레오파드용입니다.. 레오파드는 레오파드용이 따로 있는 걸로 봐서 안될듯 합니다. 스노우 레오파드에 설치하세요..
사용자 삽입 이미지

아이폰 어플은 맥OS에서만 가능합니다
한마디로 아이폰을 개발하기 위해서는 애플의 컴퓨터가 있어야되죠
그런데 일반 컴퓨터에 맥OS를 설치할 수 있게 한것이 해킨토시입니다(애플의 정식이 아님)
해킨토시를 설치하기 위해서는 하드웨어를 많이 가린다고 하더군요 자세한 정보는 인터넷을 참고하시면 될거 같네요
2010/03/29 00:56 2010/03/29 00:56

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
ASP용 로그 기록 클래스

많은 개발자들이 개발을 하면서 중간 중간 소스에 Response.Write 변수 를 추가 합니다.

이유는 디버깅 용이죠! ^^

하지만, 개발 완료 후 삭제도 해야 하고 혹여나 깜빡하고서 누락하는 경우가 있는데요.

누락한 것 중 지저분 해지기만 하고 문제가 되진 않지만 어떤 사람들은 dB 커넥션 문자열을 찍어서

노출이 되는 경우도 있기도 합니다. ㅎㅎㅎ

공개 소스 중에는 Log4J라는 모듈이 있습니다만, 이건 JSP, Ruby, .Net 용으로만 있고 ASP용은 없지요.

그래서 아쉬운 대로 만들어 봤습니다.

제가 생각했을 때 이 클래스를 사용하므로서 얻을 수 있는 이득을 나열해 보죠.


1. 운영 중에도 에러나 기타 정보를 기록하여 디버깅 및 유지보수에 용의합니다.
2. 실수로 중요 정보가 외부에 노출되는 것을 방지합니다. (예: Response.Write에 의해)
3. 확장 함수를 이용하여 받아들인 파라미터 등을 기록하는 것이 가능합니다.
4. 로그 레벨을 이용 하여 기록 기준을 정의 할 수 있으므로 성능이 나빠지는 것에 대응 할 수 있습니다.
5. 파일에 기록이 되므로 언제든 역 추적이 가능합니다. ( 1번과 비슷 한 내용이네요 ^^ )

다음은 사용 예입니다.

<!--#include virtual="ClsLogger.asp"//-->
<%On Error Resume Next%>
<%
'// Logger
Dim oLog : Set oLog = New ClsLogger

'// Request Log
TraceRequestParameter oLog

'//      FATAL : 치명적 에러
oLog.Fetal "치명적 에러!!! 관리자 빨리 보삼. : " & Err.Description

'//      ERROR : 수행 가능한 정도의 에러
oLog.Error "또 에러냐!!! : " & Err.Description

'//      WARN : 문제를 일으킬 가능성의 정보
oLog.Warn "이건 귀찮아서 처릴 안했단 말이오!!! : "

'//      INFO : 정보를 나타낼 때 사용
oLog.Info "게시판 목록 시작"

'//      DEBUG : 상세 정보를 나타낼 때 사용
oLog.Debug "지금은 개발 중..."

If ( Err.Number = 0 ) Then
   oLog.Debug "완료"
Else
   oLog.Error Err.Description
End If


'------------------------------------------------------------------------------------
'// Request 객체의 파라미터 값을 로그에 기록한다.
'// 이 함수는 ClsLogger에 포함 시킬지 말지 고민중 ... ㅠㅠ
'------------------------------------------------------------------------------------
Sub TraceRequestParameter(ByRef pLog)

   On Error Resume Next

   Dim pContentType : pContentType = LTrim(Request.ServerVariables("CONTENT_TYPE"))

   If ( InStr(pContentType, "multipart/form-data") > 0 ) Then
      Exit Sub
   End If

   If ( Not IsObject(pLog) ) Then
      Exit Sub
   End If

   Dim z
   Dim pKeyName
   pLog.Debug "============= FORM PARAMETER ============="
   For z = 1 To Request.Form.Count
      pKeyName = Request.Form.Key(z)
      pLog.Debug "Dim " & pKeyName & " : " & pKeyName & " = RequestForm(""" &
pKeyName & """)"
   Next

   For z = 1 To Request.Form.Count
      pLog.Debug Request.Form.Key(z) & " : " & Request.Form(z)
   Next

   pLog.Debug "========== QUERYSTRING PARAMETER ========="
   For z = 1 To Request.QueryString.Count
      pKeyName = Request.QueryString.Key(z)
      pLog.Debug "Dim " & pKeyName & " : " & pKeyName & " = RequestQuery(""" &
pKeyName & """)"
   Next

   For z = 1 To Request.QueryString.Count
      pLog.Debug Request.QueryString.Key(z) & " : " & Request.QueryString(z)
   Next  
   pLog.Debug "=========================================="

   Err.Clear

   On Error GoTo 0

End Sub
%>

저의 경우 주로 .Error와 .Debug를 사용합니다.

일단 속는 셈 치고 한번 사용해보셔요. ^^

많은 분들이 자기가 원하던 거라고 하시더군요. 다행 다행.

아 그리고 로그뷰어는 "mtail" 이라는 프로그램을 이용합니다. 네이년에서 mtail로 검색을 하시면 쉽게 구 할 수 있어요.

간단하게 소개하면
   기록되는 로그를 실시간으로 모니터링 할 수 있고,
   필터링도 가능합니다. 이 필터링을 이용하면 Error만 볼수도 있고 Debug만 볼수도 있습니다.

유용한 프로그램이에요 ^^
 
그럼 사용해보시고 부족한 부분은 리플 달아주세요~
2010/03/22 03:45 2010/03/22 03:45
페이저 애드인은 ajax 방식으로 게시판이나 다양한 데이터를 로드하면서
페이징 기능을 덧붙이고자 하는 경우에 도움이 되는 애드인입니다.

다만, 이는 실제 데이터를 가져오거나 하는 애드인이 아니며, 오로지 전체 레코드 수(totalItemCount)와 페이지 당 출력할 레코드 수(RecordPerPage)에 따라서 전체 페이지 수와 페이징 구역을 계산 및 출력 하는 애드인입니다.

실제로 해당 페이지의 데이터를 가져오는 함수는 여러분이 직접 작성하셔야 하며,
페이저 사용 규칙에 맞게 함수를 호출하시면 페이징이 자동으로 렌더될 것입니다.

샘플은 http://taeyo.net/jQuery/Sample/pager.htm 을 참고하십시오.
현재, 태오 사이트의 새로운 디지털 다이어리는 이 애드인을 사용하여 만들어지고 있습니다.

다음은 사용방법입니다.

1. 페이저를 출력할 위치를 html 태그로 작성한다.
예 : <span id="pager"></span>

2. jQuery의 ready 함수 안에서 다음과 같이 페이저를 초기화 한다.
$("#pager").pager({
pager: "#pager",
pagerMode: "image", //text, image 중 선택
totalItemCount: _totalItemCount,
recordPerPage: _recordPerPage,
currentPage: _currentPage,
pageIndexChanged: Pager.pageIndexChanged,
prev10Text: "<<",
next10Text: ">>",
prev10ImgSrc: "images/Prev10.gif",
next10ImgSrc: "images/next10.gif",
selectedPageFontColor: "orange"
});

_totalItemCount와 _recordPerPage, _currentPage는 전역변수로 선언되어야 할 것이다.
그리고, 이 값은 여러분이 적절하게 설정하면 된다.

3. 페이저의 클릭 이벤트와 관련된 콜백 메서드들을 여러분에게 맞게 정의하자.

var Pager = {
pageIndexChanged: function(selectedPage) {
_currentPage = selectedPage;
loadBoardData(); //목록 조회 및 출력 메서드 호출
}
}
여기서의 loadBoardData() 메서드는 여러분이 데이터베이스에서 데이터를 조회하는 메서드이다.
메서드 명은 여러분의 상황에 맞게 바꾸면 된다.
강조했듯이, 페이저 애드인이 실제 데이터를 로드해주지는 않는다.

4. loadBoardData() 메서드 안에서 여러분의 작업이 모두 끝난 다음, 제일 마지막에 다음과 같은 코드를 추가하여
페이저를 갱신하도록 한다. 갱신을 하지 않으면, 페이저의 페이징 정보가 실제 갯수와 동기화 되지 않을테니 말이다.
갱신을 위해서는 다음의 메서드를 호출하면 된다. 반드시 refresh의 인자로 _totalItemCount, _recordPerPage를 넘겨줘야만
제대로 갱신된다는 점에 주의하자.
또한, refresh 메서드는 계산된 전체 페이지 갯수를 반환한다.

function loadBoardData()
{
//여러분의 작업
//...
//...

var pageCount = $("#pager").pager.refresh(_totalItemCount, _recordPerPage);
}

끝.

ps : 1차 배포 후, 일부 로직을 개선하여 좀 더 코드를 줄였습니다. 현재 파일은 2차 배포버전입니다.

2010/03/22 03:43 2010/03/22 03:43
날쿼리 방식의 SQL 좀 쉽게 짜기위해 만들어본 DataBase Class 입니다.

태요사이트에서 몇개 클래스 긁어다가 만들때 좀 썼습니다.

간략하게 예를 들면
sql = "select seq,name from tb_board where seq = 1" 를 클래스를 써서 표현하자면..

db.initSQL("select")
db.setTable("tb_board")
db.setColumn("seq")
db.setColumn("name")
db.setWhere "seq", 1, "number"
뭐 이런식으로 씁니다.

살짝만 생각하면, 어지간한 쿼리는 아주 간단하고 깔끔하게 처리할 수 있어요



쿼리.sql 에 테이블이 하나 빠져서 방금 다시 올렸어요
2010/03/22 03:41 2010/03/22 03:41
asp 용 썸넬 생성 dll 입니다.

나누미플러스나, KMS썸넬등은 2003 서버에서 뻗어버리는 경우가 많아서..
코드프로젝트에 올려진 소스에서 쓰잘데기 없는부분 빼버리고,
썸넬만 만드는 부분 함수로 만들어놨습니다. (sub 함수로 전환시켜서 쓰는게 더 편할듯 하네요)

참고로.. 덱스트든 abc든 일단 업로드 끝나고, 저장한 원본 파일명 던져주면 됩니다.

DLL 은 가장 최근꺼구요..
원 개발자가 만든 소스나 메서드 종류 보시려면.. 다운 받아서 살펴보심 되요.. (물론 C++ 소스일껍니다)
2010/03/22 03:39 2010/03/22 03:39
스팸메일 수신을 차단하기 위하여 실시간 스팸차단리스트(KISA-RBL)를 활용하는 방법입니다.

KISA-RBL 서버에서 스팸리스트를 다운로드하는 방법과
메일 서버(Sendmail, qmail, Postfix, Exchange Server)에서 참조할 수 있는 방법이 설명되어 있습니다.

첨부파일을 참고해 주세요.

출처 : kisarbl.or.kr (한국인터넷진흥원 스팸대응팀)
2010/03/22 03:38 2010/03/22 03:38
사용자 삽입 이미지

http://google.com/trends?q=%EC%86%90%EB%8B%B4%EB%B9%84%2C%ED%83%9C%EC%97%B0&ctab=875759130&geo=all&date=all
 
언제생긴건지 구글에 트랜드를 비교해볼수 있는곳이생겻네요
, 로 구분해서 검색해볼수 있습니다 잼나네요
2010/03/18 03:54 2010/03/18 03:54

http://www.ajaxload.info


가끔 사이트를 열었을때 파일을 불러오기 전 로딩 중입을 알려주는 모양을 보셨을텐데요..

이사이트에 가심 편하게 로딩이미지를 만들어 쓰실수가 있어요..

저두 아직은 써보지 않았지만..

불러올 데이터가 많을때  이런 로딩 이미지가 있으면 용이하겠죠 ^^


사용자 삽입 이미지
Indicator type --> 는 로딩될때 나오는 모양들

Background color  --> 로딩이미지가 사용될 곳의 바탕색깔

Foreground color  --> 로딩 이미지 색깔


입니다.

선택후 아이콘을 누르면 바로 아래에 선택된 로딩이미지가 보여

집니다. ^^

이외 Top 10 로딩이미지도 있으니

사용해보세요..


2010/03/18 03:49 2010/03/18 03:49

http://tools.pingdom.com/fpt/?url=youngsam.kr


우측에 youngsam.kr 변경 하시면 됩니다.

2010/03/18 03:47 2010/03/18 03:47
* 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
 

<!--
function StatusHidden() {
window.status = "안녕하세요";
setTimeout("StatusHidden()", 0);
}
StatusHidden();
//-->

 
2010/03/18 03:37 2010/03/18 03:37
 

Ajax Libraries

Each library is available via both google.load() and directly, via <script/> tag. The google.load() approach offers the most functionality and performance. In the sections that follow, we document all of the libraries that are available. For each library we list its name (as in the name used in google.load()), all of the versions that we have on hand for the library, etc.

jQuery
name: jquery
versions: 1.2.3, 1.2.6, 1.3.0, 1.3.1
load request: google.load("jquery", "1.3.1");
extras: uncompressed:true, e.g., google.load("jquery", "1.3.1", {uncompressed:true});
path: http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js
path(u): http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.js
site: http://jquery.com/
note: 1.2.5 and 1.2.4 are not hosted due to their short and unstable lives in the wild...
jQuery UI
name: jqueryui
versions: 1.5.2, 1.5.3
load request: google.load("jqueryui", "1.5.3");
extras: uncompressed:true, e.g., google.load("jqueryui", "1.5", {uncompressed:true});
path: http://ajax.googleapis.com/ajax/libs/jqueryui/1.5.3/jquery-ui.min.js
path(u): http://ajax.googleapis.com/ajax/libs/jqueryui/1.5.3/jquery-ui.js
site: http://ui.jquery.com/
note: This library depends on jquery. Before loading this module, you must load jquery. e.g.:
  google.load("jquery", "1.3.1");
  google.load("jqueryui", "1.5.3");
Prototype
name: prototype
versions: 1.6.0.2, 1.6.0.3
load request: google.load("prototype", "1.6.0.3");
path: http://ajax.googleapis.com/ajax/libs/prototype/1.6.0.3/prototype.js
site: http://www.prototypejs.org/
script.aculo.us
name: scriptaculous
versions: 1.8.1, 1.8.2
load request: google.load("scriptaculous", "1.8.2");
path: http://ajax.googleapis.com/ajax/libs/scriptaculous/1.8.2/scriptaculous.js
site: http://script.aculo.us/
note: This library depends on Prototype. Before loading this module, you must load Prototype. e.g.:
  google.load("prototype", "1.6");
  google.load("scriptaculous", "1.8.2");
MooTools
name: mootools
versions: 1.11, 1.2.1
load request: google.load("mootools", "1.2.1");
extras: uncompressed:true, e.g., google.load("mootools", "1.2.1", {uncompressed:true});
path: http://ajax.googleapis.com/ajax/libs/mootools/1.2.1/mootools-yui-compressed.js
path(u): http://ajax.googleapis.com/ajax/libs/mootools/1.2.1/mootools.js
site: http://mootools.net/
Dojo
name: dojo
versions: 1.1.1, 1.2.0, 1.2.3
load request: google.load("dojo", "1.2.3");
extras: uncompressed:true, e.g., google.load("dojo", "1.2.3", {uncompressed:true});
path: http://ajax.googleapis.com/ajax/libs/dojo/1.2.3/dojo/dojo.xd.js
path(u): http://ajax.googleapis.com/ajax/libs/dojo/1.2.3/dojo/dojo.xd.js.uncompressed.js
site: http://dojotoolkit.org/
SWFObjectNew!
name: swfobject
versions: 2.1
load request: google.load("swfobject", "2.1");
extras: uncompressed:true, e.g., google.load("swfobject", "2.1", {uncompressed:true});
path: http://ajax.googleapis.com/ajax/libs/swfobject/2.1/swfobject.js
path(u): http://ajax.googleapis.com/ajax/libs/swfobject/2.1/swfobject_src.js
site: http://code.google.com/p/swfobject/
Yahoo! User Interface Library (YUI)New!
name: yui
versions: 2.6.0
load request: load request: google.load("yui", "2.6.0");
extras: uncompressed:true, e.g., google.load("yui", "2.6.0", {uncompressed:true});
path: http://ajax.googleapis.com/ajax/libs/yui/2.6.0/build/yuiloader/yuiloader-min.js
path(u): http://ajax.googleapis.com/ajax/libs/yui/2.6.0/build/yuiloader/yuiloader.js
site: http://developer.yahoo.com/yui/
2010/03/18 03:33 2010/03/18 03:33
2008년부터 구글에서 유명한 java script hosting을 하고 있습니다.

구글의 jquery hosting을 쓰면 빠른속도(구글은 여기저기에 cdn이 있으니까요)와 함께
호스팅에서 발생하는 traffinc을 줄이는 것이 가능 합니다.

(원본)
<script type="text/javascript" src="<?=$g4['path']?>/js/jquery.min.js"></script>

(수정본)
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.js"></script>
2010/03/18 03:32 2010/03/18 03:32