서비스를 도메인에 연결하고 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. 과정 중 입력 사항

  1. 이메일 입력
  2. 이용 약관 동의 (A 입력)
  3. 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)


참고사이트