# Šifrování disků a souborů

TLS, SSH i VPN chrání data **na cestě**. Tahle stránka je o datech **v klidu** — na disku serveru, v záloze, na flashce, kterou vozíš k rodičům.

Je to disciplína, kde se dělá jedna zásadní chyba: šifruje se, aniž by bylo jasné, proti čemu. Proto začneme tím.

Navazuje na [stavební kameny](Sifrovani-zaklady) a doplňuje [zabezpečení serveru](Zabezpeceni-serveru).

## Proti čemu to vlastně chrání

Šifrování disku má **velmi úzký** a velmi konkrétní účel:

| Situace | Pomůže? |
|---|---|
| Ukradený notebook nebo NAS | **ano** |
| Vyhozený nebo prodaný disk | **ano** |
| Disk poslaný do reklamace | **ano** |
| Záloha ležící u kamaráda nebo v cizím cloudu | **ano** |
| Zabavený vypnutý stroj | **ano** |
| Útočník, který se dostal na **běžící** systém | **ne** |
| Ransomware | **ne** — a naopak, on šifruje tobě |
| Zranitelná webová aplikace | **ne** |
| Uniklé heslo do služby | **ne** |
| Zabavený **běžící** stroj | **ne** |

Vidíš ten vzorec? **Šifrování disku chrání data, dokud je systém vypnutý.** Jakmile běží, klíč je v paměti a souborový systém je odemčený — root i útočník vidí všechno naprosto normálně.

To není jeho nedostatek, to je jeho definice. Jen je potřeba mít správná očekávání a neusnout na vavřínech: **na běžícím serveru dělá práci [firewall](Linux-firewall), [aktualizace](Zabezpeceni-serveru) a přístupová práva, ne LUKS.**

Kde má naopak šifrování naprosto zásadní přínos, je **záloha mimo dům**. Pravidlo 3-2-1 tě vede k tomu, že jedna kopie leží někde, kde na ni nevidíš. Ta kopie musí být šifrovaná — jinak jsi právě rozdal svoje data.

## LUKS: šifrovaný disk na Linuxu

Standardní řešení, součást jádra, žádná instalace navíc.

### Vytvoření

```bash
cryptsetup luksFormat --type luks2 /dev/sdb1
cryptsetup open /dev/sdb1 data
mkfs.ext4 /dev/mapper/data
mount /dev/mapper/data /mnt/data

# a zpátky
umount /mnt/data
cryptsetup close data
```

Výchozí nastavení je dobré a nemá se měnit: **AES-256 v režimu XTS** a odvození klíče z hesla přes **Argon2id**, který je [odolný proti hádání na grafických kartách](Hashe-a-podpisy#hesla-úplně-jiná-disciplína).

```bash
cryptsetup luksDump /dev/sdb1
```

### Hlavička je jediné, co tam opravdu záleží

Tohle je nejdůležitější odstavec o LUKS.

Disk se nešifruje přímo tvým heslem. Existuje **hlavní klíč**, který vznikne náhodně při vytvoření svazku a nikdy se nemění. Ten je uložený v hlavičce disku, zašifrovaný tvým heslem — a hesel může být osm (LUKS2 jich zvládne víc).

Z toho plynou tři věci:

**Změna hesla je okamžitá.** Nepřešifrovává se disk, jen se přebalí hlavní klíč.

**Můžeš mít víc hesel.** Tvoje, záložní v trezoru, klíčový soubor pro automatické odemčení.

**Poškozená hlavička = konec.** Pár kilobajtů na začátku disku drží jediný klíč k celému obsahu. Přepsaná hlavička znamená, že data jsou nenávratně pryč, i kdyby zbytek disku byl v naprostém pořádku.

**Zálohuj hlavičku. Hned po vytvoření.**

```bash
cryptsetup luksHeaderBackup /dev/sdb1 --header-backup-file /bezpecne/luks-sdb1.img
```

Ten soubor ulož mimo daný disk. **Zároveň ale pozor:** obsahuje hlavní klíč zabalený starými hesly — když někdy heslo změníš kvůli podezření na únik, stará záloha hlavičky ho pořád přijímá. Chraň ji jako samotná data.

```bash
cryptsetup luksAddKey /dev/sdb1              # přidat heslo
cryptsetup luksKillSlot /dev/sdb1 1          # odebrat slot
```

### Odemčení bez klávesnice

Server v komoře nemá kdo při každém restartu odemknout. Možnosti, od nejjednodušší:

**Klíčový soubor na jiném médiu** — v `/etc/crypttab` s klíčem na USB. Levné a průhledné, ale kdo ukradne server i s flashkou, má obojí.

**TPM čip.** Klíč vydá čip jen tehdy, když se stav systému shoduje s tím při zápisu:

```bash
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=7 /dev/sdb1
systemd-cryptenroll --recovery-key /dev/sdb1     # nouzový klíč, vytiskni si ho
```

Disk vytažený z tohoto stroje nikdo neotevře. Zároveň si uvědom, co to znamená: **stroj se odemkne sám, takže krádež celého stroje tě nechrání**, pokud útočník umí spustit systém. Kombinace TPM + PIN to řeší.

**Odemčení přes SSH při startu.** Nejelegantnější řešení pro domácí server:

```bash
apt install dropbear-initramfs
# klíč do /etc/dropbear/initramfs/authorized_keys
update-initramfs -u
```

Po restartu naběhne minimální SSH v initramfs, ty se připojíš, zadáš heslo a systém pokračuje. Chová se to přesně tak, jak chceš: **bez tebe stroj nenaběhne**, ale nemusíš k němu chodit.

Počítej s tím, že to má vlastní host key, takže si do konfigurace klienta dej výjimku:

```
Host server-boot
    HostName 192.168.1.10
    User root
    UserKnownHostsFile ~/.ssh/known_hosts.boot
```

### Výkon

S hardwarovým AES (každý procesor od roku 2010) je režie **jednotky procent** a na NVMe disku ji nepoznáš. Ověř si, že se akcelerace používá:

```bash
cryptsetup benchmark
grep -o aes /proc/cpuinfo | head -1
```

Když se `aes` v `cpuinfo` neobjeví (staré Atomy, některé ARM desky), zvaž místo AES-XTS variantu `--cipher xchacha12,aes-adiantum-plain64` — Adiantum je navržený přesně pro procesory bez akcelerace a je v takovém případě podstatně rychlejší.

### Šifrování konkrétního adresáře

Když nechceš celý disk:

**gocryptfs** — šifrovaný adresář nad běžným souborovým systémem, dobře se synchronizuje do cloudu:

```bash
gocryptfs -init ~/.sifrovane
gocryptfs ~/.sifrovane ~/tajne
```

**ZFS s nativním šifrováním** — když už ZFS používáš, je to nejčistší cesta:

```bash
zfs create -o encryption=on -o keyformat=passphrase tank/tajne
```

Šifruje se na úrovni datasetu, `zfs send` umí posílat data **zašifrovaná** na cílový stroj, který heslo nezná. Pro zálohu k někomu jinému je to ideální.

Pozor na jednu vlastnost: **metadata jako názvy datasetů a velikosti zůstávají viditelné.**

## Soubory: použij age

`age` je moderní nástroj na šifrování souborů. Dělá jednu věc a nedá se nastavit špatně.

```bash
# vlastní klíč
age-keygen -o ~/.age/klic.txt
# Public key: age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p

# zašifrovat pro sebe
age -r age1ql3z7... -o zaloha.tar.age zaloha.tar

# dešifrovat
age -d -i ~/.age/klic.txt -o zaloha.tar zaloha.tar.age

# jen heslem, bez klíčů
age -p -o soubor.age soubor
```

Nejlepší vlastnost: **umí použít tvůj SSH klíč**, takže nemusíš spravovat další sadu klíčů.

```bash
age -R ~/.ssh/id_ed25519.pub -o data.age data.tar
age -d -i ~/.ssh/id_ed25519 -o data.tar data.age
```

Uvnitř je X25519 na výměnu klíčů a ChaCha20-Poly1305 na data — přesně to, co [dělá TLS](Sifrovani-zaklady#jak-se-z-toho-staví-protokol), jen bez sítě.

### GPG: když musíš

GPG umí totéž a ještě mnohem víc, ale je to nástroj z jiné doby: složitá konfigurace, matoucí správa důvěry, keyservery, které nikdo neudržuje, a rozhraní plné pastí.

Použij ho, když potřebuješ **ověřovat cizí podpisy** — podpisy balíčků, vydání softwaru, komunikaci s někým, kdo GPG používá.

```bash
gpg --verify software.tar.gz.asc software.tar.gz
gpg -c soubor                            # symetricky, heslem
gpg -e -r prijemce@example.cz soubor     # pro příjemce
```

Na vlastní soubory sáhni po `age`. Na podepisování vlastních věcí použij [SSH klíč](Verejny-a-soukromy-klic#praktické-podepsat-a-ověřit-soubor).

### Co nepoužívat

**`openssl enc`** — nemá ověřenou integritu (zašifrovaný soubor jde nepozorovaně přepsat), odvození klíče z hesla je i s `-pbkdf2` slabší než u konkurence a formát není nikde pořádně popsaný.

**Zip s heslem** — starý ZipCrypto je prolomený triviálně. Novější AES v zipu je v pořádku, ale závisí na tom, který nástroj archiv vytvořil, a to nikdy nevíš jistě.

**„Šifrování" v kancelářských programech** — u starších formátů jde o kosmetiku.

## Zálohy

Nejdůležitější použití šifrování v klidu, protože záloha z definice leží někde jinde.

**Šifruj u sebe, ne v cíli.** Cílové úložiště nesmí mít klíč — jinak jsi svoje data svěřil poskytovateli.

```bash
# restic
restic -r sftp:zaloha@nas:/zalohy init
restic -r sftp:zaloha@nas:/zalohy backup /data /etc
restic -r sftp:zaloha@nas:/zalohy snapshots
restic -r sftp:zaloha@nas:/zalohy check --read-data-subset 5%
restic -r sftp:zaloha@nas:/zalohy restore latest --target /obnova
```

```bash
# borg
borg init --encryption=repokey-blake2 zaloha@nas:/zalohy
borg create zaloha@nas:/zalohy::"{now}" /data /etc
borg check zaloha@nas:/zalohy
```

Obojí šifruje **na tvém stroji** AES-256 a klíč odvozuje z hesla pomalou funkcí. Cílové úložiště vidí jen hromadu nesrozumitelných bloků — může to tedy klidně být cizí NAS nebo objektové úložiště v cloudu.

Tři věci, které se u zálohovacího hesla podceňují:

**Heslo musí být silné.** U `borg init --encryption=repokey` leží klíč v repozitáři zabalený tvým heslem. Kdo má kopii repozitáře, může heslo hádat offline, jak dlouho chce. Tady se `mrkev-tramvaj-pisek-hlina` vyplatí.

**Heslo musí přežít havárii.** Zapsané v [správci hesel](#hesla-a-tajemství), který je sám zálohovaný jinde, plus na papíře v šuplíku. Zašifrovaná záloha bez hesla je smazaná záloha.

**Vyzkoušej obnovu.** Nevyzkoušená záloha je jen naděje, jak už zmiňuje [zabezpečení serveru](Zabezpeceni-serveru#zálohy). U šifrované to platí dvojnásob, protože přibyl další způsob, jak si zavřít dveře.

**Neměnná kopie.** Šifrování nechrání před ransomwarem — ten smaže i zašifrovanou zálohu, ke které má server přístup. Řeší to `append-only` režim, oddělené účty, nebo prostě disk, který je většinu času odpojený.

## Hesla a tajemství

### Správce hesel

Není to volitelná vymoženost, je to základní nástroj. KeePassXC (lokální soubor), Bitwarden nebo Vaultwarden (vlastní server), `pass` (soubory + GPG + Git).

Databáze je zašifrovaná hlavním heslem, které musí být **dlouhé a jediné, které si pamatuješ**. Čtyři až pět náhodných slov je lepší než osm znaků s háčky — viz [entropie](Nahodnost-a-entropie#entropie-kolik-nepředvídatelnosti-tam-doopravdy-je).

### Tajemství v konfiguracích

Tohle je v homelabu nejčastější reálný únik. Ne prolomená šifra — hesla k databázi v `docker-compose.yml`, který je v Gitu.

```bash
# jsou práva rozumná?
find /opt -name "*.env" -o -name "docker-compose.yml" | xargs ls -l
chmod 600 .env
```

**Nikdy to nedávej do Gitu.** Když se to stane, nestačí commit smazat — historie zůstává a tajemství je spálené. Musí se **změnit**, ne skrýt.

Když konfigurace v Gitu být musí, patří tam zašifrovaná. Nejlepší dnešní kombinace je `sops` s `age`:

```bash
age-keygen -o ~/.config/sops/age/keys.txt
export SOPS_AGE_RECIPIENTS=age1ql3z7...
sops -e -i secrets.yaml     # zašifruje hodnoty, klíče nechá čitelné
sops secrets.yaml           # otevře v editoru, po uložení zase zašifruje
```

Chytré je, že šifruje **jen hodnoty**. Struktura souboru zůstane čitelná, takže `git diff` má pořád smysl a konflikty jdou řešit.

### Kontejnery

```yaml
services:
  db:
    environment:
      POSTGRES_PASSWORD_FILE: /run/secrets/db_heslo
    secrets:
      - db_heslo
secrets:
  db_heslo:
    file: ./secrets/db_heslo.txt
```

Lepší než proměnná prostředí, protože ta je vidět v `docker inspect` i v `/proc/<pid>/environ` každému, kdo se na stroj dostane.

Zároveň si nic nenamlouvej: **kdo je ve skupině `docker`, je [fakticky root](Zabezpeceni-serveru#docker-znamená-root)** a dostane se ke všemu. Tohle je ochrana proti nedbalosti, ne proti útočníkovi.

## Časté chyby

**Šifrovaný disk na běžícím serveru jako ochrana proti hackerům.** Nechrání. Chrání proti krádeži hardwaru.

**Nezálohovaná hlavička LUKS.** Nejlevnější způsob, jak přijít o všechno.

**Zapomenuté heslo od zálohy.** Druhý nejlevnější způsob.

**Data zašifrovaná až v cíli.** Když šifruje poskytovatel, chrání tě před ostatními zákazníky, ne před poskytovatelem.

**Šifrovaná záloha na disku trvale připojeném k serveru.** Ransomware ji smaže stejně jako všechno ostatní.

**Klíč vedle dat.** Klíčový soubor na tomtéž disku, heslo v `crypttab`, `age` klíč vedle šifrovaného archivu.

**Šifrování místo mazání.** Když data nepotřebuješ, nejlepší ochrana je nemít je.

**Přešifrování pomalého SSD kvůli pocitu.** Zjisti, jestli disk nemá vlastní hardwarové šifrování (SED/OPAL) — mnohé mají a implementace bývají mizerné, takže je stejně chceš vypnout a použít LUKS.

## Tahák

```bash
# LUKS
cryptsetup luksFormat --type luks2 /dev/sdX
cryptsetup open /dev/sdX nazev ; cryptsetup close nazev
cryptsetup luksDump /dev/sdX
cryptsetup luksHeaderBackup /dev/sdX --header-backup-file h.img
cryptsetup luksAddKey /dev/sdX ; cryptsetup luksKillSlot /dev/sdX 1
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=7 /dev/sdX

# soubory
age-keygen -o klic.txt
age -R ~/.ssh/id_ed25519.pub -o data.age data.tar
age -d -i ~/.ssh/id_ed25519 -o data.tar data.age
age -p -o data.age data.tar          # jen heslem

# zálohy
restic -r sftp:user@nas:/z init / backup /data / snapshots / check
borg init --encryption=repokey-blake2 user@nas:/z

# tajemství v Gitu
sops -e -i secrets.yaml ; sops secrets.yaml

# generování hesel
openssl rand -base64 32
```

## Kam dál

- **[Stavební kameny](Sifrovani-zaklady)** — co je uvnitř AES-XTS a ChaCha20-Poly1305
- **[Hashe, HMAC a podpisy](Hashe-a-podpisy)** — proč Argon2id na hesla
- **[Náhodnost a entropie](Nahodnost-a-entropie)** — odkud se bere hlavní klíč
- **[Zabezpečení serveru](Zabezpeceni-serveru)** — ochrana běžícího systému
- **[Postkvantová kryptografie](Postkvantova-kryptografie)** — dlouhodobě uložená data
