웹 - 브라우저와 웹 서버

가이드 목표:

  • 웹 서버와 브라우저의 동작 원리를 알아봐요.
  • 우리가 겪게 될 문제들에 대해 알아봐요.
  • 리버스 프록시 서버에 대해 알아봐요.
  • Nginx Proxy Manager 의 사용법을 익혀요.
  • LetsEncrypt / SSL 설정 방법에 대해 익혀요.

필요한 것들:

  • 내 서버와 연결된 도메인
  • docker가 설치된 우분투 서버
  • 공유기와 인터넷에 대한 이해

이전 가이드들을 통해 이제 우리는 IP 주소 대신 멋진 도메인으로 서버에 접속할 수 있게 됐어요. 정말 편리하죠? 하지만 이제 여러 웹 서비스를 배포해서 운영하다 보면 몇 가지 새로운 고민거리가 생기기 시작할 거예요.

이번 가이드에서는 브라우저와 웹 서버에 대해 간단히 알아보고, 우리가 겪을 문제점들을 살펴보려 해요. 그리고 이를 해결하기 위한 리버스 프록시 기술을 배워볼 거예요.


브라우저와 웹 서버

우리가 브라우저에 google.com 을 입력하면 어떤 일이 발생할까요? 브라우저는 먼저 도메인 주소를 IP 주소로 변환하고 서버 컴퓨터를 찾아가요. 그리고 80 또는 443번 포트의 서비스에게 웹 페이지의 정보를 달라고 요청하게 돼요. 이렇게 수신받은 정보를 여러분의 브라우저에 그려주는 거죠.

여기서 중요한 특징은 브라우저는 서버가 항상 80 또는 443번 포트를 사용할 것이라 기대하고 있다는 점이에요. 그래서 브라우저에서 쉽게 접속 가능한 서비스를 만드려면 서버는 반드시 해당 포트만을 사용해야 해요.


우리가 겪을 문제들

서브도메인

이러한 웹의 특징 때문에 겪게 될 첫번째 문제는, 서비스 별로 다른 도메인을 할당할 수 없다는 것이에요. 예를 들어 notes.tinyrack.net으로는 메모 서비스를, forum.tinyrack.net으로는 포럼 서비스를 운영하고 싶다고 가정해 보세요.

graph TB;

forum["forum.tinyrack.net<br>공인_IP"]
notes["notes.tinyrack.net<br>공인_IP"]
root["tinyrack.net<br>공인_IP"];

subgraph router["공유기"];
  router-80["80 / 443"];
end;
subgraph server["서버"];
  server-80["80 / 443"];
end;

forum --> router-80;
notes --> router-80;
root --> router-80;
router-80 --> server-80;

하지만 하나의 공인 IP를 사용할 때, 도메인 설정만으로는 이렇게 각각의 서브 도메인으로 서로 다른 서비스를 연결하기 쉽지 않아요. 도메인은 어느 공인 IP를 향해야 하는지만 알려줄 뿐, 그곳에서 어떤 서비스로 요청을 보내야 하는지는 알려주지 못하거든요.

graph TB;

internet["인터넷"];

subgraph router["공유기"];
  router-80["80"];
  router-81["81"];
  router-82["82"];  
end;

subgraph server["서버"];
  server-80["80: 메모 서비스"];
  server-81["81: 북마크 서비스"];
  server-82["82: 포럼 서비스"];
end;

internet --> router-80;
internet --> router-81;
internet --> router-82;

router-80 --> server-80;
router-81 --> server-81;
router-82 --> server-82;

이를 해결하기 위한 간단한 방법은 서비스별로 포트를 분리하는 것이에요. 위 그림처럼 서비스들이 각각 다른 포트를 사용하게 만들면 tinyrack.net:80 은 메모 서비스, tinyrack.net:81 북마크 서비스, tinyrack.net:82 은 포럼 서비스로 사용할 수 있게 돼요.

그런데 이 방법은 뭔가 이상적이지 않아요. 브라우저는 서버가 항상 80 또는 443 포트를 사용할 것이라 기대하기 때문에, 이와 다르면 도메인 주소에 포트 번호까지 기입해야만 접속되거든요. 다른 도메인을 사용할 수 없다는 문제도 여전할 거고요.


보안 문제

또 하나의 큰 문제는 바로 보안이에요. 브라우저에서 오래된 사이트를 들어가 보면, 위와 같은 브라우저의 경고를 본 적이 있으실 거예요. 그리고 아마 여러분의 만드는 서버에 접속해도 이 경고가 나올 거고요.

graph BT;

server["서버"]
subgraph internet["인터넷"]
  hacker["악성 해커"]
end
computer["컴퓨터"]

computer --> internet --> server

브라우저를 통해 웹 서버에 접속한다는 건 내 컴퓨터에서 출발한 데이터가 인터넷 세상을 거쳐 서버 컴퓨터에 도달한다는 것을 의미해요. 그런데 이 과정에서 내 데이터는 아주 중대한 보안 위협에 노출되어 있어요.

만약 구글에 로그인하기 위해 아이디와 비밀번호를 전송한다고 가정해 보세요. 그런데 인터넷에서 악성 해커가 이 데이터를 중간에 탈취한다면, 내 비밀번호를 알아낼 수 있게 돼요. 이는 큰 문제가 되겠죠?

그래서 웹 서버는 SSL이라는 기술을 통해 사용자와 통신하는 데이터를 암호화 할 필요가 있어요. 이렇게 암호화된 데이터는 중간에 해커가 탈취하더라도 데이터를 열 수 없어서 사용자의 데이터가 안전해지게 돼요. 이렇게 통신이 암호화되어 안전한 사이트는 브라우저에서도 '연결이 안전함’과 같이 나오게 돼요.

브라우저는 서버와 통신할 때 80 또는 443 번 포트를 사용한다고 말씀드렸던 것을 기억하시나요? 브라우저는 SSL 연결이 가능한 서버는 443(https)번 포트로 통신하고, 그렇지 않은 경우는 80(http)포트와 통신하도록 약속이 되어 있어요.

그런데 우리가 설치하는 웹 서버 소프트웨어들은 대부분 이런 SSL 암호화 기술이 내장되어 있지 않아요. 이는 개발자들의 문제는 아니고, 보통은 소프트웨어를 사용하는 쪽에서 알아서 해결할 것이라 가정했기 때문이에요. 그래서 이 문제는 우리가 직접 해결해야만 해요.


리버스 프록시 서버

graph TB;

forum["forum.tinyrack.net"]
notes["notes.tinyrack.net"]
root["tinyrack.net"];

subgraph router["공유기"];
  router-80["80 / 443"];
end;

subgraph server["서버"];
  subgraph nginx["리버스 프록시"];
    nginx-80["80 / 443"];
  end
  server-forum["포럼 서비스<br>8080"];
  server-notes["메모 서비스<br>5230"];
  server-blog["블로그 서비스<br>3000"];
end;

forum --> router-80;
notes --> router-80;
root --> router-80;
router-80 --> nginx-80;

nginx-80 --> server-forum;
nginx-80 --> server-notes;
nginx-80 --> server-blog;

리버스 프록시 서버는 위 문제들을 해결하기 위한 솔루션이에요. 리버스 프록시는 클라이언트(컴퓨터, 스마트폰 등)와 서버 컴퓨터 사이에서 클라이언트의 요청을 대신 받아 서버로 전달하는 역할을 가진 중간자 서버를 의미해요.

이런 중간자 서버가 굳이 필요하다는게 좀 이상하죠? 이는 이 서버에서 사용자가 요청한 도메인 주소를 분석하고 이를 여러 서버로 분리해 전달해 줄 수 있기 때문이에요. 이를 구성하면 forum.tinyrack.net 의 요청은 포럼 서버로 전달하고, notes.tinyrack.net의 요청은 메모 서버로 전달해 줄 수 있게 돼요. 이제 좀 매력이 있어 보이지 않나요?

리버스 프록시 서버의 또 다른 장점은 SSL 암호화 기술을 아주 쉽게 적용할 수 있다는 것이에요. 이를 통해서 우리가 배포하는 서비스들의 보안성을 크게 향상시킬 수 있게 될 거예요.