NodeJS - (보안) https 설정 ( Nodejs+letsencrypt )

neity16·2020년 9월 17일
5

NodeJS

목록 보기
20/22
post-thumbnail

준비사항

[ 실행 환경 ]

  • EC2 : ubuntu20.04(필자의 환경일 뿐이며, Linux면 거의 다 될 것이라 예상됨)
  • Express 기반의 Nodejs 프로젝트

[ 사전 준비 ]

  1. AWS EC2에 웹 애플리케이션배포되어 실행된 상태
  2. AWS EC2서버에 Route53을 이용해서 도메인 등록이 완료된 상태
  3. EC2에 certbot 설치
    sudo add-apt-repository ppa:certbot/certbot
    sudo apt-get update
    sudo apt-get install certbot

[ letsencrypt 인증 원리 ]

  1. 요청한 도메인특정 경로파일인식되면 임시키 발급  
    certbot certonly --webroot -w ./public -d [DOMAIN]
    (특정 경로 : ./public , 도메인 : [DOMAIN])
  2. http요청으로 발급한 임시키에 접근되는지 확인
    : 바로 이 단계에서 letsencrypt서버에 http(80번포트)로 요청하는데
       이 요청을 처리하지 못하면 인증서가 발급되지 않는다.
       즉, 80번 포트로 우리의 서버가 접근 가능하게 하니까 포트포워딩이 필요

[ 포트 포워딩 ]

: ec2 의 node 서버는 현재 3000번 포트를 사용중이다.
  인증서를 설치하기 위해 80번 포트를 3000번으로 포트포워딩 해야함
  (EC2 보안 규칙에서 80번포트는 이미 열어둔 상태여야 함)

(현재 포트 포워딩 상태 확인)
sudo iptables -t nat -L

(포트 포워딩 지정) 80번 요청시 -> 3000번 으로 가도록
sudo iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3000


(포트 포워딩 취소 : 실수했을 때)
sudo iptables -D PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3000

인증서 설치

[ 인증서 발급 받기 ]

(EC2에 접속하여 실행)
1. sudo apt-get install letsencrypt
(express / 위치로 이동)
2. mkdir public
3. cd public
4. vi public.js
5. 아래 내용으로 파일 생성

import express from 'express
const app = express();
app.use(express.statis('public'));
  1. mkdir -p .well-known/acme-challenge
    (express / 위치로 이동)
  2. certbot certonly --webroot -w ./public -d [DOMAIN]
    [ 성공 화면! ]

    이렇게 수행이 완료되면 EC2서버/etc/letsencrtpy/live
    자신의 도메인이름으로 폴더가 생성되었고 그 내부에 인증서가 있을 것이다.

[ Node JS 설정 ]

  const options = { // letsencrypt로 받은 인증서 경로를 입력
  ca: fs.readFileSync('/etc/letsencrypt/live/[도메인 명]/fullchain.pem'),
  key: fs.readFileSync('/etc/letsencrypt/live/[도메인 명]/privkey.pem'),
  cert: fs.readFileSync('/etc/letsencrypt/live/[도메인 명]/cert.pem')
  };
  http.createServer(app).listen(3000);
  https.createServer(options, app).listen(443);

: 이렇게 options 객체로 인증서를 받아온 후 https모듈을 이용해 app에 연결!


[ HTTPS 적용 화면 ]

[ letsencrypt 자동 갱신 ]

   letsencrypt90일동안 유효한 무료 인증서 입니다.
   그래서 90일이 되기 전에 갱신을 해줘야 합니다.
   우리는 linux의 스케쥴러crontab으로 자동 갱신 설정!!


[ crontab 명령어 ]

: 일정 시간마다 정해진 작업을 실행하게 하는 명령어

             [ 분 ][ 시 ] [ 일 ][ 월 ] [ 요일 ] 순서로 기입


               (우리가 사용할 명령 해석해보기!)
0 0 1 */2 * /usr/bin/certbot renew --renew-hook="sudo pm2 restart inventory"
: 2개월마다 1일에 인증서를 갱신하고 서버 재시작!


              (crontab 사용해서 등록하기!)

  • 현재 crontab 목록 확인
    sudo crontab -l
  • crontab 등록
    sudo crontab -e
       : 앞에서 언급한 명령어를 입력
  • sudo crontab -l 로 다시 목록 확인
  • crontab 실행 로그 확인
    view /var/log/syslog

시행착오 과정


  • 용어의 혼동

    1) letsencrypt : Https의 확산을 늘리기 위한 취지로 시작된 비영리 프로젝트
    2) certbot: letsencrypt인증서자동으로 발급 및 갱신을 해주는 봇 프로그램

  • 같은 letsencrypt 인증서 발급하는 방법이 여러가지

    1) --webroot : 서버가 실행중일 때
    2) --standalone : 서버가 꺼진 상황에서 certbot이 간이로 잠깐 키고 인증

  • aws ec2의 도메인을 따로 만들어서 연결

    : Route53 이용해서 받으면 된다. (유료)

  • aws ec2환경에서 포트 포워딩 필요

    : 인증 과정에서 http요청으로(80번 포트) 서버에 접근이 되어야 인증서
      발급이 되기때문에 80->3000(내 서버 포트)포워딩 해줘야 했다.

  • Greenlock-Express 모듈의 버전 변경으로 사용법이 변경

    : express에 쉽게 사용하기 위해 greenlock-express 모듈을 이용하려고 했으나
    참고하는 많은 자료는 .create() 모듈을 사용하지만 현재는 .init()을 사용한다.
    (계속 하다가 실패해서 node에 직접 적용한 방식 채택)

  • NODE_ENV 변수 가져오기 실패

    : NODE_ENV배포용이면 'production' 개발용이면 'development'로   설정해
      개발용이면 http만 실행하려고 했으나, 직접 Ubuntu 환경에서
      process.env변수로 가져오는 과정이 힘들어서 일단 변수 export로 임시 해결

(참고 자료)
https://certbot.eff.org/docs/using.html#webroot

https://jsp-dev.tistory.com/entry/Express-letsencrypt%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC-https-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0

https://hellominchan.tistory.com/5

https://tristan91.tistory.com/490

http://hanjoonkblog.blogspot.com/2016/11/nodejs-lets-encrypt-https.html

profile
Developer & PhotoGrapher

3개의 댓글

comment-user-thumbnail
2021년 3월 25일

안녕하세요! 잘읽었습니다. 혹시 IMAP, SMTP설정시 과금이 생길 수 있다는게 무슨 의미인지 알려주실 수 있나요?
비용이 드는건가요?

1개의 답글
comment-user-thumbnail
2022년 4월 25일

안녕하세요! 인증서 자동갱신부분에서 pm2 restart를 하는데 pm2 명령을 프로젝트 폴더에서 해야하는데 그렇게 작동할까요? 아니면 Root에서 실행되나요?

답글 달기