공부합시다/Security2008/12/26 17:27

openssl 명령으로 운영중인 웹서버의 SSL인증서 정보를 살펴볼 수 있다.

 
# openssl s_client -connect 웹서버:443
 


imaps(IMAP over SSL, 993포트), pop3s(POP3 over SSL, 995포트)는 포트만 변경하여 다음과 같이 확인한다.

 
# openssl s_client -connect IMAP서버:993
# openssl s_client -connect POP3서버:995
 


1. 샘플로 살펴보자.

 
# echo "" | openssl s_client -connect logins.daum.net:443
CONNECTED(00000003)
---
Certificate chain
0 s:/1.3.6.1.4.1.311.60.2.1.3=KR/2.5.4.15=V1.0, Clause 5.(b)/serialNumber=120-81-47521/C=KR/ST=Seoul/L=Seocho-gu/O=Daum Communications Corp./OU=Pi Lab/OU=Terms of use at www.verisign.com/rpa (c)05/CN=logins.daum.net
... 생략 ...
---
Server certificate
-----BEGIN CERTIFICATE-----
... 생략 ...
-----END CERTIFICATE-----
subject=/1.3.6.1.4.1.311.60.2.1.3=KR/2.5.4.15=V1.0, Clause 5.(b)/serialNumber=120-81-47521/C=KR/ST=Seoul/L=Seocho-gu/O=Daum Communications Corp./OU=Pi Lab/OU=Terms of use at www.verisign.com/rpa (c)05/CN=logins.daum.net
issuer=/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa (c)06/CN=VeriSign Class 3 Extended Validation SSL SGC CA
---
No client certificate CA names sent
---
SSL handshake has read 4843 bytes and written 340 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
Server public key is 1024 bit
SSL-Session:
    Protocol  : TLSv1
    Cipher    : DHE-RSA-AES256-SHA
    Session-ID:
    Session-ID-ctx:
    Master-Key: 1160B88DAC017E265FE29B1BE9A85B30FB731B9190A96C06067570E89FEC011EDECA36BB299239959B7DB68A753570E4
    Key-Arg   : None
    Start Time: 1230104266
    Timeout   : 300 (sec)
    Verify return code: 20 (unable to get local issuer certificate)
---
DONE
 


-msg 옵션을 추가하면 전송되는 TLS/SSL 프로토콜까지 살펴볼 수 있다. 이 메시지를 통해서 SSL handshake 과정이 쉽게 파악된다. 아래는 결과중에 메시지 부분만 뽑아낸 것이다. >>> 로 표시 된 것은 Client -> Server로 보낸 메시지이고, <<< 로 표시된 것은 Server -> Client로 보낸 메시지이다.

 
>>> SSL 2.0 [length 008c], CLIENT-HELLO
<<< TLS 1.0 Handshake [length 002a], ServerHello
<<< TLS 1.0 Handshake [length 10e1], Certificate
<<< TLS 1.0 Handshake [length 018d], ServerKeyExchange
<<< TLS 1.0 Handshake [length 0004], ServerHelloDone
>>> TLS 1.0 Handshake [length 0086], ClientKeyExchange
>>> TLS 1.0 ChangeCipherSpec [length 0001]
>>> TLS 1.0 Handshake [length 0010], Finished
<<< TLS 1.0 ChangeCipherSpec [length 0001]
<<< TLS 1.0 Handshake [length 0010], Finished
>>> TLS 1.0 Alert [length 0002], warning close_notify
 


[ SSL handshake ]


2. 인증서의 만료일자는 어떻게 살펴볼 수 있을까?

 
# echo "" | openssl s_client -connect logins.daum.net:443 | openssl x509 -noout -dates
notBefore=Oct 14 00:00:00 2008 GMT
notAfter=Oct 30 23:59:59 2009 GMT
 


notBefore= : '이전에는 없음', 발급일
notAfter=  : '이후에는 없음', 만료일

s_client 로 얻은 결과를 다시 'openssl x509' 명령으로 넘겨서 얻은 결과이다. -dates 옵션 대신 -startdate -enddate, -text를 사용해도 만료일을 확인할 수도 있다. 이외 -purpose, -subject, -issuer, fingerprint, serial, -hash 등의 옵션으로 인증서의 부분별 정보를 파악할 수 있다.

3. 참고자료

* Monitoring SSL certificate expiration date
  http://doodlog.blogspot.com/2008/11/monitoring-ssl-certificate-expiration.html

* OpenSSL Command-Line HOWTO
  http://www.madboa.com/geek/openssl/

* 커피닉스의 '네트워크(network)  > TCP/IP, 프로토콜, 포트' 중 SSL Handshake 자료
  http://coffeenix.net/?cata_code=56

* SSL 운영(https)시 도메인기반 Virtual host가 안되는 이유 (글 좋은진호, 2007.9)
  http://coffeenix.net/board_view.php?bd_code=1543


-- 출처 : http://coffeenix.net/board_view.php?bd_code=1661  좋은진호님의 블로그

Posted by 제논
즐겨봅시다2008/12/17 16:55
Posted by 제논
즐겨봅시다2008/12/17 16:27
Posted by 제논

grep : 패턴을 이용한 search => regular expression을 잘 만드는 것이 필요하다.

  grep option(s) pattern filename(s)

OS/tdir] grep -n dba /etc/group       # -n : 파일 안에서의 패턴이 발견된 라인 및 라인 번호
OS/tdir] grep
-v dba /etc/group           # -v  : 패턴이 발견되지 않은 라인
OS/tdir] grep -n dba
/etc/group /etc/passwd          # 파일을 여러개 나열...
OS/tdir] grep
-i the ~/tdir/*                 # -i : 대소구분 무시(ignore) => the 대소구분 없이
OS/tdir] grep
-li the ~/tdir/*                 # -l : 패턴이 들어있는 파일 이름만... 
OS/tdir] grep
-c the ~/tdir/*                 # -c : 패턴이 들어있는 라인 번호만...

[패턴을 좀더 정교하게 표현하려면 regular expression을 사용해야 한다]

^      : ^패턴            : 패턴으로 시작하는 모든 라인 찾기
$      : 패턴$           : 패턴으로 끝나는 모든 라인 찾기
.       : d...              : d로 시작하는 4자리 character 찾기
*      : [a-d]*          : a, b, c, d로 시작하는 character 찾기
[]    : [Dd]atabase  : Database 또는 database 찾기
[^]   : [^D]             : D가 나타나지 않는 라인 찾기

OS/tdir] grep -i ^the ~/tdir/*              # the로 시작하는 라인 찾기
OS/tdir] grep -i
meal.$ ~/tdir/*          # meal.으로 끝나는 라인 찾기
OS/tdir] grep
c...d ~/tdir/*                # c로 시작하고 d로 끝나는 5자리 character 찾기

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

▒  egrep(expression grep) : searches  files  for  a pattern of characters
                                           and prints all lines that contain that pattern.

 

OS/tdir] egrep '(a|A)d+' /etc/passwd   # ad 또는 Ad가 포함된 라인 찾기
OS/tdir] vi grep_test                               # 아래 내용을 추가하세요... 붙여넣기... ^^

An Oracle database is a collection of data treated as a unit.
The purpose of a database is to store and retrieve related information.
A database server is the key to solving the problems of information management.

OS/tdir] egrep 'Oracle|purpose' grep_test   # Oracle 또는 purpose가 포함된 라인 찾기

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

sed : stream editor => file을 열지 않고 data를 편집하는 기능

  sed [-options] [address] command file... [>newfile]

 

# sed '/pattern/d' filename # file에서 패턴이 포함된 라인을 지우고 그 결과를 화면에 표시
                                          #
원본 파일에는 아무런 변화가 없다.

OS/tdir] cp grep_test sed_test
OS/tdir] cat sed_test
OS/tdir] sed
'/purpose/d' sed_test                  # purpose 라는 단어가 들어간 라인 삭제

 # sed '#d' filename      : # 라인만 삭제
# sed
'$d' filename      : 마지막 라인 삭제
# sed
'#,$d' filename   : # 라인부터 마지막 라인까지 지우기
# sed
'#,#d' filename   : # 라인부터 # 라인까지 지우기  

OS/tdir] sed '1d' sed_test     # 1 라인만 삭제
OS/tdir] sed
'$d' sed_test     # 마지막 라인만 삭제

OS/tdir] sed '/purpose/d' sed_test > set_out     # sed 처리 결과를 sed_out 으로 저장
OS/tdir] cat set_out

OS/tdir] sed '/purpose/p' sed_test             # 패턴이 포함된 라인이 두번 출력(print)된다.
OS/tdir] sed
-n '/purpose/p' sed_test        # 패턴이 포함된 라인만 출력된다.

OS/tdir] sed 's/$/  Oracle/' sed_test       # 각 라인의 마지막에 원하는 글자 추가

OS/tdir] sed 's/  */#/g' sed_test              # space를 찾아서 #기호로 변환한다.
OS/tdir] sed '
s/  */-/g' sed_test              # space를 찾아서 -기호로 변환한다.
                                                                      # * 기호 앞에 space가 두개라는 점에 유의

OS/tdir] # 한번에 여러 가지 편집 수행
OS/tdir] sed
-e 's/database/DATABASE/g' -e 's/information/INFORMATION/g' sed_test

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

awk : 패턴 검색과 처리를 위한 언어

=> 명령어의 이름은 개발자인 Alfred V. Aho, Peter J. Weinberger, Brian W. Kernighan 3인의
    머리글자를 사용해서 만든 것이다.

  awk '{ action}' filename

OS/tdir] ls -l | awk '{print $0}'              # 전체 필드가 모두 나타나도록...

drwxr-xr-x   2   prof9i4  dba          512  4월   25일  15:44   a_dir
drwxr-xr-x   2   prof9i4  dba          512  4월   18일  23:53   b_dir

     $1     $2     $3   $4        $5  $6   $7     $8    $9
                                        $0                                            

 

OS/tdir] ls -l | awk '{print $1}'                    # 1번 필드만 나타도록...
OS/tdir] ls -l | awk '{print $1, $9}'               # 1번과 9번 필드만 나타나도록...
OS/tdir] ls -l | awk '{print $3 "\t" $4 "\t" $9}'                # Tab 키가 적용된 결과...
OS/tdir] ls -lt | awk '{print $9, "is using", $5, "bytes"}'     # text 추가
OS/tdir] ls -lt | awk '
$5 <= 200 {print $0}'   # 5번 필드가 200 이하일 경우 출력

Posted by 제논

서버 셋팅 UTF-8로 만들기

2006/12/04 13:06  

http://towis.net/entry/서버-셋팅-UTF-8로-만들기



1. 환경
-------------------------
OS : Redhat Fedora core 6
Apache : httpd-2.2.3-5
PHP : php-5.1.6-3.1
MySQL : mysql-5.0.27-1

2. 설정방법 및 순서
-------------------------
1. apache 환경파일 편집 (httpd.conf)
2. php 환경파일 편집 (php.ini)
3. mysql 환경파일 편집 (my.cnf)
4. apache, mysql 서비스 재시작
5. mysql에서 캐릭터셋 확인 및 디비생성
6. php 소스에 한글문자열이 있으면 파일저장할때 UTF-8 파일형식으로 저장


/etc/httpd/conf/httpd.conf 에서 캐릭터셋 수정
AddDefaultCharset UTF-8


/etc/php.ini 에서 캐릭터셋 수정
;default_charset = "iso-8859-1"
default_charset = "utf-8"


/etc/my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
# Default to using old password format for compatibility with mysql 3.x
# clients (those using the mysqlclient10 compatibility package).
old_passwords=1
##참고사항##
old_passwords=1 이부분을 그대로 두게되면 mysql 암호화 방식을
구번전처럼 사용한다는 뜻입니다. 즉 16자리 암호화죠.
신버전으로 사용하길 원한다면 저 윗부분을 주석처리 해주세요.
그럼 암호화 방식이 42자리로 늘어 보안에 훨씬 도움이 됩니다.
#old_passwords=1 <-이렇게 주석걸어 두세요~


init_connect=SET collation_connection = utf8_general_ci
init_connect=SET NAMES utf8
default-character-set=utf8
character-set-server=utf8
collation-server=utf8_general_ci

[mysql.server]
user=mysql
basedir=/var/lib

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

[client]
default-character-set=utf8

[mysql]
default-character-set=utf8

붉은색 글자가 추가된 내용들이다.

환경변수를 모두 수정후 apache 및 mysql 서비스 재시작
mysql> use test
Database changed

mysql> show variables like 'c%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | utf8                       |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | utf8                       |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
| collation_connection     | utf8_general_ci            |
| collation_database       | utf8_general_ci            |
| collation_server         | utf8_general_ci            |
| completion_type          | 0                          |
| concurrent_insert        | 1                          |
| connect_timeout          | 5                          |
+--------------------------+----------------------------+
14 rows in set (0.00 sec)


* MySql에서 데이터베이스 생성
mysql>CREATE DATABASE 디비명 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

참고로 MySQL 내용을 보면 알겠지만 MySQL-5 버전 부터는 utf-8 이 아닌 utf8로 바뀌었다.
즉 php 언어 같은 부분으로 db선택을 utf8로 하려면 아래와 같이 해야 한다.

@mysql_query("set names utf8");
아마도 mysql 버전이 5가 아니었다면
@mysql_query("set names utf-8"); 로 했을것이다.

mysql 만 utf8이며 php 와 apache 는 기존 그대로utf-8 이다.

Posted by 제논

리눅스서버관리/서버관리 2006/06/19 00:55 아이
아파치 웹 서버 장애 해결하기

글·홍석범 오늘과내일 넷센터 ( antihong@tt.co.kr )


시스템 관리자는 시스템에 대해 보수적이어야 한다는 말이 있다. “보수적”이라는 말은 특정한 정치적 성향을 뜻하는 것이 아니라 시스템에 대해 단 1%라도 문제가 될 수 있는 여지를 제거하고, 각 유저에게는 불편함을 주지 않는 한
도 내에서 가급적 사용 권한을 제한하여 혹시나 있을지 모를 시스템의 침해나 크래킹 등에 대비해야 한다는 것을 뜻한다. 아울러 시스템 관리자는 새로운 룰을 적용 또는 변경하거나 프로그램을 새로이 도입할 때에도 이 프로그램으로 인하여 다른 문제가 발생할 수 있는 여지는 없는지 여부를 신중히 검토 후 도입해야 한다.
이번 호에서는 아파치 웹 서버를 운영시 접할 수 있는 여러 가지 장애와 이에 따르는 원인과 해결 방법을 찾아보도록 하겠다.

* 접속이 느려지거나 접속이 안 될 때
가끔 접속자가 많은 서버를 운영하다 보면 갑자기 웹 접속이 되지 않거나 접속이 너무 느려 아파치 데몬 개수를 확인해 보면 httpd가 256개나 떠 있는 경우가 있다. 기본적으로 아파치 웹 서버의 경우 Max Clients가 256으로 설정되어
있어 동시에 256개의 데몬이 뜨게 되면 더 이상의 접속을 받아들이지 않고, 기존의 프로세스가 죽을 때까지 대기한 후 접속이 끊기게 되면 그제서야 접속을 받아들이게 된다.
따라서 동시 접속이 많은 경우에는 이전의 웹 접속이 끊길 때까지 대기해야 하므로 접속 속도가 느린 것처럼 느끼게 되는 것이다. 일반적으로 정상적인 접속의 경우에 256개의 프로세스가 모두 뜨는 경우는 그리 많지 않기에 현재의 상태가 비정상적인 접속인지 여부를 판단해야 한다. 이를 판단할 수 있는 방법은 netstat ?na | grep ES로 ESTA BLISHED된 연결 상태를 확인하여 클라이언트의 IP가 정상적인 연결인지 여부를 확인하면 된다.
또는 netstat -na|grep ES|awk '{print $5}'|sort로 클라이언트의 IP만 따로 소트하여 확인해 봐도 된다. 통상적으로 HTTP 1.1 규약에서부터 적용되기 시작한 KeepAlive 기능을 지정하였을 경우 한 클라이언트 IP에서 동시에 3~5개 정
도의 http 프로세스를 생성하므로 한 IP에서 3~5개 정도의 프로세스를 생성하는 것은 정상적인 현상이다. 비정상적인 접속의 경우에는 다음과 같은 이유가 있을 수 있다.

* 서비스 거부 공격(DoS)이 가해졌을 때
DoS는 동시에 서비스할 수 있는 프로세스의 한계가 있다는 점을 악용한 공격이다. 한번의 실행으로 100개나 200개 등 원하는 만큼의 동시 접속을 맺은 후 이 접속을 끊지 않고 유지할 수 있는 공격 코드가 인터넷 상에 공개되어 있
다. 그러나 이러한 공격의 경우 공격지의 IP를 속이기가 매우 어려우므로 netstat으로 확인 후 비정상적인 접속으로 확인 될 경우 해당 IP를 차단하면 된다.
특정 IP의 라우팅을 차단하는 방법은 다음과 같이 route를 이용한 방법과 iptables(커널 2.4 이상)를 이용한 방법 두 가지가 있다.

* include를 잘못하여 무한 루프가 돌 경우
요즘에는 php와 mysql을 연동하여 많이 사용하고 있는데, 프로그래밍 과정에서의 실수로 php 파일에서 같은 php 파일을 include하는 경우가 있다. 또는 a.php 파일에서 b.php 파일을 include하고 b.php 파일에서 다시 a.php 파일을
include하는 경우도 그러한 경우일 것이다. 이러한 경우에는 무한 루프가 돌게 되어 결국은 아파치 데몬이 금새 Maxclients에서 지정한 개수로 차 버리게 되는데, 어떤 파일에서 무한 루프가 돌고 있는지 찾기가 힘들다.
따라서 임시로 다음과 같이 include를 하지 못하도록 차단을 하는 방법이 있다.

# iptables -A INPUT -p tcp -i lo -s xxx.xxx.xxx.xxx --sport
1024:65535 -j DROP
이는 같이 서버 내에서 include 시에는 lo(Lookback Interface)를 통해 sport 가 1024 이후의 하이 포트를 이용하여 통신한다는 특성을 이용한 것이다. 그러나 이 설정을 하였을 경우 로컬 서버에서 클라이언트 포트를 전혀 사용할 수
없게 되므로 다른 서비스에도 장애가 되기 때문에 임시로만 사용하기 바란다.
또는 ps aux | grep http로 보이는 프로세스에서 ls -la/proc /pid/로 각각의 http 프로세스가 어떤 파일을 참조하고 있는지 일일이 추적하는 방법도 있다.
(예:cwd -> /home/user1/public_html/infinite_loop/)

* 프로세스가 과도한 메모리를 사용할 경우
특별히 이상한 프로세스는 없는데, 시스템의 부하가 갑자기 올라가는 경우가 있다. 심할 경우에는 콘솔에서 키 작동이 되지 않아 제어 자체가 불가능한 경우도 있는데, 이러한 경우는 어쩔 수 없이 시스템을 재시작하는 수밖에 없다.
이는 의도적이든 아니든 유저가 cgi나 php 등의 프로그램을 잘못 짜서 과도한 메모리를 소모하는 프로세스를 실행하기 때문인 경우인데, 실제로 시스템의 메모리를 많이 소모하는 프로그램을 짜는 것은 단 몇 줄의 코드로도 가능하다.
다음과 같이 메모리를 소모하는 간단한 C 코드를 작성해 보자(참고로 스크립트 키드의 악용을 막기위해 코드 중 일부를 변경하였다).

/* memory.c */

#include <unistd.h>
#include <stdlib.h>

void html_content(void);

int main() {
char *some_memory;
int size_to_allocate = ONE_K;
int megs_obtained = 0;
int ks_obtained = 0;

html_content();
printf("Program Executed !!!<p>");

while (1) {
for (ks_obtained = 0; ks_obtained < 1024; ks_obtained++) {
some_memory = (char *)malloc(size_to_allocate);
if (some_memory == NULL) exit(EXIT_FAILURE);
sprintf(some_memory, "Hello World");
}
printf("Now allocated %d Megabytes<br>\n", megs_obtained);
}
exit(0);
}

void html_content(void)
{
printf("Content-type: text/html\n\n");
}
작성 후 gcc -o memory.cgi memory.c로 컴파일 한 후 이 파일을 http://domain.com/memory.cgi 와 같이 웹에서 실행해 보도록 하자. 아무리 메모리와 CPU의 여유가 있는 시스템이라 하더라도 이 프로그램을 실행하자마자 거의 통제 불능 상태로 되어 결국 시스템 재부팅하게 될 것이다. 이렇듯이 메모리를 무한정 소모하는 것을 차단하기 위해서는 아파치의 설정 인자 (Directive) 중에서 RLimitMEM을 사용하여 차단할 수 있다. 이 인자는 아파치 웹 서버에서 생성된 특정 프로세스가 작동시 소요 가능한 최대 메모리의 양을 제한하는 것으로 메모리를 많이 소모하는 CGI가 작동할 때 이 인자에서 지정된 메모리까지만 실행이 되고 그 이상 소요시에는 더 이상 작동하지 않도록 해 준다.
예를 들어 httpd.conf에 다음과 같이 설정하였다면 모든 디렉토리에서는 메모리를 20MB나 최대 21MB까지만 사용이 가능하고 /home /special/public_html/* 디렉토리 이하에 접근 시에는 특별히 50MB까지 메모리 이용이 가능하게 된다.

RLimitMEM 20480000 21504000

<Directory /home/special/public_html/*>
RLimitMEM 51200000 52224000
</Directory>

실제로 위와 같이 설정 후 memory.cgi를 웹에서 호출하면 아래와 같이 일정량의 메모리만 사용되고 중단하는 것을 확인할 수 있다.
이와 비슷한 인자로 CPU 점유율을 제한하는 RLimitCPU와 사용자당 프로세스의 개수를 제한할 수 있는 LimitNPROC이 있다. 이에 대해서는 http://httpd.apache.org/docs-2.0/mod/core.html 를 참고하기 바란다.
용량 큰 파일의 업/다운로드시 부하가 유발될 경우 누구나 업/다운로드가 가능한 자료실을 운영하고 있을 경우 사이즈가 너무 큰 파일을 업/다운로드 할 경우 부하가 많이 걸리게 되어 결국 시스템의 성능 저하를 유발하게 된다. 최근 배포되는 게시판/자료실 프로그램에서는 대부분 업로드할 수 있는 용량 등을 제한할 수 있는 기능이 있지만 그렇지 않은 프로그램도 상당수 있어 웹 서버 차원에서 이 제한을 적절히 설정할 필요가 있다.
아파치에서는 이와 관련하여 웹 서버에서 업/다운로드 할 수 있는 파일의 사이즈를 제한하는 Limit RequestBody 기능을 이용할 수 있다.
LimitRequestBody는 클라이언트가 요청시 http 프로토콜을 통해 서버가 제공 할 수 있는 메시지의 크기를 바이트 단위로 정의하는 것으로 무한대를 의미하는 0부터 2,147,483,647(2Giga)까지 설정 가능하며 이 설정으로 대용량의 파일을 업/다운로드 하는 형태의 서비스 거부 공격을 차단할 수 있다. 이를 설정하는 방법은 httpd.conf를 열어 다음과 같은 라인을 추가하면 된다.

<Directory />
LimitRequestBody 7168000
</Directory>
<Directory /home/special/>
LimitRequestBody 10240000
</Directory>

위와 같이 LimitRequestBody 인자를 설정하면 아파치 웹 서버를 이용하여 업/다운로드 하는 모든 파일의 사이즈를 7MB로 제한하고 /home/special/ 이하에 대해서는 10MB로 제한하게 된다. 위와 같이 설정시 지정된 사이즈를 초과하는 파일을 업/다운로드 시에는 다음 그림과 같은 에러 메시지가 뜨며 업/다운로드가 되지 않는다.
특정한 이름의 파일을 실행을 제한하려면 최근에는 대부분의 사이트들이 대화방(채팅)을 위해 자바로 프로그래밍된 자바 대화방을 사용하는 추세이지만 얼마 전까지만 하더라도 C나 펄로 된 CGI 대화방을 설치하여 사용하는 것이 유행이었다. 그런데 이 대화방의 경우 대화방에 참여하는 유저 중 한 명이 글을 입력할 경우 모든 유저에게 이 내용이 실시간으로 나타나야 하는 특성상 시스템의 메모리를 매우 많이 소모하는 대표적인 프로그램 중 하나였다.
따라서 채팅 CGI 프로그램을 원천적으로 사용할 수 없도록 하는 방법을 고민하게 되었는데, 해결 방법은 대부분의 채팅 프로그램이 xxxchat.cgi 또는 chatxxx.cgi라는 파일을 실행 파일 이름으로 한다는 특징을 이용하면 된다.
즉, httpd.conf를 열어 다음과 같이 설정하면 파일명에 ‘chat’이라는 단어가 포함된 CGI 파일은 작동하지 않게 되는 것이다.

<Files "*chat*.cgi">
Order allow,deny
Deny from all
</Files>
이러한 방식으로 특정한 파일에 대해 웹에서의 접근을 차단할 수 있다. 따라서 CGI 파일에 아무리 소유권과 실행 권한을 주었다 하더라도 웹 서버 자체에서 접근을 거부하였으므로 웹에서 접근하면 ‘Forbidden’에러가 나게 된다.
이러한 식으로 특정 파일 이름을 가진 파일의 실행이나 접근을 차단할 수 있다.

* 검색 로봇의 접근 차단하기
갑자기 특정한 IP 주소에서 짧은 시간에 많은 접속을 하여 시스템의 부하가 올라가 웹 접속 로그를 살펴보니 다음과 같이 이해할 수 없는 내용이 남는 경우가 있다.

211.51.63.4 - - [26/Sep/2001:22:19:42 +0900] "GET /robots.txt HTTP/1.0"
404 285
211.51.63.4 - - [26/Sep/2001:22:19:43 +0900] "GET /index.asp HTTP/1.0"
404 284
211.51.63.4 - - [26/Sep/2001:22:19:43 +0900] "GET /index.php HTTP/1.0"
404 284
211.51.63.4 - - [26/Sep/2001:22:19:43 +0900] "GET /index.php3 HTTP/1.0"
404 285
211.51.63.4 - - [26/Sep/2001:22:19:43 +0900] "GET /default.htm HTTP/1.0"
404 286
211.51.63.4 - - [26/Sep/2001:22:19:43 +0900] "GET /default.html
HTTP/1.0" 404 287
211.51.63.4 - - [26/Sep/2001:22:19:43 +0900] "GET /default.asp HTTP/1.0"
404 286
211.51.63.4 - - [26/Sep/2001:22:19:43 +0900] "GET /default.php HTTP/1.0"
404 286
211.51.63.4 - - [26/Sep/2001:22:19:43 +0900] "GET /default.php3
HTTP/1.0" 404 287
211.51.63.4 - - [26/Sep/2001:22:19:43 +0900] "GET /main.htm HTTP/1.0"
404 283
211.51.63.4 - - [26/Sep/2001:22:19:43 +0900] "GET /main.html HTTP/1.0"
404 284
211.51.63.4 - - [26/Sep/2001:22:19:43 +0900] "GET /main.asp HTTP/1.0"
404 283
211.51.63.4 - - [26/Sep/2001:22:19:44 +0900] "GET /main.php HTTP/1.0"
404 283
211.51.63.4 - - [26/Sep/2001:22:19:44 +0900] "GET /main.php3 HTTP/1.0"
404 284

무작위로 index.php, index.asp, index.php3, default.html, default.asp 등의 파일을 순서대로 요청하는 것으로 보아 검색 엔진일 가능성이 높다고 가정
할 수 있다. 특히 robots.txt 파일을 요청하는 것으로 검색 엔진이라고 장담 할 수 있을 것이다.
httpd.conf에서 Logformat를 common 대신 {User-agent} 변수를 추가하여 정의 하면 서버에 접근하는 에이전트 정보도 알 수 있는데, UA(User Agent)는 일반적인 웹브라우저 뿐만 아니라 검색 로봇이나 방랑 로봇 등 웹 서버에 접속하여 웹페이지를 가져오거나 해석하는 모든 종류의 프로그램을 뜻한다.
이는 흔히 사용하는 익스플로러나 넷스케이프 등의 브라우저 외에도 라이코스의 스파이더(spider)나 알타비스타의 스쿠터(Scooter)와 같은 검색 로봇과 텔리포트(Teleport)나 WebZIP, GetRight 등 오프라인 브라우저 모두 UA의 범위에 속한다. 검색 로봇이 어떤 사이트를 방문하여 문서를 인덱싱하거나 오프라인 브라우저가 페이지를 한꺼번에 요청하여 긁어 가는 것은 일반 사용자가 웹 브라우저로 서버에 접속하여 원하는 페이지를 보는 일반적인 경우와 그 성격이 다르다. 여러 페이지를 동시에 요청하는 정도를 벗어나 아예 한 웹사이트의 모든 페이지를 짧은 시간에 통째로 긁어가기도 하기 때문에 이러한 경우에는 서버에 매우 많은 프로세스를 생성하면서 웹 서버의 로드가 크게 올라가게 되는 것이다. 특히 DB와 연동하는 사이트의 경우에는 심할 경우 정상적인 서비스를 하지 못 할 정도이다.
모든 사이트가 검색 엔진에 등록될 필요는 없거나 또는 허용된 일부 유저만 접근이 가능한 페이지의 경우 로봇의 접근을 차단할 필요가 있으므로 이러한 경우에는 다음과 같이 설정된 robots.txt 파일을 웹 서버의 최상위 / 디렉토리
에 두면 모든 검색 로봇이 /secure 디렉토리를 인덱싱하지 않는다.

User-agent: *
Disallow: /secure

“User-agent: *”는 모든 로봇를 대상으로 한다는 것을 뜻하며 예를 들어 알타비스타 스쿠터 등 특정한 UA에 대해서만 설정하고 싶다면 다음과 같이 하면 된다.

User-agent: scooter

검색 로봇과 관련된 더 자세한 정보를 얻기 원한다면 다음의 사이트를 참고하기 바란다.

http://info.webcrawler.com/mak/projects/robots/robots.html
http://info.webcrawler.com/mak/projects/robots/norobots.html

아울러 웹 서버에서 특정한 유저 에이전트의 접근을 차단하려면 httpd.conf에 다음과 같이 BrowserMatch를 사용하여 설정해도 된다.

BrowserMatch "WebZIP" go_out
BrowserMatch "Teleport" go_out
BrowserMatch "GetRight" go_out
BrowserMatch "WebCopier" go_out
BrowserMatch "NetZip Downloader 1.0" go_out
BrowserMatch "NetZip-Downloader/1.0.62" go_out
BrowserMatch "Teleport Pro/1.29" go_out
BrowserMatch "Teleport Pro/1.24" go_out
BrowserMatch "Teleport Pro/1.26" go_out
<Directory /home/no-ua/>
Options Includes ExecCGI
AllowOverride None
Order allow,deny
Allow from all
Deny from env=go_out
</Directory>

위와 같이 설정 시에는 /home/no-ua/ 디렉토리 이하에 대해서는 go_out이라는 변수에 지정한 WebZip이나 Teleport 등 UA 프로그램의 접근을 차단하게 된다.
다른 UA도 차단하고 싶으면 위와 같이 웹 서버의 로그를 살펴보아 에이전트 정보에 남는 UA를 go_out으로 추가해 주면 된다. 같은 방식으로 만약 특정 디렉토리 이하에 대해서 MSIE 브라우저로 접근하지 못하도록 설정하려면 다음과 같이 BrowserMacth를 이용한다. 이렇게 하면 에이전트 정보에 MSIE라 설정되는 UA는 차단될 것이다.

BrowserMatch "MSIE" msie
<Directory />
Options Includes ExecCGI
AllowOverride None
Order allow,deny
Allow from all
Deny from env=msie
</Directory>
최근에는 각종 로봇이 버전을 새롭게 하며 계속적으로 나오고 있으므로 지속적으로 로그를 살펴보아 접근 통제를 하고자 하는 UA를 설정하는 것이 좋다.

* 외부의 데이터 무단 링크로 인한 부하 없애기
최근에 와레즈 사이트를 통해 게임이나 오락, 동영상 등 각종 데이터들이 공유되면서 와레즈 사이트에서 관련 없는 임의의 서버에 데이터를 업로드한 후 무단 링크하여 서비스하는 경우가 많다. 이러한 경우 데이터 전송량이 갑자기 늘어 서버의 부하가 급격히 올라감은 물론 한정된 회선의 대역폭도 소모하게 되어 서버를 관리하는 관리자들에게는 이러한 무단링크가 큰 골치 거리 중에 하나다.
대부분의 무단 링크가 대용량이기 때문에 이를 차단하기 위해 위와 같이 LimitRequestBody를 이용하여 임의의 용량 이상의 데이터에 대한 업/다운로드 용량을 제한하는 방법도 있지만 다음과 같이 BrowserMatch 대신 SetEnvIFNoCase Referer를 이용하는 방법도 있다.

SetEnvIFNoCase Referer "warez" link_deny
SetEnvIFNoCase Referer "free" link_deny
SetEnvIFNoCase Referer "home" link_deny

<FilesMatch "\.(avi|mpe?g|zip|asf|exe)$">
Order allow,deny
allow from all
deny from env=link_deny
</FilesMatch>

위와 같이 설정 시에는 Referer이 warez 또는 free나 home이 포함되었을 경우 이 사이트를 link_deny라는 변수에 할당하고, 환경변수가 link_deny일 때는 확장자가 avi나 mprg, zip, asf 등인 파일에 대한 엑세스를 제한하고 있다. 따라
서 홈페이지 주소에 warez나 free 또는 home이 포함된 주소에서 위의 데이터를 무단 링크하였을 경우에는 이를 차단할 수 있다. Nocase를 추가로 설정하였을 경우에는 대소문자를 가리지 않아 링크하는 사이트가 대소문자에 관계없이 http://my.warez.org/ , http://My.Warez.Org/ , http://MY. WAREZ.ORG/ 모두 적용된다.
다른 확장자를 추가하고나 설정을 변경하고자 할 경우에는 정규식(Regurar Expression)을 이용하여 설정하면 된다. 또는 이와는 반대로 아예 httpd.conf 에서 다음과 같이 설정할 수도 있다.

<VirtualHost tt.co.kr>
ServerAdmin webmaster@tt.co.kr
DocumentRoot /home/tt/public_html
ServerName tt.co.kr
ServerAlias www.tt.co.kr
SetEnvIf Referer tt\.co\.kr link_allow
SetEnvIf Referer www\.tt\.co\.kr link_allow
SetEnvIf Referer ^$ link_allow
<FilesMatch ".(mpg|asf|wmv)$")
Order Deny,Allow
Allow from env=link_allow
Deny from all
</FilesMatch>
</VirtualHost>

위와 같이 설정하였을 경우 외부에서는 mpg, asf, wmv 확장자를 갖는 파일에 대해서는 일체의 무단 자료 링크가 불가능하게 되며 오직 link_allow에서 지정한 도메인에서만 링크가 가능하게 된다. 위와 같이 설정 후 외부에서 무단 링
크를 하였을 때 error_log를 살펴보면 다음과 같이 무단으로 링크한 자료의 다운로드가 작동하지 않는 것을 확인할 수 있다.

[Tue Sep 4 15:55:44 2001] [error] [client 211.230.82.78]
client denied by server configuration: /home/tt/public_html/data/3-2.wmv

아파치 데몬은 떠 있는데, 접속이 되지 않는 경우
분명 데몬은 정상적으로 떠 있고 MaxClients에 도달하지도 않았는데, 실제로 접속이 되지 않는 경우가 있다. 이러한 경우라면 웹 서버가 TCP SYN Flooding 공격을 받고 있을 가능성이 있다. netstat -na | grep SYN으로 확인하여 많은 SYN_RECEIVED 프로세스가 보인다면 이 공격 때문이며 이러한 경우에는 첫 번째 줄의 명령을 사용하거나 두 번째 줄의 syncookies 기능을 enable하면 된다.

# sysctl ?w net.ipv4.tcp_syncookies=1
# echo 1 > /proc/sys/net/ipv4/tcp_syncookies

Syncookie 기능은 일단 커널에서 지원되어야 하므로 이 설정이 적용되지 않으면 커널에서의 설정여부를 확인해 보아야 한다. 이 공격에 대한 보다 자세한 내용은 본지 7월호에 실린 “TCP SYN Flooding 공격의 원인과 해결책”을 참고 하기 바란다.

코드레드나 님다(Nimda) 등 웜 공격으로 로그 파일의 크기가 커질 때 최근에 코드레드와 님다 등 윈도우 NT/2000 기반의 IIS를 공격하는 무차별적인 웜 공격으로 인하여 부하가 유발되고 로그 파일이 불필요한 데이터로 채워지는 경우가 있다. 로그 파일의 크기가 커지는 것은 감안하더라도 당장 계속적으로 커지는 로그 파일 때문에 서버에 부하를 유발하는 것이 더욱 큰 문제다.
서버에서 로그를 남기는 방식은 매번 클라이언트의 요청이 있을 때마다 웹 서버에서 패킷 헤더에 있는 클라이언트의 정보를 받아낸 후 로그 파일을 열도록 한 후 로그 파일을 읽어 파일의 제일 끝으로 이동하여 로그 정보를 추가한 후 파일을 닫는 것인데, 불필요한 요청이 있을 때마다 이 작업을 계속하여야 하므로 서버에 부하를 유발함은 당연한 현상이다.
따라서 아예 로그를 남기지 않도록 하거나 로그를 남긴다 하더라도 불필요한 정보를 남기지 않도록 하는 것이 미소하게나마 서버의 성능을 높이는 것이 될 것이다. 그럼 실제로 불필요한 정보는 아예 로그를 남기지 않는 방법에 대해
알아보도록 하자. 이를테면 코드레드의 경우 다음과 같이 무차별적인 로그가 남게 된다.

2001/08/01 23:39:50.765446 152.158.99.4:58781 -> 211.233.38.193:80 [AP]
GET/default.ida?
NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
NNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
이러한 로그를 막기 위해서는 httpd.conf 파일을 열어 Custom Log 윗줄에
SetEnvIf Request_URI “/default.ida$” cord-red와 같이 정의한 후
CustomLog/usr/local/apache/logs /access.log combined라고 설정되어 있는 부 분을
CustomLog /usr/local /apache/logs//access.log combined env=!cord-red 라고 수정을 한다.
!는 not의 의미이므로 위 설정은 환경변수 cord-red로 정의된 요청을 거부하라는 뜻이다. 위와 같이 설정 후 아파치를 재시작하면 코드레드와 관련된 로그가 남지 않게 된다. 코드레드에 이은 님다 웜의 경우도 같은 방식으로 설정하
여 로그에 남지 않도록 설정할 수 있다.
또한 같은 원리를 이용하여 iptables를 이용하여 아예 패킷 자체를 차단할 수도 있는데, 코드 레드의 경우 default.ida 문자열을 요청한다는 특징을 이용하여 다음과 같이 차단할 수 있다.

iptables ?A INPUT -i eth0 -p tcp --tcp-flags ACK ACK --dport 80
-m string --string ‘/default.ida?’ -j REJECT --reject-with tcp-reset와 같이 iptables의 ?strings를 이용하여 특정 문자열이 포함된 패킷을 차단하는 방법도 있기는 하지만 이 방법은 커널과 iptables를 다시 컴파일해야 하는 문제가 있다. 님다 웜 역시 이외 cmd.exe 와 root.exe를 포함하므로 같은 방식으 로 다음과 같이 차단할 수 있다.

iptables -A INPUT -p tcp --tcp-flags ACK ACK --dport 80 -m string --
string "cmd.exe" -j REJECT --reject-with tcp-reset
iptables -A INPUT -p tcp --tcp-flags ACK ACK --dport 80 -m string --
string "root.exe?" -j REJECT --reject-with tcp-reset

* 서버 네임(ServerName) 인자 관련 에러 대처
아파치 서버를 시작시 자주 만나는 에러와 관련된 설정 중 하나가 바로 다음과 같은 서버 네임이다.

# /usr/local/apache/bin/apachectl start
httpd: cannot determine local host name.
Use the ServerName directive to set it manually.
./apachectl startl: httpd could not be started

대부분 서버 네임은 리눅스 설치 시 입력한 호스트 이름을 자동으로 가지고와 설정되나 DNS상에 존재하지 않은 도메인명이나 설사 존재하더라도 로컬 서버가 아닌 잘못된 도메인을 정의시 이러한 현상이 나타난다. 이러한 경우에는 서버 네임을 실제 로컬 서버의 호스트 이름이나 IP 주소로 설정해 주어야 한다.
또한 서버 네임을 잘못 설정 시 나타날 수 있는 현상 중 하나가 http: //domain.com/~user와 같이 접속할 때의 문제다. 즉, 서버 내 계정 사용자의 홈페이지를 접속시 http://domain.com/ ~user/와 같이 접속하면 접속이되나 http://domain.com/~user 와 같이 /를 붙이지 않으면 접속이 되지 않는 경우다.
클라이언트가 서버의 디렉토리에 접속시 끝에 /(trailing)을 하지 않은 경우 서버는 클라이언트에게 /을 붙여 다시 접속을 하라고 요청한다. 그렇지 않으면 상대 URL 경로를 인식하지 못하는 문제가 있기 때문이다. 만약 DNS가 정상
적으로 세팅되어 작동하고 있을 경우에는 문제가 없지만 그렇지 않은 경우에는 접속이 되지 않는 경우가 생긴다. 또는 위에서처럼 서버 네임에 지정된 호스트네임이 실제로 DNS 상에 리졸빙이 되지 않는 경우도 이러한 현상이 나타나므로 이러한 경우에는 httpd.conf의 서버 네임 옵션에 실제 서비스 중인 도메인명으로 입력해 주면 된다.

* 특정 파일의 접근 제한이 되지 않을 때
가끔 서버를 운영하다보면 특정한 디렉토리 이하에 대해서는 인증된 유저만 접속이 가능하게 한다거나 특정 IP 대역의 유저만 접근하도록 하고자 할 필요가 있을 때가 있다. 특정 디렉토리 이하에 대해서 접근을 제어하고자 할 때에
는 .htaccess를 사용하거나 httpd.conf에서 <Directory>를 이용하여 제어를 할 수 있지만, 만약 특정한 파일에 대해서 외부에서의 접근을 제한하고자 한다면 어떻게 하여야 할까?
이때는 Location을 사용하면 된다. httpd.conf 파일에 다음과 같이 설정시 모든 디렉토리 이하의 secret.html 파일에 대해서는 192.168.1.1에서만 접근이 가능하게 된다.

<Location /secret.html>
order deny,allow
deny from all
allow from 192.168.1.1
</Location>

만약 여러 도메인이 설치되어 있는 호스팅 서버의 경우 secret.tt. co.kr 도메인 내의 secret.html에 대해서만 접근을 제어하고자 할 경우에는 다음과 같이 버추얼 호스트 설정에서 하면 된다.

<VirtualHost secret.tt.co.kr>
ServerAdmin antihong@tt.co.kr
DocumentRoot /usr/local/apache/htdocs/secret/
ServerName secret.tt.co.kr
<Location /secret.html>
order deny,allow
deny from all
allow from 192.168.1.1
</Location>
</VirtualHost>

또는 위와 같이 IP가 아니라 특정한 ID/PW를 입력한 유저에 대해서만 특정 파일에 대하여 접근을 허용하고자 할 때가 있다. 이러한 경우에는 httpd.conf에 다음과 같이 설정하면 된다.

<VirtualHost secret.tt.co.kr>
ServerAdmin antihong@tt.co.kr
DocumentRoot /usr/local/apache/htdocs/secret/
ServerName secret.tt.co.kr
<Files secret.html>
AuthName "ID/PW 를 입력하세요."
AuthType Basic
AuthUserFile /usr/local/apache/htdocs/.htpasswd
Require valid-user
</Files>
</VirtualHost>

그리고 htpasswd ?c htpasswd id로 .htpasswd 파일에 ID/PW를 생성하여 secret.html에 접근시 ID/PW를 정확히 입력한 유저에 대해서만 접근이 가능하게 된다.

한글 도메인으로 접속이 되지 않을 때 한글.com 형식의 한글 도메인 서비스가 1년 가까이 아직 정상적인 서비스가
되고 있지는 않지만 현재는 포워딩 방식으로나마 일부 사용 가능하다. 즉, 그 자체로 한글.com으로의 사용은 불가능하며 단지 한글.com을 접속시 다른 도메인으로 포워딩 할 수 있는 것이다. 현재 http://www.gabia.com/http://www.doregi.com/ 등에서 한글 도메인을 검색해 보면 예를 들어 팬메일.net의 경우 BQ--3DJSZOSUY56A.NET와 같이 BQ- 형식의 RaceCode 문자로 되어 있는데, 실제로는 bq--3djszosuy56a.mltbd.net와 같이 mltbd.net(한글.com 일 경우에는 mltbd.com, 한글.org 일 경우에는 mltbd.org)의 2차 도메인 형식으로 서비스된다. 따라서 위와 같이 WHOIS 검색을 한 후 나온 RaceCode을 DNS 서버에서 먼저 설정하여야 하는데, DNS 서버의 named.conf에서 설정하여야 할 내용은 다음과 같다.

zone "bq--3djszosuy56a.mltbd.net" {
type master;
file "bq--3djszosuy56a.mltbd.net.zone";
};

bq--3djszosuy56a.mltbd.net.zone 파일의 형식은 일반 zone 파일 형식과 동일하게 설정하면 된다.
그리고 DNS 서버에서 지정한 해당 웹 서버에서는 다음과 같이 버추얼 호스트 설정을 하여 원래의 사이트인 http://panmail.net/ 으로 리다이렉트하면 된다
(현재까지는 포워딩 서비스만 제공하므로 Redirect를 이용하여야 한다).

<VirtualHost bq--3djszosuy56a.mltbd.net>
ServerAdmin webmaster@bq--3djszosuy56a.mltbd.net
DocumentRoot /usr/local/apache/htdocs/panmail
ServerName bq--3djszosuy56a.mltbd.net
ServerAlias www.bq--3djszosuy56a.mltbd.net
Redirect / http://panmail.net
</VirtualHost>

위와 같이 설정 후 아파치를 재시작하면 팬메일.net으로 접속시 http://panmail.net/ 으로 접속이 되는 것을 확인할 수 있을 것이다.


* 기타 시스템 장애 대처법
리눅스가 윈도우 계열과 다른 가장 큰 특징 중 하나는 로그(log)를 철저히 남긴다는 것이다. 남겨진 로그 정보를 이용하여 각종 시스템의 장애나 상태를 점검할 수가 있는데, 아파치 웹 서버 역시 마찬가지다. 문제나 장애가 발생 시에는 반드시 error_log를 남기게 하여 /usr/local /apache/logs/error_log의 메시지를 살펴보면 문제의 원인과 해결책을 어렵지 않게 찾을 수 있게 될 것이다.
문제가 발생하였다고 당황하거나 무턱대고 관련 게시판에 질문을 올리지 말고, 에러 로그의 내용을 기초로 차근차근 문제의 원인을 분석하고 해결해 나간다면 조금씩 서버 관리자에 가까워지는 자신을 발견할 수 있을 것이다.

Posted by 제논
[Apache Error Code]

100 : Continue
101 : Switching protocols
200 : OK, 에러없이 전송 성공
201 : Created, POST 명령 실행 및 성공
202 : Accepted, 서버가 클라이언트 명령을 받음
203 : Non-authoritative information, 서버가 클라이언트 요구 중 일부만 전송
204 : No content, 클라언트 요구을 처리했으나 전송할 데이터가 없음
205 : Reset content
206 : Partial content
300 : Multiple choices, 최근에 옮겨진 데이터를 요청
301 : Moved permanently, 요구한 데이터를 변경된 임시 URL에서 찾았음
302 : Moved temporarily, 요구한 데이터가 변경된 URL에 있음을 명시
303 : See other, 요구한 데이터를 변경하지 않았기 때문에 문제가 있음
304 : Not modified
305 : Use proxy
400 : Bad request, 클라이언트의 잘못된 요청으로 처리할 수 없음
401 : Unauthorized, 클라이언트의 인증 실패
402 : Payment required, 예약됨
403 : Forbidden, 접근이 거부된 문서를 요청함
404 : Not found, 문서를 찾을 수 없음
405 : Method not allowed, 리소스를 허용안함
406 : Not acceptable, 허용할 수 없음
407 : Proxy authentication required, 프록시 인증 필요
408 : Request timeout, 요청시간이 지남
409 : Conflict
410 : Gone, 영구적으로 사용할 수 없음
411 : Length required
412 : Precondition failed, 전체조건 실패
413 : Request entity too large,
414 : Request-URI too long, URL이 너무 김
415 : Unsupported media type
500 : Internal server error, 내부서버 오류(잘못된 스크립트 실행시)
501 : Not implemented, 클라이언트에서 서버가 수행할 수 없는 행동을 요구함
502 : Bad gateway, 서버의 과부하 상태
503 : Service unavailable, 외부 서비스가 죽었거나 현재 멈춤 상태
504 : Gateway timeout
505 : HTTP version not supported

Posted by 제논
공부합시다/Security2008/12/16 15:11
기초적인 보안을 위해 불필요한 계정의 삭제 및 퍼미션의 설정에 관한 내용 입니다.

1. 불필요한 계정은 삭제 한다.
: ftp, xfs, adm, lp, newes, gopher를 /etc/passwd와 /etc/group에서 주석처리 또는
  userdel uid, groupdel gid를 해서 삭제 한다.
1)
#userdel adm
#userdel lp
#userdel sync
#userdel shutdown
#userdel halt
#userdel news      ( 뉴스그룹으로 위장하여 표적이 되기 쉽다. )
#userdel uucp
#userdel operator
#userdel games
#userdel gopher
#userdel ftp        (anymous FTP server를 운영하지 않으면 삭제 한다.)

2)
#groupdel adm
#groupdel lp
#groupdel news
#groupdel uucp
#groupdel games
#groupdel dip
#groupdel pppusers
#gropudel slipusers

2. 퍼미션 설정변경
: 중요한 설정 파일의 퍼미션을 변경하여 일반 유저들의 접근을 제한한다.
1) /etc/
chmod 700 /etc/exports
  "      /etc/fstab
  "      /etc/hosts         
  "      /etc/hosts.deny   
  "      /etc/hosts.allow   

2) /bin/
chmod 700 /bin/mount
chmod 700 /bin/umonut

3) /sbin/
chmod 700 /sbin/netreport

4) /usr/bin/
chmod 700 /usr/bin/top 
  "      /usr/bin/find 
  "      /usr/bin/lynx    lynx,wget 명령어는 일반적으로 해커들이 해킹툴을 가져올때 자주쓰는 명령어
  "      /usr/bin/wget 
  "      /usr/bin/chage
  "      /usr/bin/finger    서버 이용자 파악을 하지 못하게 함
  "      /usr/bin/wall     
  "      /usr/bin/man       
  "      /usr/bin/chfn     
  "      /usr/bin/write     
  "      /usr/bin/finger   
  "      /usr/bin/nslookup 
  "      /usr/bin/suidperl  suid 걸린 파일
  "      /usr/bin/sperl5.6.0 perl중에 suid걸린 파일(버젼에따라 틀림)
  "      /usr/bin/whereis   
  "      /usr/bin/cc        소스 컴파일은 루트이외에 못하도록 조치
  "      /usr/bin/c++       
  "      /usr/bin/gcc     
  "      /usr/bin/make     
  "      /usr/bin/pstree   
  "      /usr/bin/rlog     
  "      /usr/bin/rlogin    필요없는 경우에는 삭제
  "      /usr/bin/which     
  "      /usr/bin/who       
  "      /usr/bin/w         
  "      /bin/mail          계정상에서 텔넷으로 메일을 확인하지 못하게
         
5) /usr/sbin
chmod 700 /usr/sbin/usernetctl

6) chattr +i /etc/fstab와 같이 속성에 Lock을 걸어 파일을 수정 할 수 없게 한다.

3. 시스템 관련 명령어를 특정 사용자그룹에서만 사용가능 하도록 설정 한다.
- /etc/group을 열어 wheel:x:10:root,kim 와 같이 kim 이라는 계정을 wheel 그룹에 추가 한다.
그러면, root를 포함하여 wheel 그룹에 속한 tt라는 계정만이 위 명령어를 수행할 수 있다
chmod 750 /bin/ps
          /bin/su            root로 전환할 유저를 제한
          /bin/netstat
          /bin/dmesg
          /bin/df
          /usr/bin/who
          /usr/bin/finger
          /usr/bin/last
          /usr/bin/top
          /usr/bin/w

chgrp wheel /bin/ps
            /bin/su
            /bin/netstat
            /bin/dmesg
            /bin/df
            /usr/bin/w
            /usr/bin/who
            /usr/bin/finger
            /usr/bin/last
            /usr/bin/top



--------------------------------------
su 사용 제한 하기
Linux 2008/10/01 15:37
http://blog.nice2seeyou.com/mike/211


/etc/pam.d/su 에 보시면 새로운 라인 2개를 보실 수 있습니다.

# Uncomment the following line to implicitly trust users in the "wheel" group.
auth sufficient /lib/security/pam_wheel.so trust use_uid

이 부분은 wheel 그룹에 포함되어 있는 그룹들은 패스워드 인증 없이 바로 root 의 권한을 가질수 있게 해 줍니다.

# Uncomment the following line to require a user to be in the "wheel" group.
auth required /lib/security/pam_wheel.so use_uid

이 부분은 wheel 그룹에 포함되어 있는 그룹들만이 root 로의 su 를 허락하게 합니다.

--------------------------------------------------------------------------------
/etc/pam.d/su 에 첫줄에 다음을 추가
auth required /lib/security/pam_wheel.so debug group=wheel

/etc/group 의 wheel 그룹에 su - 허용하고자 하는 사용자 그룹 등록
wheel:x:10:root,someone

만약 허용되지 않은 그룹의 사용자가 su - 를 시도하면
/var/log/message 에 PAM-Wheel[25873]: Access denied for \'babo\' to \'root\'
와 같이 로그가 남습니다.

Posted by 제논
FreeBSD에서 리눅스의 tmpfs 파일시스템, ramdisk처럼 메모리를 파일시스템으로 사용하는 방법을 설명한다. ramdisk는 메모리를 사용하므로 서버가 부팅시 깨끗하게 지워지며, 디스크 액세스가 빈번하게 일어나는 경우에 효과를 볼 수 있다. FreeBSD 5.x, 6.x 기준 ramdisk 사용하는 방법을 설명한다.


1. mdconfig 명령 이용

  # mdconfig -a -t swap -s 512M -u 1
  # newfs -U /dev/md1
  # mount /dev/md1 /var/tmp

mdconfig은 메모리 디스크(md)를 설정하고 enable하는 명령이다.

-a : 메모리 디스크를 attach한다. -d는 반대로 detach한다.
-t : 메모리 디스크의 유형을 선택한다.
-s : 메모리 디스크의 크기를 설정한다. 숫자뒤에 b(Byte), k(KByte), m(MByte), g(GByte), t(terabyte) 단위 설정 가능
-u : md(memory disk) device의 unit 번호를 지정한다. 지정하지 않으면 자동으로 할당한다.

메모리 디스크 유형에는 swap과 malloc 2가지가 있다. 보통 swap 유형을 사용하며, 여기서 swap은 메모리가 부족한 경우에 disk로 swap될 수 있는 메모리 영역을 할당한다는 것을 의미하는 것이지, 기본적으로 disk로 swap됨을 의미하는 것이 아니다. malloc 유형은 malloc() function 으로 할당하는 경우로, 메모리가 부족할 때 시스템 패닉이 생길 수 있다.

newfs의 -U는 soft-updates를 enable하는 옵션으로 디스크의 쓰기 속도를 향상시킨다. 메모리 디스크를 attach했다면 md device 목록을 확인해보자. (mount여부와 무관하게 attach했다면 목록에서 볼 수 있음)

  # mdconfig -l
  md1

메모리는 실제 사용을 할 시점에 할당이 된다. mount를 했지만 메모리 디스크에 파일이 없을 때의 메모리 상태이다.

 Mem: 442M Active, 550M Inact, 175M Wired, 24K Cache, 112M Buf, 2596M Free

100MBytes 파일을 하나 만들어보자.

  # dd if=/dev/zero of=foobar.img bs=1024k count=100


free 메모리가 줄어들었음을 확인할 수 있다. 파일을 삭제하면 다시 메모리는 반환된다.
 Mem: 442M Active, 602M Inact, 221M Wired, 24K Cache, 112M Buf, 2498M Free


메모리 디스크가 더 이상 필요가 없다면 detach를 한다.

  # umount /var/tmp
  # mdconfig -d -u 1



2. mdmfs 명령을 사용하여 한방에

mdmfs는 mdconfig, newfs, mount 명령을 한방에 처리해주는 명령이다. 기본으로 soft-updates가 enable된 상태의 swap기반(swap-based) 디스크를 사용한다. swap backing대신 malloc backing 디스크를 원하면 -M 옵션을 사용하면 된다.

  # /sbin/mdmfs -s 512M md1 /var/tmp
  # mount
  ... 생략 ...
  /dev/md1 on /var/tmp (ufs, local, soft-updates)


3. /etc/fstab 설정

  /dev/md1    /var/tmp        mfs    rw,-s512M 2 0


4. 참고자료

* RAMdisks, creating under FreeBSD 5.x
http://freebsdwiki.net/index.php/RAMdisks,_creating_under_FreeBSD_5.x
* FreeBSD Handbook (Chapter 17 Storage)
http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/disks-virtual.html

Posted by 제논
리눅스와 맥OS X에서 램디스크 만들기
http://techblog.tistory.com/entry/Ramdisk


리눅스 커널 2.4 이후 버젼의 리눅스를 사용하고 있으면 이미 램디스크 지원이 내장되어 있다. 확인하고 싶으면 다음의 명령어를 사용하면 된다.

$ dmesg | grep RAMDISK
RAMDISK driver initialized: 16 RAM disks of 16384K size 1024 blocksize

CentOS나 RHEL인 경우 위와 같은 출력이 나오고 다른 리눅스 배포판인 경우도 유사한 결과가 나온다. 아래 명령어로 만들어 져 있는 램 디스크를 볼 수 있다.

$ ls -l /dev/ram*
lrwxrwxrwx 1 root root 4 Apr 24 12:05 /dev/ram -> ram1
brw-rw---- 1 root disk 1, 0 Apr 24 12:05 /dev/ram0
brw-rw---- 1 root disk 1, 1 Apr 24 12:05 /dev/ram1
brw-rw---- 1 root disk 1, 10 Apr 24 12:05 /dev/ram10
brw-rw---- 1 root disk 1, 11 Apr 24 12:05 /dev/ram11
brw-rw---- 1 root disk 1, 12 Apr 24 12:05 /dev/ram12
brw-rw---- 1 root disk 1, 13 Apr 24 12:05 /dev/ram13
brw-rw---- 1 root disk 1, 14 Apr 24 12:05 /dev/ram14
brw-rw---- 1 root disk 1, 15 Apr 24 12:05 /dev/ram15
brw-rw---- 1 root disk 1, 2 Apr 24 12:05 /dev/ram2
brw-rw---- 1 root disk 1, 3 Apr 24 12:05 /dev/ram3
brw-rw---- 1 root disk 1, 4 Apr 24 12:05 /dev/ram4
brw-rw---- 1 root disk 1, 5 Apr 24 12:05 /dev/ram5
brw-rw---- 1 root disk 1, 6 Apr 24 12:05 /dev/ram6
brw-rw---- 1 root disk 1, 7 Apr 24 12:05 /dev/ram7
brw-rw---- 1 root disk 1, 8 Apr 24 12:05 /dev/ram8
brw-rw---- 1 root disk 1, 9 Apr 24 12:05 /dev/ram9
lrwxrwxrwx 1 root root 4 Apr 24 12:05 /dev/ramdisk -> ram0

결과에 나온 모든 램 디스크 크기는 동일하다. 위의 예제에서는 모두 16MB이다. 이걸 128MB까지 사용할 수 있게 변경해 보겠다. 단 여기서는 사용할 수 있게 해 주는거지 실제로 128B를 할당해주는게 아니다. 후에 드라이브중 하나를 포맷해 줌으로서 실제 영역을 할당해주게 된다. 램디스크 용량은 1024의 배수로 지정해 줘야 하기 때문에 128MB인 경우 131072K가 된다.

에디터를 사용해 /etc/grub.conf 파일을 열어보면 아래와 같은 라인을 찾을 수 있을 것이다.

kernel /vmlinuz-2.6.9-42.0.10.EL ro root=/dev/VolGroup00/LogVol00

이 라인의 뒤쪽 부분에 ramdisk_size=131072를 추가해주면 된다.

kernel /vmlinuz-2.6.9-42.0.10.EL ro root=/dev/VolGroup00/LogVol00 ramdisk_size=131072

변경된 파일을 저장하고 에디터를 종료한다. 이 시점에서 램디스크 용량을 변경했지만 변경된 내용을 적용하려면 시스템을 리부트 시켜줘야 한다. 시스템이 리부트되고 나서 나머지 설정을 해 주면 된다.

$ mke2fs -m 0 /dev/ram0

위의 명령을 사용해서 ram0 램디스크를 사용할 수 있게 포맷 해 준다. 이 과정에서 커널이 메모리에 램디스크를 위한 용량을 할당해주게 된다. 포맷이 끝나면 램디스크를 마운트 시켜주면 된다.

$ mkdir /mnt/rd
$ mount /dev/ram0 /mnt/rd

이제 램디스크를 사용할 수 있다. 이렇게 만들어 진 램디스크를 특정 사용자가 사용할 수 있게 해 주려면 chown 명령을 사용해서 오너를 변경해주면 된다.

$ chown testuser.testuser /mnt/rd

mount명령을 사용하면 램디스크가 /mnt/rd에 마운트 된 걸 볼 수 있다.

$ mount
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
/dev/hda2 on /home type ext3 (rw)
tmpfs on /dev/shm type tmpfs (rw)
none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)
sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw)
/dev/ram0 on /mnt/rd type ext2 (rw)

주의할것은 램디스크이기 때문에 여기에 저장된 내용은 시스템을 리부팅하면 모두 지워지게 된다는 것이다. 단 램디스크를 언마운트 했다가 다시 마운트 하는 경우에는 램디스크 내용이 그대로 살아있다.

시스템이 부팅할 때 마다 자동으로 램디스크를 만들도록 설정하고 싶으면 아래의 내용을 /etc/rc.local 파일에 추가해주면 된다.

mke2fs -m 0 /dev/ram0
mount /dev/ram0 /mnt/rd
chown testuser.testuser /mnt/rd

Posted by 제논
TAG Linux, ramdisk