[8장] 통합점: 게이트웽, 터널, 릴레이

janjanee·2022년 8월 1일
0
post-thumbnail

2020.12.13 작성글 이전


8장 통합점: 게이트웨이, 터널, 릴레이

8.1 게이트 웨이

모든 리소스를 한 개의 애플리케이션으로만 처리할 수 없는 문제를 해결하기 위해
인터프리터 같이 리소스를 받기 위한 경로를 안내하는 역할을 하는 게이트웨이를 고안해냈다.

  • 게이트웨이는 요청을 받고 응답을 보내는 포털 같이 동작하는데, 동적인 콘텐츠 생성 및 데이터 베이스에 질의를 보낼 수 있다.
  • 게이트웨이는 HTTP 트래픽을 다른 프로토콜로 자동변환하여, HTTP 클라이언트가 다른 프토콜을 알 필요 없이 서버에 접속할 수 있게 한다.

다음은 게이트웨이의 세 가지 예시이다.

  • HTTP/FTP 서버 측 FTP 게이트웨이

    게이트웨이는 FTP 커넥션을 맺고 FTP 서버에 적절한 명령을 전송한다.

    클라이언트는 적절한 HTTP 헤더와 함께 HTTP를 통해서 문서를 받는다.

  • HTTPS/HTTP 클라이언트 측 보안 게이트웨이

    게이트웨이는 암호화된 웹 요청을 SSL을 통해 받고, 요청을 해독해서 생성한 일반 HTTP 요청을

    목적지 서버로 전달한다.

  • HTTP/CGI 서버 측 애플리케이션 게이트웨이

    게이트웨이는 애플리케이션 서버 게이트웨이 API를 통해서 HTTP 클라이언트를 서버 측 애플리케이션 프로그램에 연결한다.

    웹에서 물건을 사거나 일기예보를 보거나 주식시세를 볼 때, 사실은 애플리케이션 서버 게이트웨이를 방문하는 것이다.

8.1.1 클라이언트 측 게이트웨이와 서버 측 게이트웨이

  • 웹 게이트웨이는 한쪽에서는 HTTP로 통신하고 다른 쪽에서는 HTTP가 아닌 다른 프로토콜로 통신한다.

  • 게이트웨이는 클라이언트 측 프로토콜과 서버 측 프로토콜을 빗금(/)으로 구분해 기술한다.

    (ex- HTTP/NNTP 게이트웨이)

  • 서버 측 게이트웨이

    • 클라이언트와 HTTP로 통신
    • 서버와 외래 프로토콜로 통신
  • 클라이언트 측 게이트웨이

    • 클라이언트와 외래 프로토콜로 통신
    • 서버와 HTTP로 통신

8.2 프로토콜 게이트웨이

  • 프락시에 트래픽을 바로 보내는 것과 같이 게이트웨이에도 HTTP 트래픽을 바로 보낼 수 있다.

  • 브라우저에 명시적으로 게이트웨이를 설정하여 자연스럽게 트래픽이 게이트웨이를 거쳐 가게 하거나, 게이트웨이를

    대리 서버(리버스 프락시)로 설정할 수 있다.

브라우저에 gw1.joes-hardware.com HTTP/FTP 게이트웨이를 사용하게 설정을 하면 아래와 같이 동작한다.

  • 일반적인 HTTP 트래픽에 영향을 끼치지 않음
  • FTP URL을 포함한 요청은 gw1.joes-hardware.com 게이트웨이로 HTTP 요청을 보낸다.
  • 게이트웨이는 클라이언트의 요청을 FTP 요청으로 변환하여 처리 후 클라이언트에게 그 결과를 HTTP로 전송한다.

8.2.1 HTTP/*: 서버 측 웹 게이트웨이

서버 측 웹 게이트웨이는 클라이언트로부터 HTTP 요청이 원 서버 영역으로 들어오는 시점에
클라이언트 측의 HTTP 요청을 외래 프로토콜로 전달한다.

예를 들어, 게이트웨이는 원 서버의 FTP 포트(21 포트)로 FTP 커넥션을 연결하고 FTP 프로토콜을 통해서 객체를 가져온다.
게이트웨이는 다음의 일들을 한다.

  • USER와 PASS 명령을 보내서 서버에 로그인
  • 서버에서 적절한 디렉터리로 변경하기 위해 CWD 명령
  • 다운로드 형식을 ASCII로 설정
  • MDTM으로 문서의 최근 수정 시간 가져옴
  • PASV로 서버에게 수동형 데이터 검색을 하겠다고 함
  • RETR로 객체를 검색
  • 제어 채널에서 반환된 포트로 FTP 서버에 데이터 커넥션을 맺음. 데이터 채널이 열리는 대로, 객체가 게이트웨이로 전송

8.2.2 HTTP/HTTPS: 서버 측 보안 게이트웨이

기업 내부의 모든 웹 요청을 암호화함으로써 개인 정보 보호와 보안을 제공하는데 게이트웨이를 사용할 수 있다.
게이트웨이는 자동으로 사용자의 모든 세션을 암호화할 것이다.

8.2.3 HTTPS/HTTP: 클라이언트 측 보안 가속 게이트웨이

  • HTTPS/HTTP 게이트웨이는 보안 가속기로 유명하다.
  • 웹 서버의 앞단에 위치하고, 보이지 않는 인터셉트 게이트웨이나 리버스 프락시 역할을 한다.
  • 보안 HTTPS 트래픽을 받아서 복호화하고, 웹 서버로 보낼 일반 HTTP 요청을 만든다.
  • 게이트웨이와 원 서버 간에 있는 네트워크가 안전한지 확인을 확실히 하고 사용할 것.

8.3 리소스 게이트웨이

애플리케이션 게이트웨이에서 유명했던 최초의 API는 공용 게이트웨이 인터페이스(Common Gateway Interface, CGI) 였다.

  • CGI

    특정 URL에 대한 HTTP 요청에 따라 프로그램 실행, 프로그램의 출력을 수집, HTTP 응답으로 회신하는데

    웹 서버가 사용하는 표준화된 인터페이스 집합

8.3.1 공용 게이트웨이 인터페이스

공용 게이트웨이 인터페이스(CGI)는 최초의 서버 확장이자 지금까지도 가장 널리 쓰이는 서버 확장

  • 웹에서 동적인 HTML, 신용카드 처리, 데이터베이스 질의 등 제공하는데 사용
  • CGI 애플리케이션이 서버와 분리되면서 펄, Tcl, C, 다양한 셸 언어를 포함하여 수 많은 언어로 구현할 수 있게됨
  • 거의 모든 HTTP 서버가 지원
  • CGI가 내부에서 어떤 처리를 하는지 사용자에게 보이지 않음
  • 모든 CGI는 요청마다 새로운 프로세스를 만드는 데 부하가 크고, 서버 장비에 부담을 준다.
    • 위 문제를 해결한 Fast CGI가 개발됨. 데몬으로 동작해서 성능저하 문제를 해결

8.3.2 서버 확장 API

  • 확장 API는 프로그래머가 자신의 코드를 서버에 연결하거나 서버의 컴포넌트를 자신이 만든 것으로 교체할 수 있게 함
  • 유명한 서버 대부분은 개발자에게 확장 API를 한 개 이상 제공

8.4 애플리케이션 인터페이스와 웹 서비스

인터넷 커뮤니티는 각 웹 애플리케이션이 서로 통신하는데 사용할 표준과 프로토콜 집합을 개발하였다.
이 표준은 원래 웹 서비스가 독립형 웹 애플리케이션 그 자체를 의미함에도 불구하고, 그냥 그대로 웹 서비스로 불리게 되었다.

웹 서비스가 새로운 용어는 아니지만, 여기서 웹 서비스는 애플리케이션이 정보를 공유하는데 사용하는 새로운 메커니즘을 의미한다.
웹 서비스는 HTTP 같은 표준 웹 기술 위에서 개발한다.

8.5 터널

웹 터널은 HTTP 프로토콜을 지원하지 않는 애플리케이션에 HTTP 애플리케이션을 사용해 접근하는 방법을 제공한다.

  • 웹 터널을 사용하면 HTTP 커넥션을 통해서 HTTP가 아닌 트래픽을 전송할 수 있고, 다른 프로토콜을 HTTP 위에 올릴 수 있다.
  • 웹 터널을 쓰는 일반적 이유는 HTTP 커넥션 안에 HTTP가 아닌 트래픽을 얹기 위해서 이다.
  • 웹 터널을 사용하면 웹 트래픽만 허용하는 방화벽이 있더라도 HTTP가 아닌 트래픽을 전송할 수 있다.

8.5.1 CONNECT로 HTTP 터널 커넥션 맺기

  • 웹 터널은 HTTP의 CONNECT 메소드를 사용하여 커넥션을 맺는다.

  • CONNECT 메소드는 터널 게이트웨이가 임의의 목적 서버와 포트에 TCP 커넥션을 맺고 클라이언트와 서버간에

    오는 데이터를 무조건 전달하기를 요청한다.

다음은 SSL 터널을 연결하기 위해 사용되는 CONNECT 순서이다.

  • 클라이언트는 게이트웨이에 터널을 연결하려고 CONNECT 요청을 보냄
  • 클라이언트의 CONNECT 메서드는 TCP 커넥션을 위해 게이트웨이에 터널 연결을 요청
  • TCP 커넥션이 생성됨
  • TCP 커넥션이 맺어지면, 게이트웨이는 클라이언트에게 HTTP 200 Connection Established 응답 전송
  • 이 시점에 터널이 연결.
    • HTTP 터널을 통해 전송된 클라이언트의 모든 데이터 -> TCP 커넥션으로 바로 전달
    • 서버로부터 전송된 모든 데이터 -> HTTP 터널을 통해 클라이언트에게 전달

CONNECT 요청

CONNECT home.netscape.com:443 HTTP/1.0
User-agent: Mozilla/4.0
  • 요청 URI는 호스트 명이 대신하여 콜론에 이어 포트를 기술
  • 시작줄 다음에는 다른 HTTP 메시지와 같이, 추가적인 HTTP 요청 헤더 필드가 있거나 없다.
  • 보통 각 행은 CRLF로 끝나고, 헤더 목록의 끝은 빈 줄의 CRLF로 끝난다.

CONNECT 응답

HTTP/1.0 200 Connection Established
Proxy-agent: Netscape-Proxy/1.1
  • 일반 HTTP 메시지와 같이 200 응답 코드는 성공을 뜻한다. 편의상 사유구절은 'Connection Established'
  • Content-Type 헤더를 포함할 필요 없음

8.5.2 데이터 터널링, 시간, 커넥션 관리

  • 터널을 통해 전달되는 데이터는 게이트웨이에서 볼 수 없어서, 게이트웨이는 패킷의 순서나 흐름에 대한 어떠한 가정도 할 수 없다.
  • 클라이언트는 성능을 높이기 위해 CONNECT 요청을 보낸 다음, 응답을 받기 전에 터널 데이터를 전송할 수 있다.
  • 게이트웨이는 커넥션이 맺어지는 대로 헤더를 포함해서 읽어들인 모든 데이터를 서버에 전송해야 한다.
  • 요청 후에 터널을 통해 데이터를 전송한 클라이언트는 인증요구나 200 외의 응답이 왔을 때 요청 데이터를 다시 보낼 준비가 되어있어야 한다.
  • 터널의 끝 어느 부분이든 커넥션이 끊어지면, 그 끊어진 곳으로부터 온 데이터는 반대편으로 전달된다.

8.5.3 SSL 터널링

  • 웹 터널은 원래 방화벽을 통해서 암호화된 SSL 트래픽을 전달하려고 개발되었다.

  • 터널을 사용하면 SSL 트래픽을 HTTP 커넥션으로 전송하여 80 포트의 HTTP만을 허용하는 방화벽을 통과시킬 수 있다.

  • SSL 트래픽이 기존 프락시 방화벽을 통과할 수 있도록 HTTP에 터널링 기능이 추가되었다.

  • 이 터널링 기능은 HTTP 메시지에 암호화된 날 데이터를 담고 일반 HTTP 채널을 통해 데이터를 전송한다.

  • 터널은 HTTP가 아닌 트래픽이 포트를 제한하는 방화벽을 통과할 수 있게 해줘서 보안 SSL 트래픽이 방화벽을

    통과하는 데 유용하게 사용될 수 있다.

  • 하지만 터널은 악의적인 트래픽이 사내로 유입되는 경로가 될 수도 있다.

8.5.4 SSL 터널링 vs HTTP/HTTPS 게이트웨이

HTTPS 프로토콜(SSL상의 HTTP)은 다른 프로토콜과 같은 방식으로 게이트웨이를 통과할 수 있다.
원격 HTTPS 서버와 SSL 세션을 시작하는 게이트웨이를 두고 클라이언트 측의 HTTPS 트랜젝션을 수행하는 방식이다.
응답은 프락시가 받아서 복호화하고 난 후, HTTP를 통해 클라이언트로 전송한다.

위 접근은 몇 가지 단점이 존재한다.

  • 클라이언트-게이트웨이 사이에는 보안이 적용되지 않은 일반 HTTP 커넥션이 맺어져 있음
  • 프락시가 인증을 담당하기에, 클라이언트는 원격 서버에 SSL 클라이언트 인증(X509 인증서 기반의 인증)을 할 수 없다.
  • 게이트웨이는 SSL을 완벽히 지원해야 한다.

이 상황에서 SSL 터널링을 사용하면, 프락시에 SSL을 구현할 필요가 없다.
프락시 서버는 트랜젝션의 보안에는 관여하지 않고 암호화된 데이터를 그대로 터널링 할 뿐이다.

8.5.5 터널 인증

HTTP의 다른 기능들은 터널과 함께 적절히 사용할 수 있다.
특히 프락시 인증 기능은, 클라이언트가 터널을 사용할 수 있는 권한을 검사하는 용도로 터널에서 사용할 수 있다.

8.5.6 터널 보안에 대한 고려사항들

터널의 오용을 최소화하기 위해, 게이트웨이는 HTTPS 전용 포트인 443 같이 잘 알려진 특정 포트만을 터널링할 수 있게 허용해야 한다.

8.6 릴레이

HTTP 릴레이는 HTTP 명세를 완전히 준수하지는 않는 간단한 HTTP 프락시이다.

단순 맹목적 릴레이를 구현하는데 관련된 더 일반적인 문제 중 하나는, 맹목적 릴레이가 Connction 헤더를
제대로 처리하지 못해서 keep-alive 커넥션 행에 걸리는 것이다.

자세히 설명하자면 다음과 같다.

  • 웹 클라이언트 -> Connection: Keep-Alive 헤더를 보내서, 릴레이에 keep-alive 커넥션 요청 메시지 전송.

    keep-alive 채널에 대한 요청이 받아들여졌는지 확인하기 위해 응답을 기다린다.

  • 릴레이가 HTTP 요청을 받지만, Connection 헤더를 이해하지 못하므로, 요청을 서버로 넘긴다.

    하지만 Connection 헤더는 홉과 홉 사이에만 사용하는 헤더다. 단일 전송 링크만을 지원하고 체인을 따라 전달할 수 없다.

  • 릴레이 된 HTTP 요청이 웹 서버에 도착. 웹 서버는 아무것도 모른채 keep-alive 통신에 동의하고

    Connection: Keep-Alive 응답 헤더로 응답한다.

    이 시점부터 웹 서버는 릴레이와 함께 keep-alive 통신을 하고, keep-alive의 규칙에 맞게 동작할 것이다.

    하지만 릴레이는 keep-alive에 대해 모른다.

  • 릴레이는 웹 서버로 부터 받은 헤더를 포함한 응답을 클라이언트에게 전달한다.

    클라이언트는 릴레이가 keep-alive 통신에 동의했다고 추측한다.

    서버, 클라이언트가 keep-alive 통신을 하고 있다고 믿지만, 실제로 통신하는 릴레이는 keep-alive를 모르는 상태

  • 릴레이는 keep-alive를 모르기 때문에, 원 서버가 커넥션을 끊기를 기다리며 받은 데이터를 전부

    클라이언트에게 전달한다.

    원 서버는 릴레이가 자신에게 커넥션을 맺고 있기를 요청했다고 생각하여 커넥션을 끊지 않는다.

    릴레이는 커넥션이 끊길 때를 기다리며 계속 커넥션을 맺고(hang) 있다.

  • 클라이언트가 응답을 받으면, 바로 다음 요청을 keep-alive 커넥션을 통해 릴레이에게 전송한다.

    단순한 릴레이는 같은 커넥션으로 또 다른 요청이 오는 것을 예측하지 못한다.

    브라우저는 계속 돌고 있지만, 아무런 작업도 진행되지 않는다.

이러한 문제를 예방하기 위해 릴레이를 조금 똑똑하게 만드는 방법도 있지만, 여러 문제를 예방하기 위해서
HTTP를 제대로 준수하는 프락시를 사용하는게 좋다.

profile
얍얍 개발 펀치

0개의 댓글