서비스를 도메인에 연결하고 SSL
설정값을 추가하는 내용을 정리해 보겠습니다.
서버 문제발생 - 해결필요
Ubuntu 22.04 업데이트 진행 중 시스템 기본값을 유지하면서 업데이트를 진행 했어야 하는데, 무리하게 업데이트를 진행함으로 인하여 서비스에 문제가 발생하여 외부 접속이 안되는 상황이 발생하였습니다.
$ mokutil --sb-state
disable
## UEFI BIOS에서 Secure Boot를 비활성화하는 방법:
## 시스템 재부팅
## 부팅 시 BIOS/UEFI 설정 진입 (일반적으로 F2, F12, DEL, ESC 키)
## Secure Boot 옵션을 찾아 "Disabled"로 변경
# 변경 사항 저장 후 시스템 재부팅
# 다시 패키지 설치 시도:
$ sudo dpkg --configure -a
$ sudo apt-get install -f
# 이제 shim-signed 패키지가 정상적으로 설치될 가능성이 높습니다.
Install
Certbot 3
우분투 기본제공 패키지를 활용하면 Certbot 1.21
을 설치 합니다.
$ sudo apt update
$ sudo apt install certbot python3-certbot-nginx -y
$ certbot --version
ImportError: cannot import name 'appengine' from 'urllib3.contrib'
(/home/username/.local/lib/python3.10/site-packages/urllib3/contrib/__init__.py)
$ pip install "urllib3<1.26"
$ certbot --version
certbot 1.21.0
1.21
버젼은 Nov 4, 2021
에 작성된 것으로 여러가지 문제가 발생할 수 있습니다. Certbot Github 를 보면 업데이트가 활발하게 진행되고 있고, 2025년 3월 현재 최신버젼으로는 certbot 3.2.0 을 제공하고 있습니다. Certbot Instructions 문서에 작성한 대로 snap
을 활용하여 설치를 진행합니다.
# 작업을 진행하기 전에 기존 `Certbot`을 제거 합니다
sudo apt remove certbot -y
sudo apt autoremove -y
# Snapd 패키지 설치 (최신 Certbot을 위해 필요)**
sudo apt update
sudo apt install snapd -y
# Certbot 최신 버전 설치**
sudo snap install core; sudo snap refresh core
sudo snap install --classic certbot
# 심볼릭 링크 설정 (snap -> apt)
sudo ln -s /snap/bin/certbot /usr/bin/certbot
certbot --version
certbot 3.2.0
Nginx
현재 서버에는 MariaDB 11.4 LTS
를 설치 하였습니다. `djang
sudo apt update sudo apt install system76-driver-nvidia sudo apt install nvidia-cuda-toolkit
🔹 1-5. Certbot 버전 확인
certbot --version
출력 예시:
certbot 2.11.0
✅ 2. Nginx 설정 확인
Certbot이 자동으로 SSL 설정을 적용하려면, Nginx가 올바르게 설정되어 있어야 합니다.
🔹 2-1. Nginx 설치 및 실행 여부 확인
sudo apt install nginx -y
sudo systemctl status nginx
Nginx가 실행되지 않았다면:
sudo systemctl start nginx
sudo systemctl enable nginx
🔹 2-2. Nginx 서버 블록 설정 확인
Nginx의 기본 설정 파일(/etc/nginx/sites-available/default
또는 /etc/nginx/sites-available/yourdomain
)을 열어 도메인이 올바르게 설정되어 있는지 확인하세요.
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
location / {
proxy_pass http://127.0.0.1:8000; # Django, Flask 등 백엔드 서버
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
설정을 수정했다면 Nginx를 다시 로드하세요.
sudo nginx -t # 설정 확인
sudo systemctl reload nginx
✅ 3. Certbot을 이용한 SSL 인증서 발급
이제 Let’s Encrypt에서 SSL 인증서를 발급받고 자동 설정을 적용합니다.
🔹 3-1. SSL 인증서 발급 및 자동 적용
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
🔹 3-2. 과정 중 입력 사항
- 이메일 입력
- 이용 약관 동의 (
A
입력) - HTTP → HTTPS 강제 리디렉션 여부 선택
- 1번: HTTPS로 자동 리디렉트 (권장)
- 2번: HTTP와 HTTPS 둘 다 유지
이제 Certbot이 자동으로 SSL 인증서를 적용하며, /etc/nginx/sites-available/yourdomain
파일이 업데이트됩니다.
✅ 4. Nginx 설정 확인
Certbot이 적용한 Nginx 설정을 확인합니다.
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
return 301 https://$host$request_uri; # HTTP → HTTPS 리디렉트
}
server {
listen 443 ssl;
server_name yourdomain.com www.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
🔹 4-1. 설정 파일 테스트 후 적용
sudo nginx -t # 설정 파일 검증
sudo systemctl reload nginx # 설정 반영
✅ 5. SSL 인증서 자동 갱신 설정
Let’s Encrypt 인증서는 90일마다 갱신해야 합니다. Certbot은 자동 갱신을 설정할 수 있습니다.
🔹 5-1. 갱신 테스트
sudo certbot renew --dry-run
✅ 정상적으로 실행되면 자동 갱신이 설정된 것입니다.
🔹 5-2. 갱신 크론잡 확인
Certbot은 자동으로 /etc/cron.d/certbot
에 갱신 작업을 추가합니다. 확인하려면:
sudo systemctl list-timers | grep certbot
만약 자동 갱신을 수동으로 설정하고 싶다면, crontab
을 수정합니다.
sudo crontab -e
그리고 다음 줄을 추가합니다.
0 3 * * * certbot renew --quiet && systemctl reload nginx
✅ 이제 SSL 인증서가 자동으로 갱신됩니다!
✅ 6. 문제 해결
❌ 문제 1: “certbot: command not found”
🔹 해결 방법:
sudo ln -s /snap/bin/certbot /usr/bin/certbot
❌ 문제 2: “Could not bind to IPv4 or IPv6”
🔹 원인: Nginx가 80 포트를 사용 중이어서 Certbot이 인증 실패
🔹 해결 방법:
sudo systemctl stop nginx
sudo certbot certonly --standalone -d yourdomain.com -d www.yourdomain.com
sudo systemctl start nginx
❌ 문제 3: 인증서가 만료되었는데 자동 갱신이 안 됨
🔹 해결 방법:
sudo certbot renew --force-renewal
sudo systemctl reload nginx
🎯 최종 정리
✅ 1. Certbot 2.11 설치
✅ 2. Nginx 설정 확인
✅ 3. Certbot으로 SSL 인증서 발급 및 자동 적용
✅ 4. Nginx 설정 확인 및 재시작
✅ 5. SSL 인증서 자동 갱신 설정
✅ 6. 문제 발생 시 해결 방법 적용
이제 Ubuntu + Nginx에서 무료 SSL 인증서를 사용하여 HTTPS를 안전하게 운영할 수 있습니다! 🚀
CertBot 1.21
certbot 은 Python 으로 작성되어 있어서, 이를 실행하기 위한 Python 실행파일 및 패키지는 /home/username/.local/lib/python3.10/
에 설치되어 있는 것을 활용하는 것을 확일할 수 있습니다.
$ sudo apt update
$ sudo apt install certbot python3-certbot-nginx -y
$ certbot --version
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/requests_toolbelt/_compat.py", line 48, in <module>
from requests.packages.urllib3.contrib import appengine as gaecontrib
ImportError: cannot import name 'appengine' from 'requests.packages.urllib3.contrib'
(/home/username/.local/lib/python3.10/site-packages/urllib3/contrib/__init__.py)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
...
File "/usr/lib/python3/dist-packages/requests_toolbelt/adapters/ssl.py", line 16, in <module>
from .._compat import poolmanager
File "/usr/lib/python3/dist-packages/requests_toolbelt/_compat.py", line 50, in <module>
from urllib3.contrib import appengine as gaecontrib
ImportError: cannot import name 'appengine' from 'urllib3.contrib'
(/home/username/.local/lib/python3.10/site-packages/urllib3/contrib/__init__.py)
위 오류는 urllib3
패키지를 다운그레이드 해 줌으로써 해결 가능합니다. pip install "urllib3<1.26"
실행하면 오류가 해결되는 것을 확인 할 수 있습니다.
$ certbot --version
certbot 1.21.0
인증서 발급받기
Django 에서 ORM 문법을 활용하여 데이터를 호출하는 때에 초보자가 혼동하는 부분이 .first()
와 .last()
입니다. 데이터 베이스에 가장 최근에 저장된 내용이 .first()
이고, 저장한지 오래된 자료가 .last()
메서드를 활용하여 호출 하면 됩니다.
In [1]: from app_news.models import NewsList
: NewsList.objects.first()
: NewsList.objects.order_by('-pk')[0]
Out[1]: (id:20) <NewsList: [경제] 해수부, 항만건설사업 BIM 적용지침 마련…"기술도입 활성화 기대">
In [2]: NewsList.objects.last()
: NewsList.objects.order_by('pk')[0]
Out[2]: (id:1) <NewsList: '매각 중단' 홈플러스익스프레스, 유동성 확보에 힘 보탤까>
`Datetime
# models.py
from django.db import models
class Post(models.Model):
datetime = models.DateTimeField()
# `Datetime` 필드를 특정 날짜로 필터링
from myapp.models import Post
filtered_data = Post.objects.filter(datetime__date=target_date)