이전에 fe할때는 AWS에서 도메인을 구매하고 route 54과 ACM, ALB을 이용해서 배포 했는데 nginx로 하는 방법을 훑어보니 훨씬 쉬웠다.
뭔가 블로그들이 다 쉬운걸 어렵게 설명한 느낌이 있어서 내가직접 쉽게 할 수 있도록 작성해보자 해서 이렇게 작성중입니다.
만약 이러한 과정이 처음이라면 아래 접은 글을 확인해주세요.
웹 서버 나라에 Nginx라는 친절한 경비병이 살고 있었습니다. Nginx 경비병은 여러 웹사이트 마을을 안전하게 지키는 역할을 맡고 있었어요.
어느 날, 웹사이트 마을 사람들은 인터넷 강도들이 가로챌 수 없는 안전한 통신을 원하게 되었습니다. 그래서 마을 사람들은 Nginx 경비병에게 안전한 HTTPS 보호막을 만들어 달라고 요청했습니다.
Nginx 경비병은 HTTPS 보호막을 만드는 데 필요한 중요한 세 가지를 알고 있었습니다: 열쇠, 인증서, 그리고 비밀 메시지. 이제 Nginx 경비병이 어떻게 HTTPS 보호막을 만드는지 살펴볼까요?
1. 열쇠와 인증서 만들기
먼저 Nginx 경비병은 마법 열쇠 상자를 만들어야 했습니다. 이 상자는 두 개의 열쇠를 가지고 있었는데, 하나는 비밀 열쇠(private key)이고, 다른 하나는 공개 열쇠(public key)였습니다.
- 비밀 열쇠: Nginx 경비병만 알고 있는 비밀.
- 공개 열쇠: 누구에게나 알려줄 수 있는 열쇠.
이제 Nginx 경비병은 이 열쇠들을 가지고 인증서(authority) 마법사를 찾아갔습니다. 인증서 마법사는 Nginx 경비병의 열쇠를 확인하고, "이 열쇠들은 안전합니다!"라는 인증서를 발급해 주었습니다.
2. Nginx 경비병의 준비 작업
Nginx 경비병은 마법 열쇠와 인증서를 웹사이트 마을의 안전한 저장소에 보관했습니다. 이 저장소는 /etc/nginx/ssl이라는 특별한 장소에 있었어요. 그런 다음, Nginx 경비병은 마법 책(nginx 설정 파일)을 열어 다음과 같이 썼습니다
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/nginx/ssl/certificate.crt;
ssl_certificate_key /etc/nginx/ssl/private.key;
location / {
proxy_pass http://localhost:8080;
}
}
이렇게 설정하면, 모든 방문자는 자동으로 안전한 HTTPS 보호막을 통해 웹사이트 마을에 접근하게 됩니다.
3. HTTPS 보호막의 작동 방식
이제 모든 것이 준비되었습니다. 웹사이트 방문자가 Nginx 경비병에게 다가오면, Nginx 경비병은 다음과 같이 행동합니다:
- 방문자가 웹사이트 마을에 오려고 합니다.
- Nginx 경비병은 방문자에게 "공개 열쇠"를 줍니다.
- 방문자는 공개 열쇠를 사용하여 자신만의 비밀 메시지를 암호화합니다.
- Nginx 경비병은 자신의 비밀 열쇠를 사용하여 그 메시지를 해독합니다.
- 이렇게 하면 방문자와 Nginx 경비병 사이의 통신이 안전하게 보호됩니다.
결국 웹사이트 마을은 안전하게 보호되었고, 사람들은 안심하고 인터넷을 사용할 수 있게 되었습니다. 그리고 Nginx 경비병 덕분에 모든 통신이 안전하게 이루어졌답니다.
전체적인 흐름은 아래와 같습니다.
1. nginx 설치
2. certbot(SSL/TLS 인증서 발급 도와주는 곳) 설치 및 ssl 인증서 발급
3. nginx 설정 파일 업데이트(우리가 구매한 도메인이 무엇인지 알려줘야 함)
❓ certbot이란?
Certbot은 Let's Encrypt(스폰서 : 마이크로소프트, aws, meta 등등)에서 제공하는 무료 오픈 소스 소프트웨어 도구로, 웹사이트에 SSL/TLS 인증서를 발급하고 자동으로 갱신해주는 역할을 합니다. 이를 통해 웹사이트와 방문자 간의 통신을 암호화하여 안전하게 만들 수 있습니다. Certbot은 다양한 웹 서버와 통합할 수 있으며, 주로 Apache와 Nginx에서 많이 사용됩니다.
여러분의 도메인이 kfc.com이라고 가정을 해봅시다.
📌방법1: 호스트서버에서 NGINX 직접 설정
아래는 바로 AL2023 (아마존 서버에) 설치하는 방법입니다.
1️⃣ NGINX 설치
sudo dnf install nginx -y
sudo systemctl start nginx
sudo systemctl enable nginx
(-y 옵션을 추가하면 사용자의 수동 입력 없이 모든 질문에 자동으로 'Yes'로 응답하여 설치를 진행)
만약 set the server_name directive to ... 에러가 발생한다면?

어렵지 않습니다. 그냥 설정 파일만 일부 수정하면 됩니다.
1. nginx 설정 파일 열기
sudo nano /etc/nginx/nginx.conf
2. http 블록에 server_names_hash_bucket_size 추가
http {
server_names_hash_bucket_size 64;
# 기타 설정들
include /etc/nginx/conf.d/*.conf;
...
}
만약 이렇게 해도 에러가 발생한다면 64가아니라 128로 설정해보세요.
https://nginx.org/en/docs/http/server_names.html#optimization
2️⃣ Certbot 설치 및 SSL 인증서 발급
sudo dnf install certbot -y // 1. certbot 설치
sudo dnf install python3-certbot-nginx -y // certbot Nginx 플러그인 설치
sudo certbot --nginx -d kfc.com -d www.kfc.com // certbot 실행
1. 이메일 입력(인증서 갱신일 안내 메일)
2. 서비스 약관 동의
3. 이메일 공유 여부
4. HTTP 접근을 HTTPS로 리다이렉트 시킬지 여부
3️⃣ NGINX 설정 파일 업데이트
sudo nano /etc/nginx/conf.d/kfc.com.conf
❗️ 경로를 위와같이 한 이유는 글 맨 아래쪽에 설명되어있습니다.
당황하지 말자 설정 파일 업데이트는 절대 어렵지 않다.
아래처럼 해주면 됩니다.
❗️전부 복사 금지 kfc.com에 여러분 도메인을 넣어주세요
server {
listen 80;
server_name kfc.com www.kfc.com;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name kfc.store www.kfc.store;
ssl_certificate /etc/letsencrypt/live/kfc.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/kfc.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
proxy_pass http://localhost:8080;
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;
}
}
4️⃣ NGINX 설정 테스트 및 재시작
sudo nginx -t
sudo systemctl restart nginx
📌 방법 2 : Docker에서 NGINX 설정
1️⃣ NGINX Dockerfile 작성
프로젝트 디렉토리에 nginx 폴더를 생성하고, 그 안에 Dockerfile과 설정 파일을 작성합니다.
❗️전부 복사 금지 kfc.com에 여러분 도메인을 넣어주세요
nginx/Dockerfile
FROM nginx:latest
COPY ./kfc.com.conf /etc/nginx/conf.d/kfc.com.conf
COPY /path/to/your/fullchain.pem /etc/letsencrypt/live/kfc.com/fullchain.pem
COPY /path/to/your/privkey.pem /etc/letsencrypt/live/kfc.com/privkey.pem
COPY /path/to/your/options-ssl-nginx.conf /etc/letsencrypt/options-ssl-nginx.conf
COPY /path/to/your/ssl-dhparams.pem /etc/letsencrypt/ssl-dhparams.pem
EXPOSE 80 443
❗️전부 복사 금지 kfc.com에 여러분 도메인을 넣어주세요
server {
listen 80;
server_name kfc.com www.kfc.com;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name kfc.com www.kfc.com;
ssl_certificate /etc/letsencrypt/live/kfc.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/kfc.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
proxy_pass http://여러분도커이미지이름:8080;
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;
}
}
2️⃣ Docker compose 파일 작성
version: '3'
services:
여러분 도커 이미지 이름:
image: 767398038771.dkr.ecr.ap-northeast-2.amazonaws.com/여러분 도커 이미지 이름:latest
container_name: 여러분 도커 이미지 이름
ports:
- "8080:8080"
nginx:
build:
context: ./nginx
container_name: nginx
ports:
- "80:80"
- "443:443"
depends_on:
- 여러분 도커 이미지 이름
📌 nginx conf 경로
상당수 블로그에서 nginx.conf에 바로 설정하도록 알려주고 있습니다.
물론 이 방법이 틀렸다는 것은 절대 아닙니다.
다른 방법도 있다는 것을 알려드리고자 합니다.
nginx.conf는 설정 파일을 개별적으로 관리할 수 있습니다.
예를 들면 아래와 같습니다.
- nginx.conf: 서버 전체에 대한 글로벌 설정을 포함.
- /etc/nginx/conf.d/default.conf: 기본 서버 블록 설정.
- /etc/nginx/conf.d/example.com.conf: example.com 도메인에 대한 설정.
- /etc/nginx/conf.d/another-site.conf: 또 다른 사이트에 대한 설정
이렇게 할 수 있는 이유는 `sudo cat /etc/nginx/nginx.conf`를 해보시고 위로 조금 올리다보면 http 안쪽에 include가 보입니다.
그곳을 자세히 보면 `/etc/nginx/conf.d/*.conf;` 로 설정되어있기에 `/etc/nginx/conf.d/` 디렉터리에 있는 모든 `.conf`파일을 포함기 때문입니다.
이렇게 하면 각 사이트나 애플리케이션의 설정을 개별적으로 관리하면서, 서버 전체의 글로벌 설정은 별도로 관리할 수 있습니다.
👍 장점
1. 유지보수의 편리성
- nginx.conf 파일은 서버의 글로벌 설정을 관리합니다. 이는 워커 프로세스, 글로벌 로그 설정, 그리고 서버 전체에 영향을 미치는 다른 중요한 설정들을 포함합니다.
- /etc/nginx/conf.d/ 디렉토리 내의 개별 설정 파일들(예: atrserver.store.conf)은 각기 다른 도메인이나 애플리케이션의 설정을 개별 파일로 관리합니다. 이렇게 하면 특정 사이트나 애플리케이션의 설정을 수정할 때 전체 nginx.conf 파일을 수정할 필요가 없어져서 유지보수가 용이합니다.
2. 구조화된 관리
- 여러 개의 사이트나 애플리케이션을 운영할 경우, 각각의 설정을 별도의 파일로 관리하면 구조화된 형태로 설정을 관리할 수 있습니다. 이는 설정의 가독성을 높이고, 설정 충돌을 방지하는 데 도움이 됩니다.
- 예를 들어, 여러 개의 가상 호스트를 운영할 경우, 각 호스트에 대한 설정을 별도의 파일로 분리하면 특정 호스트의 설정을 쉽게 찾고 수정할 수 있습니다.
3. 자동화와 배포
- CI/CD(지속적 통합/지속적 배포) 파이프라인을 통해 설정 파일을 자동화된 방식으로 배포할 때, 개별 설정 파일을 사용하면 특정 설정만 변경하여 배포할 수 있어 효율적입니다.
- 설정 파일을 템플릿화하여 사용하는 경우에도, 각 설정 파일을 개별적으로 관리하는 것이 더 쉽습니다.
📌 자동 갱신
let's encrypt에서 발급하는 인증서는 유효기간이 3개월이기 때문에 주기적으로 갱신을 해주어야 합니다.
이때 우리는 `crontab`을 활용해서 매월 1일에 인증서를 갱신해줄 수 있습니다.
인증서 만료일 확인 : sudo certbot certificates
인증서 갱신 : sudo certbot renew
인증서 갱신 테스트 : sudo certbot renew --dry-run
❓ crontab
Crontab은 유닉스 계열 운영 체제에서 시간 기반 작업 스케줄러인 cron을 설정하고 관리하는 파일입니다.
이를 통해 정기적으로 실행해야 하는 명령어나 스크립트를 자동화할 수 있습니다.
📌 Crontab 기본 개념
1. crontab 파일 : crontab 파일은 cron 작업의 스케줄을 지정하는 텍스트 파일입니다. 각 사용자마다 별도의 crontab 파일이 있으며, 해당 사용자의 작업이 기록됩니다.
2. Crontab 명령어: crontab 명령어를 사용하여 crontab 파일을 관리합니다.
- crontab -e: 현재 사용자의 crontab 파일을 편집합니다.
- crontab -l: 현재 사용자의 crontab 파일을 출력합니다.
- crontab -r: 현재 사용자의 crontab 파일을 삭제합니다.
1️⃣ Certbot 설치
crontab파일을 수정하기 위해서는 먼저 cronie가 서버에 다운로드 되어있어야합니다.
cronie는 대부분의 Linux 배포판에 기본적으로 포함되어있지만 AL2023에는 포함되어있지 않아서 다운로드를 해야합니다.
만약 cronie가 다운되어있다면 3번부터 하시면 됩니다.
sudo dnf install cronie -y
2️⃣ cronie 서비스 시작 및 활성화
cronie 서비스를 시작하고 시스템 부팅 시 자동으로 시작되도록 설정합니다.
sudo systemctl start crond
sudo systemctl enable crond
3️⃣ crontab 설정
sudo crontab -e
편집기에서 다음 줄을 추가합니다
0 0 1 * * certbot renew --renew-hook="sudo systemctl restart nginx"
(매월 1일 0시에 인증서를 갱신)
💎참고
4️⃣ 갱신 확인
다음 명령어를 사용하여 Certbot이 자동 갱신 작업을 수행하는지 확인할 수 있습니다
sudo certbot renew --dry-run
이 명령어는 실제 갱신을 시도하지 않고 갱신이 제대로 작동하는지 테스트합니다.
📌 Reference
https://nginx.org/en/docs/http/server_names.html#optimization