반응형
04-29 06:41
Today
Total
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
관리 메뉴

개발하는 고라니

[Nginx] Nginx as a WebSocket Proxy 본문

Web/Nginx

[Nginx] Nginx as a WebSocket Proxy

조용한고라니 2021. 9. 5. 03:21
반응형

최근에 사이드 프로젝트를 진행하고 있다. 기획 및 설계, 구현과 테스트 빌드 그리고 배포까지 스스로 해보는 것이 목표이다. 배포는 클라우드 서비스를 이용해 진행했는데, 처음으로 웹 서버(Nginx)를 사용해보았다. 특히 웹 서버를 사용하면 서버의 정보(예: port)를 숨길 수 있는 'Reverse Proxy'를 할 수 있다. 특정 URL로 접근하는 경우 특정 포트로 넘겨주는 작업을 할 수 있는데, 이는 웹소켓을 연결하는 과정에서 문제가 되었다.

 

이 글은 Reverse Proxy를 적용한 Nginx 환경에서 WebSocket을 WebSocket Server와 연결할 때 주의할 점에 대해 다룬다.

WebSocket

웹소켓 프로토콜은 웹 어플리케이션의 클라이언트와 서버 간 실시간-양방향 통신을 할 수 있는 방법이다. HTML 5의 일부분이고, 웹소켓은 이전의 가능했던 방법 보다 쉽게 어플리케이션을 개발하는데 용이하다. 대부분의 브라우저는 웹소켓을 지원한다.

 

웹소켓 프로토콜은 HTTP 프로토콜과 다르다. 그러나 웹소켓 핸드셰이크(WebSocket HandShake)는 HTTP와 상호호환된다. HTTP Upgrade 기능을 사용함으로써 HTTP 에서 웹소켓으로 커넥션을 업그레이드한다. 이를 통해 웹소켓 어플리케이션은 기존 인프라에 더 쉽게 맞출 수 있다. 예를 들어 웹소켓 어플리케이션은 표준 HTTP 포트 80, 443을 사용할 수 있으므로 기존 방화벽 규칙을 사용할 수 있다.

Issue

웹소켓 어플리케이션은 실시간 응용 프로그램 개발을 용이하게 하기위해 클라이언트와 서버 간의 긴 시간 연결을 연채로 유지한다. HTTP로부터 웹소켓으로 연결을 업그레이드하는데 사용되는 HTTP Upgrade 매커니즘은 Upgrade 및 Connection 헤더를 사용한다.

 

Reverse Proxy 서버는 웹소켓을 지원하는데 몇몇 문제를 맞이한다. 하나는 웹소켓은 hop-by-hop 프로토콜이라는 것이다. 그래서 프록시 서버가 클라이언트로부터의 'Upgrade Request'를 가로챌 때, 백엔드 서버에 자체 업그레이드 요청을 명시해주어야 한다. (적절한 헤더를 포함해서) 또한, HTTP에서 사용하는 일반적인 단기 연결과 달리 웹소켓 연결은 긴 시간 살아있기 때문에 Reverse Proxy는 이러한 연결이 유휴 상태인 것처럼 보인다. 그러므로 연결을 닫지않고 연결 상태로 유지하도록 허용해야한다.

 

Nginx는 클라이언트와 백엔드 서버 사이의 터널을 설치해줌으로써 웹소켓을 지원한다. 클라이언트에서 서버로 요청을 보내는 데 Nginx가 업그레이드 요청을 보내기 위해 Upgrade와 Connection 헤더가 반드시 명시되어야한다.

 

location /example/ { #웹 소켓 연결을 위한 Endpoint
  proxy_pass http://34.64.12.243:8080; #웹 소켓 서버가 있는 Origin

  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "Upgrade";
  proxy_set_header Host $host;
}

이를 마치면 Nginx는 웹소켓 커넥션을 다룬다.

 

과정

$vi /etc/nginx/sites-available/proxy.conf
...
# 아래 부분 추가
      location /api/stomp {
               proxy_pass http://00.00.00.000:8080; # WebSocket Server

               proxy_http_version 1.1;
               proxy_set_header Upgrade $http_upgrade;
               proxy_set_header Connection "Upgrade";
               proxy_set_header Host $host;
       }
...

 

rm /etc/nginx/site-enabled/proxy.conf

 

- site-available/proxy.conf 파일을 site-enabled로 링크를 건다.

ln -s /etc/nginx/site-available/proxy.conf /etc/nginx/site-enabled/

 

- nginx를 재시작한다.

systemctl restart nginx

결과

기존에 Websocket 핸드셰이크가 404가 떴었고, SockJS가 웹소켓 API를 사용할 수 있도록 애뮬레이팅 해주었던 것으로 유추했었다.

이제 Nginx에 설정만 몇 줄 넣어주었더니 웹소켓을 잘 받아들여 인식하니 빨간색 없이 잘 된다.

 

# Reference 

 

Using NGINX as a WebSocket Proxy

Learn how to use NGINX as a reverse proxy and load balancer for WebSocket applications

www.nginx.com

 

RFC 6455 - The WebSocket Protocol

About | IETF Datatracker | Version 7.36.0.p1 | 2021-08-12 | Report a bug: Tracker: Email: Python 3.6.12 | Django 2.2.24

datatracker.ietf.org

 

반응형
Comments