debian / ubuntu · linia poleceń

Szyfrowanie
od ręki, po konsoli.

Komplet komend do szyfrowania dysków, plików i kluczy w Debianie — LUKS/cryptsetup dla całych partycji, GPG dla pojedynczych plików, oraz kroki, żeby sprawdzić, czy naprawdę działa.

root@debian: ~
01 — Pełne szyfrowanie dysku

LUKS / cryptsetup

Standard szyfrowania blokowego w Linuksie. Szyfruje całą partycję — najlepsze rozwiązanie dla dysków systemowych, zewnętrznych nośników i backupów.

podstawa

Instalacja narzędzia

Pakiet cryptsetup obsługuje standard LUKS.

bash
sudo apt update && sudo apt install cryptsetup -y
nieodwracalne

Szyfrowanie partycji

Nadpisuje dane na /dev/sdX1 — rób to tylko na pustej partycji.

bash
sudo cryptsetup luksFormat /dev/sdX1
dostęp

Odblokowanie wolumenu

Tworzy zmapowane urządzenie pod /dev/mapper/.

bash
sudo cryptsetup luksOpen /dev/sdX1 sejf
system plików

Formatowanie i montowanie

Po otwarciu wolumenu zakładasz na nim zwykły system plików.

bash
sudo mkfs.ext4 /dev/mapper/sejf
sudo mount /dev/mapper/sejf /mnt/sejf
zamknięcie

Odmontowanie i zamknięcie

Zawsze zamykaj wolumen po odłączeniu nośnika.

bash
sudo umount /mnt/sejf
sudo cryptsetup luksClose sejf
klucze

Dodanie zapasowego hasła

LUKS wspiera do 8 slotów kluczy — warto mieć zapasowy.

bash
sudo cryptsetup luksAddKey /dev/sdX1
02 — Pojedyncze pliki

Szyfrowanie GPG

Gdy nie potrzebujesz szyfrować całego dysku — GPG szyfruje pojedyncze pliki, symetrycznie (hasłem) albo asymetrycznie (kluczem publicznym).

hasło

Szyfrowanie symetryczne

Najprostsza metoda — plik chroniony jednym hasłem.

bash
gpg -c dokument.pdf # tworzy dokument.pdf.gpg
odszyfrowanie

Otwieranie pliku .gpg

Poprosi o hasło ustawione przy szyfrowaniu.

bash
gpg -d dokument.pdf.gpg > dokument.pdf
para kluczy

Generowanie klucza GPG

Kreator poprowadzi Cię przez wybór typu i długości klucza.

bash
gpg --full-generate-key
klucz publiczny

Szyfrowanie dla odbiorcy

Do odszyfrowania będzie potrzebny klucz prywatny odbiorcy.

bash
gpg -e -r odbiorca@przyklad.pl dokument.pdf
lista

Twoje klucze

Podgląd wszystkich kluczy w Twoim pęku (keyring).

bash
gpg --list-secret-keys --keyid-format LONG
eksport

Backup klucza prywatnego

Zapisz w bezpiecznym miejscu, offline — to jedyna kopia.

bash
gpg --export-secret-keys -a TWOJ_ID > backup-klucza.asc
na wypadek utraty

Certyfikat unieważnienia

Wygeneruj od razu po utworzeniu klucza — pozwala go unieważnić, jeśli zgubisz klucz prywatny.

bash
gpg --gen-revoke TWOJ_ID > cert-uniewaznienia.asc
częsty błąd

Szyfruj też do siebie

Bez tego zaszyfrujesz plik dla kogoś innego i sam go już nie odczytasz.

bash
gpg -e -r odbiorca@przyklad.pl -r twoj@email.pl dokument.pdf
03 — Dostęp zdalny

Klucze SSH

Klucz prywatny sam w sobie powinien być zaszyfrowany hasłem (passphrase) — na wypadek, gdyby ktoś dostał się do Twojego dysku.

generowanie

Nowy klucz Ed25519

Nowoczesny, szybki i bezpieczny algorytm — zalecany domyślnie.

bash
ssh-keygen -t ed25519 -C 'twoj@email.pl'
hasło do klucza

Zmiana passphrase

Dodaje lub zmienia hasło chroniące istniejący klucz prywatny.

bash
ssh-keygen -p -f ~/.ssh/id_ed25519
wygoda

Agent kluczy

Wpisujesz hasło raz na sesję, zamiast przy każdym połączeniu.

bash
eval $(ssh-agent -s)
ssh-add ~/.ssh/id_ed25519
04 — Katalog domowy

Szyfrowanie /home

Jeśli nie chcesz szyfrować całego dysku, możesz zaszyfrować tylko wybrany katalog domowy przy pomocy eCryptfs — bez ponownej instalacji systemu.

instalacja

Narzędzia eCryptfs

Pakiet potrzebny do obsługi zaszyfrowanego katalogu.

bash
sudo apt install ecryptfs-utils -y
nowy użytkownik

Konto z zaszyfrowanym /home

Najczystszy sposób — od razu przy zakładaniu konta.

bash
sudo adduser --encrypt-home nowyuser
prywatny folder

Zaszyfrowany folder Private

Migruje wybrane dane istniejącego użytkownika do sejfu eCryptfs.

bash
ecryptfs-setup-private
!

Zanim zaczniesz szyfrować cokolwiek produkcyjnie

Zrób kopię zapasową danych poza szyfrowanym nośnikiem. Zgubione hasło lub uszkodzony nagłówek LUKS (LUKS header) oznacza dane nie do odzyskania — nie ma "resetu hasła" w kryptografii. Backup nagłówka: cryptsetup luksHeaderBackup /dev/sdX1 --header-backup-file naglowek.img.

06 — Detale, które łatwo pominąć

To, o czym zapominamy

Zaszyfrowany dysk główny nic nie da, jeśli swap albo kasowane pliki zostawiają dane w czystej postaci gdzie indziej.

wyciek przez RAM

Szyfrowanie swapa

Losowy klucz generowany przy każdym starcie — swap i tak jest tylko tymczasowy.

bash — /etc/crypttab
swap /dev/sdX2 /dev/urandom swap,cipher=aes-xts-plain64,size=256
wygoda vs bezpieczeństwo

Auto-odblokowanie LUKS przy starcie

Keyfile w initramfs pozwala pominąć ręczne hasło — ale tylko jeśli dysk z keyfile też jest bezpieczny.

bash
sudo dd if=/dev/urandom of=/root/klucz.key bs=512 count=4
sudo cryptsetup luksAddKey /dev/sdX1 /root/klucz.key
echo 'sejf /dev/sdX1 /root/klucz.key luks' | sudo tee -a /etc/crypttab
kasowanie danych

Bezpieczne usuwanie plików

rm tylko odpina wskaźnik — dane fizycznie zostają na dysku, dopóki nie zostaną nadpisane.

bash
shred -u -z -n 3 plik-tajny.txt
i

Dyski SSD — shred to za mało

Na SSD, przez wear-levelling kontrolera, shred nie gwarantuje nadpisania fizycznych komórek. Dla SSD lepszym rozwiązaniem jest blkdiscard (TRIM całego urządzenia) albo szyfrowanie od początku — wtedy usunięcie klucza LUKS wystarcza, żeby dane stały się nieczytelne.

05 — Kontrola

Czy to naprawdę działa?

Krótka checklista, żeby upewnić się, że szyfrowanie faktycznie jest aktywne, zanim zaufasz mu ważne dane.

bash — weryfikacja
sudo cryptsetup isLuks /dev/sdX1 && echo 'To jest LUKS'
# mapowanie /dev/sdX1 na TYPE="crypto_LUKS"
lsblk -f
sudo cryptsetup status sejf
# cipher: aes-xts-plain64, keysize: 512 bits
file dokument.pdf.gpg
dokument.pdf.gpg: PGP RSA encrypted session key
07 — Zanim Certbot zadziała

DNS od zera

Certbot pobierze certyfikat SSL tylko wtedy, gdy domena naprawdę wskazuje na Twój serwer. Bez poprawnego DNS-u każda próba certbot --apache skończy się błędem.

analogia
Domena      = nazwa domu
DNS         = tablica adresowa
IP serwera  = dokładny adres domu

twojadomena.pl  -->  123.123.123.123

# ktoś wpisuje https://twojadomena.pl
# DNS mówi: "idź na serwer 123.123.123.123"
Jak wygląda strefa DNS

Docelowa tabelka

strefa dns
Typ     Nazwa       Wartość
────────────────────────────────
A       @           185.50.20.10
A       www         185.50.20.10
z komputera

Sprawdzenie DNS — Windows

Pokazuje, na jakie IP obecnie wskazuje domena.

cmd
nslookup twojadomena.pl
z komputera

Sprawdzenie DNS — Linux/macOS

Bardziej szczegółowy odpowiednik nslookup.

bash
dig twojadomena.pl
z serwera

Test z poziomu VPS

Jeśli odpowiedź pokazuje IP Twojego serwera — DNS działa poprawnie.

bash
ping twojadomena.pl
dopiero teraz

Uruchomienie Certbota

Certbot pyta DNS, sprawdza odpowiedź serwera i dopiero potem wydaje certyfikat.

bash
sudo certbot --apache
!

Najczęstsze błędy DNS, przez które Certbot nie przechodzi

Stare IP — rekord A @ wskazuje na inny adres niż aktualny serwer.
Brak rekordu www — domena główna działa, ale www.twojadomena.pl już nie.
Zamknięty port 80 — Certbot musi dostać się przez http://twojadomena.pl/.well-known/acme-challenge/, więc port 80 musi być otwarty.

08 — Brakujące ogniwo

Apache musi wiedzieć, co obsłużyć

DNS wskazuje na serwer, ale to Apache decyduje, którą stronę pokazać dla danej domeny. Bez poprawnego VirtualHost, Certbot nie znajdzie czego szukać — a strona i tak się nie wyświetli.

konfiguracja

Plik VirtualHost

Tworzysz plik konfiguracyjny dla domeny w katalogu sites-available.

bash
sudo nano /etc/apache2/sites-available/twojadomena.pl.conf
zawartość pliku

Minimalny VirtualHost

ServerName i ServerAlias to właśnie te domeny, które Certbot później zapyta.

apache
<VirtualHost *:80>
    ServerName twojadomena.pl
    ServerAlias www.twojadomena.pl
    DocumentRoot /var/www/twojadomena.pl
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
aktywacja

Włączenie strony

a2ensite tworzy dowiązanie symboliczne do sites-enabled.

bash
sudo a2ensite twojadomena.pl.conf
sudo apache2ctl configtest
sudo systemctl reload apache2
bez tego nic nie wejdzie

Firewall — porty 80 i 443

Certbot łączy się przez port 80, a docelowa strona przez 443 (HTTPS).

bash
sudo ufw allow 'Apache Full'
sudo ufw status
subdomeny

CNAME zamiast kolejnego A

Dla subdomen (np. sklep.twojadomena.pl) zwykle wygodniej wskazać na domenę główną niż dublować adres IP.

strefa dns
CNAME   sklep   twojadomena.pl.
globalna propagacja

Sprawdzenie z zewnątrz

Lokalny dig może pokazywać cache — warto zerknąć też z innego miejsca na świecie.

przeglądarka
whatsmydns.net # wpisujesz domenę, patrzysz na wynik z wielu krajów
!

Kolejność ma znaczenie

Certbot poprawnie zadziała tylko w tej kolejności: 1) DNS wskazuje na serwer → 2) VirtualHost istnieje i jest włączony (a2ensite) → 3) port 80 jest otwarty w firewallu → 4) dopiero certbot --apache. Pominięcie któregokolwiek kroku kończy się błędem walidacji domeny.

09 — Ostatni krok

Certyfikat wydany. Co dalej?

Sam certyfikat SSL to nie koniec pracy. Warto sprawdzić, czy się odnawia sam, czy ruch faktycznie przechodzi na HTTPS, i czy konfiguracja jest bezpieczna, a nie tylko "zielona kłódka".

kontrola

Podgląd wydanego certyfikatu

Pokazuje domenę, ścieżki do plików i datę ważności.

bash
sudo certbot certificates
test na sucho

Test automatycznego odnawiania

Let's Encrypt wydaje certyfikaty tylko na 90 dni — bez auto-odnawiania strona wygaśnie.

bash
sudo certbot renew --dry-run
Congratulations, all renewals succeeded
automat

Harmonogram odnawiania

Certbot instaluje to zwykle sam jako systemd timer — warto tylko potwierdzić, że jest aktywny.

bash
systemctl list-timers | grep certbot
wymuszenie

Przekierowanie HTTP → HTTPS

Certbot zwykle pyta o to sam podczas instalacji — tak wygląda ręczne wymuszenie w VirtualHost.

apache
<VirtualHost *:80>
    ServerName twojadomena.pl
    Redirect permanent / https://twojadomena.pl/
</VirtualHost>
moduł

Upewnij się, że mod_ssl działa

Certbot zwykle włącza to automatycznie, ale warto zweryfikować po ręcznych zmianach.

bash
sudo a2enmod ssl
sudo systemctl restart apache2
nie tylko kłódka

Realny test bezpieczeństwa SSL

Zielona kłódka nie znaczy "bezpiecznie" — słabe szyfry i stare protokoły też ją pokazują.

przeglądarka
ssllabs.com/ssltest # pełna ocena konfiguracji A–F
i

Certyfikat wygasł mimo auto-odnawiania?

Najczęstsza przyczyna: coś innego zajęło port 80 w momencie odnawiania (np. inny serwer WWW albo firewall zablokował ruch tymczasowo), więc walidacja domeny się nie powiodła. Sprawdź logi: sudo cat /var/log/letsencrypt/letsencrypt.log — tam zobaczysz dokładny powód.

10 — Gdy Certbot dostaje 404

Diagnoza: błąd weryfikacji ACME

Port 80 odpowiada, ale Let's Encrypt dostaje 404 pod /.well-known/acme-challenge/. To prawie zawsze znaczy, że żądanie trafia do złego VirtualHosta albo jest przechwytywane przez reverse proxy — nie że domena czy DNS są błędne.

pierwszy krok

Który VirtualHost naprawdę odpowiada

Apache wybiera vhost po ServerName/ServerAlias — gdy domena nie pasuje do żadnego, ląduje w pierwszym zdefiniowanym dla danego portu.

bash
sudo apache2ctl -S
test z Host

Wymuszenie konkretnej domeny

Symuluje żądanie tak, jakby przyszło na daną domenę — pokazuje, czy problem jest po stronie Apache czy DNS.

bash
curl -i -H 'Host: example.pl' http://127.0.0.1/.well-known/acme-challenge/test.txt
niezależny katalog

Osobny webroot tylko dla challenge

Odseparowuje weryfikację ACME od aplikacji czy reverse proxy — dużo bardziej przewidywalne niż poleganie na DocumentRoot strony.

apache
Alias /.well-known/acme-challenge/ /var/www/letsencrypt/.well-known/acme-challenge/

<Directory "/var/www/letsencrypt/.well-known/acme-challenge/">
    Options None
    AllowOverride None
    Require all granted
</Directory>
reverse proxy

Wyjątek przed ogólnym ProxyPass

Bez tego cały ruch, także do challenge, trafia prosto do aplikacji za proxy — i ta odpowiada własnym 404.

apache
ProxyPass /.well-known/acme-challenge/ !
ProxyPass / http://127.0.0.1:3000/
ProxyPassReverse / http://127.0.0.1:3000/
stabilniejszy tryb

Webroot zamiast pluginu Apache

Certbot rozdziela uwierzytelnianie i instalację — webroot pozwala wskazać dokładnie ten sam katalog, który dopiero co przetestowałeś.

bash
sudo certbot certonly --webroot -w /var/www/letsencrypt -d example.pl -d www.example.pl
test ręczny

Sprawdzenie bez Certbota

Zanim w ogóle uruchomisz Certbota, upewnij się, że zwykły plik testowy jest publicznie widoczny.

bash
echo 'acme-test' | sudo tee /var/www/letsencrypt/.well-known/acme-challenge/test.txt
curl -i http://example.pl/.well-known/acme-challenge/test.txt
HTTP/1.1 200 OK ... acme-test
!

Zgoda „Y" na początku Certbota to nie to samo

Potwierdzenie widoczne przy pierwszym uruchomieniu Certbota dotyczy wyłącznie zgody na wiadomości od EFF — nie ma żadnego związku z błędem 404 czy weryfikacją domeny. Jeśli certyfikat się nie wydaje, przyczyny szukaj wyłącznie w konfiguracji VirtualHosta i dostępności /.well-known/acme-challenge/.

11 — Nowość od stycznia 2026

Certyfikat bez domeny

Let's Encrypt wystawia teraz certyfikaty bezpośrednio dla publicznych adresów IP, np. https://57.128.255.40. Haczyk: taki certyfikat jest ważny tylko 160 godzin (niecały tydzień), więc automatyczne odnawianie musi działać bez zarzutu.

wymaganie

Sprawdź wersję Certbota

Certyfikaty IP wymagają Certbota 5.4 lub nowszego — starsza wersja z apt tego nie obsłuży.

bash
certbot --version
jeśli za stary

Instalacja aktualnej wersji przez Snap

Nie instaluj równocześnie wersji z apt i ze snapa — usuń starą przed instalacją nowej.

bash
sudo apt remove certbot python3-certbot-apache
sudo apt install snapd
sudo snap install core
sudo snap install --classic certbot
sudo ln -sf /snap/bin/certbot /usr/local/bin/certbot
hash -r
próba na sucho

Test w środowisku staging

Certyfikat testowy nie jest zaufany przez przeglądarkę — sprawdza tylko, czy cały proces przechodzi.

bash
sudo certbot certonly
  --staging
  --preferred-profile shortlived
  --webroot --webroot-path /var/www/letsencrypt
  --ip-address 57.128.255.40
właściwy certyfikat

To samo bez --staging

Dopiero po udanej próbie testowej — to samo polecenie, tym razem naprawdę wydaje certyfikat.

bash
sudo certbot certonly
  --preferred-profile shortlived
  --webroot --webroot-path /var/www/letsencrypt
  --ip-address 57.128.255.40
ręczna konfiguracja

VirtualHost :443 dla certyfikatu IP

Plugin --apache nie obsługuje jeszcze certyfikatów IP — trzeba podpiąć je ręcznie.

apache
<VirtualHost *:443>
    ServerName 57.128.255.40
    DocumentRoot /var/www/html
    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/57.128.255.40/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/57.128.255.40/privkey.pem
</VirtualHost>
bo odnawia się co kilka dni

Hook przeładowujący Apache

Uruchamia się automatycznie tylko po udanym odnowieniu — konieczne przy 160-godzinnej ważności.

bash
sudo mkdir -p /etc/letsencrypt/renewal-hooks/deploy
# plik reload-apache.sh: systemctl reload apache2
sudo chmod 755 .../reload-apache.sh
i

Domena wciąż wygodniejsza niż sam adres IP

Certyfikat na IP wymaga nowszego Certbota, ręcznej konfiguracji Apache i odnawiania co kilka dni zamiast co 60. Adres IP musi też pozostać stały — po jego zmianie certyfikat przestaje pasować. To dobre rozwiązanie tymczasowe albo gdy naprawdę nie masz domeny, ale zwykła (nawet darmowa) subdomena jest praktyczniejsza na dłuższą metę.

i

Konflikt portu 443 przy architekturze VPS + serwer domowy

Jeśli ruch trafia najpierw na VPS z publicznym IP, a stamtąd przez sieć prywatną (np. Tailscale) na Twój serwer domowy — inna usługa (jak tailscaled) może już zajmować port 443 na adresie prywatnym. Sprawdź to poleceniem sudo ss -ltnp | grep ':443'. Najczyściej jest wtedy zakończyć TLS na samym VPS-ie i przekazywać dalej już zwykły ruch HTTP przez sieć prywatną, zamiast wymuszać Apache na współdzielenie portu 443 z inną usługą.

12 — To, co pominąłem za pierwszym razem

Nginx, APT vs Snap i alternatywy

Cały poradnik do tej pory zakładał Apache. Jeśli jednak masz Nginx, albo zastanawiasz się, czy w ogóle Certbot to najlepszy wybór na Debianie 12 — to jest ta sekcja.

alternatywny serwer

To samo, ale dla Nginx

Identyczna logika co przy Apache — inny tylko plugin i flaga.

bash
sudo apt update
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d example.pl -d www.example.pl
checklista przed startem

Zanim w ogóle uruchomisz Certbota

Cztery rzeczy, które muszą być prawdą niezależnie od tego, czy masz Apache czy Nginx.

checklist
✓ rekordy DNS A (i AAAA) wskazują na serwer
✓ porty 80 i 443 otwarte w firewallu
✓ domena już działa po zwykłym HTTP
✓ poprawny server_name / ServerName w konfiguracji
decyzja

APT czy Snap?

Debian 12 ma Certbota w repozytorium, ale to starsza gałąź 2.1.x. Certbot oficjalnie rekomenduje Snapa większości użytkowników.

wybór
APT  → prostsze, "bardziej debianowe", wystarcza do zwykłego Nginx/Apache
Snap → nowsza wersja, potrzebna np. do certyfikatów IP
# nigdy nie instaluj obu równocześnie
prostsza alternatywa

Kiedy zamiast Certbota — Caddy

Jeśli dopiero budujesz serwer od zera, Caddy sam pobiera i odnawia certyfikaty oraz przekierowuje HTTP → HTTPS, bez osobnego Certbota.

info
# Caddy: automatic HTTPS wbudowane w serwer
# dobre gdy stawiasz nowy, prosty reverse proxy
wildcard

Certyfikat dla *.przyklad.pl

Zwykłe certbot --nginx czy --apache nie wystarczy — wildcard wymaga weryfikacji DNS-01.

info
# wildcard = weryfikacja DNS-01
# potrzebny plugin API operatora DNS (np. certbot-dns-cloudflare)
wiele kontenerów

Docker / wiele usług na jednym serwerze

Zamiast osobnego Certbota dla każdego kontenera, lepiej zintegrować HTTPS z jednym reverse proxy obsługującym ACME centralnie.

info
# jeden reverse proxy (np. Traefik, Caddy) z ACME
# zamiast Certbota osobno w każdym kontenerze
i

Szybka rekomendacja

Masz już działający Nginx albo Apache? Zostań przy Certbocie — jest rekomendowany przez samo Let's Encrypt. Stawiasz nowy, prosty serwer od zera? Rozważ Caddy. Masz wiele kontenerów? Zintegruj HTTPS z jednym reverse proxy zamiast mnożyć instancje Certbota.

dodatkowe źródło
Pełna rozmowa referencyjna (Certbot na Debianie 12):
chatgpt.com/share/6a69df58-f284-83eb-a369-a782349a453b