728x90

AWS Ec2 에 프로젝트를 배포하고 도메인을 연동한뒤 https 까지 추가하는 방법을 알아보겠습니다.

 

네트워크 지식이 부족한 탓에 굉장한 삽질을 했기에 글로 남겨두려고 합니다...

 

사전 준비물

  • AWS 계정
  • 도메인 (저는 Name cheap 에서 구매하였습니다)
  • 터미널
  • vim?!

 

인스턴스

 

프로젝트를 배포 할 수 있는 인스턴스가 하나 필요합니다 저는 테스트용으로 사용하려고 제일싼 프리티어로 만들었습니다.

생성까지 시간이 조금 걸려서 기다려주세요

 

생성 하실때 발급받은 pem 키를 꼭 중요한곳에 보관해주세요

pem 키가 있는 곳으로 이동하신뒤 

 

 

오른쪽 위에 연결(connect) 버튼을 눌러주세요

 

 

ssh -i 로 시작하는 걸 복사해주세요

 

chmod 400 나의pem파일.pem

chmod 로 pem 파일의 권한을 변경해준뒤

 

ssh -i "jongyunha_aws.pem" ec2-user@ec2-3-34-4-245.ap-northeast-2.compute.amazonaws.com

 

각자 복사하신 걸 터미널에 쳐주세요

 

 

정상적으로 ec2 에 접속했습니다.

 

EC2 에 docker 설치

도커 설치에 대한부분은 굉장히 도움많이 받은 블로그 링크 를 걸어 드리겠습니다.

https://megazonedsg.github.io/1-Make-Docker/

 

AWS EC2 인스턴스에 Docker 설치하기 [1/6]

1# AWS EC2 인스턴스에 Docker 설치하기

megazonedsg.github.io

 

Nginx 설정을 Docker 를 통해서 할 예정이고 Node , Java 같은 프로젝트를 Docker 를 통해서 배포할 예정이므로 이번 기회에 배워 두시는 것도 나쁘지않습니다

 

 

다음과 같이 docker compose, docker 버전이 잘나오신다면 정상적으로 설치 된것입니다.

 

도메인 구입하기

https://www.namecheap.com/

 

Buy a domain name - Register cheap domain names from $0.99 - Namecheap

At Namecheap, you can register brand new domain names using hundreds of popular TLDs. In our Marketplace, you will find thousands of domain names that have already been registered but are now for sale. While .com domains are available, of course, you'll al

www.namecheap.com

 

저는 Namecheap 에서 도메인을 구입해서 사용했는데요 기존에 사용하시던 도메인이 있으시다면 어떤곳에서 구입하시든 문제되지 않습니다.

 

 

아까 생성한 AWS 인스턴스의 퍼블릭 IPv4 주소를 복사해주신뒤 도메인 을 구입하신 곳에서 Record 를 추가해야합니다.

 

 

Type 은 A Record 로 해주세요

 

Host 에 @ 와 www 를 사용 했고 value 에는 방금 복사한 AWS 퍼블릭 IP 를 넣었습니다.

 

제가 구입한 도메인은 jongyun.org 인데 @ 와 www 는 jongyun.org , www.jongyun.org  를 사용하겠다는 의미입니다.

 

Nginx 설정

Nginx 설정을 관리하기 위해 ec2 에서 폴더를 하나 만들어주세요 개인이 구분하기 쉬운 폴더명으로 만들어주시면 되요

 

저는 test 로 만들었습니다.

 

docker-compose.yml

version: "3"

services:
  webserver:
    image: nginx:latest
    container_name: proxy 
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./myweb:/usr/share/nginx/html
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./certbot-etc:/etc/letsencrypt

  nginx:
    image: nginx:latest
    container_name: myweb
    restart: always
    volumes:
      - ./myweb:/usr/share/nginx/html

  certbot:
    depends_on:
      - webserver
    image: certbot/certbot
    container_name: certbot
    volumes:
      - ./certbot-etc:/etc/letsencrypt
      - ./myweb:/usr/share/nginx/html
    command: certonly --dry-run --webroot --webroot-path=/usr/share/nginx/html --email test@test.com --agree-tos --no-eff-email --keep-until-expiring -d jongyun.org -d www.jongyun.org

마지막 command 부분이 중요한대요 --dry-run 이라는 옵션을 빼고 실행하시게 되면 실패를 반복하게 되면 ssl 인증서를 너무많이 발급시도 하려고 해서 일정 시간이 지날때 까지 발급이 안되는 경우가 있습니다

 

그래서 dry run 옵션을 주시고 success 가 log 에 찍힐때 dry run 옵션을 빼고 인증서를 발급받습니다.

email 뒤에는 ssl 인증서를 잃어버렸을때 복구 받을 email 을 적어주시면 되고 뒤에는 구매한 도메인을 적어주시면 됩니다.

 

./nginx/nginx.conf

user nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" "$request_uri" "$uri"'
                      '"$http_user_agent" "$http_x_forwarded_for"';    
    access_log  /var/log/nginx/access.log  main;
    sendfile on;
    keepalive_timeout 65;

    upstream docker-web {
        server nginx:80;
    }

    server {
        location ~ /.well-known/acme-challenge {
                allow all;
                root /usr/share/nginx/html;
                try_files $uri =404;
        }

        location / {
                allow all;
                root /usr/share/nginx/html;
                try_files $uri =404;
        }
    }
}

 

저는 test/nginx/nginx.conf 로 경로가 되어있습니다 docker-compose.yml 은 test/docker-compose.yml 입니다

 

이렇게 파일을 설정하신뒤

docker-compose up -d

 

를 한뒤

docker logs certbot

 

하고 fail 문구가 아닌 success 문구가 뜨시면 정상적으로 인증서가 발급되신 걸 확인 할 수있습니다.

 

 

certbot-etc 라는 폴더가 생겼고

 

live 폴더 밑에 인증서가 들어있습니다.

live 폴더로 접근하기 위해서는 su 권한이 필요한대 

sudo passwd

명령어를 통해서 최초의 su 비밀번호를 만들어야 합니다.

만드신뒤 su 로 root 계정으로 변환한뒤 live 로 접속하시면 인증서를 볼 수 있습니다.

 

다시 certbot 폴더로 돌아오신뒤 ssl 보안을 강화에 필요한 파일 2가지를 curl 명령어를 통해 생성하겟습니다.

 

curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf > options-ssl-nginx.conf

curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot/certbot/ssl-dhparams.pem > ssl-dhparams.pem

 

options-ssl 파일과 ssl-dh 파일을 받아왔습니다.

 

HTTPS 설정하기 

기존에 nginx.conf 는 인증서 를 받기위한 테스트 였는데요 https 옵션을 추가해보겠습니다.

 

user nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" "$request_uri" "$uri"'
                      '"$http_user_agent" "$http_x_forwarded_for"';    
    access_log  /var/log/nginx/access.log  main;
    sendfile on;
    keepalive_timeout 65;

    upstream docker-web {
        server nginx:80;
    }

    server {
        listen 80;
        server_name jongyun.org www.jongyun.org;

        location ~ /.well-known/acme-challenge {
                allow all;
                root /usr/share/nginx/html;
                try_files $uri =404;
        }

        location / {
                return 301 https://$host$request_uri;
        }    
    }

    server {
        listen 443 ssl;
        server_name fun-coding.xyz www.fun-coding.xyz;
        
        ssl_certificate /etc/letsencrypt/live/jongyun.org/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/jongyun.org/privkey.pem;
        include /etc/letsencrypt/options-ssl-nginx.conf; # 보안 강화를 위한 옵션 추가
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;   # 보안 강화를 위한 옵션 추가

        location / {
            proxy_pass         http://13.00.00.00:8080; # AWS public ip + 프로젝트 포트
            proxy_redirect     off;                     # 서버 응답 헤더의 주소 변경 (불필요)
            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-Host $server_name;
	    proxy_set_header   X-Forwarded-Proto $scheme;
        }
    }
}

 

요기서 제일 중요한 부분은 location / {} 안에 있는 proxy_pass 입니다

저기서 저희가 배포한 프로젝트의 포트를 적어주시면 됩니다.

docker-compose down
docker system prune -a # 혹시나 몰라 모든 이미지 및 볼륨 날리기

docker-compose up -d

 

해당 인증서가 이미 발급되어서 새롭게 발급된 인증서가 없다고 나옵니다 정상적으로 실행 된 것입니다

 

 

현재 저는 스프링 서버를 8080 포트로 배포하였는데요 Nginx 에서 80 포트로 들어오게되면 443 https 로 리다이렉트 시키고 거기서 다시 내부적으로 8080 포트로 보내게 됩니다

 

 

jongyun.org 에 들에오게 되면 Https 로 들어오게 되고 정상적으로 ssl 인증서도 추가되었습니다.

 

추가적으로 현재 발급한 인증서는 90일마다 갱신해줘야하는 무료 인증서 입니다 

주기적으로 갱신하는것에 대한 글은 따로 적도록 하겠습니다

728x90