[CS] 프록시 서버와 프록시 패턴

Rosa Damascena·2023년 9월 6일
0

CS

목록 보기
1/4
post-thumbnail

📍 프록시 서버와 프록시 패턴


✔️ Proxy Server

→ 프록시 서버란

  • 프록시(Proxy)대리라는 의미로 네트워크에서 프록시 서버(Proxy Server)는 클라이언트가 자신을 통하여 다른 네트워크 서비스에 간접적으로 접속할 수 있게 해주는 컴퓨터 시스템이나 응용프로그램을 말한다.

→ 프록시 서버 종류

  1. Forward Proxy (정방향 프록시)

    • 클라이언트는 웹 요청을 보낼 때 먼저 클라이언트의 프록시 서버로 이동한다.
    • 프록시 서버가 클라이언트의 IP 주소 자체를 IP 주소로 바꾼다.
    • 프록시 서버가 웹 요청을 애플리케이션 서버로 전달한다.
    • 프록시 서버가 응답을 다시 클라이언트에 전달한다.

    ▶︎ 정방향 프록시 서버는 회사 내부 디바이스가 클라이언트인 경우에 유용하다. 네트워크 데이터를 외부인으로부터 보호하고 익명화하는 것이 가능하다.

  1. Reverse Proxy (역방향 프록시)

    • 역방향 프록시는 애플리케이션을 호스팅하는 서버와 최종 사용자 간의 중간 서버이다.
    • 들어오는 모든 인터넷 트래픽이 애플리케이션에 도달하기 전에 모니터링하고 차단한다.
    • 역방향 프록시는 방문자 트래픽을 검사하여 무단 활동이 있는지 확인한다.
    • 애플리케이션 또는 데이터베이스 서버에 보안, 익명성 및 트래픽 분산 관리 계층을 추가한다.
    • 웹 관리자는 특정 트래픽 소스를 차단하도록 역방향 프록시를 구성할 수 있다.
    • 보안 정책을 준수하는 요청만 애플리케이션 서버에 전달할 수 있다.

→ 프록시 서버를 사용하는 이유

  1. 개인 정보 보호
    : 프록시 서버 없이 클라이언트가 서버에 요청 시 IP가 노출되지만 프록시 서버 사용시 프록시 서버 IP 주소가 노출되기 때문에 개인 정보를 보호할 수 있다.

  2. 캐시 사용
    : 프록시 서버에 이전에 했던 요청들을 캐싱을 통해 저장을 해두기 때문에 같은 내용을 재요청시 서버를 거치지 않고 데이터를 주고 받을 수 있다. 이 과정에서 시간을 줄어들어 속도 향상에 도움을 준다.

  3. 인터넷 사용 제어
    : 이는 자체 프록시를 설정하는 회사 또는 기타 사용자가 주로 사용한다. 프록시를 제어하는 경우 일부 웹 주소를 금지하여 자녀, 직원 또는 프록시를 통해 실행되는 네트워크를 사용하는 사람이 원하지 않는 곳으로 가지 못하도록 할 수 있당.

  4. 접속 우회
    : 접속한 클라이언트의 실제 IP 주소를 알 수 없기 떄문에 자신의 위치를 숨길 수 있다. 이는 프록시 서버를 통해 접속을 우회할 수 있다는 것이다.

  5. 방화벽 역할
    : 개인 사용자에서 기업에 이르기까지 프록시는 온라인에서 악의적인 공격을 방어하는 방화벽 역할을 할 수 있다. 그리고 가장 기본적인 수준에서 장치의 온라인 주소를 가려 보안을 강화할 수 있다.

→ 프록시와 VPN 비교

  • 프록시 서버가상 프라이빗 네트워크(VPN)는 조직의 내부 기업 네트워크와 공용 인터넷을 중개하는 기술이다.

  • 프록시 서버와 VPN의 유사점

    • 모든 수신 및 발신 네트워크 트래픽을 프록시 서버, VPN 또는 둘 다를 통해 라우팅 할 수 있다.

    • 프록시 서버와 가상 프라이빗 네트워크(VPN) 둘 다 클라이언트의 개인 정보 보호 및 보안을 강화한다. 둘 다 클라이언트의 IP 주소를 익명화한다.

  • 프록시 서버와 VPN의 차이점

    • 클라이언트 서버 통신에서 하는 역할

      • 프록시 서버 : 클라이언트와 서버 간의 통신을 익명화한다.
      • VPN : 클라이언트와 서버 간의 통신을 익명화하고 암호화한다.
    • 들어오는 트래픽

      • 프록시 서버 : 역방향 프록시 서버는 들어오는 트래픽을 심사하고 분산한다. 프록시 서버에 도달하는 트래픽을 제어할 수 없다.
      • VPN : 원격 디바이스에 설치된 VPN 클라이언트 소프트웨어와 기업 네트워크 간의 트래픽을 암호화한다. 네트워크에 엑세스 할 수 있는 사람을 제어할 수 있다.
    • 나가는 트래픽

      • 프록시 서버 : 정방향 프록시 서버는 나가는 트래픽을 익명화한다.
      • VPN: 나가는 트래픽을 익명화 하고 암호화한다.
    • 로드 밸런싱

      • 프록시 서버 : 사용량이 많은 시간대에는 웹 요청이 애플리케이션 서버의 용량을 초과할 수 있다. 역방향 프록시 서버는 로드 밸런서 역할을 하여 요청을 백업 서버에 분산할 수 있다.
      • VPN : 로드 밸런싱 기능을 제공하지 않는다.

✔️ Proxy Pattern

→ 프록시 패턴

  • 프록시 패턴(Proxy Pattern)
    : 대상 원본 객체를 대리하여 대신 처리하게 함으로써 로직의 흐름을 제어하는 행동 패턴이다.
    즉, 대상 객체의 메소드를 직접 실행하는 것이 아닌 대상 객체에 접근하기 전에 프록시 객체의 메서드를 접근한 후 추가적인 로직을 처리한 뒤 접근하는 것이다.

▶︎ 프록시 패턴은 디자인 패턴 중 구조 패턴에 해당한다.

→ 프록시 패턴 구조

  • Subject(주체)
    : 프록시와 실제 서비스 객체가 모두 구현하는 공통 인터페이스이다. 이 인터페이스를 통해 클라이언트는 프록시와 실제 서비스 객체를 동일한 방식으로 사용할 수 있다.

  • RealSubject(실제 주체)
    : 주체의 실제 구현으로 클라이언트가 직접 접근하려는 실제 서비스 객체라고 할 수 있다.

  • Proxy(프록시)
    : 실제 주체(RealSubject)에 대한 대리자 역할을 하는 객체이다. 주로 클라이언트와 실제 주체 사이에 위치하며, 클라이언트의 요청을 중개하고 추가 기능을 수행할 수 있다.

  • Client(클라이언트)
    : Subject 인터페이스를 이용하여 프록시 객체를 생성해 이용한다. 클라이언트는 프록시를 중간에 두고 프록시를 통해서 RealSubject와 데이터를 주고 받는다.

→ 프록시 패턴 종류

  • 가상 프록시(Virtual Proxy)
    : 가상 프록시는 실제 객체를 대신하여 비용이 많이 드는 작업을 지연시키는 데 사용된다. (지연 초기화 방식)
    실제 객체가 필요한 시점에 생성되거나 초기화되며, 그 전에는 가상 프록시만 존재한다.
    이미지 뷰어에서 이미지 로딩을 미리보기로 시작하고 필요할 때만 전체 이미지를 로드하는 경우에 사용된다.

  • 원격 프록시(Remote Proxy)
    : 원격 프록시는 분산 시스템에서 객체가 다른 머신 또는 위치에 존재할 때 사용된다. 클라이언트는 로컬 프록시를 통해 원격 객체에 액세스하고, 실제로는 원격 서버에서 데이터를 가져온다. 원격 프록시는 원격 서비스에 대한 통신을 추상화하고 관리한다.

  • 보호 프록시(Protection Proxy)
    : 보호 프록시는 객체에 대한 액세스를 제어하여 보안을 강화한다.(접근 권한)
    클라이언트가 객체에 직접 접근하지 못하도록 권한 검사를 수행하거나 암호화를 해독하는 등의 보안 기능을 제공한다. 보호 프록시는 보안 감시, 인증 및 권한 부여에 사용된다.

  • 로깅 프록시(Logging Proxy)
    : 대상 객체에 대한 로깅을 추가하려는 경우 사용한다. 프록시는 서비스 매서드를 실행하기 전에 로깅을 하는 기능을 추가하여 재정의한다.

  • 캐싱 프록시(Caching Proxy)
    : 캐싱 프록시는 클라이언트 요청의 결과를 캐시하고 이 캐시의 수명 주기를 관리한다. 이는 이전에 수행한 작업의 결과를 캐시에 저장하여 동일한 요청에 대한 반복 작업을 피하고 성능을 향상시킨다. 캐싱 프록시는 주로 데이터베이스 쿼리나 웹 페이지에서 사용된다.

▶︎ 이 외에 스마트 프록시(Smart Proxy), 복잡성 감소 프록시 (Complexity Reduction Proxy), 동기화 프록시 (Synchronization Proxy) 등이 있으며, 프록시 패턴은 다양한 상황에서 다양한 종류로 활용될 수 있다.

→ 프록시 패턴 특징

  • 프록시 패턴 사용이 필요할 때
    • 접근을 제어하거나 기능을 추가해야 하는데 기존의 특정 객체를 수정할 수 없을 때
    • 초기화 지연, 접근 제어, 로깅, 캐싱 등 기존 객체 동작에 수정없이 일을 수행하고자 할 때
  • 프록시 패턴의 장점
    • 개방 폐쇄 원칙(OCP) 준수
      : 기존 대상 객체의 코드를 변경하지 않고 새로운 기능을 추가할 수 있다.
    • 단일 책임 원칙(SRP) 준수
      : 대상 객체는 자신의 기능에만 집중하고, 그 외에 부가 기능을 제공하는 역할을 프록시 객체에 위임하여 다중 책임을 회피할 수 있다.
    • 원래 하려던 기능을 수행하며 그외의 부가적인 작업(로깅, 인증, 네트워크 통신 등)을 수행하는데 유용하다.
    • 클라이언트는 객체를 신경쓰지 않고, 서비스 객체를 제어하거나 생명 주기를 관리할 수 있다.
  • 프록시 패턴의 단점
    • 많은 프록시 클래스를 도입해야 하므로 코드 복잡도가 증가한다.
      자바에서는 리플렉션에서 제공하는 동적 프록시(Dynamic Proxy) 기법을 이용해서 해결할 수 있다.
    • 프록시 패턴은 객체 간의 중간 계층을 도입하므로 약간의 오버헤드가 발생할 수 있다.
      이로 인해 성능이 약간 저하될 수 있다.

→ 프록시 패턴을 사용하는 이유

  1. 지연 로딩
    : 실제 객체가 필요한 시점에 생성하거나 초기화한다. 이를 통해 성능을 최적화할 수 있다.

  2. 보안
    : 프록시는 접근 제어 및 권한 검사를 수행하여 보안을 강화할 수 있다.

  3. 캐싱
    : 프록시는 결과를 캐싱하여 동일한 요청에 대해 중복 작업을 방지하고 성능을 향상시킨다.

  4. 원격 액세스
    : 원격 서버와의 통신을 관리하고 결과를 캐싱하여 원격 서비스에 대한 액세스를 최적화할 수 있다.

  5. 클라이언트 코드 분리
    : 클라이언트는 실제 객체가 아니라 프록시와 상호작용하므로 클라이언트 코드가 간결해지고 객체와 클라이언트 코드 간의 결합도가 낮아진다.

  6. 서비스 확장 및 변경 용이성
    : 클라이언트와 서비스 객체 사이에 프록시를 두면 새로운 기능을 추가하거나 기존 기능을 변경하기가 더 쉬워지고 클라이언트 코드 수정 없이 프록시를 교체할 수 있다.

→ 프록시 패턴 사용 예시

▶︎ 웹페이지 캐싱

: 이미 요청된 웹 페이지를 캐싱하여 동일한 요청이 다시 들어올 때 웹 페이지를 다시 다운로드 하지 않고 캐시된 페이지를 반환한다.

import java.util.HashMap;
import java.util.Map;

// 웹 페이지 인터페이스
interface WebPage {
    void display();
}

// 실제 웹 페이지 클래스
class RealWebPage implements WebPage {
    private String url;

    public RealWebPage(String url) {
        this.url = url;
        loadPage();
    }

    private void loadPage() {
        System.out.println("Loading web page: " + url);
    }

    public void display() {
        System.out.println("Displaying web page: " + url);
    }
}

// 웹 페이지 캐시 프록시 클래스
class WebPageCacheProxy implements WebPage {
    private Map<String, RealWebPage> cache = new HashMap<>();
    private String url;

    public WebPageCacheProxy(String url) {
        this.url = url;
    }

    public void display() {
        if (cache.containsKey(url)) {
            System.out.println("Retrieving web page from cache: " + url);
        } else {
            RealWebPage realWebPage = new RealWebPage(url);
            cache.put(url, realWebPage);
        }
        cache.get(url).display();
    }
}

public class ProxyPatternExample {
    public static void main(String[] args) {
        // 웹 페이지 요청과 캐시를 비교
        WebPage realPage1 = new RealWebPage("https://www.example.com/page1");
        WebPage proxyPage1 = new WebPageCacheProxy("https://www.example.com/page1");

        WebPage realPage2 = new RealWebPage("https://www.example.com/page2");
        WebPage proxyPage2 = new WebPageCacheProxy("https://www.example.com/page2");

        // 첫 번째 페이지 요청 시 실제 페이지를 로드하고 캐싱합니다.
        proxyPage1.display();

        // 두 번째 페이지 요청 시 캐시된 페이지를 사용합니다.
        proxyPage1.display();

        // 세 번째 페이지 요청 시 실제 페이지를 로드하고 캐싱합니다.
        proxyPage2.display();
    }
}

▶︎ 가상 프록시 패턴 사용

: 가상 프록시 패턴을 사용하여 이미지 로딩을 구현한다. 가상 프록시는 이미지를 필요할 때만 로드하고, 그렇지 않은 경우에는 미리보기 이미지만 표시한다.

// 이미지 인터페이스
interface Image {
    void display();
}

// 실제 이미지 클래스
class RealImage implements Image {
    private String filename;

    public RealImage(String filename) {
        this.filename = filename;
        loadFromDisk();
    }

    private void loadFromDisk() {
        System.out.println("Loading image: " + filename);
    }

    public void display() {
        System.out.println("Displaying image: " + filename);
    }
}

// 가상 프록시 이미지 클래스
class ProxyImage implements Image {
    private RealImage realImage;
    private String filename;

    public ProxyImage(String filename) {
        this.filename = filename;
    }

    public void display() {
        if (realImage == null) {
            realImage = new RealImage(filename);
        }
        realImage.display();
    }
}

public class ProxyPatternExample {
    public static void main(String[] args) {
        // 실제 이미지 로딩과 가상 프록시 이미지 로딩 비교
        Image realImage = new RealImage("large_image.jpg");
        Image proxyImage = new ProxyImage("small_image.jpg");

        // 이미지를 처음 로딩할 때 실제 이미지가 로드됩니다.
        realImage.display();

        // 이미지를 처음 로딩할 때 가상 프록시 이미지가 로드되며, 이후에는 로드되지 않습니다.
        proxyImage.display();
        proxyImage.display();
    }
}

참고 문헌

  • aws
  • cloudflare
profile
경험 수집가

0개의 댓글

관련 채용 정보