반응형

#!/bin/sh

#iptables Path
iptables=/sbin/iptables

# SERVER IP 받아오기.
HOST_IP="`/sbin/ifconfig eth0 | grep 'inet addr' | awk '{print $2}' | sed -e 's/.*://'`"
NETMASK="`/sbin/ifconfig eth0 | grep 'inet addr' | awk '{print $4}' | cut -d : -f 2`"

# rule delete
# 모두 지우고 다시 재설정합니다.
$iptables -F

######### 비정상적 패킷은 드롭시킨다. 로그에 남긴다. ###############
iptables -A FORWARD -m state --state INVALID -j DROP
iptables -A FORWARD -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
iptables -A FORWARD -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN,RST -j DROP

#iptables -A FORWARD -p tcp --tcp-flags ALL FIN,URG,PSH -m limit --limit 5/minute -j LOG --log-level notice --log-prefix "NMAP-XMAS:"
#iptables -A FORWARD -p tcp --tcp-flags SYN,FIN SYN,FIN -m limit --limit 5/minute -j LOG --log-level notice --log-prefix "SYN/FIN:"
#iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN,RST -m limit --limit 5/minute -j LOG --log-level notice --log-prefix "SYN/RST:"


#Drop RST/ACKs to limit OS detection through pinging
iptables -A FORWARD -p tcp --tcp-flags RST RST,ACK -j DROP
#iptables -A FORWARD -p tcp --tcp-flags RST RST,ACK -m limit --limit 5/minute -j LOG --log-level notice --log-prefix "RST/ACK:"

# INPUT Rules 설정
$iptables -Z INPUT
$iptables -P INPUT ACCEPT

# local 과 자기자신의 IP 는 허용.
$iptables -A INPUT -i lo -j ACCEPT
$iptables -A INPUT -s 도메인 -j ACCEPT

#  알 수 없는 패킷 즉,  NETWORK 상태가 INVALID 인 패킷들을 막아 버린다.
#  정상적인 접근에서는 나올 수 없는 상태.
$iptables -A INPUT -m state --state INVALID -j DROP

# ssh service
# ssh 접속 지역 지정.
$iptables -A INPUT -s 아이피.0.0/16 -p tcp --dport 22 -j ACCEPT
$iptables -A INPUT -s 아이피.0/24 -p tcp --dport 22 -j ACCEPT

# etc service
# 25(메일), 80(웹)은 모든 곳에서 ACCEPT 입니다. 반드시...
$iptables -A INPUT -p tcp --dport 25 -m state --state NEW,ESTABLISHED -j ACCEPT
$iptables -A INPUT -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT

# AUTH 는 서비스를 하지 않더라도 열어야 합니다. 클라이언트에서 요청합니다.
$iptables -A INPUT -p tcp --dport 113 -m state --state NEW,ESTABLISHED -j ACCEPT

# mysql
# 기본적으로 mysql 은 local에서만 접속하면 됩니다. DB 공유를 할 경우 대역 지정.
$iptables -A INPUT -p tcp --dport 3306 -m state --state NEW,ESTABLISHED -j ACCEPT

# mysql DB공유 대역설정
$iptables -A INPUT -s 아이피.0/24 -p tcp --dport 3306 -j ACCEPT

# ICMP service
# ping은 별 의미가 없지만...
$iptables -A INPUT -s 아이피.0.0/16 -p icmp --icmp-type echo-request -j ACCEPT

# 서버로 들어오는 SYN packet 을 모두 거절한다.
$iptables -A INPUT -p tcp --syn -j REJECT

# Drop All packet
# 원활한 서비스를 위해 65535 포트까지만 DROP 을 합니다. 물론 다 막아도 상관 없습니다.
$iptables -A INPUT -p tcp --dport 0:65535 -j DROP
$iptables -A INPUT -p udp --dport 0:65535 -j DROP
$iptables -A INPUT -p icmp --icmp-type echo-request -j REJECT

# 각종 서비스들에 대해 최대의 성능을 발휘할 수 있도록 TOS 설정을 한다.
$iptables -t mangle -A OUTPUT -p tcp -s 0/0 --sport 80 -j TOS --set-tos 0x10
$iptables -t mangle -A OUTPUT -p tcp -d 0/0 --dport 22 -j TOS --set-tos 0x10
$iptables -t mangle -A OUTPUT -p tcp -d 0/0 --dport 21 -j TOS --set-tos 0x10
$iptables -t mangle -A OUTPUT -p tcp -d 0/0 --dport 20 -j TOS --set-tos 0x08
$iptables -t mangle -A OUTPUT -p tcp -s 0/0 --sport 23 -j TOS --set-tos 0x10

# 외부 서비스를 위한 설정. / udp service
# dns 상호 쿼리를 위해서...
#$iptables -A INPUT -p udp --sport 53 -m state --state ESTABLISHED -j ACCEPT

# TCP service
# ftp-data, 서버자체가 클라이언트가 될 경우...
$iptables -A INPUT -p tcp --dport 20 -m state --state NEW,ESTABLISHED -j ACCEPT
$iptables -A INPUT -p tcp --dport 20 -m state --state ESTABLISHED -j ACCEPT
$iptables -A INPUT -i eth0 -p tcp --sport 1024:65535 --dport 1024:65535 -m state --state ESTABLISHED,RELATED -j ACCEPT

# ftp service
# ftp 를 이용할 수 있는 대역을 지정하였습니다. 좀더 세밀해 질 수 있겠죠.
#$iptables -A INPUT -s 아이피.0.0.0/8 -p tcp --dport 21 -j ACCEPT
#$iptables -A INPUT -s 아이피.0.0/16-p tcp --dport 21 -j ACCEPT
$iptables -A INPUT -s 아이피.0/24 -p tcp --dport 21 -j ACCEPT

# telnet
# telnet은 현재 서비스 하지 않습니다.
$iptables -A INPUT -s 아이피.0.0/16 -p tcp --dport 23 -j ACCEPT

# pop3s 를 이용하는 관계로 995번을 열고 있습니다.
#$iptables -A INPUT -p tcp --dport 995 -m state --state NEW,ESTABLISHED -j ACCEPT

# ip 대역 예제.
# ip 대역뿐만 아니라 아래와 같이 상태접속을 지정할 수도 있습니다.
$iptables -A INPUT -s 아이피.0.0/16 -p tcp --dport 23 -m state --state NEW,ESTABLISHED -j ACCEPT
$iptables -A INPUT -s 아이피.0.0/16 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
$iptables -A INPUT -s 아이피.0/24 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
$iptables -A INPUT -s 아이피.0.0/16 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT

# UDP service
# udp 서비스는 하나뿐이죠?
#$iptables -A INPUT -p udp --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT

echo -e "\nDone.\n"

exit;

Inline Translator가 로드되지 못했습니다. 다시 시도하시려면 새로고침해주세요.
반응형

'오픈소스SW' 카테고리의 다른 글

http 패킷 보기  (1) 2010.06.13
보안서버 구축에 사용되는 무료인증서 StartSSL  (0) 2010.06.13
CentOS 5.2.x PHP UPDATE  (0) 2010.06.09
Apache 웹방화벽 ModSecurity 사용하기  (1) 2010.06.08
jquery datepicker 사용  (0) 2010.06.05
반응형
SW개발자에게 웹어플리케이션의 보안부분은 항상 머리가 아픈 부분입니다.
웹어플리케이션의 보안이슈를 웹서버에서 차단가능한 방법이 있으면, SW개발자는 개발에 집중할 수 있겠죠.

오늘 취약점 점검툴을 이용해서 배포하려는 사이트를 분석해보니, 해결해야 하는 취약점의 숫자가 좀 많습니다. ㅡ.ㅡ
서버측에서 접근하는 패킷에 대한 룰셋을 적용하는 방법과,  개발한 소스코드를 보정하는 방법 중, 해당 서버의 전체 어플리케이션에 대해서 웹방화벽을 설치하기로 결정하고 ModSecurity 를 적용하기로 했습니다..

ModSecurity의 설치법에 대해서는 KISA 홈페이지 를 방문해보시면. 한글로 된 가이드가 있습니다.
소스코드 설치를 원하시면 위 링크에서 컴파일에 대한 과정을 설명한 내용을 참고하시기 바랍니다.

저는 최근에는 부득이한 경우를 제외하고는 소스컴파일을 하지 않고, 설치한 패키지에 대한 운영상의 편리함을 생각해서 가능하면 apt, yum, rpm 등의 설치방식을 사용합니다. ModSecurity를 설치할 수 있는 repository를 구글링해서 Yum repository를 찾아냈습니다. (원문 url : http://portugalcode.com/index.php?topic=2850.0;wap2)

How to install mod_security by yum(Redhat-Centos 5)

(1/1)

@Scroll:
1.Download the EPEL repo :

Código
GeSHi (bash):
rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-3.noarch.rpm
Created by GeSHI 1.0.7.20

2.Then type the following command :

Código
GeSHi (bash):
yum install mod_security
Created by GeSHI 1.0.7.20

Note : Mod_security require liblua-5.1.so, If you don’t have this , it will throw an error while installing by yum.


Código
GeSHi (bash):
--> Processing Dependency: liblua-5.1.so for package: mod_security
--> Finished Dependency Resolution
mod_security-2.5.9-1.el5.i386 from epel has depsolving problems
--> Missing Dependency: liblua-5.1.so is needed by package mod_security-2.5.9- 1.el5.i386 (epel)
Error: Missing Dependency: liblua-5.1.so is needed by package mod_security-2.5.9 -1.el5.i386 (epel)
Created by GeSHI 1.0.7.20

Solution: You can download the rpm from this website

http://rpm.pbone.net/index.php3/stat/4/idpl/12580541/com/lua-5.1.4-1.i386.rpm.html

If your server complain you have installed already newer version then you can reinstall the installed version by using

Código
GeSHi (bash):
-bash-3.2# rpm -qa | grep lua
lua-5.1.4-1.el5.rf
-bash-3.2# rpm -e lua-5.1.4-1.el5.rf
-bash-3.2# rpm -Uvh lua-5.1.4-1.i386.rpm
Preparing… ########################################### [100%]
1:lua ########################################### [100%]
 
Created by GeSHI 1.0.7.20

Now type

Código
GeSHi (bash):
-bash-3.2# updatedb
 
-bash-3.2# locate liblua-5.1.so
/usr/lib/liblua-5.1.so
 
Created by GeSHI 1.0.7.20

So it shows that your server has the required file for it to install mod_security

Now run

Código
GeSHi (bash):
yum install mod_security
Created by GeSHI 1.0.7.20

It should installed now mod_security configuration files

/etc/httpd/conf.d/mod_security.conf – main configuration file for the mod_security Apache module.
/etc/httpd/modsecurity.d/ – all other configuration files for the mod_security Apache.
/etc/httpd/modsecurity.d/modsecurity_crs_10_config.conf – Configuration contained in this file should be customized for your specific requirements before deployment.
/var/log/httpd/modsec_debug.log – Use debug messages for debugging mod_security rules and other problems.
/var/log/httpd/modsec_audit.log – All requests that trigger a ModSecurity events (as detected) or a serer error are logged (”RelevantOnly”) are logged into this file.
After installing mod_security , Edit modsecurity_crs_10_config.conf file and make sure bellow line is enabled.

SecRuleEngine On

Now restart the httpd server by

Código
GeSHi (bash):
service httpd restart
Created by GeSHI 1.0.7.20

Check the /var/log/httpd/error_log for this lines
[Fri Aug 28 10:48:24 2009] [notice] ModSecurity for Apache/2.5.9 (http://www.mod security.org/) configured.

영문사이트는 아니지만 중요한 정보는 다 들어있으니 그대로 설치하기로 했습니다.

1) mod_security 설치
rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-3.noarch.rpm
위 명령으로 epel repository가 잘 설치되었다면

yum install mod_security
를 실행합니다.

두어번 의존패키지 설치를 묻는데 y를 눌러주면 설치는  끝납니다.(너무쉽죠?)


2) 방화벽에서 사용할 룰셋의 생성
설치를 마쳣으면 아파치 환경설정 디렉토리안의 mod_security.conf 파일을 확인합니다..



방화벽에서 적용할 룰셋은 자신이 직접 만들어서 사용가능하지만, 일단은 KISA에서 배포하는 룰셋을 다운로드 받아서 사용하자.
룰셋 다운로드 : http://toolbox.krcert.or.kr/ > ModSecurity 자료실 > 차단샘플 룰 을 찾아서 다운로드.

다운받은 룰셋을 yum 설치시 생성된 디렉토리에 복사하자.
아래의 modsecurity_kisa.conf 파일이 다운로드 받은 룰셋이다.
룰셋의 설정에 대한 자세한설명은 KISA홈페이지를 이용하거나 파일내의 주석을 참고하자.







룰셋파일의 내용중(modsecurity_kisa.conf)
# 웹서버의 헤더 정보 변경
# Apache 설정의 ServerTokens값이 Full로 설정되 있어야 함.
SecServerSignature "Microsoft-IIS/5.0"

# 아규먼트 구분자
SecArgumentSeparator "&"

# 다음의 메소드 이외에는 허용하지 않음.
SecRule REQUEST_METHOD "(PUT|DELETE|TRACE)" "deny, log"

SecRequestBodyAccess Off
SecResponseBodyAccess Off
SecResponseBodyMimeType (null) text/html text/plain
SecResponseBodyLimit 524288

#############################
# 3. PHP 인젝션 취약 공격 방지(공개 게시판 솔루션 대상 공격 포함)
SecRule REQUEST_URI "\.php" "chain, msg:'PHP Injection Attacks'"
# dir|page 가 들어가 있으면서 https가 요청되는 경우가 fckeditor 에서 발생하기 때문에 수정
SecRule REQUEST_URI "(dir|page|)" chain
#SecRule REQUEST_URI "=(http|https|ftp)\:/"
SecRule REQUEST_URI "=(https|ftp)\:/"
SecRule REQUEST_URI "shell_exec\(" "msg:'PHP Injection Attacks'"


참고) 저의 경우 RPM 패키지에서 제공되는 설정을 그대로 사용해서 kisa에서 배포하는 설정을 복사한 후 , 바로 룰셋을 적용하니 웹사이트가 열리지 않았습니다. 로그를 보면서 확인해본 결과
/etc/httpd/modsecurity.d/base_rules/modsecurity_crs_50_outbound.conf 파일의 설정이 문제를 일으켰고.
이 파일을 제거하고 서비스에 적용했을때 이상없는 서비스가 가능했습니다.


3) 설치 후 적용 확인

설치 및 룰셋의 설정이 완료되었으면 제대로 동작하는지 확인합니다.

modsecurity 로그파일에 아래와 같은 로그가 남는경우
ModSecurity: Failed to access DBM file "E:/tmp/resource": The system cannot find the path specified

로그를 확인하니 오류메세지가 보여서 구글링한 결과
기본설치시 제공되는 modsecurity_crs_10.config.conf 의 설정에 아래의 내용을 추가해야 한다는것을 알았습니다.
웹서버가 접근가능한 경로를 하나 생성해서 아래와 같은 내용을 추가해주어야 한다.
vi /etc/httpd/modsecurity.d/modsecurity_crs_10_config.conf

SecUploadDir /var/www/tmp
SecDataDir /var/www/tmp
SecTmpDir /var/www/tmp

웹서버를 재시작하면 이제 방화벽이 작동하게 됩니다.

룰셋이 작동하는 상태를 확인하려면 환경설정파일에서 지정한 로그파일을 확인하면 됩니다.
다운받은 룰셋을 아무수정없이 사용하는경우라면 로그파일은 아파치설치디렉토리/logs/modsec_audit.log 에 남게 되고,
파일의 내용을 확인하면 아래처럼 룰셋이 작동되고 있는 상태가 보여집니다.
















지금까지는 룰셋이 작동되기는 하지만, 차단시키지 않고 있는 상태입니다.
정상적인 작동여부를 확인하고, 자신이 원하는 형태로 룰셋이 적용되는것을 확인한 후, 반드시 환경설정파일에서 pass 부분을 deny 로 변경해야 차단이 시작됩니다.

방화벽을 적용했더니 작동안되는 부분이 있다면 항의가 많겠죠? 실 서버에 적용시에는 당연히 방화벽으로 인한 서비스의 중단이 없도록 정상적인 서비스를 방해하는 룰셋이 있다면 반드시 확인하고 사용해야 합니다.

변경 전
SecDefaultAction "pass,log,auditlog,phase:2,t:urlDecodeUni,t:htmlEntityDecode,t:lowercase"

변경 후
SecDefaultAction "deny,log,phase:2,status:406,t:urlDecodeUni,t:htmlEntityDecode,t:lowercase"

여기까지 하면 방화벽의 설치는 끝났습니다.

4) 기타
로그파일의 비대해지는 것을 방지하기 위해서 로그를 날짜별로 나누어서 보관하는것이 좋겠죠.
KISA에서 제공하는 FAQ를 보니 잘 설명되어있어서 그대로 적용했습니다. 아래 링크에서 상세내용을 확인할 수 있습니다
http://toolbox.krcert.or.kr > ModSecurity FAQ > 로그파일의 사이즈가 너무 큰데 이를 날짜나 시간별로 분할할 수 없나요?






KISA에서 제공하는 룰셋의 주요 점검 항목

PHP 인젝션 취약 공격 방지(공개 게시판 솔루션 대상 공격 포함)
명령어 실행 방지
XSS 공격 방지
SSI 인젝션 관련 공격 차단
악성 프로그램 봇, User-Agent
검색엔진 Recon/Google 이용한 해킹 방지
PHPMyAdmin 관련 공격 취약점 적용
SQL Injection 공격 차단
WebShell 공격 방지
Tomcat 취약점 이용한 공격 방지


기타) 적용 후 추가한 내용
# dir|page 가 들어가 있으면서 https가 요청되는 경우가 fckeditor 에서 발생하기 때문에 수정
SecRule REQUEST_URI "(dir|page|)" chain
#SecRule REQUEST_URI "=(http|https|ftp)\:/"
SecRule REQUEST_URI "=(https|ftp)\:/"
SecRule REQUEST_URI "shell_exec\(" "msg:'PHP Injection Attacks'"

공개SW 웹방화벽 mod_security를 이용해서  여러분의 어플리케이션을 보호해보시는 것이 어떨까요?
반응형

'오픈소스SW' 카테고리의 다른 글

iptable rule  (0) 2010.06.10
CentOS 5.2.x PHP UPDATE  (0) 2010.06.09
jquery datepicker 사용  (0) 2010.06.05
php 문자열처리 관련 function  (0) 2010.06.05
JavaScript Tree Menu  (0) 2010.05.24

+ Recent posts