이 블로그는 광고 클릭 수익으로 운영됩니다!
괜찮으시다면 광고 차단을 풀어주세요 ㅠㅠ

게시글

강좌18 - NodeJS - 10달 전 등록 / 4달 전 수정

letsencrypt와 greenlock으로 SSL(https) 적용하기

조회수:
0
이 블로그는 광고 클릭 수익으로 운영됩니다!
괜찮으시다면 광고 차단을 풀어주세요 ㅠㅠ
이 블로그는 광고 클릭 수익으로 운영됩니다!
괜찮으시다면 광고 차단을 풀어주세요 ㅠㅠ

안녕하세요. 이번 시간에는 SSL 적용 방법에 대해 알아보겠습니다.

letsencrypt를 사용해서 90일짜리 공짜 SSL을 적용해봅시다. 90마다 갱신하는 것이 귀찮기 때문에 greenlock-express라는 모듈을 사용해서 자동 갱신도 적용하겠습니다.

undefined

제 블로그에 SSL이 적용된 모습입니다. SSL을 적용하면 저렇게 초록 자물쇠 표시를 얻을 수 있습니다. 먼저 왜 SSL을 적용해야하나부터 간단히 알아보겠습니다.

SSL은 Secure Socket Layer입니다. Secure이 들어가있기 때문에 뭔가 안전해 보이죠? 클라이언트와 서버 간 오고 가는 데이터를 암호화해줍니다. 그냥 HTTP 통신을 하면 주고 받는 데이터가 노출됩니다. 공공장소에서 와이파이로 로그인을 하는데 SSL도 적용 안 되어 있고, 와이파이가 해킹당해 있다? 그러면 바로 여러분의 비밀번호가 해커에게 전달됩니다.

SSL은 인증서를 발급받아야 브라우저가 적용할 수 있습니다. 인증서는 정해진 몇몇 기관에서만 (돈 내고) 발급 가능했습니다. 그래서 개인 웹사이트를 운영하는 사람들은 적용하기를 망설였는데요. Let's Encrypt가 나와서 상황이 달라졌습니다. 고맙게도 "무료"로 SSL 인증서를 발급해줍니다. 3개월마다 갱신해야하긴 하지만, 자동 갱신을 지원하기 때문에 큰 문제는 없습니다.

HTTP1보다 효율적인 HTTP2를 사용하기 위해서도 SSL 적용이 필요합니다.

구글이 검색 순위에 SSL 적용 여부를 반영하기로 했기 때문에 SSL 적용의 중요성이 나날이 커져가고 있는데요. 노드를 서버로 운영하시는 분들도 뒤쳐질 수는 없죠! 노드에 Let's Encrypt를 적용해주는 greenlock 모듈에 대해 알아봅시다.

npm install greenlock-express

먼저 필요한 패키지들을 다운로드받습니다. greenlock-express는 express뿐만 아니라 spdy, https, restify 등의 모듈과 함께 쓸 수 있습니다. 클러스터링을 할 때는 greenlock-cluster를 씁니다. 만약 koa를 쓰신다면 greenlock-koa를, hapi라면 greenlock-hapi를 사용하면 됩니다. 바닐라 노드에 붙이려면 그냥 greenlock 패키지를 설치합니다. 사실 다른 패키지들은 모두 greenlock 패키지를 상속하고 있습니다. 커맨드라인 명령어로 쓰는 greenlock-cli도 있습니다.

먼저 설정 객체를 만듭니다.

const lex = require('greenlock-express').create({
  version: 'v02', // draft-11 버전 인증서 사
  configDir: '/etc/letsencrypt' // 또는 ~/letsencrypt/etc
  server: 'staging',
  approveDomains: (opts, certs, cb) => {
    if (certs) {
      opts.domains = ['example.com', 'www.example.com'];
    } else {
      opts.email = 'example@example.com';
      opts.agreeTos = true;
    }
    cb(null, { options: opts, certs });
  },
  renewWithin: 81 * 24 * 60 * 60 * 1000,
  renewBy: 80 * 24 * 60 * 60 * 1000,
});

create 메소드에 여러 옵션들을 넣어주는데요. 하나씩 알아봅시다.

version은 letsencrypt 인증서 버전을 의미합니다. v02와 v01이 있습니다. configDir는 발급받은 인증서 위치를 넣는 곳입니다. 이 곳을 정확하게 넣어야 동작합니다.

server에는 staging을 넣어줍니다. 나중에 staging을 production 또는 https://acme-v01.api.letsencrypt.org/directory으로 바꿔줘야 합니다. staging은 테스트용 SSL을 만들어보는 것입니다. approveDomains에는 도메인 이름들을 적어줍니다. 참고로 서브 도메인들은 다 적어줘야 합니다. www가 붙은 것도 서브도메인이기 때문에 넣어주어야 하고요. dev.example.com, api.example.com 등이 있다면 그것 또한 넣어줘야 합니다.

email에는 자신의 이메일을(나중에 만료 예정일 때 이 곳으로 이메일이 옵니다.), agreeTos는 true를 넣어줍니다. agreeTos는 약관 동의라고 생각하시면 됩니다.

renewWithin과 renewBy는 각각 인증서를 갱신할 최대 기간과 최소 기간을 뜻합니다. 80일과 81일 사이에(인증서의 수명은 90일) 갱신하도록 했습니다.

설정이 완료되었으니 https를 require한 후 다음과 같이 서버를 생성합니다.

https.createServer(lex.httpsOptions, lex.middleware(app)).listen(process.env.SSL_PORT || 443);

이제 서버를 실행하면 알아서 SSL이 붙습니다. server: 'staging'으로 하면 인증서가 잘못되었다고 나오는데 SSL이 붙은 것을 확인한 후 server: 'production'으로 바꿔줍니다. 서버를 재시작(재시작 후 몇 분 걸릴 수도)하면 이제 초록 자물쇠를 얻을 수 있습니다.

https 말고 http도 같이 사용할 때 자동으로 http로 리다이렉트되게 하려면 다음도 추가합니다. redirect-https 패키지를 설치하긴 해야 합니다.

http.createServer(lex.middleware(require('redirect-https')())).listen(process.env.PORT || 80);

간단하죠? 기본 설정은 80일 정도마다 인증서를 갱신하기 때문에 한 번 적용된 이후에는 크게 신경 쓸 필요 없습니다. 제 경험상 서브 도메인 추가할 때만 코드를 조금 수정하면 되었던 것 같습니다. 이제 노드로 된 사이트에 SSL을 적용해봅시다!

------------------------------------------------

PS: 만약 위의 방식으로 해도 안 된다면 기존에 있던 인증서 관련 폴더(~/letsencrypt/etc, /etc/letsencrypt, public/.well-known 등)를 깨끗하게 지운 후, letsencrypt를 직접 설치합시다. certbot-auto로 먼저 인증서를 발급받은 후 위의 코드를 적용해보세요. certbot-auto는 --standalone으로 하면 됩니다. 이 때는 80번, 443번 포트에 아무 프로세스도 없도록 비워둡시다. 기존 서버가 있다면 종료합니다.

또는 --webroot옵션으로 해도 됩니다. 이 때는 80번 포트를 http 모듈이 사용하고 있어야 하며, express.static이 가리키는 폴더(public 같은 것)를 --webroot-path로 지정해주어야 합니다.

투표로 게시글에 관해 피드백을 해주시면 많은 도움이 됩니다. 오류가 있다면 어떤 부분에 오류가 있는지도 알려주세요! 잘못된 정보가 퍼져나가지 않도록 도와주세요.
Copyright © 2016- 무단 전재 및 재배포 금지

댓글

5개의 댓글이 있습니다.
3달 전
질문이있습니다. Let's Encrypt 홈페이지에서 발급을 받는 건가요??
3달 전
self signed certificate는 openssl을 사용하면 쉽게 발급받을 수 있습니다.
3달 전
궁금한 점이 있어서 질문 남깁니다. 로컬 호스트로는 안되는건가요?
3달 전
네, 로컬호스트는 인증서를 발급받아도 아무런 의미가 없습니다. 발급받을 수는 있습니다. self signed certificate를 찾아보세요.
6달 전
안녕하세요! 좋은 글 잘봤습니다 ㅎㅎ
aws ec2에 node.js https 서버를 만들려고 하는데,, 똑같이 적용하면 되겠죠..??
그리고 포트는 443 말고 다른 것을 사용해도 괜찮을까요..??
6달 전
ec2에서도 똑같이 가능합니다. 443말고 다른 걸 쓰면 443 포트랑 연결해주는 작업이 추가적으로 필요합니다.
7달 전
zerocho님 답변 감사합니다. 익명타입이라 회원가입 후 다시 리플을 다네요 ^^;; https를 지원하더라도 로그인 세션이나 이런 부분들과는 관계가 전혀 없는건가요?.
7달 전
넵 없습니다. 세션은 클러스터링과 더 관련이 많아요
7달 전
안녕하세요 zerocho님 궁금한점이 있어 질문을 남깁니다. https를 적용하면 클러스터링 이슈 말고는 딱히 개발 하는데 이슈가 없나요? 예로 로그인 기능을 개발한다던가 등등이요... 백엔드에 입문하고 있어 많이 헷갈리네요.
7달 전
Https 사실상 필수입니다. 개발 이슈는 딱히 없습니다. 클러스터링도 별 문제는 못 느꼈습니다.