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

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

예) 공격지 IP 인 211.40.4.6 으로부터의 라우팅을 차단하는 설정
# route add –host 211.40.4.6 reject
# iptables –A INPUT –s 211.40.4.6 –j DROP
실제 적용되었는지 확인하는 방법은 각각 route –n 과 iptables –L –n 이다.
참고로 TCP SYN Flooding 공격의 경우 SYN 패킷만 대량으로 발송할 뿐 ESTABLISHED 상태가 되지 않으므로TCP SYN Flooding 공격과는 무관하다.

(2) 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 이후의 high port 를 이용하여 통신한다는 특성을 이용한 것이다. 그러나 이 설정을 하였을 경우 로컬 서버에서 클라이언트 포트를 전혀 사용할 수 없게 되므로 다른 서비스에도 장애가 되기 때문에 임시로만 사용하기 바란다.
또는 ps aux | grep http 로 보이는 프로세스에서 ls –la /proc/pid/ 로 각각의 http 프로세스가 어떤 파일을 참조하고 있는지 일일이 추적하는 방법도 있다.
(예:cwd -> /home/user1/public_html/infinite_loop/)

정상적인 접속의 경우에는 아래와 같이 대처한다.

(1) KeepAlive 옵션 변경
기본값으로 설정되어 있는 KeepAlive On 을 KeepAlive Off 로 변경 후 아파치를 재시작한다. KeepAlive 는 HTTP 1.1 규약에서부터 적용된 것으로 접속 속도에 큰 영향을 준다. KeepAlive 를 Off 로 설정시 다소 접속 속도는 떨어지지만 좀 더 많은 동시 접속을 수용할 수 있다. 따라서 MaxClients 에 도달할 정도로 동시 접속자가 많은 경우에는 KeepAlive 를 Off 로 설정하는 것이 다소 임시 방편이기는 하지만 해결 방법이 될 것이다.
KeepAlive 설정에 대해서는 Hit의 개념과 관련 지어 이해하면 된다. 예를 들어 10개의 이미지 파일을 링크한 HTML 페이지를 로딩시 웹브라우저는 이 HTML 파일을 다운로드하여 클라이언트에서 파싱(parsing) 을 하면서 이미지 파일등이 링크되어 있을 경우 서버에 접속하여 이미지 파일을 요청하는데, KeepAlive 가 On 일 경우에는 한 번 맺은 TCP 연결에 대해 같은 Client IP 에서 접속이 있을 것이라 가정하고 기존의 프로세스가 대기하고 있다가 이후의 접속을 처리하기 때문에 다시 접속을 맺는 절차가 필요 없이 빨리 서비스가 가능하지만, KeepAlive 가 Off 인 경우에는 이미지 파일을 불러올 때마다 매번 세션을 새로 맺고 끊는 과정을 반복하여야 하기 때문에 속도가 느려질 수 밖에 없다. 아파치 홈페이지의 문서에 의하면 많은 이미지 파일이 있는 HTML 문서를 로딩시 KeepAlive 설정에 따라 최고 50%까지 속도 차이가 날 수 있다고 한다. 그렇다고 해서 모든 사이트에서 KeepAlive 를 On 으로 하는 것이 좋은 것이 아니다. 순간적인 동시 접속자는 많지만 한 두 번 검색 후 검색 결과의 링크를 따라 다른 사이트로 빠져 나가는 검색 엔진의 경우에는 KeepAlive 를 Off 로 하는 것이 유리할 것이다. KeepAlive 를 On으로 설정하여 그대로 사용할 경우에는 15초로 설정된 KeepAlive Timeout 을 15초에서 5초 정도로 낮게 설정하는 방법도 있으며 이 값은 자신의 시스템 환경에 맞게 적절히 설정하기 바란다.

(2) 아파치의 MaxClients 조절
기본적으로는 256으로 설정되어 있는 MaxClients 의 한계를 512나 1024 와 같이 적절히 변경한다. 그러나 이 값을 변경하기 위해서는 아파치의 소스를 수정 후 다시 컴파일 하여야 하므로 아파치의 소스 디렉토리에 있는src/include/httpd.h 파일에서 HARD_SERVER_LIMIT 256 로 설정된 값을 512 나 1024로 변경 후 아파치를 재컴파일 하면 된다. 만약 커널 2.2.X 일 경우에는 /usr/src/linux/include/linux/tasks.h 에서 NR_TASKS 와 MAX_TASKS_PER_USER 변수 역시 수정한 후 커널을 재컴파일 해 주어야 하며, 2.4.X 의 경우에는 관련된 커널 제한이 없어졌으므로 아파치만 재컴파일 하면 된다.
그러나 대부분의 사이트에서는 256정도로 설정되어도 충분히 서비스가 가능하므로 무작정 이 값을 크게 늘려 메모리를 낭비할 필요가 없으니 특별한 경우가 아니라면 이 값을 늘리지 않는 것이 좋다.

(3) 추가 아파치 데몬 설정
만약 여러 도메인중 특정 도메인이나 어떠한 사이트내 특정 컨텐츠의 접속이 특별히 많아 같은 서버에 있는 다른 사이트에까지 피해를 주고 있다면 이 부분을 별도로 데몬을 띄워 서비스하는 방법도 있다. 이를테면 한 사이트에서 게시판의 접속이 매우 많다면 기존의 80번 포트외에 8080과 같은 임의의 포트로 작동하는 웹 데몬을 추가로 띄워 이 포트를 통해 접속이 많은 서비스를 담당하게 하는 것이다. 이를 위해서는 기존의 httpd.conf 파일을 httpd8080.conf 와 같이 설정 파일을 복사 후 httpd8080.conf 파일을 아래와 같이 변경하면 된다.

port 80 à port 8080
User nobody à User www
Group nobody à Group www

그리고 /usr/local/apache/bin/httpd –f /usr/local/apache/conf/httpd8080.conf 와 같이 실행하면 8080포트로 작동하는 웹서버 데몬을 추가로 띄우게 되는 것이다. 물론 이때 www 라는 계정은 서버에 생성되어 있어야 하며 Nobody 가 아닌 www 라는 별도의 계정으로 데몬을 작동하는 이유는 한 유저(nobody) 가 생성할 수 있는 프로세스의 한계가 있기 때문이며 커널 2.4.X 에서는 이 제한이 없으므로 Nobody 로 작동해도 관계 없다.
또는 기존의 웹데몬인 httpd 와 파일 이름을 다르게 하여 서로 구별을 쉽게 하기 위해 httpd 대신 httpd8080 등 다른 이름으로 변경하여 실행하여도 좋다.
웹 접속은 http://domain.com:8080/ 으로 하면 되며 이러한 방식으로 8081, 8082, 8083….등의 여러 포트를 띄울 수 있다. 실제로 얼마 전 필자가 운영하는 호스팅 서버에서 특정 사이트의 게시판의 접속이 폭주하여 모든 웹 접속이 느려진 적이 있었는데, 위와 같이 게시판 부분만 따로 떼어 8080 포트로 분리하여 서비스를 하여 문제를 해결한 적도 있다.
2005/07/01 15:19 2005/07/01 15:19
누구나 업로드나 다운로드가 가능한 자료실을 운영하고 있을 경우 사이즈가 너무 큰 파일을 업로드 또는 다운로드 할 경우 부하가 많이 걸리게 되어 결국 시스템의 성능 저하를 유발하게 된다. 최근 배포되는 게시판/자료실 프로그램에서는 대부분 업로드 할 수 있는 용량등을 제한할 수 있는 기능이 있지만 그렇지 않은 프로그램도 상당수 있어 웹 서버 차원에서 이 제한을 적절히 설정할 필요가 있다. 아파치에서는 이와 관련하여 웹 서버에서 업로드/다운로드 할 수 있는 파일의 사이즈를 제한하는 LimitRequestBody 기능을 이용할 수 있다.
LimitRequestBody 는 클라이언트가 요청시 http 프로토콜을 통해 서버가 제공할 수 있는 메시지의 크기를 byte 단위로 정의하는 것으로 무한대를 의미하는 0부터 2,147,483,647(2Giga) 까지 설정 가능하며 이 설정으로 대용량의 파일을 업/다운로드 하는 형태의 서비스 거부 공격을 차단할 수 있다. 이를 설정하는 방법은
httpd.conf 를 열어 아래의 라인을 추가하면 된다.


LimitRequestBody 7168000


LimitRequestBody 10240000


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

Order allow,deny
Deny from all


이러한 방식으로 특정한 파일에 대해 웹에서의 접근을 차단할 수 있다. 따라서 CGI 파일에 아무리 소유권과 실행 권한을 주었다 하더라도 웹서버 자체에서 접근을 거부하였으므로 웹에서 접근하면 Forbidden 에러가 나게 된다. 이러한 식으로 특정 파일 이름을 가진 파일의 실행이나 접근을 차단할 수 있다
2005/07/01 15:18 2005/07/01 15:18