< Poprzedni Budowanie serwisu mucka.pro Następny >
25 Feb 2025

Certyfikat domeny

TLS jest ogólnie przyjętym standardem zapewniania poufności i integralności transmisji danych między serwerem a klientem. Kluczowym elementem tego protokołu jest certyfikat podpisany przez Urząd Certyfikacji (eng. CA). Urząd Certyfikacji to zwykle specialistyczna firma, uwierzytelniająca podmioty, którym podpisuje certyfikaty, pobierając za to dość spore opłaty. Na szczęście kilka lat temu powstał Let's Encrypt. Urząd Certyfikujący non-profit, który pozwala podpisać certyfikat naszej strony w sposób całkowicie automatyczny, w dodatku za darmo.

(Tłumaczenie Certificate Authority jako Urząd Certyfikujący brzmi trochę groteskowo moim zdaniem, ale takie się przyjęło)

Realizacja

Zaopatrzenie serwera nginx w certyfikat podpisany przez Let's Encrypt składa się z trzech etapów.

Przygotowanie serwera na autoryzację

Po pierwsze muszę poprawnie ustawić serwery DNS, tak aby zmiany zdążyły się spropagować na cały świat. Domyślny czas życia rekordu DNS to 86400 sekund - 1 dzień. Proces dodawania rekordów na serwerach DNS linode opisałem w notatce Instalacja domeny na serwerach DNS linode.

Muszę przygotować konfigurację nginxa na automatyczną autoryzację przez serwery Let's Encrypt.

Najpierw przygotowuję strukturę katalogów.

(root) $ mkdir /var/www/certbot
(root) $ mkdir /var/log/certbot

Serwer zostanie uwierzytelniony za pomocą endpointu .well-known/acme-challenge. Przygotowuję tymczasową konfigurację, przedstawioną na listingu 1. Przekierowuje wszelkie zapytania na endpoint /.well-known/acme-challenge do katalogu /var/www/certbot. Katalog powinien być domyślnie pusty.


server {
        server_name mucka.pro;
        listen 80;
        listen [::]:80;

        access_log /var/log/nginx/mucka_pro.access_log main;
        error_log /var/log/nginx/mucka_pro.error_log info;

        location ^~ /.well-known/acme-challenge {
                default_type "text/plain";
                root /var/www/certbot;
        }

        # Rest of configuration
}

  
Listing 1. Plik /etc/nginx/conf.d/mucka_pro.conf

Przeładowuję konfigurację nginxa.

(root) $ rc-service nginx reload

Generowanie i podpisywanie certyfikatu

Do generowania i automatycznego podpisywania certyfikatu służy biblioteka certbot. Instaluję ją z repozytorium gentoo.

(root) $ emerge -av certbot

Uruchamiam certbot jako argumenty podając nazwę domeny i przygotowany katalog.

(root) $ certbot certonly --webroot --agree-tos --email xxx@xxx.com --logs-dir /var/log/certbot --webroot-path /var/www/certbot/ --domain mucka.pro -n
Saving debug log to /var/log/certbot/letsencrypt.log
Requesting a certificate for mucka.pro

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/mucka.pro/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/mucka.pro/privkey.pem
This certificate expires on 2025-05-26.
These files will be updated when the certificate renews.

Plik konfiguracyjny potrzebny do odnowienia domeny zapisał się w /etc/letsencrypt/renewal/mucka.pro.conf.

Sam certyfikat zapisał się w katalogu /etc/letsencrypt/archive/mucka.pro/ ale my będziemy wykorzystywać linki symboliczne z katalogu /etc/letsencrypt/live/mucka.pro.

Przygotowanie serwera na pracę z certyfikatem

Posiadając podpisany certyfikat mogę skonfigurować nginx'a do szyfrowanej komunikacji. Nową konfigurację przedstawiłem na listingu 2. Połączenia nieszyfrowane (na port 80) przekierowuje na szyfrowane. Z wyjątkiem konfiguracji acme-challenge która będzie potrzebna do regularnego odnawiania certyfikatu.

Połączenia szyfrowane na port 433 traktuje tak jak wcześniej nieszyfrowane. Za pomocą dyrektyw ssl_certificate ustawiam ścieżki do wygenerowanych kluczy. Pozostała konfiguracja pozostaje bez zmian.


server {
        server_name mucka.pro;
        listen 80;
        listen [::]:80;

        location ^~ /.well-known/acme-challenge {
                default_type "text/plain";
                root /var/www/certbot;
        }

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

server {
        server_name mucka.pro;
        listen 443 ssl;
        listen [::]:443 ssl;

        access_log /var/log/nginx/mucka_pro.access_log main;
        error_log /var/log/nginx/mucka_pro.error_log info;

        ssl_certificate /etc/letsencrypt/live/mucka.pro/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/mucka.pro/privkey.pem;

        # Rest of configuration
}

  
Listing 2. Plik /etc/nginx/conf.d/mucka_pro.conf

Przeładowuję konfigurację nginxa.

(root) $ rc-service nginx reload

Serwer jest gotowy do pracy. Strona https://mucka.pro/ obsługuje szyfrowany ruch.

Odnawianie certyfikatu

Certyfikat Let's Encrypt jest ważny przez 90 dni. Powinien być odnawiany co 30 dni.

Aby zautomatyzować odnawianie certyfikatu umieszczę prosty skrypt w katalogu /etc/cron.monthly.

Umieszając zadanie w crontab ryzykował bym, że jeśli serwer nie będzie włączony na początku miesiąca, odnawianie domeny w danym miesiącu nie było by wykonane.

Anacron uruchomi zaległe zadanie przy następnym starcie systemu.


#!/usr/bin/env bash

/usr/bin/certbot renew --quiet
/usr/bin/logger "Certbot renew finished with status: $?"
/usr/sbin/rc-service nginx reload

  
Listing 3. Plik /etc/cron.monthly/certbot

Podsumowanie

Zapewnienie poufności i integralności treści w internecie jest obowiązkiem ich dostawcy. Żyjemy we wspaniałych czasach, w których jest to proste do implementacji.

release date: 25 Feb 2025
language: pl
stage: release
type: article
tags: nginx
< Poprzedni Budowanie serwisu mucka.pro Następny >