현재 서비스를 중단하고 다시 시작 할 때 마다 ip주소가 변경되고 있어서 이를 고정 ip로 할당 하기 위한 작업

탄력적 IP 메뉴로 간다.
IP 주소 할당

할당 받은 IP를 현재 인스턴스에 연결

도메인을 구매한 곳에서 DNS 설정 해주기

서브 도메인을 입력했을 때 Welcome to nginx
http://api.domain.com

EC2 인스턴스는 재시작할 때마다 퍼블릭 IP가 변경되므로, 고정 IP인 Elastic IP를 할당해야 합니다.
AWS 콘솔에서 Elastic IP 할당:
1. EC2 대시보드 → 네트워크 및 보안 → 탄력적 IP
2. 탄력적 IP 주소 할당 클릭
3. 할당된 IP를 EC2 인스턴스에 연결
비용 주의사항:
A 레코드 추가:
레코드 타입: A
호스트명: api
값: [할당받은 Elastic IP]
TTL: 600
중요한 주의사항:
만약 도메인이 다른 서비스(Vercel, Netlify 등)에 연결되어 있었다면, 네임서버 설정을 확인해야 합니다.
# 현재 네임서버 확인
dig NS yourdomain.com
# 가비아 네임서버로 변경 필요시
ns.gabia.co.kr
ns1.gabia.co.kr
ns.gabia.net
# 가비아 DNS 직접 확인 (가장 빠름)
dig @ns1.gabia.co.kr A api.yourdomain.com
# 글로벌 DNS 확인
dig @8.8.8.8 A api.yourdomain.com
dig @1.1.1.1 A api.yourdomain.com
# 기본 DNS 확인
dig A api.yourdomain.com
DNS 전파 시간: 보통 10분~24시간 (TTL 설정에 따라)
# 시스템 업데이트
sudo apt update
# nginx 설치
sudo apt install nginx -y
# 서비스 시작 및 자동 시작 설정
sudo systemctl start nginx
sudo systemctl enable nginx
# 방화벽 설정
sudo ufw allow 'Nginx Full'
# 설치 확인
curl http://localhost
정상적으로 설치되면 "Welcome to nginx!" 페이지가 표시됩니다.
# snap을 통한 최신 certbot 설치
sudo apt install snapd -y
sudo snap install --classic certbot
# 명령어 링크 생성
sudo ln -s /snap/bin/certbot /usr/bin/certbot
# 버전 확인
certbot --version
DNS 전파가 완전히 완료되지 않은 상황에서는 DNS Challenge 방식을 사용하는 것이 가장 안정적입니다.
sudo certbot certonly --manual --preferred-challenges dns -d api.yourdomain.com
진행과정에서 DNS 전파가 제대로 이루어지지 않음으로 인한 메뉴얼 + 첼린지로 진행
DNS Challenge 과정:
TXT 레코드 값 제공받음:
_acme-challenge.api.yourdomain.com
값: [Certbot이 제공하는 긴 문자열]
도메인 관리 페이지에서 TXT 레코드 추가:
레코드 타입: TXT
호스트명: _acme-challenge.api
값: [Certbot이 제공한 값]
TTL: 600
TXT 레코드 전파 확인:
dig +short TXT _acme-challenge.api.yourdomain.com
인증서 발급 완료:
Certificate is saved at: /etc/letsencrypt/live/api.yourdomain.com/fullchain.pem
Key is saved at: /etc/letsencrypt/live/api.yourdomain.com/privkey.pem
/etc/letsencrypt/live/api.yourdomain.com/
├── fullchain.pem # 전체 인증서 체인 (nginx에서 사용)
├── privkey.pem # 개인키 (nginx에서 사용)
├── cert.pem # 인증서
└── chain.pem # 중간 인증서
Flask 앱을 시스템 서비스로 등록하여 자동 시작 및 관리가 가능하도록 설정합니다.
sudo nano /etc/systemd/system/flask-app.service
서비스 파일 내용:
[Unit]
Description=Flask API Application
After=network.target
[Service]
Type=simple
User=ubuntu
WorkingDirectory=/home/ubuntu/your-project-directory
Environment=PATH=/home/ubuntu/your-project-directory/venv/bin
ExecStart=/home/ubuntu/your-project-directory/venv/bin/python /home/ubuntu/your-project-directory/hello.py
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
각 옵션 설명:
Description: 서비스 설명After=network.target: 네트워크 시작 후 실행Type=simple: 단순 프로세스 타입User=ubuntu: 실행 사용자WorkingDirectory: 작업 디렉토리Environment=PATH: Python 가상환경 경로ExecStart: 실행할 명령어Restart=always: 실패시 자동 재시작RestartSec=10: 재시작 대기 시간# systemd 데몬 리로드
sudo systemctl daemon-reload
# 서비스 활성화 (부팅시 자동 시작)
sudo systemctl enable flask-app
# 서비스 시작
sudo systemctl start flask-app
# 서비스 상태 확인
sudo systemctl status flask-app
정상 동작 확인:
# Flask 앱 직접 테스트
curl http://localhost:5001
curl http://localhost:5001/hello
sudo nano /etc/nginx/sites-available/api.yourdomain.com
nginx 설정:
# HTTP to HTTPS 리다이렉트
server {
listen 80;
server_name api.yourdomain.com;
return 301 https://$server_name$request_uri;
}
# HTTPS 서버 블록
server {
listen 443 ssl;
server_name api.yourdomain.com;
# SSL 인증서 설정
ssl_certificate /etc/letsencrypt/live/api.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.yourdomain.com/privkey.pem;
# 리버스 프록시 설정
location / {
proxy_pass http://localhost: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;
}
}
# 설정 파일 활성화
sudo ln -s /etc/nginx/sites-available/api.yourdomain.com /etc/nginx/sites-enabled/
# 기본 설정 비활성화 (포트 충돌 방지)
sudo rm /etc/nginx/sites-enabled/default
# nginx 설정 문법 테스트
sudo nginx -t
# nginx 재시작
sudo systemctl restart nginx
nginx 설정 각 부분 설명:
server {
listen 80;
server_name api.yourdomain.com;
return 301 https://$server_name$request_uri;
}
proxy_set_header Host $host; # 원본 호스트명 전달
proxy_set_header X-Real-IP $remote_addr; # 클라이언트 실제 IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 프록시 체인
proxy_set_header X-Forwarded-Proto $scheme; # 원본 프로토콜 (https)
curl -I http://api.yourdomain.com

# 기본 엔드포인트
curl https://api.yourdomain.com/
curl https://api.yourdomain.com/hello
curl https://apo.yourdomain.com/sendMessage
# POST API 테스트
curl -X POST https://api.yourdomain.com/sendMessage \
-H "Content-Type: application/json" \
-d '{"message": "이력을 알려줘"}'
- 2018년 ~ 2019년: 이력
- 2020년 ~ 2025년: 이력
# 브라우저에서 확인
# https://api.yourdomain.com 접속 시 자물쇠 아이콘 확인
# 명령어로 확인
openssl s_client -connect api.yourdomain.com:443 -servername api.yourdomain.com

1️⃣ 사용자가 http://api.yourdomain.com 입력
↓
2️⃣ nginx:80 포트에서 요청 수신
↓
3️⃣ nginx 설정 적용:
server {
listen 80;
server_name api.yourdomain.com;
return 301 https://$server_name$request_uri;
}
↓
4️⃣ 301 리다이렉트 응답 전송
Location: https://api.yourdomain.com/
↓
5️⃣ 브라우저가 자동으로 HTTPS 요청
↓
6️⃣ nginx:443 포트에서 HTTPS 처리
↓
7️⃣ Flask 앱으로 프록시 전달 (localhost:5001)
https://...로 다시 접속하라고 안내| 포트 | 프로토콜 | 서비스 | 설명 | 보안 |
|---|---|---|---|---|
| 80 | HTTP | 웹 서버 | 일반 웹사이트, 암호화 없음 | ⚠️ 평문 |
| 443 | HTTPS | 보안 웹 서버 | SSL/TLS 암호화 웹사이트 | 🔒 암호화 |
| 8080 | HTTP | 웹 프록시/대체 | 개발용, 프록시 서버 | ⚠️ 평문 |
| 8443 | HTTPS | 보안 웹 대체 | 대체 HTTPS 포트 | 🔒 암호화 |
| 3000 | HTTP | 개발 서버 | React, Node.js 개발 서버 | ⚠️ 개발용 |
| 5000 | HTTP | Flask 기본 | Flask 개발 서버 기본값 | ⚠️ 개발용 |
| 포트 | 프로토콜 | 서비스 | 설명 | 플랫폼 |
|---|---|---|---|---|
| 22 | SSH | Secure Shell | 리눅스/유닉스 원격 접속 | 🐧 Linux/Mac |
| 3389 | RDP | Remote Desktop | Windows 원격 데스크톱 | 🪟 Windows |
| 5900 | VNC | Virtual Network Computing | 크로스플랫폼 원격 데스크톱 | 🌐 All |
| 23 | Telnet | Telnet | 구식 원격 접속 (비보안) | ⚠️ 사용 금지 |
| 포트 | 데이터베이스 | 설명 | 특징 |
|---|---|---|---|
| 3306 | MySQL/MariaDB | 관계형 데이터베이스 | 웹 개발 표준 |
| 5432 | PostgreSQL | 고급 관계형 DB | 기업용, 고성능 |
| 27017 | MongoDB | NoSQL 문서 DB | JSON 기반 |
| 6379 | Redis | 인메모리 캐시 | 세션, 캐싱용 |
| 1433 | SQL Server | Microsoft DB | Windows 환경 |
| 1521 | Oracle | 엔터프라이즈 DB | 대기업용 |
| 포트 | 프로토콜 | 용도 | 보안 | 설명 |
|---|---|---|---|---|
| 25 | SMTP | 메일 발송 | ⚠️ 평문 | 서버간 메일 전송 |
| 587 | SMTP | 메일 발송 | 🔒 TLS | 클라이언트 메일 발송 |
| 465 | SMTPS | 보안 메일 발송 | 🔒 SSL | 구식 보안 SMTP |
| 110 | POP3 | 메일 수신 | ⚠️ 평문 | 메일 다운로드 |
| 995 | POP3S | 보안 메일 수신 | 🔒 SSL | 보안 메일 다운로드 |
| 143 | IMAP | 메일 동기화 | ⚠️ 평문 | 서버 메일 관리 |
| 993 | IMAPS | 보안 메일 동기화 | 🔒 SSL | 보안 서버 메일 관리 |
| 포트 | 서비스 | 설명 |
|---|---|---|
| 25565 | Minecraft | 마인크래프트 서버 |
| 27015 | Steam | Steam 게임 서버 |
| 1935 | RTMP | 실시간 미디어 스트리밍 |
| 554 | RTSP | 실시간 스트리밍 프로토콜 |
| 포트 | 프로토콜 | 서비스 | 설명 |
|---|---|---|---|
| 53 | DNS | 도메인 네임 서버 | 도메인 → IP 변환 |
| 67/68 | DHCP | 동적 IP 할당 | 자동 IP 설정 |
| 21 | FTP | 파일 전송 | 파일 업로드/다운로드 |
| 990 | FTPS | 보안 파일 전송 | SSL 암호화 FTP |
| 161 | SNMP | 네트워크 관리 | 장비 모니터링 |
| 포트 | 위험도 | 이유 | 대응방안 |
|---|---|---|---|
| 23 | 🔴 높음 | Telnet 평문 전송 | SSH(22) 사용 |
| 21 | 🟡 중간 | FTP 평문 전송 | SFTP/FTPS 사용 |
| 135-139 | 🔴 높음 | Windows 공유 | 방화벽 차단 |
| 445 | 🔴 높음 | SMB 취약점 | 외부 접근 차단 |
증상: 도메인으로 접속이 안됨
해결:
# DNS 전파 상태 확인
dig @8.8.8.8 A api.yourdomain.com
dig @ns1.gabia.co.kr A api.yourdomain.com
# 임시로 hosts 파일 수정 (테스트용)
echo "YOUR_ELASTIC_IP api.yourdomain.com" | sudo tee -a /etc/hosts
# 진짜 제대로 배포 되었는지 확인 필요
# 해당 문제는 도메인에 임시로 걸어둔 사설 IP주소 문제로 추청되어 현재 수정 중에 있음
증상: HTTPS 접속 시 보안 경고
해결:
# 인증서 상태 확인
sudo openssl x509 -in /etc/letsencrypt/live/api.yourdomain.com/fullchain.pem -text -noout
# 인증서 갱신
sudo certbot renew --dry-run
증상: nginx는 동작하지만 Flask 앱 연결 안됨
해결:
# Flask 서비스 상태 확인
sudo systemctl status flask-app
sudo journalctl -u flask-app -f
# Flask 앱 직접 테스트
curl http://localhost:5001
# 서비스 재시작
sudo systemctl restart flask-app
# 전체 서비스 상태 확인
sudo systemctl status nginx flask-app
# 포트 사용 현황
sudo netstat -tlnp | grep -E ":80|:443|:5001"
# 실시간 로그 확인
sudo tail -f /var/log/nginx/access.log
sudo journalctl -u flask-app -f
# SSL 인증서 만료일 확인
sudo openssl x509 -in /etc/letsencrypt/live/api.yourdomain.com/fullchain.pem -noout -dates