Lucene 과 한글

Apache/Lucene 2007/03/09 10:19
 
 
 
 

Lucene의 한계

Lucene의 CJKAnalyzer 를 포함한 다른 어떤 분석기로도 한글을 제대로 분석할 수 없다. 실제로 CJKAnalyzer는 한글,중국어,일본어 문자열의 특성을 전혀 고려하지 않고 두 글자씩 기계적으로 잘라낼 뿐이다.
기본 Lucene 패키지에 포함된 StandardAnalyzer는 JavaCC 기반으로 만든 StandardTokenizer가 원문에서 잘라낸 각각의 토큰을 기초 정보로 사용한다. StandardTokenizer의 소스코드인 StandardTokenizer.jj(Nutch 에서는 NutchAnalysis.jj) 파일을 살펴보면 CJK 란 토큰 유형을 아래와 같이 정의하고 있다.

<#CJK: [ "\u3040"-"\u318f", "\u3300"-"\u337f", "\u3400"-"\u3d2d", "\u4e00"-"\u9fff", "\uf900"-"\ufaff" ] >

한글은 유니코드에서 "\uac00"-"\ud7a3" 의 영역을 차지하고있다.
따라서, 아래와 같이 코드를 고치고 루씬을 다시 빌드해야 한 다.
<#CJK:                                       
      [
       "\u3040"-"\u318f",
       "\u3300"-"\u337f",
       "\u3400"-"\u3d2d",
       "\u4e00"-"\u9fff",
       "\uac00"-"\ud7a3",
       "\uf900"-"\ufaff"
      ]
    >


첨부파일에서는 한글을 아예 따로 선언하고 KOREAN 을 WORD 로 인식하도록 추가해 주었다.
NutchAnalysis.jj



Lucene 한글 분석기

한국어 스템필터를 만들고, 화이트스페이스 토크나이저와 함께 간단한 한국어 분석기를 만들었다.
더 정교한 분석을 하기 위해 앞으로 해야할 일들이 많다. prototype 으로 쓰기에는 그럭저럭 쓸만한 성능을 보인다고 생각한다 ㅡ.ㅡ;;

KoreanStemFilter.java
package kr.re.ngic.bis.analysis; import java.io.IOException; import org.apache.lucene.analysis.Token; import org.apache.lucene.analysis.TokenFilter; import org.apache.lucene.analysis.TokenStream; public class KoreanStemFilter extends TokenFilter { // 이거 외에도 추가해야 할 것들이 많으며, 더 정확한 처리를 위해 NLP 관련된 코드를 추가해야 한다. private static final String[] WORD_ENDING = { "은", "는", "이", "가","에", "에는", "에게", "에게는", "에게서", "에서", "의", "한테", "해서", "습니다", "을", "를", "까지", "도", "라도", "이라도", "로", "으로", "부터" }; private TokenStream stream = null; public KoreanStemFilter(TokenStream input) { stream = input; } public Token next() throws IOException { Token token = stream.next(); if(token == null) { System.out.println("null"); return null; } Token result = new Token( stem(token.termText()), token.startOffset(), token.endOffset(), token.type()); result.setPositionIncrement(token.getPositionIncrement()); return result; } private String stem(String term) { int longestWordEndingLength = 0; int longestWordEndingId = -1; for(int i = 0; i < WORD_ENDING.length; i++) { if(term.endsWith((WORD_ENDING[i]))) { longestWordEndingLength = WORD_ENDING[i].length(); longestWordEndingId = i; } } if(longestWordEndingLength == 0 || longestWordEndingId == -1) { return term; } return term.substring(0, term.length() - longestWordEndingLength); } }


KoreanAnalyzer.java
package kr.re.ngic.bis.analysis; import java.io.Reader; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.WhitespaceTokenizer; public class KoreanAnalyzer extends Analyzer { public TokenStream tokenStream(String fieldName, Reader content) { return new KoreanStemFilter(new WhitespaceTokenizer(content)); } }

NutchDocumentTokenizer에 적용

너치는 웹문서를 분석할 때 NutchDocumentAnalyzer를 이용한다. 전체 소스를 바꾸기 보다는 그놈을 바꾸는게 간단하기 때문에 ㅡㅡ;
NutchDocumentAnalyzer의 Tokenizer 부분에 한글 분석을 위한 코드를 추가했다. ㅡㅡa..
클래스 디자인은 추후 개선하도록 하겠다.

NutchDocumentTokenizer.java
/** * Copyright 2005 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.nutch.analysis; import java.io.*; import org.apache.lucene.analysis.Tokenizer; import org.apache.lucene.analysis.Token; /** * The tokenizer used for Nutch document text. Implemented in terms of our * JavaCC-generated lexical analyzer, {@link NutchAnalysisTokenManager}, shared * with the query parser. */ public final class NutchDocumentTokenizer extends Tokenizer implements NutchAnalysisConstants { private NutchAnalysisTokenManager tokenManager; private static final String[] KOREAN_WORD_ENDING = { "은", "는", "이", "가", "에", "에는", "에게", "에게는", "에게서", "에서", "의", "한테", "해서", "습니다", "을", "를", "까지", "도", "라도", "이라도", "로", "으로", "부터" }; /** Construct a tokenizer for the text in a Reader. */ public NutchDocumentTokenizer(Reader reader) { super(reader); tokenManager = new NutchAnalysisTokenManager(reader); } /** Returns the next token in the stream, or null at EOF. */ public final Token next() throws IOException { org.apache.nutch.analysis.Token t; try { loop: { while (true) { t = tokenManager.getNextToken(); switch (t.kind) { // skip query syntax tokens case EOF: case WORD: case ACRONYM: case SIGRAM: break loop; default: } } } } catch (TokenMgrError e) { // translate exceptions throw new IOException("Tokenizer error:" + e); } if (t.kind == EOF) // translate tokens return null; else { // return new Token(t.image, t.beginColumn, t.endColumn, // tokenImage[t.kind]); return new Token(koreanStem(t.image), t.beginColumn, t.endColumn, tokenImage[t.kind]); } } private String koreanStem(String term) { int longestWordEndingLength = 0; int longestWordEndingId = -1; for(int i = 0; i < KOREAN_WORD_ENDING.length; i++) { if(term.endsWith((KOREAN_WORD_ENDING[i]))) { longestWordEndingLength = KOREAN_WORD_ENDING[i].length(); longestWordEndingId = i; } } if(longestWordEndingLength == 0 || longestWordEndingId == -1) { return term; } return term.substring(0, term.length() - longestWordEndingLength); } /** For debugging. */ public static void main(String[] args) throws Exception { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); while (true) { System.out.print("Text: "); String line = in.readLine(); Tokenizer tokenizer = new NutchDocumentTokenizer(new StringReader( line)); Token token; System.out.print("Tokens: "); while ((token = tokenizer.next()) != null) { System.out.print(token.termText()); System.out.print(" "); } System.out.println(); } } }


vim 편집기 활용법

Linux 2007/03/08 17:08

사용자의 입장에서 윈도우와 가장 두드러지게 눈에 띄는 리눅스, 그리고 다른 유닉스 운영체제의 차이점은 무엇일까? 여러 차이점, 특히 관습이나 문화적인 차이점도 많이 있겠지만 vi 에디터의 독특함도 중요하게 작용하고 있다고 본다.

최근 들어서는 유닉스를 처음 배우면서 에디터로 vi를 반드시 배워야 하는 상황은 많이 줄었지만 여전히 vi는 많이 쓰이고 있으며 그 편리함과 독특한 매력은 많은 사용자를 확보하고 있다. 아직까지 vi를 제대로 쓰지 않고 리눅스를 사용하고 있다면 이번 기회에 조금 귀찮더라도 반드시 vi 기본 명령어는 습득해 보도록 하고, 또 추가로 많이 쓰이는 vi 관련 설정을 살펴보기로 하자.

vi를 처음 접하는 사람에게 가장 까다롭게 느껴지는 것은 vi가 소위 명령어 모드(command mode)와 입력 모드(input mode)가 나뉘어져 있다는 특성 때문이다. vi를 처음 실행시키고 타이핑을 해보면 아무런 글자도 입력되지 않고 심지어는 비프음까지 동반하게 되는데 많은 사용자들이 이런 vi의 편집기답지 않은 황당한(?) 모습에 금방 거부감을 갖게 되는 경우가 많다. 하지만 일단 vi의 명렁어 모드와 입력 모드의 차이점을 인식하고 몇 가지 커서 이동 명령어만 학습하고 나면 vi의 매력을 금방 느낄 수 있으니 겉모습만을 보고 오해해서 vi를 버리지 말도록 하자.

vim은 정확히 말하자면 여러 vi 클론들 중의 하나이다. vim의 이름은 vi improved에서 따왔다고 하는데 vim은 기본적인 vi의 기능에 덧붙여서 여러 개의 파일을 동시에 편집한다든가 프로그램 소스코드에 색깔을 덧붙여 가독성을 높여주는 syntax highlighting과 같은 기능을 추가로 지원한다.

pico, nano
우선, vi를 배우는 동안 간단히 쓰기 좋은 에디터로는 pico나 pico의 자유 소프트웨어 클론인 nano를 권장한다(젠투 리눅스는 시스템 설치 과정에서 nano를 사용한다). pico나 nano는 어느 배포판이나 기본으로 설치되어 있는 경우가 많으며 명령어 안내가 간단하게 화면 아래쪽에 출력되기 때문에 불편하지만 쉽게 쓸 수 있다. 오래 전 PC통신 시절의 경험이 있는 사용자라면 이미 pico를 많이 사용해 보았을 수도 있다. pico의 사용 방법은 무척 간단하기 때문에 여기서는 생략하도록 한다.

명령어 모드와 입력 모드
앞에서 잠깐 얘기했듯이 vi는 명령어 모드와 입력 모드가 나뉘어서 동작한다. 예를 들어 명령어 모드에서는 h 키를 누르면 왼쪽 화살표 키와 같이 커서가 왼쪽으로 한 칸 이동하지만 입력 모드에서는 화면에 h 글자가 입력된다.

vi는 실행되었을 때 기본으로 명령어 모드가 작동된다. 따라서 vi를 실행한 뒤 아무리 키를 눌러봐야 글자가 타이핑되지 않는다. 입력 모드로 들어가기 위해 i 키(insert, 삽입)를 눌러 보자. i 키를 누른 이후로는 타이핑이 될 것이다. 참고로 a 키를 누르면 커서 다음 글자부터 입력이 된다. 추가로 대문자 I와 A의 차이점도 직접 확인해 보자.

서너 줄 정도 간단한 글을 입력한 다음 이제 다시 명령어 모드로 돌아가기 위해 esc 키를 눌러보자. esc 키는 vi에서 가장 중요한 키 중의 하나이며 esc를 누르면 vi는 항상 명령어 모드로 돌아간다. 여기서 다시 i나 a 키를 누르면 삽입 모드로 들어간다(한 줄을 비우고 삽입 모드로 들어가는 o와 O도 시험해 보자). 이제 esc 키를 눌러서 명령어 모드로 돌아간 뒤 커서를 상하좌우로 이동해보자.

요즘은 상황이 많이 달라졌지만, vi에서는 화면 상의 커서를 상하좌우로 이동하기 위해 키보드 위의 상하좌우 화살표 키를 원칙적으로 쓰지 않는다. vim에서는 화살표 키를 써도 커서 이동이 가능하지만 일단은 vi에서는 화살표 키를 쓰지 않는 습관을 들여 보자. vi에서는 커서 이동키로 h(좌), j(하), k(상), l(우)을 사용한다. 한 페이지 위로 올라갈 때는 pgup 키 대신 , 한 페이지 아래로 내려갈 때에는 pgdn 키 대신 를 사용한다. <표 1>를 참조해서 커서 이동키를 외우도록 하자.

<표 1> vi의 커서 이동 키

 

명령어

내용

왼쪽

h

오른쪽

l

위쪽

k

아래쪽

j

한 페이지 위로

<ctrl+v>

한 페이지 아래로

<ctrl+f>


vi에서는 왜 이렇게 낯선 커서 키 배열을 사용할까? 그 이유 중 하나는 vi가 커서 키로 사용하고 있는 h, j, k, l 키가 화살표 키보다 사용하기 훨씬 편리하기 때문이다. 다만 vi의 키 배열은 아무래도 처음 익숙해지고 외우기까지가 불편하다. 하지만 vi의 명령어 키는 모두 기본 자판만을 사용하기 때문에 커서를 움직이거나 페이지를 스크롤 하기 위해 오른손을 들어 화살표 키가 있는 곳까지 손을 뻗는 수고를 덜어준다. vi를 오래 쓰다보면 윈도우에서도 무심코 esc 키를 누르고 j, k 키를 눌러 커서를 무심코 이동시키려는 중독 증세가 나타나 간혹 사람을 당황하게 하는 경우도 생긴다.

일단 h, j, k, l 커서 키와 페이지 업, 페이지 다운 키로 , 에 익숙해진 다음 몇 가지 이동키를 더 익혀보자. 한 단어를 이동하는 키는 w, 한 단어를 뒤로 이동하는 키는 b이다. 시프트 키를 누르고 대문자 W, B를 누르면 띄어쓰기가 된 단어 단위로 커서가 이동한다. w와 비슷한 기능으로 e를 들 수 있는데 e 키는 커서가 단어의 맨 뒷부분에 위치하게 된다.

추가로 워드프로세서에서 Home 키에 해당하는 vi의 키는 0이고 End에 해당하는 키는 $이다. 윈도우 환경에서는 Home이나 End 키를 안 쓰는 사람도 많지만 vi에서는 많이 쓰이니 반드시 익혀두자. 여기에 커서 이동키로서의 (, ) (문장 단위 이동), {,} (문단 단위 이동), H, M, L(화면 첫줄, 가운뎃줄, 마지막줄) 키, 1G (첫줄), G(마지막줄)의 쓰임새까지 학습하고 나면 vi로 가장 기본적인 문서 편집을 하는 데는 문제가 없게 된다.

<표 2> vi의 추가 커서 이동키

 

명령어

내용

줄의 가장 처음(Home)

0

줄의 가장 마지막(End)

$

한 단어 오른쪽으로

w, W, e, E

한 단어 왼쪽으로

b, B

한 문장 오른쪽으로

(

한 문장 왼쪽으로

)

한 문단 오른쪽으로

}

한 문단 왼쪽으로

{

화면의 첫 줄, 가운데 줄, 마지막 줄

H, M, L

편집중인 파일의 맨 처음으로

1G

편집중인 파일의 맨 마지막으로

G



여기서 다른 에디터에서는 보기 힘든 vi의 또 다른 중요한 문법을 배워보자. w 키를 사용해 한번에 두 단어, 세 단어를 뛰어 넘어 커서를 움직이려면 어떻게 해야 할까? 방법은 그만큼의 숫자를 w 키를 타이핑하기 전에 먼저 입력해 주면 된다. 즉, 두 단어를 건너뛰고 싶으면 2w, 세 단어는 3w와 같이 타이핑을 해주면 되는 것이다. 같은 방법으로 위로 다섯줄을 올라가고 싶으면 5k, 아래로 열 줄을 내려가고 싶으면 10j와 같은 키 조합을 만들어 볼 수 있다.

vi를 종료하기 위해서는 ‘:’ 키를 눌러서 vi의 전신인 ex의 명령어 모드로 들어가야 한다. : 키를 누르면 화면 맨 아래쪽에 : 프롬프트가 뜨는 것을 볼 수 있는데 여기서 검색이라든가 새 파일 열기와 같은 좀 더 복잡한 명령을 입력할 수 있다. 종료 명령인 q를 누르고 엔터 키를 치면 vi가 종료되는데 지금은 편집 중인 파일이 있는 관계로 vi가 아직 파일이 저장되어 있지 않다는 에러 메시지를 보여준다. 강제로 종료하기 위해서는 :q! 명령을 입력하면 된다. 저장을 하려면 :w <파일이름> 명령을 실행한 뒤 q 명령으로 vi를 종료하자.

보통은 vi로 파일을 편집할 때는 $ vi 과 같이 셸에서 vi를 실행시킬 때 파일 이름을 명시해주고 종료할 때는 :wq 명령어로 저장을 하고 vi를 종료하는 방법을 쓰는 것이 편리하다.

vi에서의 텍스트 편집
삭제
이제 글자 삭제를 해볼 차례이다. 물론 vi의 입력 모드에서는 백스페이스 키가 정상적으로 작동하지만 명령어 모드에서는 백스페이스가 아닌 x 키를 사용한다. 그런데 실제 문서 편집 작업을 하다보면 글자 단위의 삭제보다는 단어나 한 줄 단위, 혹은 커서가 위치한 부분부터 줄 끝까지 삭제를 하는 경우가 많다. 이런 경우에 쓰는 vi 명령키가 d이다. d 다음에는 지울 범위를 설정해 주어야 하는데 다음과 같은 키 조합을 만들어 볼 수 있다.


◆ dw : 커서가 있는 위치부터 오른쪽으로 한 단어 삭제
◆ db : 커서가 있는 위치부터 왼쪽으로 한 단어 삭제
◆ d$ : 커서가 있는 위치부터 문장 끝까지 삭제
◆ d} : 커서가 있는 위치부터 한 문단 끝가지 삭제


앞의 경우와 마찬가지로 vi의 명령어 키 조합을 응용해 보자.


◆ d3w : 커서가 있는 위치부터 오른쪽으로 세 단어 삭제
◆ d5j : 커서가 있는 위치부터 아래로 다섯 줄 삭제


참고로 dd 명령키는 한 줄을 지울 때 사용한다. d$는 D로 간편하게 줄여 쓸 수 있다. 또한 d(delete) 대신에 c (change) 명령키를 사용하면 vi는 삭제 대신에 치환 기능을 수행한다. 치환 기능은 vi가 같은 범위의 d 명령을 수행한 다음 i 키를 알아서 눌러 입력 모드로의 전환까지 자동으로 해준다고 생각하면 된다. 텍스트 편집은 결국 어느 부분을 삭제하고 나면 그 부분을 다른 단어들로 수정하기 마련이며 vi에서는 다른 비주얼한 에디터와는 달리 삭제와 수정까지 치환 기능을 통해 한번에 간편히 해결해 주고 있다. 실제, 필자의 경우는 vi를 쓰면서 d 키보다 c 키를 더 많이 쓰는 편이다. 비슷한 기능키로 s, S와 r도 간혹 사용된다.

자르고 붙이기
윈도우나 기타 GUI 데스크탑 환경에서 자르고 붙이기(cut & paste) 기능은 이해하기도 쉽고 실제 많이 쓰는 기능이다. vi에서는 자르기(cut) 기능은 d 키로 삭제했을 때 삭제된 부분이 자동으로 기억되며, 이것을 소문자 p나 대문자 P 키를 눌러서 붙일(paste) 수 있다. 일례로 문단 하나를 cut & paste하는 경우를 생각해보자. 윈도우에서는 마우스로 해당 부분을 선택하고 풀다운 메뉴에서 「Edit | Cut」 메뉴를 선택하고 커서를 적절한 위치에 놓은 다음 풀다운 메뉴에서 「Edit | Paste」 메뉴를 선택 이런 방식으로 옮긴다.

이것을 vi에서는 d 명령으로 해당 부분을 지우고 커서를 적절한 위치에 놓은 다음 p 명령키로 붙여넣기의 방식을 따른다. 그렇다면 undo 기능은 어떻게 사용할 수 있을까? vi에서 undo 키는 단순히 u 키를 누르면 되며 vim의 경우 redo 기능이 로 추가되어 있다.

복사하고 붙이기
vi에서 복사하고 붙이기(copy & paste)에서 복사 기능을 수행하는 vi의 명령키는 y(yank)이다. d 대신에 y 키를 누르고 복사하고 싶은 부분만큼 선택한 다음 p 키를 눌러서 붙여넣기 작업을 진행하면 된다. y 키 역시 마찬가지로 yw, y$, y}, y10j와 같은 다양한 응용이 가능할 것이다. yy 명령키는 dd와 비슷한 역할을 한다. yy 명령키는 p 명령키와 같이 조합해서 특히 많이 쓰이는 편이다.

두 줄을 한 줄로 합치기
두 줄을 한 줄로 합치기 위해서는 대문자 J 명령키를 사용한다. 반대로, 한 줄을 두 줄로 나눌 때는 r 키와 엔터 키의 조합을 쓰면 편리하다. r 명령키는 커서가 위치한 곳의 문자 하나를 치환(replace) 하고 명령어 모드로 복귀한다. 여기서 잠깐 유닉스의 파이프를 이용한 팁 하나를 알아보자. vi에서는 이렇게 J 키로 두 줄을 합치다 보면 문단의 오른쪽이 들쑥날쑥해지는 것이 그다지 보기 좋지 않은 경우가 많다.

이럴 때 유닉스의 파이프(pipe) 기능을 이용해서 문단 정렬을 해볼 수 있다. 유닉스에는 기본으로 fmt 명령이 제공된다. fmt는 문단을 72컬럼 근처에서 다듬어주는 역할을 한다. 보통 다음과 같은 방식으로 쓰면 document.txt의 문단을 예쁘게 정렬해서 출력해 주는 아주 간단한 유틸리티이다.


$ cat document.txt | fmt


이것을 vi에서 사용해 보자. vi에서는 ‘!’ 키를 누르면 필터(filter)가 동작한다. ! 키를 누르고 처리할 텍스트 범위를 선택한 다음 외부 명령어 이름을 적어준 뒤 엔터를 누르면 그 외부 명령어가 처리한 텍스트 결과물이 다시 vi 편집 화면에 돌아오는 것이다. 이제 한 문단 정렬을 외부 명령어 fmt를 이용해 보자. 방법은 다음과 같다.


[1] 줄이 들쑥날쑥한 문단에 커서를 위치시킨다.
[2] ! 키를 누른다.
[3] } 키를 눌러 커서가 위치한 문단 끝까지 선택한다.
[4] 외부 명령어인 fmt를 타이핑한 뒤 엔터 키를 친다.


이렇게 하면 문단이 fmt를 통해 예쁘게 정렬된다. ! 키를 누른 이후에 선택한 부분이 fmt에 들어가서 포맷팅이 되고, 그 결과가 다시 vi 편집 화면으로 돌아온 것이다. 조금 복잡해 보이지만 vi가 간단한 기능으로도 강력한 성능을 발휘할 수 있는 특징 중의 하나이므로 한번쯤 연습해 보도록 하자. 필자의 경우에는 } 대신 아예 파일 끝부분을 가리키는 G를 이용해서 편집중인 파일 전체를 fmt를 통해 문단 정렬을 자주 하는 편이다.

파일 저장 및 vi 끝내기
파일 열기, 저장, 그리고 vi 끝내기는 : 키를 눌러서 명령어 입력 모드로 전환한 다음 이루어진다. :w 명령어로 편집 중인 파일을 저장할 수 있다. :q 명령은 vi 종료 명령이다. 안전하게 파일을 저장하고 vi를 빠져 나오려면 :wq 명령을 이용한다.

vim의 추가기능
이제 vi의 확장판 클론인 vim의 유용한 기능들을 살펴보기로 하자. vim의 여러 가지 확장된 기능 중에서 우리가 중점적으로 살펴볼 부분은 다음과 같다.


◆ syntax highlighting
◆ 들여쓰기
◆ 다중 윈도우 사용


우선 vim 사용에 편리한 설정 몇 가지를 먼저 살펴보자. vim의 설정은 /etc/vimrc나 ~/.vimrc에 저장해 놓으면 된다. vimrc의 명령어는 vim의 : 명령 프롬프트에서 직접 입력해서 실행하는 것과 동일하다.

vim 사용시 한글 관련 옵션
vim에서 한글을 쓸 때 편집 도중에 한글이 깨지지 않도록 하기 위해서는 vimrc에 다음 옵션을 추가한다.


set fileencoding=korea
set encoding=korea


set fileencoding 명령은 vim이 편집 중인 파일을 저장할 때 어떤 인코딩을 사용할 것인가를 결정해 주고 set encoding은 vim 내부에서 어떤 문자 인코딩을 사용할 것인지를 결정해 준다. 이 옵션으로도 vim에서 한글 단어 단위의 커서 이동이나 한글 문자 삭제시 글자가 깨진다면 bash 셸에서 언어 환경을 한국어로 명시해 주자.


$ export LANG=ko_KR.eucKR


참고로 최근 들어 많은 배포판들이(특히 GNOME 데스크탑 환경에서) 한국어 환경의 한글 코드를 완성형에서 유니코드(utf-8)로 이동했다. 이런 경우는 굳이 앞의 encoding과 fileencoding 설정을 사용할 필요가 없으며 경우에 따라서 utf-8이나 korea를 상황에 맞게 설정해 주면 된다.

[로케일 설정]  
로케일(locale)은 리눅스 시스템의 언어 설정을 가리킨다. 요즘은 윈도우도 윈도우 2000, XP부터 하나의 윈도우에서 여러 나라의 언어를 모두 지원하는 추세가 확립되고 있지만 아직까지도 윈도우는 한글 윈도우와 영문 윈도우가 구분되어 출시되고 있다. 이에 반해 비영어권 사용자의 숫자가 초기부터 많았던 리눅스나 유닉스 계열 운영체제에서는 처음부터 일관된 방법으로 하나의 애플리케이션이 여러 나라의 언어를 쉽게 지원할 수 있는 프레임워크를 만드는 데 신경을 많이 써 왔다. 이러한 작업을 국제화(internationalization, i18n)라고 부른다. 참고로 국제화의 줄임말로 i18n을 쓰는 이유는 국제화의 i와 n사이에 18개의 글자가 있기 때문이라고 한다.

따라서 기본적으로 리눅스 시스템이나 배포판을 한글화한다는 얘기는 일단 리눅스 시스템의 언어 설정을 한국어로 해놓고 필요한 한글 메시지 번역이라든가 폰트 추가 및 설정과 같은 작업을 추가하는 것이 된다. 리눅스 시스템의 언어는 LANG 환경 변수를 통해 설정한다. 로케일 설정에는 LANG 변수 이외에도 여러 가지 다른 설정이 있지만 사용자 입장에서는 LANG 변수만 바꾸어 주면 전체 시스템의 언어가 바뀐다. 한국어의 경우 다음과 같은 LANG 셋팅을 많이 쓴다.

$ export LANG=ko_KR.eucKR

여기서 ko_KR.eucKR의 의미를 짚어보고 넘어가자. 맨 앞의 ko는 언어를 가리킨다. 한국어 이외의 언어를 몇 가지 예를 들어보면 en은 영어, de는 독일어, jp는 일본어를 의미한다. 그 다음 KR은 지역을 나타낸다. 비슷하게 KR은 한국, JP는 일본, US는 미국, CA는 캐나다, DE는 독일과 같은 예를 들어볼 수 있다.

그렇다면 LANG 환경변수 설정에서 왜 ko_KR과 같이 나라와 지역을 같이 쓸까? 그 이유는 같은 나라에서도 여러 가지 언어가 쓰일 수 있으며, 같은 언어라도 여러 나라에서 쓰이는 경우가 있기 때문이다. 일례로 미국에서의 영어는 en_US, 캐나다에서의 영어는 en_CA로 표기한다. 캐나다의 경우 fr_CA의 불어도 쓸 수 있을 것이다. 따라서 우리나라의 경우 ko_KR은 대한민국에서 쓰는 한국어가 된다. 북한은 이 원칙을 따른다면 아마도 ko_KP로 쓸 수 있을 것이다.

그리고 맨 마지막으로 eucKR은 인코딩 방법을 의미한다. eucKR은 현재 우리가 쓰고 있는 완성형 코드이다. 최근 들어 리눅스 배포판은 유니코드로 넘어가고 있는 추세인데 유니코드를 지원하는 리눅스 시스템에서는 내부적으로 이제 한글을 쓸 때에도 eucKR을 쓰지 않고 유니코드를 사용하고 있다. 유니코드로 한국어를 쓰려면 다음과 같이 로케일 설정이 바뀔 것이다.

$ export LANG=ko_KR.utf-8

참고로, 이런 로케일 설정은 요즘은 gdm이나 kdm과 같은 그래픽 화면 로그인 스크린에서 설정하는 것이 가장 편리하다. GNOME이나 KDE 로그인 스크린에서 언어를 선택하는 옵션이 그것이다.

마지막으로 지역화(localization, l10n)에 대해서도 잠깐 알아두자. 지역화의 줄임말인 l10n도 i18n과 같은 명명법을 따른 표기이다. 지역화는 국제화와는 달리 어떠한 프로그램이나 운영체제를 아예 특정 언어 전용으로 만드는 것을 의미한다. 리눅스 환경에서는 한텀과 같은 애플리케이션이 대표적인 예가 될 것이며, 윈도우의 경우는 한글 윈도우 98이 좋은 예가 된다. 지역화는 언어마다 각기 다른 애플리케이션이 만들어져야 하기 때문에 국제화보다 범용성이 떨어지는 편이며, 장기적인 개발비용을 줄이는 관점에서 국제화가 많이 권장되고 있다.

syntax highlighting
vim에서는 vi와는 달리 프로그램 소스 파일을 편집할 때는 여러 가지 색깔을 사용해서 소스코드 가독성을 높여주는 syntax highlighting 기능을 지원한다. syntax hightlighting 기능을 켜는 명령은 다음과 같다. 이 명령 역시 vimrc에 추가해 놓으면 편리하다.


:syntax on


참고로 언어에 따른 syntax hightlighting의 구체적인 설정은 /usr/share/vim 아래쪽의 설정 파일에서 다룬다. vim의 syntax highlighting 기능의 특징 중 하나는 화면 배경색의 밝기에 따라 syntax highlighting용 색상 구성을 다르게 쓸 수 있다는 점이다. 자신이 쓰고 있는 터미널의 배경색에 따라 다음 두 가지 중의 하나를 선택해 보자.


:set background=light 또는 :set background=dark


필자의 경우 흰색 배경의 한텀을 주로 쓰는 까닭에 light 옵션을 주로 쓰고 있다.

들여쓰기 설정
소스코드에서 탭 크기를 얼마로 잡을 것인지의 문제는 종종 게시판에서 플레임까지도 잘 번지는 주제이다. 소스코드의 탭 크기를 공백 8개로 할 것인가 아니면 탭 문자 하나로 둘 것인가, 만약 공백으로 처리한다면 4개로 할 것인가 8개로 할 것인가부터 시작해서 실로 다양한 스타일이 존재한다. 어느 경우든, 사용자의 입장에서는 탭 키를 한번 눌렀을 때 사용자가 원하는 쪽으로 들여쓰기가 알아서 된다면 무척 편리할 것이다.

우선, 자동으로 들여쓰기를 할 것인지 아닐 것인지를 설정해보자. 프로그램 소스코드를 짤 때는 블럭이 바뀌면 줄이 바뀔 때 마다 탭 키를 눌러 들여쓰기를 해야 하기 때문에 이 옵션을 켜 놓고 코딩을 하는 경우가 많다. 이 기능은 다른 vi에서도 작동한다.


:set autoindent 또는 :set ai


이 옵션을 해제하려면 다음과 같은 명령을 사용한다.


:set noautoindent 또는 :set noai


파일을 편집 중에 탭 키를 눌었을 때, 이것을 탭 문자 하나로 인식할 것인지, 혹은 디폴트 8개의 공백 문자로 인식할 것인지 설정하기 위해서는 expandtab 옵션을 설정한다.


:set expandtab 또는 :set et


이 때, vim에서 탭 문자 하나를 강제로 입력하려면 , tab의 조합을 누르면 된다. 는 컨트롤 문자를 vi에서 입력할 때 쓰는 명령키이다. expandtab 옵션을 해제하려면 앞의 경우와 마찬가지로 set noexpandtab 명령을 쓰면 될 것이다.

여기서(필자의 의견으로는) expandtab 옵션은 항상 켜놓고 탭 문자 하나를 여러 개의 공백 문자로 치환해서 사용하는 것이 좋다고 생각한다. 이렇게 작성한 소스코드는 어느 에디터에서 열어보더라도 똑같은 모습으로 들여쓰기가 잘 되어 있는 상태가 유지될 것이기 때문이다. 다만, 탭 문자의 들여쓰기를 공백 8개, 4개, 혹은 2개로 할 것인지에 대해서는 사람마다 취향이 다르고 프로젝트마다 스타일이 다를 수 있으며 그때 그때 상황에 맞추는 것이 좋다고 생각한다. tabstop 옵션은 vim에서 탭 문자 하나가 몇 개의 공백으로 보일 것인지를 설정할 때 사용한다.


:set tabstop=4     디폴트 값은 8이다. 약자로 set ts=4도 사용한다.


앞의 expandtab 옵션과 연계해서 생각해 보면, tabstop이 4로 설정되어 있고 noexpandtab 옵션이 설정되어 있다면 vim에서 탭 키는 탭 키를 누를 때마다 공백 4개의 폭으로 커서가 이동하고 내부적으로 탭 키는 누를 때마다 탭 문자 하나씩으로 인식하게 된다. 만약, 이렇게 편집한 파일을 다른 tabstop이 디폴트 8로 설정되어 있는 다른 vi나 기타 에디터에서 열어본다면 에디터가 탭 문자 하나를 8개의 공백 크기로 인식하는 바람에 소스코드가 완전히 다른 모습으로 보인다는 점을 고려해야 한다.

탭과 관련된 옵션으로 shiftwidth 옵션도 살펴볼 필요가 있다. shiftwidth 옵션은 들여쓰기를 할 때마다(탭 키를 누를 때마다가 아니라는 점에 유의하자) 몇 개의 공백 크기를 쓸 것인가를 설정해 준다. cindent 옵션과 같이 많이 쓰인다. tabstop과 gpt갈릴 수 있으므로 항상 tabstop 값과 같이 놓고 쓰면 편리하다.


:set shiftwidth=4 디폴트 값은 8이다. 약자로는 set sw=4를 쓴다.


C 소스코드를 작성할 때는 C 문법 스타일을 맞추어 주는 cindent 옵션을 켜놓으면 편리하다.


:set cindent


탭에 관해서 얘기가 조금 복잡해진 감도 있지만 간단히 정리를 해 보면 이렇게 생각해 볼 수 있다. 우선, 탭 문자를 여러 개의 공백 문자로 치환할 것인지 혹은 탭 문자를 있는 그대로 하나로 쓸 것인지 결정하는 것이 중요하다. 그리고 일단 여러 개의 공백 문자를 쓰기로 결정했다면 tabstop 값과 shiftwidth 값을 일치시켜서 혼동을 없애는 편이 좋으며, 반대로 탭 문자를 그대로 사용하겠다면 다른 에디터와의 호환 여부를 고려할 필요가 있다. 필자가 쓰는 탭 관련 설정은 다음과 같다.


모든 탭을 공백 4개로 설정한다.
set tabstop=4
set shiftwidth=4
set expandtab

set autoindent


다중 윈도우 사용
원래 vi는 다중 윈도우를 연다든가, 여러 개의 파일을 동시에 편집하는 기능이 들어 있지 않았다. emacs가 에디터 내에서 에디터 이상의 기능을 수행할 수 있는 통합 환경이라면 vi는 심플한 유닉스의 초기 설계 철학을 닮은 에디터라고 볼 수 있다. 하지만 vim의 추가 기능 중 다중 윈도우나 복수 개의 파일 편집 기능은 상당히 편리하며 널리 쓰이고 있다.

다중 윈도우 기능은 요즘 아래아한글이나 MS 워드에서도 손쉽게 볼 수 있다. 마우스로 오른쪽 스크롤바 위쪽의 핸들을 아래로 주욱 잡아당기면 파일 하나에 화면이 2개 생기는 것을 볼 수 있다. vim에서는 화면을 나누기 위해서는 split 명령을 사용한다. vsplit 명령을 쓰면 화면을 세로로 나눌 수도 있다.


:split 줄여서 sp로 쓴다


이 상태에서 , w 키를 차례로 누르면 커서가 다른 화면으로 이동하게 된다. 다음에 j 키를 누르면 아래 화면으로 이동하게 되고, 다음에 k 키를 누르면 윗 화면으로 이동하게 된다(h, j, k, l 모두 사용 가능하다). 여기서 화면 하나를 닫기 위해서는 , c 명령키나 close 명령을 사용한다.


:close 줄이면 cl로 쓴다


여러 개의 파일을 동시에 편집
이제 화면을 둘로 나누면서 새로운 파일을 편집해 보자.


:new


new 명령을 내리면 같은 파일을 두 개의 윈도우에서 같이 편집하던 아까의 split 명령과는 달리, new 명령으로 열린 윈도우는 완전히 새로운 파일을 편집하게 됨을 볼 수 있다. :new 과 같이 파일명을 명시해 줄 수도 있다. 이제 vim에서 화면을 윈도우로 나누지 말고 복수 개의 파일을 편집하는 방법을 알아보자. vim에서는 여러 개의 파일을 편집하기 위해 다음과 같이 vim을 실행하는 것이 가능하다.


$ vi hello.c hello.h main.c


파일을 전환하기 위해서는 다음 명령을 사용한다. 다음과 같이 간단히 정리해 보았다.


이동 : next (:n) - previous (:prev)
저장 후 이동 : wnext (:wn) - wprevious (:wp)


현재 커서가 위치하고 있는 파일 정보와 다른 파일들의 리스트를 보기 위해서는 :args 명령을 사용한다. 현재 편집 중인 모든 파일을 저장하는 :wall 명령어도 자주 사용된다.

[bash 셸에서 vi 키 사용하기]  
대부분 리눅스 배포판에서 기본 셸로 쓰고 있는 bash는 기본적으로 emacs 스타일의 편집키를 지원한다. 하지만 bash에서는 vi 편집 모드도 지원한다.

아마도 대부분의 리눅스 사용자들은 셸을 쓰면서 조금 전에 입력한 명령어로 다시 돌아가기 위해 직관적으로 위쪽 화살표 키를 누르는 습관이 있을 것이다. 이렇게 셸에서 명령어 history 기능을 이용하는데 오른쪽으로 손을 뻗어야 하는 불편이 있는 위쪽 화살표 키 말고 다른 키를 쓸 수도 있다. 이것이 bash에서는 emacs 스타일의 편집키를 쓸 수도 있고 vi 스타일의 편집키를 쓸 수도 있도록 되어 있다. bash 역시 GNU 프로젝트의 영향이 큰 까닭에 아무래도 디폴트는 emacs 스타일로 맞추어져 있다. emacs에서 위쪽 화살표에 해당하는 키는 이다. 개인적인 편차가 있겠지만 필자의 경우는 위쪽 화살표 키에 손을 뻗기보다는 그냥 <ctrl+p>를 누르는 편이 훨씬 편리하고 손목에 부담을 적게 받는다. 이제 vi 모드로 bash를 써 보자. vi 모드를 켜는 명령은 다음과 같다. .bash_profile에 넣어두고 써도 된다.

$ set -o vi

혹은 /etc/inputrc나 .inputrc에 다음 설정을 사용해도 된다.

set editing-mode vi
set keymap vi

이후로는 셸 프롬프트에서 esc 키를 누르면 vi의 명령어 모드로 진입한 것처럼 vi 편집키가 작동한다. 이제 위쪽 화살표 대신에 k 키를 쓸 수 있게 된 것이다. 추가로 자주 쓰는 cw와 같은 명령어를 사용해 보자.

굳이 vi 모드로 bash를 쓰지 않더라도, bash의 기본 설정인 emacs 스타일의 편집키는 항상 사용하는 습관을 들여 보자. emacs에서 커서 상하좌우 이동키는 각각 <ctrl+p>, <ctrl+n>, <ctrl+f>, <ctrl+b>이다. 여기에 Home에 해당하는 <ctrl+a>와 end의 <ctrl+e>까지라도 알아두자. emacs 편집키 역시 타이핑을 할 때 손목의 피로도를 줄일 수 있을 뿐만 아니라 다른 프로그램, 특히 GNU 계열의 응용 프로그램에서 디폴트로 많이 쓰인다.

참고로 이렇게 하나의 유틸리티에서 쓰는 명령어를 다른 곳에서도 그대로 지원해서 좀 더 사용자가 새로운 프로그램을 쉽게 쓸 수 있게 해주는 방식이 유닉스에서는 특히 많이 보이는 편이다. 간단한 예로, 페이지 단위로 텍스트 파일을 출력시켜 주는 more 프로그램에서는 스페이스바를 누르면 다음 페이지로 넘어가게 되는데 유닉스 환경에서는 스페이스바를 누르면 다음 페이지로 넘어가는 프로그램들이 한둘이 아니다. 심지어는 윈도우의 대표 브라우저인 인터넷 익스플로러도 스페이스바를 누르면 다음 페이지로 넘어간다. 인터넷 익스플로러가 오래된 유닉스의 모자이크(Mosaic) 브라우저의 소스코드를 기반으로 하고 있기 때문이다. 모질라 브라우저 역시 스페이스바를 누르면 다음 페이지로 넘어간다.

이런 이유로 유닉스를 쓰면서 vi와 emacs의 편집키는 적어도 둘 중 하나는 외워두는 것이 상식이다. 이들 편집키는 vi나 emacs를 벗어난 환경에서도 많이 쓰이며, 실제 사용해보면 무척 편리하다.


자신에게 맞는 편집기를 선택하자
이번 호에서는 리눅스의 대표적인 편집기인 vim에 대해서 알아보았다. 실제, 여러 설문조사 결과를 보면 리눅스 환경에서는 emacs 사용자와 vi 사용자가 대략 50대 50의 비율을 나타내고 있다. emacs를 쓸 것인지 vi를 쓸 것인지는 사용자의 선택이다. emacs는 편집기 이상의 기능을 발휘하는 통합 환경인 반면 vi는 작으면서도 기능이 강력한 편집기로서의 특성을 보인다. 필자 개인적으로는 vi를 주로 사용하고 emacs는 잘 쓰지 않는 까닭에 이번 기사에서는 emacs를 다루지 않았지만, vi 대신에 emacs를 사용하는 것도 좋은 선택임을 강조해 보고 싶다.

다음 호에서는 오픈소스 개발에서 많이 쓰이는 diff, patch부터 시작해서 cvs의 사용법을 리뷰하고 최근의 오픈소스 환경에서 중요하게 부상하고 있는 경향을 몇 가지 추가해 보기로 하겠다.


리눅스 시스템 관리자가 되기 위해서는 많은 것을 알아두어야 한다. 시스템 관리자의 관리 여하에 따라 많은 사람들의 시스템 장애를 초래할 수 있기 때문이다. 물론 시스템 관리자가 모든 것을 미리 예방할 수는 없다. 하지만 불가피한 상황을 제외하고는 시스템이 정상적으로 작동되도록 해야한다.

이번 호에서는 시스템, 네트워크, APM, 메일, 보안, 장애 발생시 복구 등에서 일어날 수 있는 시스템 관리자의 행동요령에 대해 알아볼 것이다. 시스템 관리자는 항상 모니터와 키보드와 함께 한다는 사실을 기억해야 한다.

막강한 시스템 길들이기

시스템이 네트워크에 연결되어 있다면, 다음과 같이 한국 표준시간 서버에서 표준시간을 받아서 설정할 수 있다.

# rdate -s time.kriss.re.kr

시스템이 온라인 상태가 아니라면 아래와 같이 수동으로 설정할 수도 있다.

# date -s ?1999-12-30 22:22:40?

위와 같이 실행하면 실행할 때만 적용되므로 이후 시간이 늦어지는 것을 막기 위해서는 주기적으로 변경 가능하게 크론(/etc/crontab)에 설정하는 것이 좋다.
.profile은 로그인시 적용되는 내용들이고, rc.local은 시스템 부팅시 실행해야 할 것들을 적어 놓은 것이다. 사용자 홈디렉토리의 .profile이 /etc에 있는 설정 파일보다 우선하기 때문에 홈 디렉토리에 .profile에 패스를 설정해주거나 쉘 환경 파일 등을 설정해 주면 계정 내에서 적용이 된다.rc.local에는 부팅시 가장 마지막에 실행되므로 일반적으로 부팅시 실행되어야 할 데몬 등을 적어준다.

리눅스 시스템의 자원 정보는 proc 파일시스템 구조를 통해서 알 수 있다. 이는 실제로 디스크 용량을 차지하는 파일들이 아닌 가상의 디렉토리 구조이며 리눅스 커널에 의해 사용되는 시스템의 정보를 담는 곳으로 사용된다. 다음의 위치에서 하드웨어에 대한 정보 및 시스템 관련 정보들을 확
인할 수 있다.위와 같이 관련된 정보에 해당하는 파일 이름이 존재한다. 이 파일들은 텍
스트 포맷이므로 cat 명령을 통해서 확인할 수 있다

^M 문자를 공백으로 치환하면 된다.

:1,$s/^M//g

# rpm -qa | grep 패키지 명으로 확인할 수 있다.


rpm2cpio filename.rpm | cpio -I -make-deretories -E filename

Tcp Syn Flooding은 웹으로의 공격이 대부분이므로 syn_recv 프로세스가 일정 개수가 넘게 되면 아파치를 재시작한다. 지속적인 공격일 경우 대처 방안으로 두 가지 방법이 있다.
첫째, sysctl -a |grep syn_backlog으로 확인 후 backlog를 늘려주거나

둘째, sysctl -a |grep syncookies로 확인 후 syncookies의 값을 1로 바꾸어준다.

syn_backlog의 값을 조정해주는 방법은 다음과 같다.

# sysctl -w net.ipv4.tcp_max_syn_backlog=1024
# echo 1024 > /proc/sys/net/ipv4/tcp_max_syn_backlog

syncookies의 값은 다음과 같이 변경이 가능하다.

# sysctl -w net.ipv4.tcp_syncookies=1

Umount시 위와 같은 메시지가 나는 것은 unmount하려는 디렉토리에서 실행되고 있는 프로세스가 있기 때문이다. 예로 /tmp 디렉토리를 umount시키려 할 때 위의 메시지가 뜨는 경우 mysql. socket파일이 /tmp에 있는 경우를 들 수 있다. 이 경우에는 해당 파일시스템에서 실행중인 프로세스를 제
거해야 하나 일일이 제거가 번거로우므로 Fuser에서 -k 옵션을 사용하면 간단히 해결할 수 있다.

Fuser -km 장치명

디렉토리나 파일 퍼미션 중 setuid는 소유자의 권한을 잠시 빌려 실행 후 권한을 돌려주고 실행을 마치게 되는데 실행도중 인터럽트가 발생한다면 정상적으로 권한을 반환하지 못하게 되어 소유자의 권한을 그대로 가지고 있게 된다. 이때 파일의 소유자가 루트였다면 이것은 보안에 문제가 될 수 있으며 이런 점을 이용해 해킹에 많이 사용된다. Setuid가 걸려 있는 파일 중에 실행권한이 있으며 루트권한일 경우에는 위험하다.

특정 디렉토리에서 setuid가 걸려있는 파일을 찾으려면 find /usr -perm 4755와 같이 perm 옵션으로 찾을 수 있다.

다음과 같이 ~/.bash_profile를 실행해서 변경이 적용되도록 한다.

# source ~/.bash_profile

리눅스 시스템을 재부팅하고 lilo가 뜨면 ‘linux single’로 부팅한다.
Tab 키를 누르면 등록되어 있는 라벨이 모두 보이므로, 여기에서 선택하도록 한다. 부팅 후 쉘 명령어 화면에서 /etc/passwd 파일에서 암호 부분을 삭제하거나 passwd를 실행하여 루트의 패스워드를 새로 설정해 준다.

# passwd root

위의 명령을 입력한 후 변경할 패스워드를 입력하면 된다.

보통 파티션을 나누는 것에 대해서 별다른 고려 없이 /로 모든 것을 잡아서 설치하는 경우가 종종 있다. 이럴 경우 설치시 편리하지만, 나중에 파일시스템에 문제가 생기거나 효율적으로 파티션을 관리하기에는 많은 어려움이 있다. 파티션을 나눌때는 어떤 용도로 쓸 것인지에 대해서 충분히 생각한 후 파티션을 해야 한다. 다음은 9.1GB 스카시 하드디스크를 기준으로 웹 서버에 이용될 서버에 대해 파티션한 경우의 예다.
/var 디렉토리와 같이 항상 새로운 자료가 쌓이는 곳은 안전성이 우선시 되므로, ext3 파일시스템이 유리하며, /usr와 같이 내용 변화 없이 빠르게 액세스하여 쓸 수 있어야 하는 부분은 ext2 시스템을 이용하여 성능에 초점을 두면 좋을 것이다.

1024KB인 경우에는 블럭이 작은 만큼 4096KB보다 하드의 낭비가 적다.
1023KB의 데이터를 저장하는 경우, 기본 블럭사이즈가 1024KB일 때는 1K 공간이 사용되지만, 4096KB가 기본 블럭이라면 4K를 차지하게 된다. 하지만 아주 작은 파일들이 많은 경우 해당 데이터를 액세스하는 데는 1024KB가 4096KB보다 더 걸리게 되므로 퍼포먼스가 급격히 떨어지게 된다. 따라서 자신이 이용하는 시스템의 특성과 용도에 맞게 블럭 사이즈를 지정해서 사용하면 된다.

RAID는 ‘Redundant Array of Inexpensive (or Independant) Disks’의 약어다. RAID 시스템은 여러 드라이브의 집합을 하나의 저장장치처럼 다룰 수 있게 하고, 장애가 발생했을 때 데이터를 잃어버리지 않게 하며 각각에 대해 독립적으로 동작할 수 있도록 한다.

시스템의 다운, 데이터 손실에 대비하여 보통 여러 가지 RAID 레벨 중에서 1과 5번 방법을 많이 사용한다.
RAID 1(mirroring)의 특징은 빠른 기록 속도와 함께 장애 복구 능력이 있다는 것이다. 2대의 드라이브만으로 구성할 수 있기 때문에 작은 시스템에 적합하다. 읽을 똑같은 하드가 복제되고 있으므로, 시스템에 문제 발생시 서비스 지연 시간이 매우 짧아서 웹 서비스를 하는 곳에서 유용하게 쓸 수 있다. 하지만 한 하드의 내용이 또 다른 하드에 똑같이 복사되므로 하드용량의 낭비가 심하다.
RAID 5(distributed parity)는 작고 랜덤한 입출력이 많은 경우 더 나은 성능을 제공한다. 빠른 기록 속도가 필수적이지 않다면, 일반적인 다중사용자 환경을 위해 가장 좋은 선택이다. 그러나 최소한 3대, 일반적으로는 5대 이상의 드라이브가 필요하다. 변경된 내용이 있을 경우 그것만 기록한다. 일반적으로 RAID 1은 ECC 계산을 하지 않으므로 RAID 5보다 빠르고, raid5는 하드 공간을 좀 더 여유있게 쓸 수 있다는 장점을 지닌다.

먼저 시스템의 전체 용량이 어떻게 되고, 그 중에서 백업할 가치가 있는 것은 어떤 부분인지를 결정한다. 사용할 백업 장비와 종류를 알아보고, 총 백업 시간과 어느 정도 부하가 걸리는지 예상해보고 테스트 해 본 후 마지막으로 백업 스케줄을 정한다. Full 백업은 백업할 자료를 처음부터 끝까지 다 기록하는 것이고, Incremental 백업은 이전의 데이터와 비교해서 새로 추가된 내용만 백업하는 방법이다. 따라서 Full 백업시 완전히 데이터를 백업할 수 있지만 시간이 많이 걸리고, 시스템에 부하를 초래할 수 있는 반면에 Incremental 백업은 빠른 시간내에 백업을 할 수 있지만, 백업하는 시간에 따라 데이터가 완전히 백업되지 못할 경우도 있을 수 있다.

SNMP는 ‘Simple Network Management Protocol’의 약자다. 네트워크에 연결되어 있는 장치에서 네트워크에 관련된 정보를 모으고 문제점 등을 보고할 수 있는 기능을 제공하는 프로토콜이다. 구성 요소는 에이전트와 매니저가 있다. 이것은 서버/클라이언트 구조로서 에이전트가 서버에 해당되고, 매니저가 클라이언트에 해당한다. 에러가 발생하는 경우는 선택한 장비에 SNMP가 Enable이 안 되었거나, 네트워크에 문제가 있어서 모니터링 하려는 장비까지 프로토콜이 전송되지 않는 경우, community 값이 잘못 사용된 경우 등이 있다.

/etc/rc.d/init.d이 디렉토리에 있는 서비스를 ‘서비스명’ stop 또는 start 시키거나 재시작시킨다.

quota를 이용하면 된다. df 명령으로 사용자의 홈디렉토리가 있는 디바이스를 확인한다.

ilesystem 1k-blocks Used Available Use% Mounted on
/dev/sda5 3028080 878480 1995780 31% /
/dev/sda1 62217 7713 51291 13% /boot
/dev/sda6 2759260 2088820 530276 80% /home2
/dev/sdb1 8744304 6496724 1803388 78% /home3
/dev/sdc1 35296928 25597968 7905940 76% /home4
/dev/sda10 202220 6 191774 0% /tmp
/dev/sda7 1517920 1280648 160164 89% /usr
/dev/sda8 608724 426992 150812 74% /var
# edquota username
Quotas for user jhk1:
/dev/sda6: blocks in use: 47584, limits (soft = 0, hard = 0) /* 이 부
분에 설정 */
inodes in use: 4590, limits (soft = 0, hard = 0)
/dev/sda8: blocks in use: 4, limits (soft = 0, hard = 0)
inodes in use: 1, limits (soft = 0, hard = 0)

Soft는 용량에 설정되어 있는 용량은 넘어도 어느 정도 여유가 있지만, hard 용량에 설정된 크기는 절대적이다.

따라서 hard 용량을 사용자는 넘을 수 없다. 일반적으로 soft 용량을 hard 용량보다 조금 더 적게 설정해 놓는다. 쿼터 조정후 quotacheck /dev/sda6를 해줘서 체크를 해 주도록 한다.

파일명이 하이픈(-)으로 시작하는 파일

rm ./-filename 상대경로를 이용하여 파일명을 지정해줌
rm -- -filename --를 이용 그 이후에 오는 '-filename'이라는 파일이 옵션이 아닌 파일이라는 것을 밝힘

/etc/inittab에서 사용하지 않은 가상콘솔 레벨을 주석처리 해주면 된다.

# Run gettys in standard runlevels
1:2345:respawn:/sbin/mingetty tty1
2:2345:respawn:/sbin/mingetty tty2
3:2345:respawn:/sbin/mingetty tty3
#4:2345:respawn:/sbin/mingetty tty4
#5:2345:respawn:/sbin/mingetty tty5
#6:2345:respawn:/sbin/mingetty tty6


먼저 psacct라는 패키지가 필요하다. 설치되지 않은 경우 rpm이나 소스 등을 직접 설치 한다(대부분 배포본에 기본적으로 포함되어 있으므로 그대로 사용하면 된다). 다음과 같이 명령하면 사용한 명령어를 확인할 수 있다.

더미 로그 파일 생성(데이타를 기록할 파일 생성)
# touch /var/log/pacct
# /sbin/accton /var/log/pacct 체크를 시작하게 하는 명령어 실행
# lastcomm 사용자계정 사용자가 수행한 명령어 체크 */
tar xvfpz 압축파일 또는 .tgz -C 특정경로 특정 파일의 절대경로(또는 파일명)로 입력하면 된다. test.tgz 파일에서 /home/test /test.txt파일을 /tmp 디렉토리에 압축해제를 한다면, tar xvfpz test.tgz -C /tmp /home/test/test.txt와 같이 하면 된다.

TTL이란 Time To Live의 약자다. 이것은 라우팅 에러로 인하여 데이터그램이 네트워크를 영원히 떠돌아다니는 것을 방지한다. 라우터는 네트워크 간을 이동하는 데이터그램의 TTL 필드를 감소시키며 TTL 필드가 0이 되는 데이터그램은 버린다(drop). IPv4 멀티캐스트에서 TTL은 문턱값(threshold)의 의미를 지닌다.
다음 예를 보면 그 용도가 분명해진다. 회사에서 모든 호스트가 속하는 아주 길고 대역폭에 한 부서가 대역폭을 많이 차지하는 인터넷 방송을 한다면, 랜에는 엄청난 용량의 트래픽이 발생할 것이다. 인터넷 방송도 하길 원하지만, 멀티캐스트 트래픽 때문에 인터넷 전체가 마비되어서는 안된다. 멀티캐스트 트래픽이 라우터간을 얼마나 멀리까지 이동할 수 있도록 할 것인지 제한할 필요가 있다. 이것이 TTL의 용도다.

TCP Wrapper를 사용하는 방법과 ipchains를 사용할 수 있는데 커널 2.4 버전부터는iptables을 사용한다. hosts.allow와 hosts. deny를 사용한다면, hosts.deny 파일에서 다음과 같이 모두 제한을 한다.

all : ALL

hosts.allow 파일에서 허용할 IP를 여러 개 설정할 경우 다음과 같이 스페이스로 구분하여 준다.

all : xxx.xxx.xxx.xxx xxx.xxx.xxx.xxx xxx.xxx.xxx.xxx ....

ipchains나 iptables의 경우에는 다음과 같이 설정하여 주면 된다.

# ipchains ?A input ?s xxx.xxx.xxx.xxx ?j DENY
# iptables ?A INPUT ?s xxx.xxx.xxx.xxx ?j DROP

안전한 네트워크 다지기

시스템에 기본적으로 설치된 아래의 명령들을 사용하여 네트워크가 정상적으로 작동하지 않는 경우 여러 가지 테스트를 해볼 수 있다.
/etc/sysconfig 디렉토리 밑에 하드웨어에 대한 정보가 나오는데 이더넷 카드가 여러 개 꽂혀 있다면 ifcfg-eth1, ifcfg-eth2 식으로 확인할 수 있다.

/etc/sysconfig/network-scripts/ifcfg-eth0

#cat ifcfg-eth0
DEVICE=eth0
BOOTPROTO=static /* 정적 아이피 */
BROADCAST=211.47.64.255
IPADDR=211.47.64.80
NETMASK=255.255.255.0
NETWORK=211.47.64.0
ONBOOT=yes /* 부팅시 자동인식 */

사용하는 IP를 변경하거나, 새로운 네트워크 카드 추가시에는 ifcfg-eth0 파일을 수정한 후에 반드시 ifdown ifcfg-eth0, ifup ifcfg-eth0 명령을 실행해 주어야 변경된 IP가 적용된다. 또는 /etc/rc.d /init.d/network restart를 실행해 주어도 된다.

Apache + PHP + MySQL

아파치에만 적용되는 내용은 아니지만 standalone으로 설정할 경우에는 /etc/rc.d/rc.local나 /etc/rc.d/rc3.d/밑에 설정되어 데몬으로 실행되며, inetd로 설정할 경우 /etc/inetd.conf에 추가되어 실행되어 텔넷이나 FTP와 같이 시스템 프로세스로 실행되므로 접속이 많은 httpd 인 경우standalone으로 설정하여야 한다. 그리고 inetd로 설정시에는 한정된 프로세스만 수용 가능하며 반응속도가 standalone 방식에 비해 느리다.

httpd -t 옵션으로 우선 syntax error부터 확인한 후 syntax error가 있으면 먼저 수정을 해주고 Logs 디렉토리에서 에러 로그 파일을 확인하여 수정 후 재실행한다.

php3 버전의 경우 index.php3을 php4의 경우 index.php라는 파일을 다음과 같은 내용으로 작성하여 웹에서 열어보면 버전 및 연동 현황을 확인할 수 있다.

phpinfo();

먼저 php설치 후 apache 컴파일시 php 모듈 넣어서 재컴파일 해준다.
./configure --prefix=/usr/local/apache --activate-
module=src/modules/php4/libphp4.a

아파치에서 bandwidth 모듈이 삽입되어 있는 상태라면 모든 호스트에 대해 1024byte로 속도를 제한하기 위해 아파치에서 설정해 주는 부분은 다음과 같다. Httpd.conf에서 BandWidthModule On라고 설정 후 BandWidth all 1024라고 설정한다.

아파치에서 index.html 파일이 없을 때 디렉토리 목록 출력을 원하지 않을 경우에는 DocumentRoot 디렉토리쪽에 설정되어져 있는 옵션에서 Indexes를 삭제한다. 또한 특정 디렉토리에서만 인덱스를 허용치 않을 경우에는 특정 디렉토리의 .htaccess 파일안에 ‘Options -Indexes’ 이 부분을 삽입하면 된다.

안전한 메일 관리법

센드메일에서 한번에 보낼 수 있는 메일 용량은 /etc/mail /sendmail .cf 파일에서MaxMessageSize 부분에서 다음과 같이 주석을 제거하고 바이트 단위로 설정을 해줄 수 있다. 받는 메일 계정의 용량은 Mlocal 부분에서 M=1000000 부분에서 바이트 단위로 제한량을 적는다.

MaxMessageSize=1000000

relay를 막는 방법도 있지만 그건 외부에서 로컬 서버를 SMTP로 사용하지 못하도록만 할 수 있으며 iptables를 이용하면 로컬 서버에서 보내는 메일에 대해 제한이 가능하다.

# iptables -A OUTPUT -p tcp --syn --dport 25 -j DROP

-A 기존의 iptable에 추가
-p 프로토콜
-dport 포트 넘버
로컬에서 외부로 보내는 메일이라면 remote의 25번 포트로 접속이 되므로 OUTPUT 패킷 중 목적지 포트가 25번인 패킷만 drop 한다. 메일 송수신은 tcp이므로 --syn을 추가하지 않을 경우에는 3 way-handshaking에 의해 메일을 받을 수도 없게 되므로 반드시 --syn을 추가해야 한다. 보내는 메일은 일단 메일큐 디렉토리에 저장된 후 발송되므로 메일큐 디렉토리를 삭제하거나 다른 이름으로 변경하면 메일을 발송할 수 없게 된다.

/etc/mail/access 파일에서 Relay 여부를 설정한다.

localhost RELAY

변경한 후 적용하려면 다음과 같이 실행해 준다. 또는 인증 기능(SMTP AUTH)이 지원되는 최신 버전의 센드메일을 사용한다.

# makemap hash /etc/mail/access < /etc/mail/access

간단한 방법으로 다음과 같이 텔넷으로 센드메일 포트인 25번으로 접속해 보면 알 수 있다

# telnet jimmy.tt.co.kr 25

가상 계정을 이용해서 해결할 수 있다. 아웃룩에서 jhk라는 계정을 설정하면 jhk at jungheekim.co.kr, webmaster@jungheekim.co.kr로 오는 메일을 모두 받아 볼 수 있다.

# vi /etc/mail/virtusertablewebmaster at jungheekim.co.kr jhk(jhk계정에webmaster라는 계정이 가상계정으로 설정)

해외에 출장이 잦은 사용자가 메일을 자신이 사용하는 웹메일로 포워딩해 달라고 하고, 회사에 돌아와서도 포워딩된 메일을 아웃룩에서 다시 받아보길 원한다면 다음과 같이 한다. 해당 사용자의 홈디렉토리 밑에 .forward 파일을 만들어서 이메일 주소를 입력하고 자신의 계정에는 \를 추가해 주어야 루프를 막을 수 있다.

vi ~junghee/.forward
sitsme75 at hanmail.net, junghee.kim at tt.co.kr

메일을 확인할 수 없는 상황일 때, 메일 수신 후 자동으로 미리 작성되어 있는 메시지를 보낼 수 있는 방법(즉 자동응답 메일 작성 방법)은 자신의 홈디렉토리에 “.procmailrc” 파일을 만들고 다음의 내용을 입력한다.

-------------------------------------------
:0 h c
* !^FROM_DAEMON
* !^X-Loop: YOUR@EMAIL
| (formail -r -A"Precedence: junk"
-I"From: YOUR_NAME "
-A"X-Loop: YOUR@EMAIL
cat $HOME/autoreply.txt) | $SENDMAIL -t
--------------------------------------------
그리고 ‘autoreply.txt’ 파일에 답변 글을 작성하면 그 내용이 자동 답변된다.

아웃룩에서 메일을 받아보려고 하는데, POP3가 다운되어 반응하지 않을 때 다음과 같이 조정한다. inetd는 기본적으로 1분에 fork 할 수 있는 인스턴스가 40으로 제한되어 있으므로 이 값을 늘려줘야 한다. POP3 부분에서 nowait.200이나 적절한 수만큼 늘려주면 된다. nowait 뒤에 반드시 .(점)을 찍고 허용할 만큼의 POP 데몬의 수를 입력한다. 이후 inetd를 재시작하면 적용된다.

A # vi /etc/inetd.conf
# Pop and imap mail services et al
#pop-2 stream tcp nowait root /usr/sbin/tcpd ipop2d
pop-3 stream tcp nowait root /usr/sbin/tcpd ipop3d
#imap stream tcp nowait root /usr/sbin/tcpd imapd


철통 보안 관리

① 현재 서버에서 사용하지 않고, 보안상 취약점이 있는 데몬에 대해 서비스를 중지한다.
② TCP Wrapper와 ipchains를 이용한다. 커널 2.4에서는 iptables를 이용해 각 서비스에 대해서 접속을 허락하거나, 제한한다.
③ 섀도우 패스워드를 반드시 이용한다.
④ su 권한의 사용을 특정 사용자만 가능하도록 정의한다.
⑤ 원격에서 루트 권한으로 접속할 수 없도록 한다.
⑥ 지속적으로 패치한다.


echo 1> /proc/sys/net/ipv4/icmp_echo_ignore_all

다시 응답하게 하려면 다음과 같이 실행하면 된다.

echo 0> /proc/sys/net/ipv4/icmp_echo_ignore_all

보통 백도어 파일은 rm 명령으로도 삭제되지 않는다. 속성이 있을 경우 다음과 같이 삭제 한다.

# lsattr /usr/sbin/in.fingerd
lsattr 1.12, 9-Jul-98 for EXT2 FS 0.5b, 95/08/09
-----a-- /usr/sbin/in.fingerd
==> a 속성이 있음을 확인

chattr -a /usr/sbin/in.fingerd
chattr 1.12, 9-Jul-98 for EXT2 FS 0.5b, 95/08/09
==> -a로 속성을 해제

# lsattr /usr/sbin/in.fingerd
lsattr 1.12, 9-Jul-98 for EXT2 FS 0.5b, 95/08/09
-------- /usr/sbin/in.fingerd
==>해제

lpd는 내부와 원격 프린트 작업을 수행하는 BSD 라인 프린터 데몬이다.
lpd 데몬의 접근 권한을 가지고 있는 내부 시스템이나 원격 시스템의 사용자가 특별히 변형된 불완전한 프린트작업을 요청하고 이어서 프린터 큐의 디스플레이를 요청하게 되면 해당 시스템에 버퍼 오버플로우를 일으킬 수 있다. 결국 관리자 권한으로 내부 시스템에 공격 코드를 실행시킬 수 있게 된다. 따라서 패치를 해주거나 서비스를 하지 않는다면 데몬을 중지하
는 것이 좋다.

BIND 4.x, 8.x에서 문제가 검출되었다. BIND 8 버전에서는 트랜잭션 시그너쳐(TSIG) 핸들링 코드에 버퍼오버플로우 취약점을 포함하고 있다.유효한 키를 포함하지 않는 TSIG를 발견하는 경우 BIND 8 버전에서는 에러응답을 보내기 위한 코드를 실행하게 되며, 이때 발생하는 변수 초기화 방식의 차이에 의해 해당 취약점이 발생하게 된다. DNS 시스템에 대한 요청 접근만으로 해당 취약점을 발생시킬 수 있으므로 이로 인한 위험성은 크게 된다.


BIND 4 버전에서는 nslookupComplain( ) 내부에 있는 문자 배열(syslog 를 위한 에러 메시지 작성 버퍼)에 대해 버퍼 오버플로우 취약점을 포함하고 있다. 특수한 포맷 형태를 가진 쿼리를 전송함으로써 해당 취약점을 발생시킨다.
또한 nslookupComplain( ) 내부에 있는 문자 배열(syslog를 위한 에러 메시지 작성 버퍼)에 대해 입력 검증(input validation) 취약점을 포함하고 있다. 이것은 특수한 포맷 형태를 가진 쿼리를 전송함으로써 입력 검증 취약점을 발생시킨다.


BIND 4,8 버전에서는 해당 서버가 쿼리를 처리하는 동안 정보가 누출(information leak)될 수 있는 취약점을 포함하고 있다. 특수한 포맷 형태를 가진 쿼리 전송을 통해 공격자가 프로그램 스택에 접근할 수 있게 함으로써 해당 취약점을 발생시킨다. 해결책은 BIND 버전은 8.2.3 이상이나 9.1버전으로 업그레이드하는 것이다. 이것은 해결책이 아니라 시스템 관리자가 반드시 해야 할 일이다.

장애 발생시 복구

대부분 정전이 발생한 후에도 시스템은 정상적으로 부팅되며 파일시스템도 자동으로 check하지만 간혹 관리자가 수동으로 해주어야 하는 경우가 발생한다. 리눅스가 다운 되었을때 보통 Power OFF를 하는데, 이때 문제가 발생할 수 있으므로 Magic SysRq라는 것을 이용하여 안전하게 재부팅하는 방법을 이용한다.
Magic SysRq key란 시스템의 제어가 불가능한 상태(일반적으로 ‘다운’되었다고 한다)에서도 제어를 가능하게 해주므로 커널 컴파일시 Kernel hacking ---> [*] Magic SysRq key를 체크해야 한다. Magic SysRq key를 사용하려면 다음과 같이 /proc/sys/kernel /sysrq 값을 1로 만들어야 한다.

# echo 1 > /proc/sys/kernel/sysrq
lilo: linux init=/bin/sh

그러면 커널이 뜨고 나서 바로 shell prompt ‘#’가 나타난다. 이때에는 filesystem도 read only로 마운트 되고, 동작하는 deamon process도 전혀 없는 상태가 된다. 그 상태에서 수동으로 모든 파일 시스템을 체크한다.

# fsck [-t ext2] 장치명
# e2fsck 장치명

위의 명령 사용시 문제가 생긴 블록의 수정 여부를 묻게 되는데 ‘y’를 선택하고 만약 수정여부를 묻는 질문이 많다면 -y 옵션을 사용하여 자동으로 ‘y’를 선택하게 할 수 있다.

# e2fsck -y 장치명

Ctrl-Alt-Del로 리부팅하면 아주 심하게 깨지거나, 디스크에 이상이 있지 않는 한 복구가 된다.


SENDMAIL 의 가상 계정은

/etc/mail/virtualtable

를 수정하고 업데이트 시켜 주면 된다.

호스팅 하는 곳에 가면 webmaster@도메인

으로 많은 계정을 발급해 주는 사람들을 보았을 것이다.

이경우에 위의 파일을 수정한다. 아래와 같이


이메일@도메인 [탭] 머신의 실제 아이디

ex) webmaster@userdomain.co.kr kayaprince
webmaster@mydomain.co.kr kjh0523

이렇게 작성하고 파일을 저장하고 빠져 나와서

반드시 다음은 해 주어야 한다.

makemap hash virtualtable < virtualtable

그리고 메일 서버를 리스타트 해준다.

/etc/rc.d/init.d/sendmail restart


페도라 코어 5 설치기...#2(웹서버구축 APM)


리눅스 설치시에 웹서버를 패키지로 선택해서 설치할수도 있다...
아주 쉽게 간편하게 설치가 되지만... 여러모로 문제가 있다...
쉽게 이야기 해서 c++을 공부 안하고 .net부터 만지는 꼴이라고 할까???
기본에 충실해야 응용력이 살아난다...-_-
인터넷에 떠도는 메뉴얼로 고대로 따라해봤다...
# yum 설치를 위해 GPG-KEY 포함
rpm --import /usr/share/rhn/RPM-GPG-KEY-fedora
------------> 참고로 위에 키포함을 안하고 yum을 계속 사용하다보면 만드시 에러가 난다...-_-
# yum 업데이트
yum -y update
------------> yum은 정말 대단한 유틸이다... 쩝... 필자에 경우도 rpm만으로 레드햇9에 모든 패키지를 설치했으나 온갖 의존성 문제와 잡다한 오류들때문에 주름살만 늘어갔었다...
Yum은 Yellowdog Updater, Modified의 약자로 rpm기반의 시스템을 위한
자동 업데이터이자 패키지 설치/삭제도구이다.
Yum은 자동적으로 의존성을 처리해주며 rpm 패키지들을 안전하게 설치, 삭제 및
업데이트하기 위해 반드시 해야할 일들을 스스로 해결한다.
필자에 경우 커널업데이트를 위해 의존성있는 모든 패키지에 업그레이드가 무서워 포기했었는데 시간만 있다면
얼마든지 해낼것 같다..ㅋㅋㅋ




# 한글 설정
/etc/sysconfig/i18n
LANG="ko_KR.eucKR"
SUPPORTED="en_US.iso885915:en_US:en:ko_KR.eucKR:ko_KR:ko"
SYSFONT="lat0-sun16"
SYSFONTACM="iso15"
# 매뉴얼 설정 수정
vi /etc/man.config
수정
PAGER /usr/bin/less -isr
--------------------------> 위 두가지 한글 설정은 터미널이나 기타부분에서 한글깨짐현상을 고치기 위해서다
# 디렉토리 색상 수정
vi /etc/DIR_COLORS.xterm
수정
DIR 00;33
# 소스 컴파일을 위한 컴파일러 및 각종 모듈 yum 설치
yum -y install gcc cpp gcc-c++ compat-gcc-32-g77 flex libjpeg-devel libpng-devel libtiff-devel freetype-devel openldap-devel pam-devel sendmail-cf vsftpd telnet-server
# zlib 소스 설치
cd /usr/local/src
wget http://www.zlib.net/zlib-1.2.3.tar.bz2
tar xfj zlib-1.2.3.tar.bz2
cd zlib-1.2.3
make
make install
# freetype 2 설치
글짜를 그릴 때 쓰는 라이브러리 입니다.
wget http://ftp.superuser.co.kr/pub/etc/freetype-2.1.5.tar.gz
tar xvfz freetype-2.1.5.tar.gz
cd freetype-2.1.5
./configure
make
make install

# openssl 소스 설치
cd /usr/local/src
wget http://www.openssl.org/source/openssl-0.9.8a.tar.gz
tar xfz openssl-0.9.8a.tar.gz
cd openssl-0.9.8a
./config
make
make install

# curl 소스 설치
cd /usr/local/src
wget http://curl.haxx.se/download/curl-7.15.1.tar.bz2
tar xfj curl-7.15.1.tar.bz2
cd curl-7.15.1
. /configure --with-ssl
make
make install

# gd lib 설치
cd /usr/local/src
wget http://www.boutell.com/gd/http/gd-2.0.33.tar.gz
tar xfz gd-2.0.33.tar.gz
cd gd-2.0.33
./configure
make
make install

# webalizer 소스 설치
cd /usr/local/src
wget ftp://ftp.mrunix.net/pub/webalizer/webalizer-2.01-10-src.tgz
tar xfz webalizer-2.01-10-src.tgz
cd webalizer-2.01-10
./configure --with-language=korean
make
make install

# mysql 4.1.x 설치
cd /usr/local/src
wget http://mysql.byungsoo.net/Downloads/MySQL-4.1/mysql-4.1.16.tar.gz

 

여기서 약간문제가 발생할 것이다. 다운 로드가 안된다.

필자는 위에 글을 약간 수정하여 다룬로드 받았다.

--wget http://ftp.superuser.co.kr/pub/mysql/mysql-4.1.16.tar.gz

위 처럼 하면 다운 로드가 될것이다.

참고로 superuser.co.kr 이란 사이트는 리눅스 전문 포탈 사이트다. 참고할 것이 많다.

그곳에 다운로드 페이지에 가면 거의 모든 소스들이 있다 참고하자!


tar xfz mysql-4.1.16.tar.gz
cd mysql-4.1.16
./configure --prefix=/usr/local/mysql --localstatedir=/usr/local/mysql/data --with-charset=euckr
make
make install

/usr/local/mysql/bin/mysql_install_db
groupadd mysql
useradd -M -c MySQL_Server -d /usr/local/mysql -g mysql -s /bin/nologin mysql
chown root.mysql -R /usr/local/mysql
chown mysql.mysql -R /usr/local/mysql/data
cp /usr/local/mysql/share/mysql/my-huge.cnf /etc/my.cnf
echo "/usr/local/mysql/bin/mysqld_safe &" >> /etc/rc.local

# apache 1.3.x 설치
cd /usr/local/src
wget http://ftp.apache-kr.org/httpd/apache_1.3.34.tar.gz

 

여기도 약간 문제가 있다 아래 처럼 하여 다운 로드 하자

--wget http://ftp.superuser.co.kr/pub/apache/apache_1.3.34.tar.gz


tar xfz apache_1.3.34.tar.gz
cd apache_1.3.34
./configure --prefix=/usr/local/apache --enable-module=so
make
make install
echo "/usr/local/apache/bin/apachectl start" >> /etc/rc.local


#freetype 소스설치후 적용하기위세 freetype 옵션추가
# php 소스 설치
cd /usr/local/src
wget http://kr.php.net/get/php-4.4.2.tar.bz2/from/this/mirror
tar xfj php-4.4.2.tar.bz2
cd php-4.4.2
./configure --with-apxs=/usr/local/apache/bin/apxs --with-mysql=/usr/local/mysql --with-config-file-path=/usr/local/apache/conf --with-zlib-dir=/usr/local --with-jpeg-dir=/usr/local --with-png-dir=/usr/local --with-tiff-dir=/usr/local --with-freetype-dir=/usr/local --with-ttf --with-gd --with-openssl --with-gettext --with-kerberos --with-swf-dir=/usr/local --with-mod_charset --with-regex=php --with-curl --with-ldap --with-iconv --enable-gd-native-ttf --enable-ftp --enable-sockets --disable-debug --enable-calendar --enable-sigchild --enable-magic-quotes --enable-bcmath --enable-exif --enable-mbstring --enable-dbase --enable-sysvmsg --enable-sysvsem --enable-sysvshm --enable-yp --with-jpeg-dir --with-freetype-dir
make
make install
cp php.ini-dist /usr/local/apache/conf/php.ini


여기서 잠깐

아래에 있는 이쯤에서 에러가 났었는데.... 이글은 약간 위치가 잘못되있을수 있다.

apachectl을 가동하면 아래같은 에러가 난다.

아래에 쓰여져 있는것처럼 Selinux를 수정하고 컴퓨터를 다시키자. 필자는 설치가 끝나고 컴퓨터를

재시작했다. 그러면 아래와 같은오르는 안나올 것이다.


-------------> 이쯤에서 에러가 났었는데 .so cannot restore segment prot after reloc: Permission denied

이런 에러가 난다면 현재 Selinux환경이 활성화 때문이다.

Selinux활성화 상태에서 apache를 구동하는 방법은 조금 복잡.

그냥 Selinux를 비활성화 시키고 재부팅하면 정상적으로 구동된다.

먼저, 콘솔상태라면..

/etc/sysconfig/selinux 파일을 열어서

SELINUX=enforcing 부분을 아래와 같이 변경.
SELINUX=disabled

이와같이 변경한 다음에 재시작.

disabled 대신에 Permissive 라고 입력해도 된다.
그럼 다른 설치를 계속...




vi /usr/local/apache/conf/httpd.conf

수정
DirectoryIndex index.html index.htm index.php

수정 (public_html -> www)
UserDir www
#

# vi /usr/local/apache/conf/mime.types
두줄 추가 (확장자는 탭키로 띄운다)
application/x-httpd-php php ph inc
application/x-httpd-php-source phps

# php 파일 이외에 다른파일명으로 php해석할수있게 설정 ex) htm html
# vi /usr/local/apache/conf/httpd.conf
- .php 파일 및 html 파일에서 php 코드 실행되게 설정하려면
AddType application/x-httpd-php .php .phtml .php3 .html .htm
AddType application/x-httpd-php-source .phps

# vi /usr/local/apache/conf/php.ini
- 그림 파일 및 프래쉬 파일 로그 남기지 않게 설정
방문자 수가 많아지면 웹로그가 엄청 쌓이게 되고, 그 로그는 크기가 2G를 넘게 되면 웹페이지에 이상현상이 생깁니다. 그렇다고 로그를 안 남길 수는 없는 것이고, 이미지 파일들은 로그남기는 것에서 제외합니다.
CustomLog logs/access_log common 이렇게 되어 있는 것을 ..
SetEnvIfNoCase Request_URI (gif|png|jpg|css|js|bmp|jpeg|swf)$ IMAGE=1
CustomLog /usr/local/apache/logs/access_log common env=!IMAGE
이렇게 바꾸면^^; 쉽게 가능합니다.
- 업로드 용량 제한 풀기
기본적으로 업로드는 2M로 제한되어 있습니다. 만약 2M 이상으로 하면 여러 가지 설정들을 바꾸어 줘야 합니다. 업로드 되는 시간을 길 게 해 주어야 하고, 한번에 잡아먹을 메모리를 크게 해 주어야 합니다.
default_socket_timeout = 600
post_max_size = 20M
memory_limit = 20M
upload_max_filesize = 20M

- 업로드 용량 제한 풀기
# vi /usr/local/apache/conf/php.ini
기본적으로 업로드는 2M로 제한되어 있습니다. 만약 2M 이상으로 하면 여러 가지 설정들을 바꾸어 줘야 합니다. 업로드 되는 시간을 길 게 해 주어야 하고, 한번에 잡아먹을 메모리를 크게 해 주어야 합니다.
default_socket_timeout = 600
post_max_size = 20M
memory_limit = 20M
upload_max_filesize = 20M

- post, get , 쿠키 , 세션등의 변수를 일반변수로 (개인 서버용일경우 보안상 OFF 권장)
예 전에 php는 기본적으로 위 변수를 일반변수로 사용할 수 있었습니다. 하지만 보안에 취약 하기 때문에 php 설치시 기본적으로 일반변수로 사용못하게 설정합니다. 이렇게 되면 문제가 예전에 사용하던 짜여졌던 프로그램은 정상적으로 실행되지 않습니다. 보안보다는 호환성이 더 중요하죠^^;
register_globals=On 이렇게 설정합니다.


약간 방법이 틀리지만 위에 있는

.so cannot restore segment prot after reloc: Permission denied

란 오류가 나오면 컴퓨터를 재작동 안하고 아래의 ZendOptimizer 를 설치하면서 apachectl이 가동된다 그러면 아파치는작동이 된다.


# ZendOptimizer 설치
cd /usr/local/src
wget ftp://ftp.sir.co.kr/zendoptimizer/ZendOptimizer-2.5.10a-linux-glibc21-i386.tar.gz
tar xfz ZendOptimizer-2.5.10a-linux-glibc21-i386.tar.gz
cd ZendOptimizer-2.5.10a-linux-glibc21-i386
./install.sh

php.ini 경로
/usr/local/apache/conf


--필자는 아레의 mod_throttle 을 설치 하지 않았다.그리고 그와 연관된 httpd.conf 수정도 하지 않았다. 한 마디로 여기서 끝을 내었다. 하지만 작동 하는데 무리는 없었다.


ftp는 설치 하는건 언급하지 않겟다.

 

그리고 홈페이지가 외부에서 보이지 않는다면 방어벽 설정의 문제일 것이다

 

setup을 눌러서 방어벽에서 사용자 설정에 들어가 http란 문구에 * 표시를 하고 정상적으로 종료를 하면 외부에서 보이는데도 무리가 없을 것이다.

현제 이설치기는 삼성 smart server zss122 란 컴퓨터에 설치한 설치기다.

사양에 대한 설치나 다른 여타 기타에 대한 전문 지식이 없는 필자로선

설치된게 신기하기만 하다.일단 다운로드 받을수 있게 해 놓은 화일을 참조 하고 설치해보자.



# mod_throttle 소스 설치
cd /usr/local/src
wget ftp://ftp.sir.co.kr/etc/mod_throttle-3.1.2.tgz
tar xfz mod_throttle-3.1.2.tgz
cd mod_throttle-3.1.2/
make install

#####################################################
##### 인스톨시 다음과 같은 에러시 다음과 같이 하세요. ############
##### make: *** [install] Error 127make: *** [install] Error 127 ############
####################################################
---> 해당 디렉토리에 Makefile 에 APXS 경로를 지정해준다.

------>경로 지정법

# vi Makefile

APXS=/usr/local/apache/bin/apxs
APACHECTL=/usr/local/apache/bin/apachectl

절대경로로 수정한 다음 저장 하고 다시 make install 실행

(참고 인스톨시 에러가 발생한다. 그리고 APM세팅 방식을 DSO방식으로 설치한다.
STATIC방식으로 설치해도 되지만, 그 부분은 다시 설정해야한다.)

* static방식으로 설치 했을 경우 ...
configure 시--add-module=$mod_throttle_source_PATH/mod_throttle.c 추가.

* 그럼 DSO방식으로 설치 했을 경우...
* 모듈을 만들어준다.
[root@abcd mod_throttle-3.1.2]# /usr/local/apache/bin/apxs -c mod_throttle.c(모듈을 만들어준다)
gcc -DLINUX=22 -DUSE_HSREGEX -fpic -DSHARED_CORE -DSHARED_MODULE
-I/usr/local/apache/include -c mod_throttle.c
gcc -shared -o mod_throttle.so mod_throttle.o

* 에러부분에 추가 해주면 된다.

[root@abcd mod_throttle-3.1.2]# /usr/local/apache/bin/apxs -i -a -n 'throttle' mod_throttle.so
[activating module `throttle' in /usr/local/apache/conf/httpd.conf]
cp mod_throttle.so /usr/local/apache/libexec/mod_throttle.so
chmod 755 /usr/local/apache/libexec/mod_throttle.so
cp /usr/local/apache/conf/httpd.conf /usr/local/apache/conf/httpd.conf.bak
cp /usr/local/apache/conf/httpd.conf.new /usr/local/apache/conf/httpd.conf
rm /usr/local/apache/conf/httpd.conf.new


##############################################
vi /usr/local/apache/conf/httpd.conf


ThrottlePolicy Volume 500M 1d


SetHandler throttle-status


SetHandler throttle-me


SetHandler throttle-me


ServerAdmin root@xxx.com
ServerName xxx.com
DocumentRoot /home/xxx
# 하루 500M
ThrottlePolicy Volume 500M 1d
# 하루 천번
ThrottlePolicy Request 1000 1d


여기서 잠깐 필자는 quota 설정을 하지 않았다.

혹시 하게 된다면

설정을 마친후,

mount -o remount /home

를 실시 했을때에 오류가 난다면 quota 설정을 하지 말라고 추천하겟다.

오류가 나오는 상태에서 아래와 같은 설정이 남아있으면

컴퓨터 부팅시 오류로 부팅도 안된다. 그리고 read-only 화일이라 수정도 안된다.

한마디로 컴퓨터 다시 밀어야 하는 사태가 벌어진다. 필자도 이것때문에 2시간 이상을

허비하고 말았다.


# quota 설정

1. fstab 옵션추가 (usrquota,grpquota) :
vi /etc/fstab
/home 에 usrquota 추가
default,usrquota

2. remount (umount , mount) :
mount -o remount /home

3. 데이터베이스 파일생성(quota.user , quota.group) :
touch /home/quota.user
chmod 600 /home/quota.user
quotacheck -av
convertquota -u /home

4. 사용자마다 적용수치 기록 :
edquota 계정
repquota -a


5. 활성화 :
quotaon /home

# qpopper 4.0.8 소스 설치
cd /usr/local/src
wget ftp://ftp.qualcomm.com/eudora/servers/unix/popper/qpopper4.0.8.tar.gz
tar xvfz qpopper4.0.8.tar.gz
cd qpopper4.0.8
./configure --enable-specialauth --enable-servermode --enable-shy
make
cp popper/popper /usr/sbin/popper

vi /etc/xinetd.d/pop3

service pop3
{
disable = no
socket_type = stream
wait = no
user = root
server = /usr/sbin/popper
log_on_success += HOST DURATION
log_on_failure += HOST
}

# /etc/rc.d/init.d/xinetd restart

# sendmail 수정 및 실행
vi /etc/mail/sendmail.mc

TRUST_AUTH_MECH(`EXTERNAL DIGEST-MD5 CRAM-MD5 LOGIN PLAIN')dnl
define(`confAUTH_MECHANISMS', `EXTERNAL GSSAPI DIGEST-MD5 CRAM-MD5 LOGIN PLAIN')dnl
DAEMON_OPTIONS(`Port=smtp,Addr=0.0.0.0, Name=MTA')dnl

# 계정당 용량 설정
vi /etc/sendmail.cf
Mlocal, P=/usr/bin/procmail, F=lsDFMAw5:/|@qSPfhn9, S=EnvFromL/HdrFromL, R=EnvToL/HdrToL,
M=20495360, <-- 이 부분만 추가 : byte 단위 (예:20메가)
T=DNS/RFC822/X-Unix,
A=procmail -t -Y -a $h -d $u

m4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cf
#/etc/rc.d/init.d/sendmail restart
#/etc/rc.d/init.d/saslauthd restart

# 기본 서비스

ntsysv 실행

auditd
crond
iptables
kudzu
named
network
pop3
saslauthd (보내는 메일서버 패스워드 인증?)
sendmail
sshd
syslog
telnet
vsftpd
xinetd


# 그룹사용자 추가
groupadd webhost

# path 추가

vi /etc/profile

pathmunge /usr/X11R6/bin after
pathmunge /usr/local/mysql/bin after
pathmunge /usr/local/apache/bin after

# vsftpd 설정 변경

vi /etc/vsftpd/vsftpd.conf

주석제거
xferlog_file=/var/log/vsftpd.log



# 재시작

sync
reboot


***이제 설치가 다 되었으면 웹브라우저에 localhost를 입력하면 아파치 테스트 페이지가 나온다...

php테스트는 다 알겠지만...-_-

phpinfo();
?>

내용에 페이지를 하나 작성해서 띄어보면 끝~~~~


APM설치 도움 : PHPSCHOOL



서버점검 아찌들한테 배운 crontab에 대해서 정리합니다.

유닉스나 리눅스에는 매일 혹은 매주, 아니면 한달에 한번 등등 주기적으로 해야 하는 작업을 주는 cron이라는 도구가 있습니다.
(윈도우에 autoexec.bat과 비슷하지만...crond라는 프로세스 때문에...
부팅될때만이 아닌 스케줄링 프로그램과 같은 역활을 합니다.)

그러면 간단한 사용방법과 응용법에 대해 살펴보도록 하죠,

cron을 쓰려면 crontab이라는 명령을 이용합니다...
*TIP = 유닉스나 리눅스에는 man이라는 명령어가 있습니다.
어떤 명령어에 사용법을 보여주는 아주 좋은 것이지요...
crontab -(option) (user) //이런식입니다.
root로 로긴하셨다면 그냥 crontab -e 하시면 root로 정의 되있는 crontab을 설정 편집할수 있습니다.
하지만 유닉스(solaris6.x)같은 경우 editor를 설정해줘야 하는데
잠깐 집고 넘어가겠습니다...

*클론탭 위치 = var/spool/cron/crontabs
sh //쉘을 실행합니다.
editor = vi;export editor
위에 export라는 명령어는 저도 잘 이해 못하고 있지만...
서로 다른 쉘 사이에 명령어나 데이터를 쓸수 있게 해줍니다...
맞나? ㅡㅡㅋ
어쨋든 이렇게 하고 쉘에서 나와 crontab -e 를 실해하면 됩니다...
리눅스 같은 경우 별다른 설정 없이 그냥 하시면 됩니다...
crontab -l // 클론 설정되어 있는 것을 보여줍니다.

이해가 잘 안되시는 분들을 위해 좀더 쉽게 설명하면...
실행될 프로그램이나 쉘,프로세서들을 파일 하나(*이것이 쉘 스크립트 입니다.) 에 작성하고 그 스크립트를 클론탭에 설정해놓으면 정해진 시간에 실행 되는 것입니다....
쉘에 관해서는 저도 잘 몰라서 천천히 공부하려고 합니다...

간단한 파일 시스템 백업을 예로 하죠...

backup이라는 폴더를 만들어주거나 새로운 하드로 마운트 해줍니다.
backup폴더안에 daily_backup이라는 파일을 만들어 줍니다...
vi로 백업할 내용을 적어줍니다...
ex) echo "backup start"
tar cvf /backup/`date +%y%m%d`.tar /dev/hda
echo "backup done"
이해가 잘 안가실테데...
백업은 ufsdump나 tar나 dump등 마음대로 하십쇼....
위와 같이 하면 backup 폴더에 /dev/hda에 내용이 당일 날짜에 tar파일이 생깁니다.
ex)030601.tar
그다음 만든 쉘스크립트(daily_backup)에 실행 속성을 줘야 합니다...
아시는분은 아시겠지만 chmod로 설정합니다...
chmod 777 daily_backup 이나 chmod a+x daily_backup등으로 하면 됩니다...
리눅스 같은 경우 파일 색깔이 변하죠...
그다음 이제 대망에 클론탭 삽입만 하면 됩니다...
crontab -e 를 실행하셔서...다음 과 같이 추가합니다...
59 23 * * * /backup/daily_backup
23시59분애일 애월 매요일 실행하라는 뜻입니다..
추가하고 저장하시면 끝입니다...
그리고 crond 가 실행중인지 체크하세요..
ps -ef | grep cron


If you take a look at the /etc/passwd file (as root), you'll see lines something like this for each user:
username:x:501:501:username:/home/username:/bin/bash

Just change the shell from /bin/bash to something non-existent (like /bin/nologin) for users that you wish to prevent logging in like so:
username:x:501:501:username:/home/username:/bin/nologin

Obviously /bin/login doesn't exist, so they can't log in as they have no valid shell.