커피닉스, 시스템 엔지니어의 쉼터 커피향이 나는 *NIX
커피닉스
시스템/네트웍/보안을 다루는 곳
* HanIRC의 #coffeenix 방
[ 장비 및 회선 후원 ]
HOME > 네트워크(network) > 웹 서버(web, httpd, apache) 도움말
검색 : 사이트 WHOIS 웹서버 종류

WebDAV (7, 글 1, 자료 4)
웹서버 튜닝 (5, 글 4, 자료 2)
웹서버 사용 통계 자료 (2, 자료 1)
Apache SSL / mod_ssl (4, 글 3, 자료 2)

  GeoIP 활용(아파치 웹로그에 국가코드 남기기 외) 작성일 : 2008/04/23 08:34
 
  • 글쓴이 : 좋은진호 ( http://coffeenix.net/ )
  • 조회수 : 20666
          [ 이전화면 / 수정 ]   비밀번호 :     인쇄용 화면
      제  목 : GeoIP 활용(아파치 웹로그에 국가코드 남기기 외)
    작성자 : 좋은진호(truefeel, http://coffeenix.net/ )
    작성일 : 2008.3.18(화)
    정리일 : 2008.4.20(일)
    수정일 : 2008.4.23(수)

    MaxMind의 GeoIP 데이터를 이용해서 다음 2가지에 활용할 것이다.
    1) 웹페이지에 접속한 IP가 어느 국가인지를 아파치 웹로그에 코드로 남기고, 또한 특정 웹페이지를 국가별로 접근을 제한하는 방법을 알아본다.
    2) IP를 지정하면 그 IP가 어느 국가의 것인지를 알아내는 php 스크립트에 대해 알아볼 것이다.

    iptables에 GeoIP를 이용해서 국가별로 IP를 차단하는 것은 '6. GeoIP로 국가별 IP 차단 설정 자료'를 참고하기 바란다.

    1. GeoIP C API 설치

    apache의 mod_geoip 모듈이나 php의 geoip.so 모듈을 설치하기 위해서는 먼저 GeoIP C API 먼저 설치해야 한다.
    http://www.maxmind.com/app/c 에서 받아 설치한다.

     
    # ./configure --prefix=/usr/local/GeoIP
    # make
    # make install
     


    /usr/local/GeoIP/share/GeoIP/ 에 GeoIP 바이너리 포맷 파일(GeoIP.dat)이 존재한다. 현재 약 1MB.

    2. apache에서 GeoIP 활용하기

    http://www.maxmind.com/app/mod_geoip 에서 mod_geoip2(현재 버전 1.2.1)를 받아온다. apache는 /usr/local/www에 설치되어 있고, Apache 2.2.x 기준으로 설명한다. 아래에 -I/usr... 에서 -I는 대문자 I(아이), -lGeoIP 에서 -l 은 소문자 L(엘)이다. (브라우저 글꼴에 따라 구별이 잘 안될 수 있으니 주의) apxs 명령을 내리면 /usr/local/www/modules/mod_geoip.so 에 자동으로 설치된다.

     
    # apxs -i -a -L/usr/local/GeoIP/lib -I/usr/local/GeoIP/include -lGeoIP -c mod_geoip.c
     


    apache 모듈이 설치된 상태에서 phpinfo() 를 살펴보면, Apache Environment 부분에서 GEOIP_CONTINENT_CODE, GEOIP_COUNTRY_CODE, GEOIP_COUNTRY_NAME환경 변수를 볼 수 있다.



    apache 웹로그의 마지막칸에 국가코드를 남기는 방법을 설명한다. 로그에 국가코드를 남김으로써, 1) IP를 갖고 whois로 어느 국가인지를 찾아볼 필요가 없어지고, 2) 특정페이지를 어느 국가에서 요청하는지 통계를 뽑아볼 수도 있고, 3) 웹해킹시도를 할 때 어느 국가에서 공격하는 것인지 바로 확인할 수 있다.

     
    <IfModule geoip_module>
            GeoIPEnable On
            GeoIPDBFile /usr/local/GeoIP/share/GeoIP/GeoIP.dat
    </IfModule>

    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %{Host}i %{GEOIP_COUNTRY_CODE}e" cnxlog

    CustomLog logs/access_log cnxlog
     


    위에서 %{변수명}i 형식은 요청할 때의 Header중 해당 값을 말한다. %{변수명}e 는 환경변수를 의미한다. LogFormat 설정 중에 2가지를 살펴보자.

    %{Host}i : 요청한 호스트명을 로그에 남긴다. 이를테면 하나의 서버에 2개 이상의 도메인을 갖고 있을 때 유용하다.
               www.foobar.com, www.foobar.net, foobar.com 등의 도메인이 있을 때 어떤 도메인으로 요청했는지를 남길 수 있게 된다.
    %{GEOIP_COUNTRY_CODE}e : GEOIP_COUNTRY_CODE 환경변수, 즉 국가코드를 남긴다.

    다음은 특정은 페이지를 지정한 국가에서 접근할 수 없도록 설정한 예이다.

     
    <IfModule geoip_module>
            GeoIPEnable On
            GeoIPDBFile /usr/local/GeoIP/share/GeoIP/GeoIP.dat

            <Location /data>
               SetEnvIf GEOIP_COUNTRY_CODE CN blockcountry
               SetEnvIf GEOIP_COUNTRY_CODE RU blockcountry
               SetEnvIf GEOIP_COUNTRY_CODE TH blockcountry

    #          SetEnvIf GEOIP_COUNTRY_CODE KR allowcountry

               <Limit GET POST>
                 Order Allow,Deny
                 Allow from all
                 Deny  from env=blockcountry
               </Limit>
            </Location>
    </IfModule>
     


    위는 특정 국가만 제한하는 것인데, 반대로 특정 국가만 허용하려면 위의 내용중에 location 부분을 다음과 같이 수정하면 된다.

     
            <Location /data>
               SetEnvIf GEOIP_COUNTRY_CODE KR allowcountry
               <Limit GET POST>
                 Order Deny,Allow
                 Deny  from all
                 Allow from env=allowcountry
               </Limit>
            </Location>
     


    위의 2가지 설정(로그에 국가코드, 특정 국가 제한)이 적용된 로그 예(일부 로그는 변경 처리함)이다. 2번째 줄은 특정 국가 접속시 403 에러를 발생하며, 접근이 제한됐음을 확인할 수 있다.

     
    125.129.xxx.xxx - - [01/Apr/2008:01:07:15 +0900] "GET /bbs/ HTTP/1.1" 200 29388 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; ko; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13" foobar.com KR
    61.243.xxx.xxx - - [01/Apr/2008:01:17:20 +0900] "GET /data/linux_base/editors.html HTTP/1.1" 403 520 "-" "Mozilla/4.0 (compatible; MSIE 5.5; Windows 98; DigExt)" foobar.com CN
     


    3. php용 모듈 설치

    apache 모듈만 설치되어 있어도, php에서 다음과 같이 접속한 곳의 국가 코드를 확인해볼 수 있다.

     
    <?
    $country_code = apache_note("GEOIP_COUNTRY_CODE");
    $country_name = apache_note("GEOIP_COUNTRY_NAME");

    echo "$country_code<br>";
    echo "$country_name<br>";
    ?>

    [ 결과 ]

    KR
    Korea, Republic of
     


    그러나 GeoIP php 모듈을 설치한다면 더 자세한 정보를 얻을 수 있다. apache만의 모듈로는 현재 접속한 IP의 국가코드만 알 수 있지만, php 모듈로는 본인이 원하는 IP를 지정하여 알아낼 수 있다. 또한 도메인을 지정할 수도 있는데, 이땐 도메인을 IP로 lookup한 다음에  어느 나리인지 등을 알아낸다.

    php 모듈을 설치해보자. http://pecl.php.net/package/geoip/ 에서 최신 GeoIP PHP extension(현재 geoip-1.0.2.tgz)을 받는다. configure할 때 php-config 명령 경로와 GeoIP의 디렉토리를 자신의 환경에 맞게 지정한다.

     
    # phpize
    # ./configure  --with-php-config=/usr/local/bin/php-config --with-geoip=/usr/local/GeoIP
    # make
    # make install
     


    php.ini 에 모듈 설정을 추가한다. 필요시에 extension_dir = "" 로 php모듈이 있는 디렉토리를 지정한다.

     
    extension=geoip.so

    ... 생략 ...
    [geoip]
    geoip.custom_directory=/usr/local/GeoIP/share/GeoIP
     


    4. php에서 GeoIP 테스트

    php용 샘플 소스는 http://www.maxmind.com/download/geoip/api/php/ 에서 확인할 수 있다. 여기서는 테스트를 위해 만들어본 테스트용 소스를 소개할 것이며, 그 결과도 함께 살펴본다.

    * geoip_php.html 내려받기
     
    <?
    // GeoIP 테스트
    //
    // 2008.3
    // by 좋은진호(truefeel, http://coffeenix.net/ )

    $geoip_database_info = geoip_database_info(GEOIP_COUNTRY_EDITION);
    $geoip_db_filename   = geoip_db_filename(GEOIP_COUNTRY_EDITION);
    $all_info            = geoip_db_get_all_info();

    echo "geoip_database_info = $geoip_database_info <br>\n";
    echo "geoip_db_filename   = $geoip_db_filename <br>\n";

    // 도메인별로 서버가 어느 국가에 위치해 있는지 알아보기
    $arURL  = array(
            "www.google.co.kr",
            "www.daum.net",
            "www.naver.com",
            "www.skype.com",
            "www.bbc.co.uk",
            "www.badoo.com",
            "mixi.jp",
            "www.baidu.com",
            );

    foreach ( $arURL as $u ) {
            $country        = geoip_country_name_by_name($u);
            $country_code   = geoip_country_code_by_name($u);
            $country_3code  = geoip_country_code3_by_name($u);

            echo "* $u = $country, $country_code, $country_3code <br>\n";
    }

    //
    echo "<pre>";
    print_r($all_info);
    echo "</pre>";

    ?>
     




    5.참고자료

    * PHP : GeoIP Functions
      http://www.php.net/manual/en/ref.geoip.php
    * PECL :: Package :: geoip
      http://pecl.php.net/package/geoip/
    * GeoIP PHP API
      http://www.maxmind.com/app/php
    * Installation of PECL extensions
      http://www.php.net/manual/en/install.pecl.php

    6. GeoIP로 국가별 IP 차단 설정 자료

    * 국가별로 접속 차단설정을 하고자 할 때 (글 홍석범)
      http://www.tt.co.kr/~antihong/documents/iptables_country.pdf
    * ssh dictionary attack 막기 (글 김정균)
      http://my.oops.org/42
    * RHEL/CentOS 에서 GeoIP kernel module 빌드 (글 김정균)
      http://my.oops.org/117
    * centos5 geoip patch하기
      http://kldp.org/node/82983
      커피닉스 카페 최근 글
    [10/20] Cross Compiler 깔
    [07/14] SSL АО
    [04/26] Re: 도스화면 원격조종 여부
    [04/25] 도스화면 원격조종 여부
    [10/30] Cshell에서 난수 설정
    [10/23] 공항철도주식회사 SE 구인 件
    [01/26] Re: wget으로 다른서버에있는 디렉토리를 가져오려고합니다.
    [01/25] wget으로 다른서버에있는 디렉토리를 가져오려고합니다.
    [01/11] 특정 안드로이드 WebView 버전에서 SSL 문제 (WebView 버그)
    [08/01] DNS forwarder (전달자) 서버를 통해서 쿼리하면 역방향을 받아오질 못합니다.
    [05/16] (주)후이즈 시스템엔지니어 (경력자) 모집
    [02/15] [AWS] Cloudfront edge 확인하기
    [01/20] Mobile Service/eCommerce 기업에서 Server / Java / PHP 개발자 구인
    [01/11] 탄탄한 퍼블리싱 모바일기업에서 Mobile 개발자를 모십니다.
    [01/11] 탄탄한 퍼블리싱 모바일기업에서 Web Front 개발자를 모십니다.
      New!   최근에 등록한 페이지
      KiCad EDA Suite project (Free/Libre/Open-Source EDA Suite) (CAD)
      오픈캐스케이드 캐드 (OpenCASCADE CAD)
      QCad for Windows --- GNU GPL (Free Software)
      The Hello World Collection
      IPMI를 활용한 리눅스 서버관리
      DNS 설정 검사
      nagiosgraph 설치 방법
      Slony-I 설치 방법 (postgresql replication tool)
      Qmail기반의 Anti spam 시스템 구축하기
      clusterssh

    [ 함께하는 사이트 ]




    운영진 : 좋은진호(truefeel), 야수(yasu), 범냉이, sCag
    2003년 8월 4일~