컴퓨터 / Computer

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

공유지기 3 7,792 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 생성 이거도 안해도 됩니다.
티셔츠 17수 라운드 반팔 프린트스타 베이직 오버핏 남녀공용
고급스러운 파스텔톤 컬러 아놀드파마 숙녀 메쉬 단목 0015iu
참빗(A-18)
신형 가이드 컷트빗 곡선형 커트 빗 바리깡 셀프이발
롯데 효도라디오 ATX-08 TF재생 SOS경보음 손전등
캐논 유지보수카트리지 MC-G01
오젬 갤럭시탭S7 가로/세로거치 펜홀더 케이스
유파 전기토스터 EK-222W
접이식 좌식 소파 체어 1인 등받이 방석 바닥 의자
이케아 YLLEVAD 윌레바드 미니액자 화이트13x18cm
우드케어 오일스테인 woodcare 10리터
벽데코타일DIY접착식10P 데코타일 셀프인테리어 타일
남성 조깅 헬스 스포츠 반바지 속바지 레깅스 운동복
카프리썬 오렌지 200ml x 20입 (10입x2박스)
(냉장)칠갑 생메밀면 1KGX10EA)
초슬림 만능 틈새 먼지 브러쉬 다용도 청소솔

아이코닉스 띠띠뽀 말하는 관제센터 놀이세트 (729182)
칠성상회
하이브리드 와이퍼 윈도브러쉬 국내 전차종 350-650mm
칠성상회

맨위로↑