AWS EC2 fastapi 외부 접근

yoonene·2025년 1월 27일

EC2에서 8000번 포트로 api를 띄우면 외부에서 바로 접근이 되지 않았다! (보안 그룹에서 모든 포트를 다 열어주고 싶지 않았다.)
따라서 리버스 프록시를 설정하여 EC2에서 열어둔 http 80번 포트를 통해 외부에서 접근하면 내부 8000번 포트로 접근되도록 해야 한다.

이를 위해 Nginx를 사용하였다.
나는 도메인은 따로 설정하지 않고 공용 IP/EIP를 사용하는 기준으로 설정하였다.

1. Nginx 설치

  1. EC2에 접속:

    ssh -i <YOUR_KEY.pem> ubuntu@<EC2_PUBLIC_IP>
  2. 패키지 업데이트 및 Nginx 설치:

    sudo apt update
    sudo apt install nginx -y
  3. Nginx 서비스 시작 및 활성화:

    sudo systemctl start nginx
    sudo systemctl enable nginx
  4. Nginx 상태 확인:

    sudo systemctl status nginx
  5. 브라우저에서 http://<EC2_PUBLIC_IP>를 입력해 Nginx 기본 페이지가 나오는지 확인.


2. Nginx를 리버스 프록시로 설정

  1. Nginx 설정 파일 생성:

    sudo nano /etc/nginx/sites-available/your-app
  2. 아래 내용을 입력 (Uvicorn이 EC2의 127.0.0.1:8000에서 실행 중인 기준):

    server {
        listen 80;
        server_name <EC2_PUBLIC_IP>;  # EIP를 사용하면 고정된 IP를 넣으면 됨.
    
        location / {
            proxy_pass http://127.0.0.1:8000;  # Uvicorn 실행 주소
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
        }
    
        location /healthcheck {
            default_type text/plain;
            return 200 'OK\n';
        }
    }
  3. 설정 파일 활성화:

    sudo ln -s /etc/nginx/sites-available/your-app /etc/nginx/sites-enabled/
  4. 기본 설정 파일 비활성화:

    sudo rm /etc/nginx/sites-enabled/default
  5. Nginx 설정 테스트:

    sudo nginx -t
  6. 설정이 정상이라면 Nginx 재시작:

    sudo systemctl restart nginx
  7. 브라우저에서 http://<EC2_PUBLIC_IP>로 접속해 Uvicorn 서버가 제대로 작동하는지 확인.


여기까지 하면 http://<EC2_PUBLIC_IP>:8000/endpoint로 외부에서 request 보낼 수 있게 된다!

2번까지만 해도 원하는 포트로 접속 가능하지만, http만 사용했을 때에는 보안 문제가 있다.

HTTP 보안 문제

  • http만 사용하면 트래픽이 암호화되지 않아서, 네트워크에서 데이터를 도청하거나 변조할 위험이 있음.
  • 따라서 민감한 정보를 주고받는 경우 HTTPS는 필수.

HTTPS 설정하는 법 (자체 서명 인증서 사용)

  1. SSL 인증서와 키 생성:

    sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
        -keyout /etc/ssl/private/nginx-selfsigned.key \
        -out /etc/ssl/certs/nginx-selfsigned.crt
  2. 필요한 디렉토리와 기본 설정 파일 생성:

    sudo nano /etc/nginx/snippets/self-signed.conf
  3. 아래 내용을 입력:

    ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
    ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
  4. SSL 설정 강화:

    sudo nano /etc/nginx/snippets/ssl-params.conf
  5. 아래 내용을 입력:

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_dhparam /etc/ssl/certs/dhparam.pem;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:10m;
    ssl_session_tickets off;
    ssl_stapling on;
    ssl_stapling_verify on;
  6. Diffie-Hellman 파라미터 생성:

    sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
  7. Nginx 설정 파일 수정:

    sudo nano /etc/nginx/sites-available/your-app

    아래 내용을 추가:

    server {
        listen 443 ssl;
        server_name <EC2_PUBLIC_IP>;
    
        include snippets/self-signed.conf;
        include snippets/ssl-params.conf;
    
        location / {
            proxy_pass http://127.0.0.1:8000;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
        }
    
        location /healthcheck {
            default_type text/plain;
            return 200 'OK\n';
        }
    }
    
    server {
        listen 80;
        server_name <EC2_PUBLIC_IP>;
        return 301 https://$host$request_uri;  # HTTP -> HTTPS 리다이렉트
    }
  8. Nginx 설정 테스트 후 재시작:

    sudo nginx -t
    sudo systemctl restart nginx
  9. 브라우저에서 https://<EC2_PUBLIC_IP>로 접속. 경고가 뜰 수 있지만 이는 자체 서명 인증서 때문이며 무시해도 됨.


최종 확인

  1. Uvicorn 서버 실행.
  2. Nginx를 통해 http://<EC2_PUBLIC_IP>로 접근 확인.
  3. HTTPS 설정 후 https://<EC2_PUBLIC_IP>로 접근 확인.
profile
NLP Researcher / Information Retrieval / Search

0개의 댓글