컴퓨터 / Computer

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

공유지기 3 7,923 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
여성 230-255mm 니트 삭스 슬립온 뮬
여성 볼드 체인 통굽 슬리퍼
남녀 공용 밴딩 조거 바지 카고 팬츠 작업복 여름 봄
스마트폰 아이패드 태블릿 초미세 정전식 터치펜
DocuPrint P265dw 재생카트리지 대용량 검정 2600매
LG V50 IS 투명 젤리 케이스 V500
갤럭시 노트20 빨강머리앤v1 wk플립 N981 케이스
이케아 GLASIG글라시그 미니양초홀더 유리5x5cm 5개입
롱 냉장고 손잡이 커버 2개입 문고리 커버 DD-12706
마이로맨스 디퓨져 방향제
이케아 GLASIG글라시그 미니양초홀더 유리5x5cm 5개입
뉴욕웨이 WPI 초코맛 2kg 단백질보충제 헬스보충제
(벨라홈) 분리기능적층형 재활용분리수거함1P(CN9109)
ACEPEED 자전거 핸드폰 휴대폰 거치대 용품
키모니 하이소프트홀그립 KGT102

바로바로610 국산 핸디형 무선 차량용 진공 청소기
칠성상회
3000포켓노트 A5 백색 DAYSTORY
칠성상회

맨위로↑