슈퍼슬랩은 웹을 기반으로 한 게임 사이트다. 즉 HTTP 프로토콜을 기반으로 작동하는 웹사이트다.
우리가 개발하던 슈퍼슬랩 프로젝트는 지인들과 같은 공간에 있을 때 진행하는 게임이기 때문에 로그인 기능의 필요성이 낮았고, 그렇기 때문에 중요하다고 할만한 데이터가 없었다.
이런 이유로 사실 http, https 구별은 우리 프로젝트에 비중이 크지 않은 이슈였다. 하지만 웹 개발을 하는데, SSL 설정을 안 한다? 못 참지 이건! 무엇보다 간.지.가 안 나잖아 http는..
헛소리고! 현재 프로젝트에서 당장은 SSL의 필요성이 낮다는 결론을 내리게 되었지만, 결론을 도출하는 과정에서 http와 https의 차이가 뭔지, SSL은 무엇인지 공부하게 되었다.
SSL?
SSL(Secure Sockets Layer)은 암호화 기반 인터넷 보안 프로토콜이다. 웹 상의 데이터는 누구나 읽을 수 있는 일반 텍스트 형태로 전송된다.
(e.g. 고객이 쇼핑 웹사이트에서 신용 카드 번호 입력, 카드 번호 숨겨지지 않은 채 전달)
즉 사용자 개인 정보를 보호하기 위해 SSL이 제작되었다. SSL은 사용자와 웹 서버 사이 이동하는 모든 데이터를 암호화하여 누군가 데이터를 가로채더라도 무작위 문자만 볼 수 있게 한다.
SSL은 특정한 유형의 사이버 공격도 차단한다. SSL은 웹 서버를 인증하는데, 공격자들이 사용자를 속여 데이터를 훔치기 위한 가짜 웹사이트를 만드는 일이 있기 때문에 이러한 인증이 중요하다.
어찌됐든 SSL을 설정하여 HTTPS로 웹사이트를 개발하는 것이 보안을 위한 기본이라 생각하여 SSL을 설정하기로 결정했다. SSL을 설정하기 위해 다양한 방법들이 있었고, 그 중에서 NGINX를 이용하는 방법도 있었다.
여기서부터 또 꼬꼬무 시작. NGINX가 뭐야 ^__^?
NGINX
엔진엑스! 가벼움과 고성능을 목표로 하는 웹 서버 소프트웨어로, 동시접속 처리에 특화되어 있다고 한다.
여기서 또또또또 WHY 발생. 웹 서버(Web Server)는 정확히 뭔데? 내가 node.js로 만들던 서버와는 뭐가 다른건데? 이런 궁금증을 가지고 검색하면서 알게 된 키워드는 WAS(Web Application Server). 하나씩 차근차근 공부해보자구
Web server
위키백과에서 찾은 정의는 이렇다.
- 웹 서버: 웹 브라우저와 같은 클라이언트로부터 HTTP 요청을 받아들이고, HTML 문서와 같은 웹페이지를 반환하는 컴퓨터 프로그램
- 웹 서버(하드웨어): 위에 언급한 기능을 제공하는 컴퓨터 프로그램을 실행하는 컴퓨터
웹 서버(Web Server)는 HTTP를 통해 웹 브라우저에서 요청하는 HTML 문서나 이미지 파일 등을 전송해주는 서비스 프로그램을 말한다. 이때 정적인 콘텐츠는 WAS를 거치지 않고 바로 클라이언트에게 제공하여 WAS의 부담을 줄일 수 있다.
* 정적인 콘텐츠?
항상 동일한 페이지 반환. e.g. image, html, css 등과 같이 컴퓨터에 저장되어 있는 파일들
웹서버의 기능을 요약하자면,
1. 정적 콘텐츠 관리
2. 인증
3. HTTPS 지원
4. 대용량 파일 지원
Web Application Server
웹 애플리케이션 서버(Web Application Server, WAS)는 웹 애플리케이션과 서버 환경을 만들어 동작시키는 기능을 제공하는 소프트웨어 프레임워크이다.
WAS의 기본 기능은 다음과 같다.
- 프로그램 실행 환경과 DB 접속 기능 제공
- 여러 개의 트랜잭션 관리
- 업무를 처리하는 비즈니스 로직 수행
동작하는 것을 보면 클라이언트의 요청(Request)을 WAS에 보내고, WAS가 처리한 결과를 클라이언트에게 응답(Response)하는 형식이다.
다시 본론으로 돌아와서! 엔진엑스는 트래픽이 많은 웹사이트를 위해 확장성을 위해 설계한 비동기 이벤트 기반 구조의 웹서버 소프트웨어다.
내가 NGINX를 공부하게 된 이유가 뭐였지? SSL 설정을 위해서다. 즉 SSL을 위해서는 NGINX의 역할이 뭔지 알아볼 필요가 있다.
NGINX의 역할
- 정적 파일 처리하는 웹 서버
- 리버스 프록시 역할
- SSL(참고로 나는 프로젝트를 진행할 때, SSL 설정을 위해 무료로 인증서를 제공하는 Let's Encrypt에서의 certbot을 이용하여 HTTPS를 활성화했음)
- 로드 밸런싱을 통한 WAS 부하 분산
SSL 설정해보겠다고 난리친 덕분에 새로운 개념들을 배울 수 있어서 정말 좋았던 기억이 있다. 아 그리고 엔진엑스도 자바스크립트처럼 비동기 이벤트 기반 구조를 가진다고 한다.
동기vs비동기, 블로킹vs논블로킹? JS 더 깊게 이해하기(1)
위의 그림을 보면, 스레드 기반은 하나의 커넥션 당 하나의 스레드를 사용하여 브라우저의 요청을 처리하는 반면에 이벤트-드리븐 반식은 여러 개의 커넥션을 하나의 스레드에 있는 Event Handler에서 비동기 방식으로 처리한다. 이런 특성 때문에 자원 활용 측면에서 nignx가 효율적이고, 요즘 사용 비중도 점점 더 커지고 있는 추세라고 한다.
또 다른 꼬꼬무! 리버스 프록시는 뭘까? 프록시 개념은 정글 네트워크 주차 때 공부했었!지만 자세히 기억 안나서 다시 공부했었음 ㅋ... 그래도 이때 공부한 흔적 덕분에 더 쉽게 이해할 수 있었지!
Proxy Server
프록시 서버는 클라이언트가 자신을 통해서 다른 네트워크 서비스에 간접적으로 접속할 수 있게 해 주는 컴퓨터 시스템이나 응용 프로그램을 말한다. 즉 클라이언트와 서버 사이에 대리로 통신을 수행하는 것을 일컫는다. 프록시 서버 중 일부는 프록시 서버에 요청된 내용들을 캐시를 이용하여 저장한다. 캐싱으로 원격 서버에 접속하여 데이터를 가져올 필요가 없게 됨으로써 전송 시간을 절약할 수 있고 외부와의 연결을 사용하지 않아도 된다는 장점이 있다. 또한 외부와의 트래픽을 줄이게 됨으로써 성능 개선에도 이점이 있다.
프록시 서버는 Forward Proxy, Reverse Proxy로 나눌 수 있다.
Forward Proxy
프록시 서버를 클라이언트와 접근하고자 하는 원격 리소스 사이에 위치시킨다. 그림으로 보면 이렇다.
즉 클라이언트가 서버로 요청을 할 때 직접 요청하지 않고 프록시 서버를 통해 요청하는 방식이다. 일반적으로 프록시라고 하면 포워드 프록시를 말한다고 한다. 이 방식의 특징은 서버에게 클라이언트가 누구인지 감추는 역할을 한다는 것이다. 서버가 응답 받은 IP는 프록시 서버의 IP이기 때문에 클라이언트가 누군지 알 수 없다.
Reverse Proxy
리버스 프록시는 프록시 서버의 위치를 인터넷 리소스 앞에 두는 방식이다.
클라이언트가 서버를 호출할 때 리버스 프록시를 호출하게 되고 프록시 서버가 서버를 요청하여 받은 응답을 클라이언트에게 전달한다.
리버스 프록시는 서버가 누구인지 감추는 역할을 한다. 클라이언트는 리버스 프록시 서버를 먼저 호출하게 되기 때문에 실제 서버의 IP를 알 수 없다.
여하튼! 엔진엑스를 설정한 후부터 사용자가 슈퍼슬랩 브라우저로 들어오면 엔진엑스 서버에서 정적 파일을 제공한다.
그런데 문제가 있었다. 슈퍼슬랩 도메인을 입력하면 index.html 파일이 성공적으로 화면에 출력된다. 문제는 로그인 버튼이나 다른 버튼을 누르면 에러가 발생했다. 즉 만들어 놓았던 API들이 전혀 무용지물인 상황이었다.
하지만 어떻게 해서든 해결해야 하는 것이 개발자가 되기 위한 필수 요소일지니... 폭풍 구글링을 하면서 엔진엑스에 대해 더 공부해보고, 관련 에러 문구를 찾아보면서 문제를 해결하려고 했다.
결국은 niginx에서 백엔드, 즉 슈퍼슬랩 WAS로 향하는 트래픽을 처리하도록 설정해야 했다. 루트 경로인 '/' 외의 '/api/ 경로일 때 처리하도록 해야 했다. 그래서 config에서 location /api 블록을 만들고 그 안에 proxy_pass http://localhost:000; 을 입력하여 백엔드 프로세스가 실행 중인 포트의 로컬 호스트로 리다이렉션하도록 설정하였다.
그래서 내가 작성한 nginx.conf 파일은 다음과 같다.
# Default server configuration
#
server {
listen 80;
listen [::]:80;
root /home/ubuntu/superLuck/build;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name superslap.site 0.00.00.00;
location / {
try_files $uri $uri/ /index.html;
}
location /api {
proxy_pass http://localhost:0000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
# websocket reverse proxy
location ~* \.io {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy false;
proxy_pass http://localhost:0000;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/superslap.site/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/superslap.site/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
# Virtual Host configuration for example.com
#
# You can move that to a different file under sites-available/ and symlink that
# to sites-enabled/ to enable it.
#
#server {
# listen 80;
# listen [::]:80;
#
# server_name example.com;
#
# root /var/www/example.com;
# index index.html;
#
# location / {
# try_files $uri $uri/ =404;
# }
#}
server {
if ($host = superslap.site) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name superslap.site 0.00.00.00;
return 404; # managed by Certbot
}
▼reference
'개발자 도전기 > [SW사관학교 정글] 개발일지' 카테고리의 다른 글
나만의무기Rewind | Intro | 개발자 홀로서기 취업 도전은 광탈, 차근차근 다시 리와인드 하자구 (2) | 2022.01.05 |
---|---|
정글에서 살아남기 | WEEK19 | 정글 안녕!!! 그동안 감사했습니다! 개발자 홀로서야 할 때 (6) | 2021.12.25 |
정글에서 살아남기 | WEEK18 | 프로젝트 끝. 이제 진짜 정글로 갈 준비... (0) | 2021.12.12 |
정글에서 살아남기 | WEEK17 | 최종 발표까지 D-6!!!!! (0) | 2021.12.06 |
정글에서 살아남기 | WEEK16 | 프로젝트 시연까지 4일, 최종 발표까지 13일 남음..! (0) | 2021.11.28 |
댓글