[알토르] #17 ssl을 이용해 nginx에 https 적용하기

Hyungjun·2024년 7월 13일
0

알토르

목록 보기
19/23

Mission

  • 24시간 실행
  • Letsencypt 인증서 설치해서 http를 https로 바꿔주는 작업
    • 443포트도 ⇒ 5000번 포트에 포트포워딩
    • ssl개념에 대해 간단하게 정리해보기
    • ssl인증서가 무엇인지
  • Vercel에 배포 된 프론트엔드코드와 ↔ EC2에 배포 된 백엔드코드가 통신이 정상적이게 동작


#1 EC2에서 파이썬 24시간 실행

  1. 파이썬 코드 24시간 실행 - nohup
    ec2 에 flask 코드를 127.0.0.1:5001에 24시간 실행시킬 것이다.
    이때 조심해야 할 점은 python 코드를 실행시키는 데 필요한 라이브러리들을 모두 설치해 주어야 한다.
    dotenv, openai, cors, flask를 다운받아 주었다.

  2. nohup
    nohup는 파이썬 스크립트를 백그라운드에서 실행할 수 있게 해준다.

output.log에 결과를 출력하면서 오류를 확인하며 실습을 진행하였다.
(라이브러리가 없다는 오류, 등 각종 오류들)

$ nohup python3 your_script.py > output.log 2>&1 &

백그라운드에서 잘 실행되고 있는지 확인할 수 있다.

$ ps -ef | grep python3

#2 HTTPS로 만들기

1) 배경지식

현재 http://api.junresume.com 도메인을 입력하면 nginx 기본페이지가 열리도록 해놓았다. 첫번째 목표는 https://api.junresume.com 를 입력해도 페이지가 켜지도록 하는 것이다.

HTTPS는 HTTP 통신 프로토콜에 secure이 더해진 것이다.

HTTPS의 기능
1. 기밀성 : HTTPS는 내가 보내는 정보를 알아보기 힘들게 만들어 준다.
2. 무결성 : 통신중에 정보가 변조되지 않도록 한다.
3. 인증 : 접속한 사이트가 안전한 사이트인지 인증해준다.

양방향 암호화 방식 중에는 대칭키 방식과 비대칭키 방식이 있다.

  1. 대칭키 방식

    송신자와 수신자가 같은 내용의 키를 갖고 있다. 같은 내용의 키로 암호화하고 복호화한다. 하지만 맨 처음 통신을 할 때 키를 알려줘야하는 데 이때 보안에 위험이 있다.

  2. 비대칭키 방식 (공개키 방식)

    이를 해결하기 위해 비대칭키(공개키) 방식이 고안되었다. 서버에서 개인키를 만들고 공개키를 뿌린다. 송신자가 공개키로 암호화해서 보내면 서버가 개인키로 복호화해서 데이터를 사용한다.

2) CA

CA(certificate authority)는 인증기관으로, 공개키와 도메인이 연결되어있음을 알리는 인증서를 발급해준다.
공개키가 진짜인지를 인증해주는 역할을 한다.
이번 실습에는 Let's encrypt 라는 CA를 사용하였다.

3) HTTPS 통신 과정

  1. 통신을 시작할 때, 클라이언트와 서버는 서로 신뢰하지 못하기에 handshake 과정이 필요하다. 서로 랜덤 데이터를 보내고 서버에서는 클라이언트로 인증서도 보낸다. 클라이언트는 인증서가 정품인지 CA의 인증서 리스트로 확인한다.

  2. 인증서는 CA의 개인키로 암호화 되어있는데, 만약 인증서가 진짜라면 브라우저에 있는 CA의 공개키로 복호화할 수 있다. 인증서를 복호화하면 서버의 공개키가 포함이 되어있다.

    비대칭키로 통신을 하면 대칭키보다 컴퓨터의 부담이 크다. 그래서 비대칭키과 대칭키 방식을 혼합해서 사용한다.

  3. 아까 주고받은 랜덤 데이터로 임시키를 만들어내서 서버의 공개키로 암호화해서 서버로 보낸다. 임시키를 이용해 대칭인 세션키가 만들어지고, 이 세션 키는 서버와 클라이언트 만이 가지고 있게 되니 대칭키 방식으로 데이터를 주고받을 수 있게 된다.

  4. ssl개념
    SSL(Secure Scokets Layer)은 암호화 기반 인터넷 보안 프로토콜, TLS는 SSL의 업데이트 버전이며 명칭만 다르다고 볼 수 있다. SSL은 개인정보 보호를 제공하기 위해, 웹에서 전송되는 데이터를 암호화한다.

  5. ssl인증서
    SSL은 SSL인증서(=TLS인증서)가 있는 웹사이트만 실행할 수 있다. 인증서는 사람의 신분증과 유사하다고 볼 수 있다. SSL인증서에는 공개 키가 포함된다. 이 공개키 덕분에 암호화가 가능하게 된다. 클라이언트의 요청은 공개 키를 이용해 서버에 암호화 하여 전달한다. 서버에도 공개되지 않는 개인 키가 있는데 이 개인 키를 이용해 암호화된 데이터를 복호화한다.

#3 실습

  1. 원래 로컬 컴퓨터에서 실행해왔기 때문에 front에서 http://api.junresume.com/sendMessage로 post 요청을 하고 있었다.

  2. 이제는 back 또한 Ec2에 배포를 하고 보안이 필요하기 때문에 https로 바꿔주어야 한다.

  3. 프론트 코드에 fetch 부분의 코드에는https://api.junresume.com/sendMessage 로 수정해주고 github에 push해주면 몇분이면 vercel이 업데이트해준다.

  4. 그렇게 되면 http로 80번 포트로 오던 요청이 https로 443포트로 요청이 오게된다.

  5. certbot를 이용하여 https 방식을 사용할 수 있도록 해준다.
    다음 명령어를 입력한다.

  $ sudo apt-get update
  $ sudo apt-get upgrade

  # 서버에 certbot 추가하기
  $ sudo apt-get-repository ppa:certbot/certbot
  $ sudo apt-get update
  $ sudo apt-get install python-certbot-nginx
  $ sudo certbot --nginx -d api.junresume.com

https로 nginx 메인페이지가 연결되는 것을 볼 수 있다.

#4 리버스 프록시

리버스 프록시는 주로 웹 서버 앞단에 위치하여 클라이언트 요청을 백엔드 서버로 전달하고, 백엔드 서버의 응답을 클라이언트에게 반환하는 역할을 한다.

  1. sites-available
    이 디렉토리는 모든 가능한 사이트 설정 파일을 저장하는 곳이다. 여기에 있는 파일들은 실제로 활성화되지 않았지만 사용 가능한 설정 파일들이다.

새 사이트를 추가하고 싶다면 이 디렉토리에 설정 파일을 작성하고 저장한다. 이 디렉토리는 가용 사이트 설정의 저장소 역할을 한다.

  1. sites-enabled
    이 디렉토리는 실제로 Nginx 서버에서 활성화 된 사이트 설정 파일들의 심볼릭 링크를 저장하는 곳이다. Nginx는 이 디렉토리 내의 파일들만을 읽어와 활성화 합니다.

sites-available 디렉토리에 사이트 설정 파일을 작성한 후, 이를 sites-enabled 디렉토리 내로 심볼릭 링크(ln -s)를 생성하여 넣으면 해당 설정이 활성화 된다.

Nginx 설정

  1. Nginx 설정 파일 열기

    sudo nano /etc/nginx/sites-available/api.junresume.com
  2. Nginx 설정

    server {
        listen 443 ssl;
        server_name api.junresume.com;
    
        ssl_certificate /etc/letsencrypt/live/api.junresume.com/fullchain.pem; //공개키 경로
        ssl_certificate_key /etc/letsencrypt/live/내api.junresume.com/privkey.pem; //개인키 경로
    
        location / {
            proxy_pass http://127.0.0.1:5001;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }
    
    server {
        listen 80;
        server_name api.junresume.com;
    
        # Redirect all HTTP requests to HTTPS
        # 80번 포트로 오는 요청을 모두 443포트로 리다이렉트 해줌.
        return 301 https://$host$request_uri;
    }
  3. 심볼릭 링크 생성

    설정이 완료 후, 설정 파일을 sites-enabled 디렉토리로 심볼릭 링크를 생성하여 활성화

    sudo ln -s /etc/nginx/sites-available/api.junresume.com /etc/nginx/sites-enabled/
  4. Nginx 재시작

    sudo nginx -s reload

결과

로컬 컴퓨터에서만 잘 구동되었던 페이지였지만,
이제 프론트(next.js)는 vercel로 배포하고 백(flask)은 EC2로 배포하면서 https 프로토콜로 통신까지 되게 완성하였다.

개발자 도구를 사용해서 네트워크 부분을 보니 post 요청이 EC2 컴퓨터의 443 포트로 잘 가고 있는 것을 확인 할 수 있다.

참고
https://velog.io/@may_soouu/letsencrypt-nginx%EC%97%90-%EC%9D%B8%EC%A6%9D-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0ssl
https://luminitworld.tistory.com/85
https://www.youtube.com/watch?v=H6lpFRpyl14

profile
Cloud Security Expert

0개의 댓글