Web server란 무엇인가

February 17, 2019 · 6 mins to read

1. Web server란?

  • HTTP 요청을 처리하고 응답을 제공하는 소프트웨어, 혹은 장비.
  • HTTP 및 그에 맞는 TCP요청을 구현한 것으로, OS와 TCP 커넥션 관리에 대한 책임을 나눠 갖는다.
  • OS는 computer system의 하드웨어를 관리하고, TCP / IP 네트워크를 지원한다. 또한, 리소스 유지를 위해 file system과 프로세스 등을 관리한다.

2. Web server가 하는 일

웹서버는 보통의 경우 다음 7가지의 일을 하게 된다.

step of a basic webserver request

  1. 커넥션 맺기
  2. Request 받기 - HTTP 요청 메시지를 네트워크로 부터 읽어들인다.
  3. Request 처리 - 요청메시지를 해석하여 특정 행동을 취한다.
  4. 리소스 접근 - 메시지에서 지정한 리소스에 접근한다.
  5. Response 만들기 - 올바른 헤더를 포함한 HTTP response 메시지를 생성한다.
  6. Response 전송.
  7. Transaction에 해당하는 log 생성.

3. Web server가 하는 일을 단계별로 살펴보기

1. 클라이언트의 connection 수락

클라이언트가 이미 서버에 대해 지속 커넥션을 맺고 있다면 클라이언트는 그 커넥션을 그대로 사용하는 것이 가능하다. 만약 그렇지 않다면 새 커넥션이 필요해 진다.

  • 새 커넥션 다루기
    만약 클라이언트가 웹서버에 TCP 커넥션을 요청하면, 웹서버는 그 커넥션을 맺고 IP를 추출해 클라이언트를 확인한다. 웹서버는 언제든 이 커넥션을 거절하거나 끊을 수 있다.
  • 클라이언트의 hostname 식별
    대부분의 웹서버는 reverse DNS를 통해서 클라이언트의 IP주소를 클라이언트의 hostname으로 변경한다. 이는 접근제어와 logging을 위해 사용된다.

    hostname lookup은 web transaction을 느려지게 할 수도있기 때문에, 많은 대용량 웹서버는 hostname 분석 기능을 꺼놓거나 특정 content에 대해서만 실행한다.

  • ident를 통해 클라이언트 사용자 알아내기
    몇몇 웹서버는 ident 프로토콜 (opens new window)을 지원한다. HTTP 커넥션을 초기화한 클라이언트의 이름을 알 수 있어 logging에 유용하게 사용된다. 그렇기때문에 보통의 log format의 두 번째 필드는 각 요청의 ident 사용자 이름이 된다.

    만약 클라이언트가 ident 프로토콜을 지원한다면 클라이언트는 ident 요청을 받기 위해 113번 포트를 열어두게 된다. 만약 웹서버와 클라이언트 모두 ident 프로토콜을 지원한다면, 웹서버는 다음과 같은 방법으로 클라이언트의 이름을 알 수 있다.

ident request

ident 프로토콜은 조직 내부에서는 종종 사용하지만 public service에서는 잘 동작하지 않는데, 그 이유는 다음과 같다.

  • 많은 클라이언트의 PC는 ident용 daemon을 실행하고 있지 않다.
  • HTTP transaction을 지연시킨다.
  • 방화벽이 ident를 막는 경우가 많다.
  • 조작이 쉽고 가상 IP를 지원하지 않으며, 프라이버시 침해의 우려가 있다.

2. Request 메시지 수신

웹서버는 network 커넥션에서 data를 읽고 parsing하여 request 메시지를 구성한다. Request 메시지를 구성하는 절차는 다음과 같다.

  1. Request 메시지를 parsing하여 method, URI, HTTP version을 찾는다.
  2. 메시지 header를 읽는다.
  3. Request 본문을 읽는다. 이때 Content-length를 참고한다.

Request 메시지를 parsing할 때 웹서버는 data를 불규칙하게 받을 경우가 발생한다. 그렇기 때문에, 일정 분량의 data를 확보할 때 까지 메시지의 일정 부분을 메모리에 저장한다.

1. 메시지의 내부 표현

몇몇 웹서버는 request 메시지 조작을 위해 내부의 자료구조에 저장한다.

2. 커넥션의 input / output 출력 처리 아키텍처

고성능 웹서버는 수천개의 커넥션을 동시에 연결할 수 있도록 지원한다. 이 커넥션들은 웹서버가 많은 클라이언트들과 한 개 이상의 커넥션을 통해 통신할 수 있도록 도와준다. 웹서버들은 다양한 방식으로 요청을 받고, 처리하게 된다.

web server input/output architectures

  • Single threaded

    • 한 번에 하나의 요청을 처리한다.
    • 하나의 transcation 완료 시 다음의 request를 처리한다.
    • 하나의 transaction 처리 중에는 모든 다른 커넥션은 무시한다. 그렇기 때문에 서비스의 성능 문제를 야기할 수 있다.
  • Multi process, multi threaded

    • 여러 요청을 동시에 처리하기 위해 여러개의 프로세스, 스레드를 할당한다.
    • 이는 미리 만들어 질 수도 있고(thread pool), 필요시 만들어질 수도 있다.
    • 몇몇 웹서버는 매 커넥션마다 스레드/프로세스를 할당기도 하는데, 이는 메모리와 리소를 많이 소비하게 된다. 그렇기 때문에 최대로 할당할 수 있는 개수에 제한을 둔다.
  • Multiplexed I/O

    • 모든 커넥션은 활동을 감시당하며, 그 상태가 바뀔 경우 해당 커넥션에 대한 작은 양의 처리가 수행된다.
    • 처리가 완료되면, 커넥션은 다음번 상태 변경을 위해 열린 커넥션 목록(open connection list)으로 돌아간다.
    • 스레드와 프로세스는 유휴상태의 커넥션에 매여 매번 기다리느라 리소스를 낭비하지 않아도 된다.
  • Multiplexed, multi threaded I/O

    • Multiplexed I/O 아키텍쳐와 multi threaded 아키텍쳐를 결합한 방식이다.
    • 여러개의 스레드는 각각 열려있는 커넥션을 감시하고 조금씩 작업을 수행하며, 작업이 끝나면 커넥션은 다음번 상태 변경을 위해 열린 커넥션 목록(open connection list)으로 돌아간다.

3. Request의 처리

웹서버가 request를 받으면, 웹서버는 request로 부터 메소드, 리소스, header, 본문을 얻어내어 처리하게 된다.

몇몇 메소드(POST 등)은 반드시 엔터티 본문을 필요로 하며, OPTIONS 같은 경우는 필요하지 않다.

4. 리소스의 매핑과 접근

웹서브는 리소스 서버로, HTML, JPEG같은 미리 만들어진 contents를 제공한다. 또는 리소스 생성 어플리케이션이 만들어낸 동적 contents역시 제공할 수 있다. 이런 리소스를 제공하기 위해 웹서버는 보통 다음과 같은 개념을 사용하게 된다.

1. Docroot

웹서버는 여러 종류의 리소스 매핑을 지원한다. 요청 URI를 웹서버의 파일시스템 안에 있는 file name으로 쓰는 것이 대표적인 방법이다. 이를 위해 웹 서버의 directory 하나를 미리 예약해 사용할 수 있다. 이를 docroot, 혹은 root라 부른다.

Docroot가 설정되어있으면 웹서버는 request 메시지에 있는 URI를 가져와서 docroot뒤에 붙이는 방법으로 정적 리소스를 제공한다.

2. Directory 목록

웹서버는 경로가 file이 아닌 directory를 가리키는 URI에 대한 요청을 받을수도 있다. 대부분의 웹서버는 directory에 대한 요청을 받았을 경우 다음과 같은 동작을 하게 된다.

  • 에러를 반환
  • ‘색인파일’을 반환
  • Directory를 탐색한 후 그 내용을 반환

먼저, 요청한 URI에 대응하는 directory에서 index.html을 찾는다(어떤 파일을 제공할지는 웹서버의 세팅에서 변경하거나 추가할 수 있다). 만약 찾지 못했다면 directory의 내용이 반환된다.

이는 directory listing이라는 웹 취약점 중 하나로, 의도하지 않은 중요한 파일이 노출될 가능성이 있다. 그렇기 때문에 웹서버의 설정을 통해 directory에 대한 색인을 정지시켜야 한다.

3. 동적 contents 리소스 매핑

웹서버는 URI를 동적 content와 매핑할 수 있다. 이를 위해 Web Application Server(WAS)가 필요하며, 어떤 요청을 WAS에 연결해 줄 것인지에 대한 설정 역시 필요하다.

4. Server side include(SSI)

SSI에 대한 설명은 다음 링크로 대체하고자 한다. [Apache SSI] (opens new window)

5. 접근제어

웹서버는 특정 리소스에 대한 클라이언트의 접근을 제어할 수 있다. 클라이언트의 IP주소를 기반으로 엑세스를 제어하거나 비밀번호를 요구할 수도 있다.

5. Response 만들기

웹서버가 리소스를 식별하면 서버는 동작을 수행한 후 response 메시지를 반환하게 된다.

  1. 응답 엔터티 본문이 있다면, 본문과 함께 Content-Type, Content-Length, 실제 본문 등 세 가지를 메시지에 포함시킨다.
  2. MIME 타입 결정 웹서버는 응답 본문의 MIME 타입을 결정해야 할 책임이 있다. MIME 타입을 결정하는 몇 가지 방법은 다음과 같다.
  3. mime.types: 파일 이름의 확장자를 사용
  4. Magic typing: 파일의 내용을 검사하여 알려진 패턴에 대한 테이블에서 해당하는 패턴을 찾아 타입을 정함
  5. 유형 명시: 특정 파일이나 directory 내의 파일에 대한 MIME 타입을 명시해 놓음
  6. 유형 협상: 특정 형식에 대해 여러 타입을 지정해 놓고 사용자가 사용하기 편한 타입으로 지정
  7. Redirection 웹서버는 다음의 경우 클라이언트에게 redirection 메시지를 보낼 수 있다.
  8. 영구히 리소스가 옮겨진 경우(301)
  9. 임시로 리소스가 옮겨진 경우(303, 307)
  10. Load balancing이 필요한 상황
  11. /를 빠뜨린 경우, /를 추가한 URI로 redirection

6. Response 보내기

이전에 정리한 글 (opens new window)을 전체적으로 읽어보는 것을 추천한다.

7. Logging

웹서버는 trasction이 종료되었을 때 transaction이 어떻게 수행되었는지를 log file에 기록한다.

4. Conclusion

이번장은 내용이 간단한 만큼 빠르게 정리할 수 있었다. 평소 아무생각 없이 사용하던 Apache web server와 nginx가 많은 일을 처리한다는 것을 알 수 있었다.

사실 중요한 파트지만이 책에서 중요하지 않은 파트는 없는 것 같지만 내용 자체가 간단하여 그동안 정리한 내용을 복습하는 느낌이었다.


참고


© 2021, Built with Gatsby