우아한테크코스 Level3 팀 프로젝트의 스프린트 3의 요구 사항 중에, HTTPS를 적용해야 하는 요구 사항이 있었습니다. HTTPS를 적용한 방법에 대해 알아보겠습니다.
먼저, Nginx를 통해서 Https를 구현했는데요. 아래와 같은 이유때문에 Nginx를 선택했습니다.
먼저, 저희 팀은 가비아에서 도메인을 구입했습니다.
sokdaksokdak.com
구매한 도메인에 프론트 서버가 있는 ec2의 public ip를 연결
해줘야 합니다.
가비아 > 서비스 관리 > DNS 관리툴
에서 연결할 도메인을 체크하고 DNS 설정
을 클릭하면 위의 창이 보입니다.
호스트에 www(www.sokdaksokdak.com)와 @(sokdaksokdak.com)를 추가해주고
값/위치에 프론트 서버가 있는 ec2의 Public IP를 지정해주었습니다.
이제 sokdaksokdak.com으로 접속했을 시에, 프론트 서버로 요청이 전송됩니다.
$ sudo apt install nginx # nginx 설치
$ sudo service nginx start # nginx 실행
$ sudo service nginx status # nginx가 잘 실행중인지 확인
먼저, 위의 명령어를 통해 Ngnix를 프론트 서버가 존재하는 ec2에 설치하고 실행
시킵니다.
Let’s Ecrypt는 이메일과 도메인만으로, 빠르게
인증서를 발급할 수 있는 무료
서비스입니다.
인증서는 Certbot을 통해서 받을 수 있습니다.
먼저 아래의 명령어로 Certbot을 설치해줍니다. apt를 통해서 설치하셔도 무방합니다.
$ sudo snap install certbot --classic
$ sudo certbot --nginx -d {도메인}
ex)
$ sudo certbot --nginx -d sokdaksokdak.com
위의 명령어를 통해 인증서를 발급하면서 nginx에 인증서 관련 설정을 자동
으로 할 수 있습니다.
위의 명령어를 작성하면 Successfullu received certificate.
라는 안내와 함께 인증서 정보를 출력줍니다.
$ cd /etc/nginx/sites-available
$ vi default
위의 경로에 가보시면 default
라는 파일이 있습니다. 해당 파일을 열어보면 CertBot이 nginx의 사이트에 인증서 관련 설정
을 보실 수 있습니다.
저는 default 파일을 삭제하고, 아래와 같이 .conf 파일을 따로 작성해주었습니다. 파일의 이름은 제한이 없습니다. 하지만 위치는 반드시 /etc/nginx/sites-available
이어야 합니다.
#프론트 서버의 nginx 관련 설정
server {
listen 443 ssl; # 443 포트의 요청을 받음
server_name sokdaksokdak.com; # 도메인 지정
location / {
root /home/ubuntu/2022-sokdak/frontend/dist; # 빌드된 프론트의 파일 위치
index index.html; # 렌더링 해줄 html 파일 이름
try_files $uri $uri/ /index.html; # 사용자가 존재하는 않는 uri로 요청을 보내도, index.html을 보여줌
}
ssl_certificate /etc/letsencrypt/live/sokdaksokdak.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/sokdaksokdak.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}
server {
listen 80; # 80 포트의 요청을 받음
server_name sokdaksokdak.com;
return 301 https://sokdaksokdak.com$request_uri; # 동일한 uri를 https로 리다이렉트
}
위는 프론트 서버에 nginx를 구축할 때의 설정입니다.
위의 server 블럭은 sokdaksokdak.com으로 443(https) 요청이 왔을 때, index.html
을 띄워주는 것입니다.
아래의 server 블럭은 sokdaksokdak.com으로 80(http) 요청이 왔을 때, 443
으로 리다이렉션 해주는 설정입니다.
/etc/letsencrypt/{위에서 인증서 발급받은 도메인}/fullchain.pem
을 작성하면 됩니다./etc/letsencrypt/{위에서 인증서 발급받은 도메인}/privkey.pem
.conf 파일 설정 후, 아래의 명령어로 nginx 문법에 틀린 것이 있는지 체크
해줍니다. 오타나 문제가 있을 수 있으니, 한번씩 체크하시는걸 추천합니다!
$ sudo nginx -t
$ sudo ln /etc/nginx/sites-available/2022-sokdak.conf /etc/nginx/sites-enabled/
다음으로, 위의 명령어를 통해 방금 .conf를 수정했던 /etc/nginx/sites-available 디렉토리와 /etc/nginx/sites-enable 디렉토리에 심볼릭링크
를 걸어주어야합니다. 또한, sites-enable에 존재하는 default 파일은 삭제하였습니다.
sites-available은 nginx에 대한 .conf 파일을 설정하는 곳이고, sites-enabled에 있는 설정은 실제로 nginx가 실행될 때 적용되는 nginx 설정을 읽는 디렉토리입니다. sites-available에서는 nginx에 대한 .conf 파일을 설정하고, sites-enable과 심볼릭링크하여 nginx에 설정을 적용하는 방식입니다.
$ sudo nginx -s reload
# 혹은
$ sudo service nginx restart
그 후에, 위의 명령어를 통해 nginx를 재시작하면
백엔드는 Spring이 돌아가고 있는 EC2에 Nginx를 설치하지 않고, Nginx를 위한 EC2를 별개로 구축
했습니다. 아래와 같은 이유를 고려하지 않으시면, 프론트의 https처럼 하나의 EC2에 Nginx를 설치해도 됩니다.
이유는 아래와 같습니다.
위에서 프론트엔드 방법과 동일하게 하시면 됩니다.
다른 점은 listen하고 있는 server_name이 다른 도메인이라는 것입니다.
server {
listen 443 ssl; # 443 포트의 요청을 받음
server_name was.sokdaksokdak.com; # 도메인 지정
location / {
proxy_pass http://{백엔드서버 IP}:8080; //Spring과 nginx가 같은 ec2에 있기 때문에, localhost로 요청 위임
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
}
ssl_certificate /etc/letsencrypt/live/was.sokdaksokdak.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/was.sokdaksokdak.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}
server {
listen 80; # 80 포트의 요청을 받음
server_name was.sokdaksokdak.com;
return 404; # http로 요청하면 404 응답
}
또한, 프론트엔드의 location과는 설정이 다릅니다.
Nginx는 서버에 대한 요청을 처리할 수 없기 때문에, Spring에게 요청을 위임해야합니다. 따라서, proxy_pass에는 Spring이 동작하고 있는 주소를 지정해줍니다.
.conf에서 proxy_set_header를 위와 같이 설정해주면, Spring으로 들어오는 요청에 대한 로깅은 아래와 같습니다.
###### HTTP Request ######
GET /boards/contents HTTP/1.0
x-forwarded-for: 218.39.176.142 # $proxy_add_x_forwarded_for 로 설정
x-forwarded-proto: https # $scheme 로 설정
x-real-ip: 218.39.176.142 # $remote_addr로 설정
host: was.sokdaksokdak.com # $http_host 로 설정
connection: close
$proxy_add_x_forwarded_for
로 설정해주었습니다. $proxy_add_x_forwarded_for
로 설정하면, 원 client의 IP를 x-forwarded-for 헤더에 append 해줍니다.$scheme
로 설정해줍니다.$remote_addr
(원 클라이언트의 IP) 로 설정해주었습니다.위와 같이 설정하면 아래와 같은 통신 구조가 구축됩니다!
끗!
https://velog.io/@pinot/Ubuntu-Nginx-환경에서-CertBot을-사용하여-https-사용하기
https://gist.github.com/woorim960/dda0bc85599f61a025bb8ac471dfaf7a
https://maximorlov.com/tips/sites-available-vs-sites-enabled-in-nginx/
우아한테코크스 4기 BE 릭