컴퓨터 / Computer

varnish 쓸때 실제 접속자 ip 사용하기

공유지기 3 7,878 2016.08.24 22:42

0_fivEmSUN_cafc0046fceae53820e6e11ed19a3a0d3034ec3c.jpg 


지난 번에 varnish 설치하고 phpmyadmin 접속 안되는 현상이 나타났는데, 알고보니 http 접속 로그라든지 REMOTE_ADDR을 통해 접속자 ip 가져오는 것에 문제가 생겼다. 그리하여 이를 해결하고자 이 글을 추가해서 쓴다. 

 

varnish 동작 원리에 대해서는 글이 많으니 간단히 설명한다.

 

웹서버(httpd) -  varnish - 외부 접속자들

 

위 구조에서 외부 접속자들의 ip가 varnish를 지나서 웹 서버로 가면 모두 127.0.0.1로 표시가 된다. 아파치 로그 뿐만 아니라 그누보드나 자체 서비스의 로그에도 접속자 ip가 127.0.0.1로 기록된다. 이 문제가 phpmyadmin 문제와 결부가 되어 3가지 방법으로 해결을 시도하였다. 

 

1안 : 변수 변경

아파치에서 외부 ip를 확인하는 변수는 "REMOTE_ADDR"인데 이 변수를 다른 변수로 대체하여 사용하는 방법을 찾았다. 대체 가능한 변수는 "HTTP_X_FORWARDED_FOR"인데 웹 서버 설정에서 바꾸어야 할 부분이 있다. 

* httpd.conf

1. 추가 :  LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" varnishcombined

2. 수정

     ErrorLog logs/seven2015-error_log varnishcombined

     Customlog logs/seven2015-access_log varnishcombined

 

그리고 이렇게 하기 위해서 varnish 설정 파일을 수정해야 한다. 

* default.vcl : 주석 해제 

 sub vcl_pipe {

      set bereq.http.connection = "close";

     return (pipe);

 }

다른 부분은 그대로 두고 저 항목만 주석을 푼다. 

 

이제 저렇게 하고 운영 중인 체크박스와 그누보드를 아래와 같이 수정 작업하였다. 

* Checkbox 

 대체 :  REMOTE_ADDR -> HTTP_X_FORWARDED_FOR 

* GNUBoard

 - bbs/visit_insert_inc.php

 대체 :  REMOTE_ADDR -> HTTP_X_FORWARDED_FOR   

 - /common.php 

 대체 :  REMOTE_ADDR -> HTTP_X_FORWARDED_FOR   

 그런데 저렇게 수정하다보니 REMOTE_ADDR 변수가 들어가 있는 부분이 무척 많았다. 그리고 대다수 프로그램들이 REMOTE_ADDR을 쓰다보니 저렇게 수정하다보면 설치하는 프로그램 모두를 저렇게 바꾸어야 하는 수고가 든다. 


2안 : mod-rpaf 설치  (잘 안됨)

그래서 다른 방법을 찾아보니 누군가가 mod-rpaf를 쓰면 된다고 하였다. 그래서 아래 순서대로 진행을 해 보았다. 

* 다운 받기 (이게 원 사이트에 가면 잘 다운받을 수가 없어서 아래 구글에서 받았다.)

 - 파일 : https://code.google.com/p/nginxda/downloads/detail?name=mod_rpaf-0.6.tar.gz&can=2&q=

 - 위치 : /usr/local/src 

 

* 압축 풀기

 - tar xzvf mod_rpaf-0.6.tar.gz

 - cd mod_rpaf-0.6

* 설치 

 apxs -i -c -n mod_rpaf-2.0.so mod_rpaf-2.0.c

 

* httpd.conf 수정

 - 아래 추가 

LoadModule rpaf_module modules/mod_rpaf-2.0.so

# mod_rpaf Configuration

RPAFenable On

RPAFsethostname On

RPAFproxy_ips 127.0.0.1 10.0.0.1

RPAFheader X-Forwarded-For

 -> 127.0.0.1 -> 서버 ip로 변경  (10.0.0.1은 삭제)

 

저렇게 하고 httpd를 다시 실행시켰는데, 잘 동작하지 않았다. 첫번째 방법은 프로그램 설치할때만 작업을 해야 하는데, 이번 방법은 뭔가 적용이 잘 안되었다. 

 

3안 : 프로그램 추가 없이 변수 전달로 처리

이 방법을 쓰니 "HTTP_X_FORWARDED_FOR" 변수를 "REMOTE_ADDR" 변수로 연결하는데, 설치하는 프로그램에 관계없이 프로그램을 설치할때 httpd.conf만 잘 수정하면 된다.

 

* default.vcl 수정

 - 아래 항목을 추가

# Below is a commented-out copy of the default VCL logic.  If you

# redefine any of these subroutines, the built-in logic will be

# appended to your code.

 sub vcl_recv {

     if (req.restarts == 0) {

        if (req.http.x-forwarded-for) {

            set req.http.X-Forwarded-For =

                req.http.X-Forwarded-For + ", " + client.ip;

        } else {

            set req.http.X-Forwarded-For = client.ip;

        }

    }

  

 if (req.request != "GET" &&

       req.request != "HEAD" &&

       req.request != "PUT" &&

       req.request != "POST" &&

       req.request != "TRACE" &&

       req.request != "OPTIONS" &&

       req.request != "DELETE") {

#         /* Non-RFC2616 or CONNECT which is weird. */

         return (pipe);

     }

     if (req.request != "GET" && req.request != "HEAD") {

#         /* We only deal with GET and HEAD by default */

         return (pass);

     }

     if (req.http.Authorization || req.http.Cookie) {

#         /* Not cacheable by default */

         return (pass);

     }

   return (lookup);

  #   return (pipe);

 }

#

 sub vcl_pipe {

#     # Note that only the first request to the backend will have

#     # X-Forwarded-For set.  If you use X-Forwarded-For and want to

#     # have it set for all requests, make sure to have:

      set bereq.http.connection = "close";

#     # here.  It is not set by default as it might break some broken web

#     # applications, like IIS with NTLM authentication.

     return (pipe);

 }

 

 

* varnish 재실행

 - service varnish restart 

 

 

* varnish_client_ip.php 생성

/etc/httpd/conf.d/ 에 varnish_client_ip.php 를 생성한다. 내용은 아래와 같다.

<?php

if( isset( $_SERVER[ 'HTTP_X_FORWARDED_FOR' ] ) ) {

  $_SERVER[ 'REMOTE_ADDR' ] = $_SERVER[ 'HTTP_X_FORWARDED_FOR' ];

}

 

* httpd.conf

1. 추가 :  LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" varnish

 

2. 수정 (varnish도 varnishcombined도 

     ErrorLog logs/seven2015-error_log varnish

     Customlog logs/seven2015-access_log varnish

 

3. VirtualHost 수정

아래 코드를 넣는다. 

<Directory "/var/www/www.example.com">

    php_value auto_prepend_file "/etc/httpd/conf.d/varnish_client_ip.php"

</Directory>

 

4. 예제 

이제, 아래와 같은 샘플을 넣으면 된다. 

<VirtualHost 127.0.0.1:8080>

    ServerAdmin webmaster@dummy-host.example.com

    DocumentRoot /var/www/www.example.com

    ServerName www.example.com

    ErrorLog /var/log/httpd/example.com-error_log

    LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" varnish

    CustomLog /var/log/httpd/example.com_log varnish

    <Directory "/var/www/www.example.com">

       php_value auto_prepend_file "/etc/httpd/conf.d/varnish_client_ip.php"

    </Directory>

</VirtualHost>  

5. 아파치 재실행

/usr/sbin/apachectl restart

 

이 방법을 쓰면 127.0.0.1이 아니고 제대로 접속자 ip를 볼 수 있다. 그리고 설치하는 프로그램이나 코드도 변수 수정없이 할 수 있다. 

 

 

* 참조 

 - http://stackoverflow.com/questions/10024877/varnish-client-ip-not-logging-in-apache-logs

 - http://stackoverflow.com/questions/19311164/serverremote-addr-returns-127-0-0-1

 - http://old.drupion.com/resources/downloads/mod-rpaf

 - https://code.google.com/p/nginxda/downloads/detail?name=mod_rpaf-0.6.tar.gz&can=2&q=

 - http://www.techinfobest.com/getting-real-client-ip-through-varnish/

Comments

공유지기 2019.03.09 15:13
3안의 default.vcl 수정에서,

req.request 는 모두 req.method로 바꿔야 한다네요. varnish 4에서 바뀌었다고 합니다.


출처 : https://github.com/varnish/libvmod-vsthrottle/issues/9
공유지기 2019.03.09 15:17
그리고  sub vcl_recv 절 끝부분에 있는

  return (lookup);
  #  return (pipe);



  #  return (lookup);
    return (pipe);

로 바꿔줘야 합니다.
공유지기 2019.03.09 19:15
그리고 * varnish_client_ip.php 생성 이거도 안해도 됩니다.
이케아 PARKLA 페르클라 수납박스 55x49x19cm
브이넥 골지 니트 티셔츠 반팔티 무지 데일리 4컬러
닥터클레오 콜라겐 뽑아쓰는 마스크팩 30매입, 1개
여성 사각버클 패션 플랫슈즈 버클디자인 스웨이드 단화
롯데 블루투스CD포터블카세트 핑키770 CPD 라디오 등
BOSCH 원형브러쉬 GAS14.4V-LI GAS18V-LI 겸용
FAX L380SK 캐논 슈퍼재생토너 검정
스마트폰 내시경카메라 Y101-01 1m C핀 5핀 USB타입
이케아 GLASIG글라시그 미니양초홀더 유리5x5cm 5개입
이케아 YLLEVAD 윌레바드 미니액자 화이트13x18cm
LED 전구 T 벌브 램프 40W 전구색 E26 비츠온
NEW 페인트 부자재세트 DIY 페인트도구 셀프페인팅 페인트용품
롯데 델몬트 망고 드링크 190ml 32팩
바우와우 혼합Cut 350g (강아지 간식)
폼폼푸린 프레시 수영가방
동서 카누 미니 마일드 로스트 아메리카노 9g

A4 백봉투 무지봉투 105 x 225mm 100매
바이플러스
3M 4910 하이패스 부착 투명 양면테이프 10cm x 10cm
바이플러스

맨위로↑