안녕하세요. 오늘은 certbot과 express를 이용해 https를 적용하는 방법을 포스팅하려고 합니다.
저의 프로젝트는 AWS EC2 Ubuntu 18.04 LTS를 통해 배포되어 있는 상태입니다.
또한 IP에 연결된 도메인이 있어야 인증이 가능합니다.
저는 공식 문서를 보고 진행하였기 때문에, certbot 공식 홈페이지에 접속해 줍니다.
사이트 홈에 위 사진과 같은 부분이 존재하는 것을 확인할 수 있습니다.
Software
는 Web Hosting Product
를 선택해 줍니다.
System
은 Ubuntu 18.04 LTS (bionic)
을 선택해 주면 사용법이 나와있는 페이지로 넘어갑니다.
cmd ssh를 통해 EC2 Ubuntu 환경에 접속합니다.
관련 게시글 - SSH 접속
저는 5, 6, 7번을 차례로 실행해 주었습니다.
여기서 7번은 서버가 실행되어 있지 않는 상태여야 합니다.
서버를 멈출 수 없는 상황이라면 sudo certbot certonly --webroot
으로 진행하면 될 것 같습니다. (시도해본 적이 없어 어떻게 되는지 알려주시면 감사하겠습니다.)
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
sudo certbot certonly --standalone
마지막 명령어를 입력하게 되면 email을 입력하라고 나옵니다.
저는 AWS 이메일과 통일시켜주었습니다.
이메일을 입력하고 나서는 도메인을 입력하라고 합니다.
꼭 HTTPS를 연결할 도메인으로 요청을 보내야 합니다.
Congratulations! 라는 문구가 뜨면 키 파일 받기에 성공한 것입니다!
(저는 이미 키 파일을 받아둔 상태라 캡쳐본이 없습니다..ㅠㅠ)
키 파일은 /etc/letsencrypt/live/입력한 도메인/
경로에 저장되어 있습니다!
이제 반은 왔습니다 🏃🏻♀️🏃🏻♀️
Express에서도 HTTPS 관련 코드를 작성해 주어야 합니다.
저는 dotenv
로 환경 변수를 관리하고 있었기 때문에 .env
파일에 키 파일 경로를 입력해 주었습니다.
메인으로 실행하는 js 파일로 이동합니다.
// app.js
// fs는 키 파일을 읽어올 때 필요합니다.
// http와 https로 서버를 생성합니다.
const fs = require("fs");
const http = require("http");
const https = require("https");
// .env 파일에 환경 변수를 불러올 수 있도록 합니다.
require("dotenv/config");
// production mode와 development mode를 구분하여 서버를 생성합니다.
if (process.env.NODE_ENV === "production") {
// production mode에서는 HTTPS로 접속하도록 해 줍니다.
// .env 파일에서 KEY_URL을 불러와 줍니다.
const KEY_URL = process.env.KEY_URL;
const options = {
key: fs.readFileSync(`${KEY_URL}/privkey.pem`),
cert: fs.readFileSync(`${KEY_URL}/cert.pem`),
ca: fs.readFileSync(`${KEY_URL}/chain.pem`),
};
// https 서버를 생성합니다.
// key 파일 옵션과 라우팅 정보 등이 들어있는 app을 함께 넘깁니다.
// https 포트 번호는 443입니다.
https.createServer(options, app).listen(443, () => {
console.log(`DUZZLE listening at port 443`);
});
// set up a route to redirect http to https
// https://stackoverflow.com/questions/7450940/automatic-https-connection-redirect-with-node-js-express
http
.createServer((req, res) => {
res.writeHead(301, {
Location: "https://" + req.headers["host"] + req.url,
});
res.end();
})
// Ubuntu 배포 환경 .env 파일에서는 PORT가 80으로 설정되어 있습니다.
.listen(PORT, () => {
// DUZZLE listening at port 80
console.log(`DUZZLE listening at port ${PORT}`);
});
} else {
// development mode에서는 http 서버만 생성합니다.
// 개발 환경 .env 파일에서는 PORT가 80으로 설정되어 있습니다.
http.createServer(app).listen(PORT, () => {
// DUZZLE listening at port 5000
console.log(`DUZZLE listening at port ${PORT}`);
});
}
이렇게 코드를 작성해 주면 개발 모드와 배포 모드 각각의 환경에 맞게 세팅이 완료됩니다.
Ubuntu에서 배포 모드 (export NODE_ENV=production
) 적용 후 서버 실행 시 https가 적용된 것을 확인할 수 있습니다.
처음으로 HTTPS를 적용해보며 작성한 글이므로 부족한 부분이 있을 수 있습니다 😥
글에 대한 의견은 댓글로 남겨주시면 감사하겠습니다.
읽어주셔서 감사합니다!
(현재 키 파일이 자동으로 갱신되는지의 여부를 알아보지 않아 불완전한 글임을 알려드립니다...)
https://certbot.eff.org
https://eunsukimme.github.io/nodejs/2019/09/20/Express-SSL-HTTPS/
https://gamsunghacker.tistory.com/150