배포의 마지막 과정! 안전한 자물쇠를 향한 여정이다.
80번, 443번 포트의 외부 접속을 허용하기 위해 아래와 같이 설정해놓는다.
그 외에도 필요한 규칙이 있다면 설정한다.
nginx 설치 방법 및 설정 파일 분리 방법은 이전 게시글에 있다.
letsEncript로 ssl 인증서를 발급받으면 자동으로 nginx 설정 파일을 수정해주는데, 만약 이미 443 포트를 listen 하는 서버블록이 작성되어있다면 자동으로 수정해주지 않을 수 있다. 그러니 불필요한 부분은 정리해놓는 것을 추천한다.
또한 인증서를 적용하고자 하는 도메인을 설정 파일에 작성해준다.
논외일 수 있지만 당연히 dns(domain name system) 설정은 미리 해두어야한다. aws route 53을 이용하였다.
예를 들어 soccerquick.kr, www.soccerquick.kr 도메인에 인증서를 발급받으려면 아래와 같이 입력해놓는다.
server {
listen 80;
server_name soccerquick.kr www.soccerquick.kr;
//그 외 추가 설정
}
nginx 설정 파일에 미리 도메인을 작성해놓지 않으면 아래와 같은 에러가 뜬다.
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx
Requesting a certificate for www.soccerquick.com
Performing the following challenges:
http-01 challenge for www.soccerquick.com
Using default address 80 for authentication.
Waiting for verification...
Challenge failed for domain www.soccerquick.com
http-01 challenge for www.soccerquick.com
Cleaning up challenges
Some challenges have failed.
certbot을 설치하고 인증서를 발급받는다.
아래와 같이 여러 도메인에 한꺼번에 인증서를 발급받을 수 있다.
sudo certbot --nginx -d domain.com -d www.domain.com
인증서 발급에 성공했다면 congratulation 해준다 ..
인증서 확인하는 명령어
$ sudo certbot certificates
인증서 발급이 완료되었다면 nginx 설정 파일이 자동으로 수정되어있을 것이다.
만약에 이 상태에서 https로 접속이 잘되고 데이터도 잘 불러와진다면 진정 성공한 것!
원인 - letsEncript 이전에 AWS 인증서(ACM)로 https 설정을 하려고 만지작거렸었다. 그 과정에서 남아있던 로드밸런서로 인해 완전히 꼬여버렸던 것이다.
해결 - ACM 인증서, 로드밸런서, 대상그룹 등 필요없는 것들은 깔끔하게 지웠다
xhr.js:251 Mixed Content: The page at 'https://soccerquick.kr/' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://00.00.000.000(예시):8800/api/v1/groups?itemsPerPage=8'. This request has been blocked; the content must be served over HTTPS.
원인 - https를 적용 후 http로 api 요청으로 보내서 발생하는 보안 에러이다.
request url을 https 로 변경해주면 된다.
해결 방법 1 - index.html에 meta 태그 추가
https로 요청을 업그레이드 시키는 태그이다.
<meta
http-equiv="Content-Security-Policy"
content="upgrade-insecure-requests"
/>
해결 방법 2 - 요청 url을 https로 직접 변경 (이 방법 사용)
클라이언트에서 사용하는 api url은 어차피 REACT_APP_API_URL로 통합해서 관리했기 때문에 http -> https로 직접 바꿔주었다.
정말 끝나지 않던 에러들 ..
앞선 문제가 해결되자마자 등장한 에러이고 여전히 서버에서 데이터를 못받아오고 있어서 사실 문제가 해결되고 있다는 느낌을 못받았다. 그리고 이 에러가 제일 골치아팠다. 대략적인 원인은 알 수 있었지만 아무리 구글링을 해봐도 구체적인 해결방법을 찾을 수 없었다. 정확한 원인을 몰라서 GPT도 전혀 도움을 주지 못했다.
이 에러는 말그대로 케바케 일 것 같다. 온갖 방법을 시도해보다가 해결한 방향에 집중해서 써보고자 한다.
도메인 자체로는 접속이 잘 되지만 서버에 api 요청을 할 때 문제가 발생하니 서버 데이터 요청 과정에서 ssl 인증 문제가 발생한 것으로 예측했다. 또한 앞선 mixed content 에러의 연장선에서 브라우저에서는 https 프로토콜이 적용되어있지만 암호화되지 않은 서버와 통신하면 에러가 발생하는 것이다.
ref - https://usage.tistory.com/174
2번 문제를 해결한 후 api 요청 url은 REACT_APP_API_URL = http://00.00.000.000/api/v1
이런 식으로 ip로 되어있었다. 하지만 Let's Encrypt는 ip에 ssl 보안인증서를 발행하지 않는다. 즉 도메인에만 ssl 인증서를 달 수 있다.
ref - https://community.letsencrypt.org/t/ssl-on-a-ip-instead-of-domain/90635
우선 api 요청 url을 ssl 인증서가 적용된 도메인 주소로 변경하였다.
REACT_APP_API_URL = http://www.soccerquick.kr/api/v1
그리고 리버스 프록시를 적용하였다.
server {
server_name soccerquick.kr www.soccerquick.kr;
root /home/ec2-user/Soccerquick-sk-FE/build;
index index.html index.htm;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /api/v1 {
proxy_pass http://127.0.0.1:8800;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/soccerquick.kr/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/soccerquick.kr/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
}
이제 자물쇠도 달고 데이터도 잘 받아오고 쿠키도 잘 보내진다 !
성경이 체고~