이 포스팅은 꽤나 턱별한
포스팅이다.
http://chat-app-backend.online:3000
에 배포된 백엔드 서버에 ssl을 적용하여 https로 만들어야 했다.
프론트가 https에 배포되었기 때문에 백엔드도 동일하게 https에서 요청을 받지 않으면 mixed content CORS
에러가 나기 때문.
거의 장장 2주간에 걸친 삽질끝에 해내었다. 이렇게 오랜기간 삽질하고 무언가를 뚫어낸 경험이 이번이 처음이다.
이때까지 프론트만 하다가 네트워크와 ssh를 다뤄야해서 더 힘들었었던 것도 있다.
또한, ssl을 적용할 수 있는 방법이 매우 다양해서 더 길을 헤맨것도 있는 것 같다.
그럼 일단 거두절미하고 바로 가보자.
먼저 ssh를 이용해 원격으로 vm에 접속하기 위해 아래 명령어를 입력해주자
sudo ssh ubuntu@{"ip_address"} -i {"private_key"}
우선 nginx를 reverse proxy로 이용해서 http://chat-app-backend.online:3000
으로 들어오는 요청을 https://chat-app-backend.online
으로 만든다음 서버로 요청을 흘려보낼것이다.
그리고 ssl에 필요한 공개키와 암호키를 만들고 그것을 적용할 certbot을 설치해야한다.
즉 nginx
와 certbot
두개를 다운받아야 한다.
$ sudo apt-get install certbot
$ sudo apt-get install python3-certbot-nginx // nginx plugin for certbot
$ sudo apt install nginx
이제 certbot이 자동으로 ssl을 적용하고 nginx를 이용해 http요청을 https요청으로 바꾸는 작업까지 할것이다.
그러기 전에 nginx config파일에 proxy 할 대상과 목적지를 명시해줘야한다.
아래 명령어를 입력하여 config파일에 들어가자
$ sudo vim /etc/nginx/nginx.conf
sudo를 안쓰면 read-only로 접속됨
그리고 아래 서버블록을 http블록안에 적어주고 저장해주자
server {
server_name chat-app-backend.online; // proxy할 도메인
listen 80;
location / {
proxy_set_header HOST $host;
proxy_pass http://127.0.0.1:3000; // proxy의 목적지
proxy_set_header X-Forwarded-Proto $scheme; // 쿠키 허용
add_header 'Access-Control-Allow-Origin' '*';
proxy_redirect off;
}
}
그러고 아래 명령어를 입력하여 certbot을 실행시키자
$ sudo certbot --nginx
마지막으로 express.js를 사용한다면 proxy를 허용해주어야한다.
app.set("trust proxy", true); // trust first proxy
그럼 congratulation
이라고 ssh창에 뜨면서 ssl이 성공적으로 적용된것을 볼 수 있다.
생각보다 매우 간단해서 허탈하다.
감격의 도가니 😭🎊
그리고 nginx config파일에 다시 들어가보면 certbot이 알아서 ssl설정을 한것을 확인할 수 있다.
server {
server_name chat-app-backend.online;
location / {
proxy_set_header HOST $host;
proxy_pass http://127.0.0.1:3000;
proxy_set_header X-Forwarded-Proto $scheme;
add_header 'Access-Control-Allow-Origin' '*';
proxy_redirect off;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/chat-app-backend.online/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/chat-app-backend.online/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
}
server {
if ($host = chat-app-backend.online) {
return 301 https://$host$request_uri;
} # managed by Certbot
server_name chat-app-backend.online;
listen 80;
return 404; # managed by Certbot
다만 , certbot을 통해 설치된 ssl은 90일까지만 유효하다. 이후 에는 sudo certbot renew
를 통해 수동으로 갱신해줘야한다.
그러나 개발자는 항상 자동화 하는 법!
crontab이라는 툴이 있다. 리눅스 기반시스템에 자동으로 깔려있는 툴인데 스케쥴링을 해준다.
crontab -e
를 입력해서 들어가고 난 다음 아래 코드를 추가한후 저장해주었다.
30 1 1,15 * * certbot renew --post-hook "systemctl reload nginx"
해석하면 아래와 같다.
"매달 1일과 15일, 01:15 에 certbot을 리뉴한다."
혹시 제대로 설정했는데도 welcome to nginx 가 뜬다면 default를 제거해주자
sudo rm /etc/nginx/sites-enabled/default
삽질을 이제 더이상 삽질이라고 생각하지 않기로 했다. 그 과정에서 얻은 모든 정보가 사실 하나로 합쳐져서 큰 그림을 이해할 수 있게 해준다.
참고자료