DigiMoon 맘대로 닦고 조이고 기름치는 재미가 있는 DigiMoon만의 기억 저장소

Posted
Filed under 컴퓨터 탐구/리눅스
작성자: 주인장 디지문
(http://www.digimoon.net/)
 

참고링크
http://blog.naver.com/jinvoices?Redirect=Log&logNo=10033994174
http://www.lug.or.kr/home/bbs/board.php?bo_table=centos_book&wr_id=210#bbs
http://www.1000dedi.net/hosting/gnuboard4/bbs/board.php?bo_table=serverLecture&wr_id=698&sca=&sfl=wr_subject%7C%7Cwr_content&stx=%BC%F6%C7%F5&sop=and



간만에 메뉴얼 하나 작성합니다. ^^

 인터넷 상에 나도는 리눅스 커널에 geoip 관련 패치를 하는 작업에 대한 메뉴얼들이 대부분 최신 버전의 커널 및 iptables 환경에 적용된 사례를 다룬 케이스가 거의 전무한 관계로 최신 커널 + 최신 iptables + 최신 patch-o-matic-ng 패치를 조합하는 방법에 대해 삽질을 반복한 끝에 메뉴얼을 작성해 보며 성공기를 정리해 보았습니다.
최신 버전이기 때문에 성능 및 안정성에 대해서는 장담 못 해 드립니다.



작업 시나리오

1. 2.6.27.4 Kernel 소스 다운로드
    iptables 1.4.2 소스 다운로드
    patch-o-matic-ng 소스 다운로드


 각 소스는 아래 링크에서 다운로드
(2008년 10월 29일 현재 날짜를 기준으로 최신 버전 다운로드)
ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.27.4.tar.bz2
http://ftp.netfilter.org/pub/iptables/snapshot/iptables-20081028.tar.bz2
http://ftp.netfilter.org/pub/patch-o-matic-ng/snapshot/patch-o-matic-ng-20081028.tar.bz2

 상기 소스들은 /usr/src 디렉토리에 받아 놓고 압축을 풀어 둔다.
 커널 소스와 iptables 소스는 압축을 풀어 놓으면  디렉토리 명이 길기 때문에
 짧은 디렉토리 명으로 심볼릭 링크를 걸어 두는 것이 작업상 편리하겠다.
# tar xvfj linux-2.6.27.4.tar.bz2
# ln -s linux-2.6.27.4 linux
# tar xvfj iptables-20081028.tar.bz2
# ln -s iptables-20081028 iptables





2. patch-o-matic-ng 소스로 iptables 소스와 커널 소스에 패치를 가함.
    이 메뉴얼에서는 connlimit 와 geoip 모듈만 커널에 추가시키고 iptables 에서
    이 모듈들을 컨트롤할 수 있게 하는 방법만을 다룸.

# cd /usr/src/iptables
# ./configure

※ 반드시 iptables 소스 디렉토리에서 configure 커맨드로 컴파일 환경설정을 먼저 한 뒤에 patch-o-matic-ng 로 패치를 가해 주어야 한다. 그렇지 않을 경우 패치 과정에서 iptables 소스가 패치 소스에 적합치 않다는 에러를 내며 중단된다.

# cd /usr/src/patch-o-matic-ng-20081028
# ./runme --download
# ./runme geoip
Welcome to Patch-o-matic ($Revision$)!

Kernel: 2.6.27, /usr/src/linux
Iptables: 1.4.2, /usr/src/iptables
Each patch is a new feature: many have minimal impact, some do not.
Almost every one has bugs, so don't apply what you don't need!
-------------------------------------------------------
Already applied:
Testing geoip... not applied
The geoip patch:
Author: Samuel Jean <peejix@people.netfilter.org>; Nicolas Bouliane <acidfu@people.netfilter.org>
Status: Stable

This patch makes possible to match a packet
by its source or destination country.

GeoIP options:
[!] --src-cc, --source-country country[,country,country,...]

Match packet coming from (one of)
the specified country(ies)


[!] --dst-cc, --destination-country country[,country,country,...]

Match packet going to (one of)
the specified country(ies)

NOTE: The country is inputed by its ISO3166 code.

The only extra files you need is a binary db (geoipdb.bin) & its index file (geoipdb.idx).
Take a look at http://people.netfilter.org/acidfu/geoip/howto/geoip-HOWTO.html
for a quick HOWTO.
-----------------------------------------------------------------
Do you want to apply this patch [N/y/t/f/a/r/b/w/q/?]


 이 작업 과정을 보면 geoip 패치만 가하게 되는데 connlimit 모듈은 2.6.23 커널부터 기본 포함이 되어 있어서 커널 컴파일 시 활성화만 시켜주면 되며 iptables에도 기본 extension으로 포함되어 있기 때문에 iptables에도 따로 패치를 가할 필요가 없다. geoip는 커널에도, iptables의 기본 익스텐션으로도 포함되어 있지 않으므로 patch-o-matic-ng 로 수동 패치해 줘야 한다.


3. geoip 패치가 끝났으면 먼저 패치된 커널 소스를 컴파일하여 설치


# cd /usr/src/linux


 커널 소스 디렉토리로 들어갔으면 기존에 정상적으로 사용하던 커널의 환경옵션을 그대로 가져 와서 컴파일하는 것이 좋다. /boot 디렉토리 안을 보면 이름이 config... 로 시작하는 커널 환경 변수 정보가 담겨있는 파일들이 있는데 이 중 가장 최근까지 정상적으로 사용해 오던 파일을 복사해다가 /usr/src/linux 디렉토리 안에 .config 라는 이름의 파일로 저장해서 불러들이는 방식을 취하면 된다.

# make menuconfig


그 다음 제일 하단에서 2번째에 있는 Load an Alternate Configuration File 메뉴를 통해 .config 파일을 로드한 뒤

Networking --> Networking option --> Network packet filtering framework (Netfilter) 옵션으로 들어가서
Core Netfilter Configuration을 비롯하여 넷필터, iptables 관련 모듈을 모두 체크하고 빠져 나온다.
Core Netfilter Configuration 옵션 안의 모듈들은 가급적 <M> 체크하여 모듈 형태로 저장한다.
iptables관련 모듈들은 하나가 모듈로 컴파일되면 다른 것들도 모듈로 되기를 요구하는 것 같다.
geoip 모듈은 제일 하단에 옵션이 추가되어 있는 것을 확인할 수 있을 것이다. connlimit 모듈은 중간 쯤에 나온다.

# make bzImage
# make modules
# make modules_install
# make install


대략 1시간 안팎으로 시간이 소요될 것이다. 스타 배틀넷을 서너게임 하다 돌아와 보면 어느덧 컴파일이 다 되어 있는 것을 확인할 수 있다. ^^
커널컴파일을 끝내면 /boot/grub/grub.conf 파일을 편집하여 새로운 커널로 부팅될 수 있도록 하고 시스템을 리부팅한다. lsmod 커맨드로 xt_geoip, xt_connlimit 모듈이 올라와 있나 확인하고 없다면...
# depmod -a
# modprobe xt_geoip
# modprobe xt_connlimit

위 커맨드들을 이용하여 모듈을 로딩해 본다. 잘 올라올 것이다.
이제 iptables 작업으로 넘어간다.


4. patch-o-matic-ng로 패치된 iptables 소스컴파일 설치

 여기서는 기존의 rpm 버전 iptables를 삭제하지 않고 그 위에 소스컴파일로 덮어씌우는 방식을 설명한다. 왜냐하면 rpm 버전을 삭제한 뒤 소스로 새롭게 설치하게 되면 기존의 rpm 버전에서 제공하던 system-config-securitylevel, lokkit, /etc/rc.d/init.d/iptables 와 같은 실행 스크립트 파일이 존재하지 않기 때문에 따로 스크립트로 구현하지 않는 한 일일이 iptables 룰을 추가해야 하는 불편함을 감수해야 한다. 다행스럽게도 iptables를 소스로 설치하게 되면 바이너리 파일, 환경설정 파일, 라이브러리 등이 rpm 버전과 거의 동일한 경로에 설치되므로 rpm 버전 위에 덮어 씌워 설치하면 기존의 관련 명령어를 그대로 활용할 수 있다는 장점이 있다.

# cd /usr/src/iptables
# ./configure
# make


여기까지 진행하였다면 아마 아래와 같은 에러를 내며 컴파일이 중단될 것이다.
CC       libxt_geoip.oo
libxt_geoip.c:28:38: warning: linux/netfilter/xt_geoip.h: 그런 파일이나 디렉토리가 없음
libxt_geoip.c: In function 'geoip_help':
libxt_geoip.c:44: error: 'IPTABLES_VERSION' undeclared (first use in this function)
libxt_geoip.c:44: error: (Each undeclared identifier is reported only once
libxt_geoip.c:44: error: for each function it appears in.)
libxt_geoip.c: At top level:
libxt_geoip.c:69: warning: no previous prototype for 'get_country_subnets'
libxt_geoip.c: In function 'get_country_subnets':
libxt_geoip.c:72: warning: declaration of 'index' shadows a global declaration
/usr/include/string.h:304: warning: shadowed declaration is here
libxt_geoip.c:99: warning: implicit declaration of function 'COUNTRY'
libxt_geoip.c:99: warning: too few arguments for format
libxt_geoip.c:119: error: invalid application of 'sizeof' to incomplete type 'struct geoip_subnet'
libxt_geoip.c:125: error: invalid application of 'sizeof' to incomplete type 'struct geoip_subnet'
libxt_geoip.c: In function 'load_geoip_cc':
libxt_geoip.c:137: error: invalid application of 'sizeof' to incomplete type 'struct geoip_info'
libxt_geoip.c:142: error: dereferencing pointer to incomplete type
libxt_geoip.c:142: error: dereferencing pointer to incomplete type
libxt_geoip.c:143: error: dereferencing pointer to incomplete type
libxt_geoip.c: In function 'parse_geoip_cc':
libxt_geoip.c:196: error: 'XT_GEOIP_MAX' undeclared (first use in this function)
libxt_geoip.c: In function 'geoip_parse':
libxt_geoip.c:228: error: 'XT_GEOIP_SRC' undeclared (first use in this function)
libxt_geoip.c:228: error: 'XT_GEOIP_DST' undeclared (first use in this function)
libxt_geoip.c:249: error: 'XT_GEOIP_INV' undeclared (first use in this function)
libxt_geoip.c:251: error: dereferencing pointer to incomplete type
libxt_geoip.c:251: error: dereferencing pointer to incomplete type
libxt_geoip.c:251: error: dereferencing pointer to incomplete type
libxt_geoip.c:252: error: dereferencing pointer to incomplete type
libxt_geoip.c:253: error: dereferencing pointer to incomplete type
libxt_geoip.c: In function 'geoip_print':
libxt_geoip.c:274: error: dereferencing pointer to incomplete type
libxt_geoip.c:274: error: 'XT_GEOIP_SRC' undeclared (first use in this function)
libxt_geoip.c:278: error: dereferencing pointer to incomplete type
libxt_geoip.c:282: error: dereferencing pointer to incomplete type
libxt_geoip.c:282: error: 'XT_GEOIP_INV' undeclared (first use in this function)
libxt_geoip.c:285: error: dereferencing pointer to incomplete type
libxt_geoip.c:286: error: dereferencing pointer to incomplete type
libxt_geoip.c:286: warning: too few arguments for format
libxt_geoip.c: In function 'geoip_save':
libxt_geoip.c:296: error: dereferencing pointer to incomplete type
libxt_geoip.c:296: error: 'XT_GEOIP_INV' undeclared (first use in this function)
libxt_geoip.c:299: error: dereferencing pointer to incomplete type
libxt_geoip.c:299: error: 'XT_GEOIP_SRC' undeclared (first use in this function)
libxt_geoip.c:303: error: dereferencing pointer to incomplete type
libxt_geoip.c:304: error: dereferencing pointer to incomplete type
libxt_geoip.c:304: warning: too few arguments for format
libxt_geoip.c: At top level:
libxt_geoip.c:311: error: 'IPTABLES_VERSION' undeclared here (not in a function)
libxt_geoip.c:312: error: invalid application of 'sizeof' to incomplete type 'struct xt_geoip_match_info'
libxt_geoip.c:313: error: invalid use of undefined type 'struct xt_geoip_match_info'
make[2]: *** [libxt_geoip.oo] 오류 1
make[2]: Leaving directory `/usr/src/iptables-20081028/extensions'
make[1]: *** [all-recursive] 오류 1
make[1]: Leaving directory `/usr/src/iptables-20081028'
make: *** [all] 오류 2
[root@localhost iptables]#


아래와 같이 작업하고 난 뒤 다시 컴파일해 보자.
# cp /usr/src/patch-o-matic-ng-20081028/patchlets/geoip/linux-2.6/include/linux/netfilter/xt_geoip.h /usr/src/iptables-20081028/include/linux/netfilter/
# make


그러면 또 아래와 같은 에러에 가로막힐 것이다.
make  all-recursive
make[1]: Entering directory `/usr/src/iptables-20081028'
Making all in extensions
make[2]: Entering directory `/usr/src/iptables-20081028/extensions'
  CC       libxt_geoip.oo
libxt_geoip.c: In function 'geoip_help':
libxt_geoip.c:44: error: 'IPTABLES_VERSION' undeclared (first use in this function)
libxt_geoip.c:44: error: (Each undeclared identifier is reported only once
libxt_geoip.c:44: error: for each function it appears in.)
libxt_geoip.c: At top level:
libxt_geoip.c:69: warning: no previous prototype for 'get_country_subnets'
libxt_geoip.c: In function 'get_country_subnets':
libxt_geoip.c:72: warning: declaration of 'index' shadows a global declaration
/usr/include/string.h:304: warning: shadowed declaration is here
libxt_geoip.c: At top level:
libxt_geoip.c:311: error: 'IPTABLES_VERSION' undeclared here (not in a function)
make[2]: *** [libxt_geoip.oo] 오류 1
make[2]: Leaving directory `/usr/src/iptables-20081028/extensions'
make[1]: *** [all-recursive] 오류 1
make[1]: Leaving directory `/usr/src/iptables-20081028'
make: *** [all] 오류 2
[root@localhost iptables]#


iptables 의 소스에서 /{iptables}/include/xtables.h 를 다음과 같이 수정하면 된다.
[기존 코드]
#define XTABLES_VERSION "1.4.1.1"
#define XTABLES_VERSION_CODE (0x10000 * 1 + 0x100 * 4 + 1)
#define XTABLES_API_VERSION(x,y,z)    (0x10000*(x) + 0x100*(y) + z)

[추가할 코드]
#define IPTABLES_VERSION "1.4.2"


다시 컴파일해 보면 이제 문제없이 넘어간다.
# make
# make install

※ 컴파일 중 중간에 아래와 같은 경고 구문이 뜨긴 하는데 의미는 모르겠음...
설치는 무난하게 되는 듯 하다.
CCLD     libxt_dscp.so
  CC       libxt_esp.oo
  CCLD     libxt_esp.so
  CC       libxt_geoip.oo
libxt_geoip.c:69: warning: no previous prototype for 'get_country_subnets'
libxt_geoip.c: In function 'get_country_subnets':
libxt_geoip.c:72: warning: declaration of 'index' shadows a global declaration
/usr/include/string.h:304: warning: shadowed declaration is here

  CCLD     libxt_geoip.so
  CC       libxt_hashlimit.oo



이제 기존의 rpm 버전 iptables에서 사용되던 명령어들을 삭제하고 새로이 설치한 소스 버전의 명령어들로 교체하는 작업이 필요하다.
/sbin 디렉토리안의 iptables 관련 명령 삭제 후, /usr/local/sbin 아래에 생성된 iptables 관련 명령들을 심볼릭 링크한다.(총 8개 명령)
# ls /usr/local/sbin
ip6tables        ip6tables-restore  iptables        iptables-restore
ip6tables-multi  ip6tables-save     iptables-multi  iptables-save
# ln -s /usr/local/sbin/ip6tables /sbin
# ln -s /usr/local/sbin/ip6tables-restore /sbin
# ln -s /usr/local/sbin/iptables /sbin
# ln -s /usr/local/sbin/iptables-restore /sbin
# ln -s /usr/local/sbin/ip6tables-multi /sbin
# ln -s /usr/local/sbin/ip6tables-save /sbin
# ln -s /usr/local/sbin/iptables-multi /sbin
# ln -s /usr/local/sbin/iptables-save /sbin


이제 iptables 버전을 확인해 보면 업그레이드된 버전임을 알 수 있다.
# iptables -V
iptables v1.4.2


※ 덧붙이자면 지금까지 과정을 잘 진행했다면 geoip, connlimit 뿐만 아니라 recent, strings 관련 룰도 모두 적용 가능하다. 이 4가지 기능만 잘 다룬다면 웬만한 침입 공격엔 확실하게 대응할 수 있을 것이다.


5. geoip database 설치
http://blog.naver.com/jinvoices?Redirect=Log&logNo=10033994174

국가 DB 생성 및 최신 정보로 업데이트

일단 알아두어야 할것은 geoip 모듈은 /var/geoip 경로의 DB파일 참조한다.
cvs2bin 툴을 이용하여 매월1일 업데이트 되는 geoip database를 생성한다.
   
툴 다운로드후 설치 및 CSV 파일 변환
wget http://people.netfilter.org/peejix/geoip/tools/csv2bin-20041103.tar.gz

# tar -xvzf csv2bin-20041103.tar.gz
# cd csv2bin
# make


국가별 DB를 다운로드한다.
# wget http://www.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip

unzip GeoIPCountryCSV.zip
압축을 풀면 GeoIPCountryWhois.csv 파일이 나온다. csv2bin 폴더 안에 넣어주고,

실행파일로 만들어 준다. chmod 755 GeoIPCountryWhois.csv

그다음  ./csv2bin ./GeoIPCountryWhois.csv 동시에 실행해 주면 geoipdb.bin 과 geoipdb.idx 파일이 생성된다.

mkdir /var/geoip   -> var 에 geoip 폴더는 만들고
cp geoipdb.bin /var/geoip/   -> 방금 생성되었던 두 파일을 /var/geoip/ 에 복사해준다.
cp geoipdb.idx /var/geoip/




이상 여기까지... ^^
Creative Commons License
2008/10/29 23:49 2008/10/29 23:49

작성자: 주인장 디지문(http://www.digimoon.net/) 일전에 커널과 iptables 소스를 새로 받아다가 완전히 새로 컴파일하여 geoip 모듈을 탑재하는 걸 포스팅한 적이 있는데 이번엔 기존 커널 & iptables rpm 패키지를 그대로 유지한 채 geoip 모듈만 리빌드하는 방법을 포스팅합니다. rpm으로 기본 탑재된 커널도 충분히 재구실을 하는지라... 사실 커널 소스를 받아 컴파일해서 설치하는 건 요즘 들어선 불필요...