Recommanded Free YOUTUBE Lecture: <% selectedImage[1] %>

Contents

Proxy 서버에 대하여

Proxy는 자신을 통해서 다른 네트워크에 간접적으로 접속할 수 있도록 해주는 컴퓨터 혹은 프로그램을 가리킨다. 요청을 중계하는 일을 하는 컴퓨터 혹은 프로그램으로 이해하면 된다. 이때 중계하는 프로그램을 proxy 프로그램이라고 한다. proxy 프로그램은 서버로서 작동하기 때문에 일반적으로 proxy 서버라고 한다.

proxy는 중계 목적, 중계 위치, 중계 방법에 따라서 다양한 종류가 있다.

proxy 서버를 구축하는 이유는 다음과 같다.
  1. 보안 : 익명의 사용자가 서버에 직접 접근하는 것을 막는다.
  2. 속도 : proxy 서버는 사용자의 요청을 cache 해서, 동일한 요청이 들어오면 cache의 자원을 반환한다. 이는 서비스의 속도를 높여준다.
  3. ACL : 사이트 접근에 대한 접근 정책을 정의할 수 있다.
  4. Log/Audit : 회사내 직원의 인터넷 사용을 레포팅 할 수 있다. 반대로 인트라넷의 사용을 레포팅할 수도 있다.
  5. 지역 네트워크의 제한을 우회하기 위해서 : 보안상의 이유로 80번 외에는 포트를 막아 놓는 경우가 있는데, 이러한 제한을 우회해서 원하는 다른 서비스를 이용할 수 있다.

Proxy 종류

Forward Proxy

일반적으로 사용하는 프록시 방식이다. 프록시 서버는 클라이언트와 애플리케이션 서버 사이에 위치한다. 클라이언트가 타겟 서버인 애플리케이션에 서비스를 요청할 때, 프록시 서버로 요청을 보낸다. 그러면 프록시 서버가 타겟 서버로 요청을 중계한다.

Reverse Proxy

Reverse라는 용어 때문에 헛갈릴 수 있다. 기본적인 구성은 Forward Proxy와 동일하지만, 클라이언트는 Proxy Server 배후에 있는타겟 서버의 URL(:12)이 아닌 Proxy Server의 URL로 요청한다.

Desktop PC는 배후에 있는 mail.a.com 이 아닌 Proxy Server의 URL인 www.abc.com을 요청한다. 요청을 받은 Proxy Server는 URI에 맵핑된 애플리케이션 서버로 중계를 한다. 그러므로 애플리케이션 서버는 외부로 부터 감추어지게 되는 효과를 얻게 된다.

애플리케이션 서버의 정보가 외부로 부터 감추어진 다는 이점외에, 분산 처리 시스템을 만들 수 있다는 장점도 있다. Proxy Server이 요청을 분산하는 역할을 할 수 있기 때문이다.

Open Proxy

Open Proxy는 모든 인터넷 사용자가 액세스할 수 있는 프록시 서버다. 수백에서 수천정도의 오픈 프록시가 익명으로 운영되고 있는 것으로 알려져 있다. 오픈 프락시를 이용하면 자신의 IP를 숨길 수 있다. 중국같은 나라는 정치적인 이유로 외부 사이트 접근을 막는 경우가 있는데, 공개 프록시를 이용하면 접근할 수 있다.

공개 소프트웨어를 이용한 proxy server 구축

위에 언급한 3가지 종류의 proxy server를 모두 구축해봐야 겠다. 구축 후 활용법에 대해서 고민을 해봐야지. AWS VPC 환경에서 테스트하기로 했다.

HAproxy를 이용한 Reverse proxy server 구축

흔히 볼 수 있는 프락시 서버 형태는 Reverse proxy server이다. Reverse proxy server를 이용해서 로드밸런서를 구현할 수 있기 때문이다.

클라이언트가 reverse proxy server로 요청을 보내면 proxy server는 이 요청을 내부에 있는 실제 서비스 서버에 요청을 전달한다. Proxy server에는 두 개 이상의 서비스 서버가 붙을 수 있으므로 결과적으로 요청을 분산해서 처리하는 효과를 얻을 수 있다.

Haproxy를 이용하는 주된 목적이 reverse proxy server 타입으로 작동하게 함으로써, 로드밸런싱 기능을 구현하는 것이기도 하다.

다음과 같은 환경을 구축하기로 했다.

  1. Haproxy 서버 인스턴스를 하나 만든다. 이 인스턴스는 EIP를 가진다. 유저는 EIP를 주소로 haproxy 서버에 요청을 보낼 수 있다.
  2. 두 개의 Apache 웹 서버를 만든다. 이들 웹서버는 80번 포트로 서비스한다.
  3. Haproxy는 유저의 요청을 두 개의 웹 서버로 분산해서 보내는 것으로 로드밸런싱 환경을 만든다. 로드밸런싱 방식으로 roundrobin을 사용했다.
각 호스트의 주소 정보는 다음과 같다.

호스트 사설 IP 공인 IP
Haproxy 10.10.101.50 11.11.11.11
apache01 10.10.102.188
apache02 10.10.102.189

Haproxy의 서버의 설정이다. 설명은 주석으로 대신했다.
global
        log /dev/log    local0
        log /dev/log    local1 notice
        chroot /var/lib/haproxy
        user haproxy
        group haproxy
        daemon

defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        contimeout 5000
        clitimeout 50000
        srvtimeout 50000
        # HTTP 에러 코드별로 에러정보를 남기도록 설정했다.
        errorfile 400 /etc/haproxy/errors/400.http
        errorfile 403 /etc/haproxy/errors/403.http
        errorfile 408 /etc/haproxy/errors/408.http
        errorfile 500 /etc/haproxy/errors/500.http
        errorfile 502 /etc/haproxy/errors/502.http
        errorfile 503 /etc/haproxy/errors/503.http
        errorfile 504 /etc/haproxy/errors/504.http

# 로드밸런싱할 웹 서버들의 목록
listen apache-cluster
      mode http
      balance roundrobin
      option httpclose
      option forwardfor

      # haproxy 서버의 bind 주소는 80번
      bind *:80

      # 두개의 웹 서버로 로드밸런싱한다.
      server apache01 10.10.102.188:80 maxconn 32
      server apache02 10.10.102.189:80 maxconn 32

Haproxy 서버의 EIP로 테스트를 테스트를 하면 된다.
$ wget http://11.11.11.11/
--2013-12-14 00:39:32--  http://54.249.28.65/
접속 11.11.11.11:80... 접속됨.
HTTP request sent, awaiting response... 200 OK
Length: 177 [text/html]
Saving to: ‘index.html’

100%[=============================================================>] 177         --.-K/s   in 0s      

2013-12-14 00:39:33 (30.2 MB/s) - ‘index.html’ saved [177/177]

apache01과 apache02의 로그를 보자.
# tail /var/log/apache02/access.log 
10.10.101.50 - - [13/Dec/2013:15:38:13 +0000] "GET / HTTP/1.1" 200 444 "

# tail /var/log/apache01/access.log
10.10.101.50 - - [13/Dec/2013:15:38:09 +0000] "GET / HTTP/1.1" 200 444 "-" 

모두 haproxy의 IP가 찍힌걸 확인할 수 있다. Haproxy가 HTTP 요청을 대신 전달했기 때문에, apache 로그파일에 haproxy의 IP가 찍힌건 상식적인 결과다. 접근한 클라이언트의 IP 정보는 haproxy 로그를 봐야 확인할 수 있다. 만약 웹 서버에서 클라이언트의 IP를 확인하고 싶다면 X-Forwared-For를 사용하면 되겠다.

Apache웹 서버를이용한 Forward proxy server 구축

Forward proxy server 테스트를 위해서 다음과 같은 환경을 만들었다.

HAProxy를 설치했던 인스턴스에 apache 웹서버를 설치하고 mod_proxy를 이용해서 forward proxy 설정을 한다. VPC에 인스턴스 하나 만들어서 w3m으로 forward proxy의 작동을 테스트 하기로 했다.

Open proxy server 구축

Open SSH를 이용한 Proxy Server 구축

OpenSSH는 BSD기반의 SSH 서버/클라이언트 프로그램이다. 이 프로그램을 이용하면 매우 간단하게 - 그리고 별도의 비용 없이 - Proxy Server 환경을 구축할 수 있다. 저렴한 비용이라는 장점외에 Proxy Over SSL환경을 구축함으로써 강력한 데이터 보안 환경을 구축할 수 있다는 장점도 가진다.

Port forwarding Proxy Server

SSH는 port forwarding를 이용해서 SSH 터널을 만들고 이 터널을 이용해서 데이터를 중계한다.

  1. Application Server는 SSH 클라이언트를 이용해서 Proxy Server:8080에서 Application Server:80으로 SSH 터널을 뚫는다.
  2. Home PC는 8080에서 SSH Proxy:8080으로 향하는 터널을 뚫는다. 결과적으로 Home PC:8080에서 Application server:8080까지 SSH 터널이 뚫리게 되고, 이 터널을 통해서 데이터 통신을 하게 된다. 물론 Proxy Server에는 ssh서버가 떠 있어서 이들 포트를 중계한다.

구축 테스트 - Linux

테스트를 할려면 최소 2대의 컴퓨터가 있어야 할 것이다. 여기에서는 virtualbox(:12)를 이용해서 가상화 환경을 만들어서 proxy 테스트를 했다. virtualbox로 실행한 컴퓨터가 애플리케이션 서버역할을 한다. 운영체제는 우분투 리눅스로 아파티 웹서버가 설치되어 있다. proxy server 역할을 하는 컴퓨터의 IP는 192.168.1.119이다.
  1. ssh 클라이언트를 이용해서 ssh 터널을 생성한다. 8080 포트로 향하는 데이터를 80 포트, 즉 웹 서버로 보내겠다는 의미다.
     app-server # ssh -R 8080:localhost:80 yundream@192.168.56.1
이것으로 proxy server와 애플리케이션 서버간에 SSH 터널이 개설되었다.
  1. Home PC와 proxy server사이에 SSH 터널을 만든다.
    home-pc # ssh -L 8080:localhost:8080 yundream@192.168.1.119
localhost의 8080으로 향하는 데이터를 prox server의 8080으로 보내겠다는 의미다.

이제 웹 브라우저로 테스트하면 된다. 주소는 http://localhost:8080으로 하면 된다.

원칙적으로 애플리케이션 서버는 사설망 환경이므로 서비스 접근을 할 수가 없으나, proxy server의 중계로 웹 서비스를 받는 걸 확인할 수 있을 것이다.

구축 테스트 - Windows

윈도에서는 공개 ssh 클라이언트인 putty를 이용해서 SSH 터널을 뚫을 수 있다.
  1. proxy server의 주소는 192.168.1.119이다.
    보낸 사람 Linux
  2. Connection > SSH > Tunnels에서 터널을 설정한다.
    1. source port는 8080 이다.
    2. destination은 localhost:8080이다.
      보낸 사람 Linux
  3. 로그인을 한다.
  4. 브라우저를 이용해서 테스트 한다. 주소는 http://localhost:8080이다.

SOCKS 기반 Proxy 서버 구축

포트 포워딩 기반의 프록시 서버는 간단하게 구축할 수 있다. 하지만, 서비스 포트를 다양하게 할 수 없다는 단점이 있다. 여러 서비스를 이용하기 위해서는 서비스 개수만큼 SSH 터널을 뚫어야 한다. 하나의 SSH 터널에서 동적으로 서비스 포트를 이용할 수 있다면 어떨까.

openssh는 dynamic port forwading 기능을 지원한다. 이 기능을 이용하면 클라이언트는 SOCKS proxy를 설정하는 것으로 다양한 서비스를 이용할 수 있다. ie, firefox와 같은 웹 브라우저를 이용해서 많은 네트워크 프로그램들이 SOCKS를 지원한다.

  • proxy server : 8080 포트를 연다. -D 는 dynamic port forwarding 옵션이다.
    # ssh -D 8080 yundream@application.server
  • Home PC : 8080 포트로 터널을 만든다.
    # ssh -L 8080:localhost:8080 yundream@proxy.server
이제 Home PC에서는 socks를 이용해서 Application에 서비스를 요청할 수 있다. 이 경우 클라이언트 프로그램이 socks를 지원해야 한다. 대부분의 웹 브라우저는 socks를 지원한다. 혹은 tsocks와 같은 프로그램을 이용해서 클라이언트 설정 없이, socks 위에서 클라이언트를 실행할 수도 있다.
# tsocks w3m http://192.168.56.5
# tsocks ssh yundream@192.168.56.5

장점

openssh를 이용해서 proxy 서버를 구현할 때 얻을 수 있는 장점은 다음과 같다.
  1. 때때로 openssh는 가난한 자를 위한 프록시 서버라고 불려지기도 한다. 그만큼 저렴하고 간단하게 구축 할 수 있다는 의미다.
  2. OpenSSL기반의 강력한 암호화 알고리즘을 지원한다.
  3. PAM 모듈을 개발해서, 자체 인증 환경을 갖출 수 있다.
  4. 운영체제에 관계 없이 사용할 수 있는 서버/클라이언트가 준비되어 있다.