본문 바로가기
C언어/Proxy 서버

Proxy 서버

by lacuca9 2024. 9. 20.

웹 프록시는 웹 브라우저와 최정 서버 사이에서 중개 역할을 하는 프로그램.

브라우저는 프록시에 연락하고 프록시는 요청을 최종 서버로 전달.

최종 서버가 프록시에 응답하면, 프록시는 응답을 브라우저로 전송

 

사용처

  • 방화벽 뒤의 브루어저가 프록시를 통해서만 방화벽 너머의 서버와 접속할 수 있도록 함
  • 모든 식별 정보를 제거하여 익명화 도구로 작용할 수 있다
  • 웹 객체를 캐시하여 서버로부터의 객체의 로컬 복사본을 저장하고, 이후에 캐시에서 읽어 응답

 

간단한 HTTP 프록시 구현

1. 프록시를 설정하여 들어오는 연결을 수락,
    요청을 읽고 파싱,
    웹 서버로 요청을 전달

    서버의 응답을 읽어 해당 클라이언트로 응답을 전달

2. 여러 동시 연결을 처리하도록 업그레이드 ( 동시성 처리 )

3. 최근에 접근한 컨텐츠의 간단한 주 메모리를 캐시를 사용하여 프록시에 캐싱 기능 추가

 


1. 순차 웹 프록시 구현

  1. HTTP/1.0 GET 요청을 처리하는 기본 순차 프록시를 구현
  2. 프록시 구현 단계
    1. 프록시 서버 시작
      • 명령줄에서 지정된 포트 번호에서 들어오는 연결을 수신
      •  포트에서 소켓을 열고, 연결 수신 대기
    2. 연결 수락
      • 클라이언트와 연결 확립되면, 클라이언트의 요청을 수신하기 위한 소켓을 
    3. 칼라이언트 요청 읽기
      • 클라이언트로부터 전체 HTTP 요청을 읽음. 메서드(GET), 요청된 URL 및 추가 헤더가 포함
      • 요청이 제대로 종료되었는지(빈 줄 감지) 확인

    4. 요청 파싱
      • HTTP 요청이 유효한 HTTP/1.0 GET 요청인지 확인
      • 필요한 구성 요소(예: URL)를 추출
    5. 웹 서버에 연결
      • 추출한 URL을 사용하여 적절한 웹 서버에 연결
      • 웹 서버와의 통신을 위해 새로운 소켓을 생성
    6. 웹 서버에 요청 전송
      • 클라이언트의 요청을 웹 서버에 전달. GET 요청 및 필요한 헤더를 포함
    7. 서버의 응답 읽기
      • 웹 서버로부터의 응답을 읽음. 상태 줄, 헤더, 본문으로 구성
      • 필요한 경우 청크 전송 인코딩을 처리
    8. 응답을 클라이언트에 전달
      • 웹 서버의 응답을 원래 소켓을 통해 클라이언트에게 보냄
      • 모든 연결을 적절히 종료하여 리소스 해제

 

2. HTTP/1.0 GET 요청

" http://www.cmu.edu/hub/index.html " 을 입력하면, 브라우저는 다음과 같은 형식의 HTTP 요청을 프록시로 전송한다.
" GET http://www.cmu.edu/hub/index.html HTTP/1.1 "

프록시는 "www.cmu.edu"  에 연결을 열고, 다음과 같은 형식의 HTTP 요청을 보내야 함.

" GET /hub/index.html HTTP/1.0 "

요청 라인은 HTTP/1.1로 끝나지만 프록시의 요청 라인은 HTTP/1.0으로 끝남

 

요청 헤더

중요한 요청 헤더 Host, User-Agent, Connection, Proxy-Connection 헤더.

Host 헤더는 항상 전송. 기술적으로 HTTP/1.0 사양에 승인되지 않지만, 합리적인 응답을 유도하는 데 필요함

Host 헤더는 최종 서버의 호스트명을 설명.
ex) http://www.cmu.edu/hub/index.html 에 접근하기 위해 " Host: www.cmu.edu   " 라는 헤더를 전송해야함

 

User-Agent 헤더를 항상 전송할 수 있다.

" User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:10.0.3) Gecko/20120305 Firefox/10.0.3 "

프록시는 한 줄로 전송해야 함. User-Agent 헤더는 클라이언트를 식별하며,

웹 서버는 식별 정보를 사용하여 제공하는 컨텐츠를 조작.

간단한 텔넷 스타일 테스트 중에 반환되는 자료의 내용과 다양성을 개선할 수 있다.

 

Connection 헤더를 항상 전송해야함

" Connection: close "

Proxy-Connection 헤더도 항상 전송해야 함

" Proxy-Connection: close "

 

Connection 및 Proxy-Connection 헤더는 첫 번째 요청/응답 교환이 완료된 후

연결이 유지될 것인지 여부를 지정하는 데 사용

각 요청에 대해 새 연결을 여는 것은 완전히 허용되며,

이 헤더에 close라는 값을 지정하면 웹 서버에 프록시가 첫 번째 요청/응답 교환 후에 연결을 닫으려는 의도를 알림

 

User-Agent 헤더의 값은 proxy.c에서 문자열 상수로 제공

 

브라우저가 HTTP 요청의 일부로 추가적인 요청 헤더를 전송하는 경우,

프록시는 이를 변경하지 않고 그대로 전달해야 함

 

3. 포트 번호

중요한 두 가지 클래스의 포트 번호 : HTTP 요청 포트와 프록시의 수신 포트

  • HTTP 요청 포트 : HTTP 요청의 URL에서 선택적 필드
    즉, URL이 " http://www.cmu.edu:8080/hub/index.html " 과 같은 형식을 가질 수 있으며,
    HTTP 포트인 80 대신 8080 포트에서 호스트 " www.cmu.edu " 에 연결해야 함
    프록시는 포트 번호가 URL에 포함되어 있든 없든 적절하게 작동해야 함
  • 수신 포트 : 수신 대기하는 포트. 수신 포트 번호를 지정하는 명령줄 인수를 수락해야 함.
    예를 들어, 다음 명령으로 프록시는 15213 포트에서 연결을 수신해야 함
    linux> ./proxy 15213

    1024보다 크고 65536보다 작은 비특권 수신 포트를 선택할 수 있으며, 다른 프로세스에서
    사용되지 않아야 함.
    다수가 각 머신에서 작업하고 있기 때문에, port-for-user.pl 스크립트를 제공하여
    개인 포트 번호를 선택하는 데 도움을 줌.
    사용자 ID를 기반으로 포트 번호를 생성하려면 다음을 사용:
    linux> ./port-for-user.pl droh
    droh: 45806

    port-for-user.pl에 의해 반환된 포트 p는 항상 짝수. 따라서 추가 포트 번호가 필요한 경우,
    예를 들어 Tiny 서버를 위한 경우, 포트 p와 p + 1을 안전하게 사용할 수 있음.

 

'C언어 > Proxy 서버' 카테고리의 다른 글

Proxy 서버  (0) 2024.09.20