Vlastní web na jméně .lopux
Máte jméno v Lopux-Internetu; tento návod za něj postaví skutečný web, dostupný každému, kdo používá aplikaci. Pokud jméno ještě nemáte, nejdřív si nějaké zaberte.
Předpokládá, že umíte provozovat webový server, a nic víc. Všechno, co je pro Lopux-Internet zvláštní, je tady: proč je certifikát podepsaný sám sebou, co musí běžet vedle vašeho webu a které dva záznamy rozhýbou jméno.
Snímky obrazovky ukazují anglické rozhraní. Portál mluví šesti jazyky — svůj si vyberte tlačítkem EN vpravo nahoře.
1. Co potřebujete a co nestačí
Stroj, kde TLS na portu 443 řídíte vy. VPS, dedikovaný server, krabice doma s dosažitelnou adresou. To je celý požadavek a je skutečný.
Spravované platformy tohle hostovat nedokážou, ze dvou nezávislých důvodů. Vercel, Netlify, Cloudflare Pages, většina PaaS: přidáte vlastní doménu a certifikát obstarají a vydávají oni. Celá věc tu stojí na tom, že váš server prokáže držení klíče, který jste zveřejnili vy — platforma vydávající vlastní klíč takový důkaz podat nemůže a aplikace návštěvníka web odmítne, a to právem. Jméno by ostatně stejně nepřijali: nastavení vlastní domény ověřuje vlastnictví přes obyčejný DNS, kde mysite.lopux neexistuje a existovat nebude.
CDN před tím také nepomůže — ukončuje TLS, tedy tentýž problém.
Platformy, kam lze nahrát vlastní certifikát i klíč, by technicky fungovaly. Jenže pak se ta strana může před každým návštěvníkem vydávat za váš web, potichu, a nic v této konstrukci to neodhalí. Berte to jako to, čím to je: předání vlastního soukromého klíče někomu jinému.
2. Proč je certifikát podepsaný sám sebou
Žádná certifikační autorita nesmí vydat certifikát na jméno v Lopux-Internetu. Ne proto, že by to bylo těžké, ale proto, že to není dovoleno: autorita smí vydávat jen na jména pod obyčejným kořenem DNS a tato jména leží záměrně mimo něj.
Místo abyste žádali cizího člověka, aby se za vás zaručil, zveřejníte otisk vlastního klíče v zóně svého jména a aplikace každého návštěvníka porovná server, k němuž došla, s tímto záznamem. Tím, kdo rozhoduje, je záznam.
V jedné věci je to přísnější než certifikační autorita: s autoritou by certifikát na vaše jméno mohly vydat stovky organizací a každé z nich by se věřilo. Tady funguje jen ten klíč, který jste zveřejnili vy.
3. Vyrobte certifikát
Deset let, bez hesla, a každé jméno, které obsluhujete, uvedené v subjectAltName:
openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 \
-keyout site.key -out site.crt -days 3650 -nodes \
-subj "/CN=mysite.lopux" \
-addext "subjectAltName=DNS:mysite.lopux,DNS:www.mysite.lopux"
Tři věci k tomu příkazu:
- doba platnosti tu nehraje roli. Aplikace ji záměrně ignorují: o tom, jestli váš klíč pořád
platí, rozhoduje zveřejněný záznam, ne datum uvnitř certifikátu. Nic se tedy nikdy neobnovuje. Deset let je prostě déle, než vás to bude zajímat;
-nodesznamená, že klíč nemá heslo, a přesně to webový server potřebuje, aby nastartoval bez člověka. Nechte soubor čitelný jen pro uživatele serveru (chmod 600) a mimo jakýkoli obraz,
který někam posíláte;
- nedávejte do certifikátu nic, co byste nezveřejnili. Každý, kdo s vaším serverem dokončí handshake, ho dostane a přečte si z něj jméno. Jedno jméno, žádná organizace, žádný e-mail.
4. Co běží vedle vašeho webu
Váš web mluví obyčejným HTTP a certifikát nikdy nevidí. Před ním stojí nginx, který ukončuje TLS zveřejněným klíčem a předává požadavek dovnitř.
Ten předek existuje proto, že původ v Lopux-Internetu potřebuje několik nastavení, která jsou opakem toho, co dá běžná „zpevněná nginx" šablona — a každé z nich se pokazí způsobem, který v prohlížeči vypadá v pořádku:
| Pravidlo | Co stojí chyba |
|---|---|
| žádné HSTS — a strhněte ho, pokud ho web posílá sám | hlavička připoutá prohlížeč k https:// pro to jméno, což natrvalo rozbije režim obyčejného http://, který má návštěvník dřív, než cokoli nainstaluje |
žádné přesměrování na https:// — a řekněte webu, že požadavek už přišel přes TLS | jinak framework to přesměrování vydá sám a rozbije týž režim zevnitř |
| odmítat handshake, jehož SNI není vaše jméno | skener procházející adresy si odnese váš certifikát, a v certifikátu je vaše jméno |
| jen 443 | aplikace volají 443 a nic jiného; port 80 neobslouží nikoho, kdo přišel přes Lopux-Internet |
| lhůty na handshake a na čtení | jedno spojení, které se otevře a mlčí, dokáže server zaseknout. Veřejná adresa taková sbírá během minut |
| předek drží klíč, skok dovnitř jde obyčejným HTTP | ten skok tedy nikdy nesmí opustit stroj: nezveřejňujte port samotného webu |
Tady je ten nginx celý. Vyměňte jméno, cesty a adresu za ním:
map $http_upgrade $connection_upgrade { default upgrade; '' close; }
server_tokens off;
# co není vaše jméno: zavřené dveře, bez certifikátu
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
ssl_reject_handshake on;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name mysite.lopux;
ssl_certificate /etc/ssl/site.crt; # klíč, jehož otisk zveřejňujete
ssl_certificate_key /etc/ssl/site.key;
ssl_protocols TLSv1.2 TLSv1.3; # podepsaný sám sebou
client_header_timeout 10s; # ohraničují handshake — viz níže
client_body_timeout 10s;
send_timeout 10s;
keepalive_timeout 30s;
reset_timedout_connection on;
proxy_hide_header Strict-Transport-Security;
location / {
proxy_pass http://127.0.0.1:8080; # váš web, obyčejné HTTP, ne ven
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto https; # pravidlo 2: bez přesměrování
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_connect_timeout 5s;
proxy_read_timeout 60s;
}
}
Jedna past v těchto lhůtách, kvůli které nginx prostě nenastartuje: ssl_handshake_timeout v http modulu nginx neexistuje — patří do stream. V http handshake ohraničuje client_header_timeout, a právě tato hodnota tu odvádí tu práci.
O bráně podle SNI stojí za to říct víc, protože dělá něco méně zjevného než schovávání před skenery. Bez ní server podá tentýž certifikát — a tedy totéž varování prohlížeče — dvěma návštěvníkům v opačných situacích: tomu, jehož aplikace porovnala váš klíč se záznamem dřív, než se pohnul jediný bajt stránky, a tomu, kdo napsal vaši IP adresu, kde se neověřovalo vůbec nic. Brána odstraní ten druhý případ. Nedělá z varování ověření: kdo vaše jméno zná, zapíše si ho do vlastního hosts a dorazí neověřený přesně jako dřív.
Jedno pravidlo o samotných stránkách, snadno se přehlédne: používejte relativní odkazy. /about, ne https://mysite.lopux/about. Návštěvník v režimu obyčejného http:// absolutní odkaz https:// na váš vlastní web nenásleduje a Lopux-Internet vaše stránky záměrně nepřepisuje. Odkazy na jiné weby jsou vaše věc a netýká se jich to.
5. Zveřejněte otisk klíče
Otevřete své jméno v portálu a sjeďte k sekci Certifikáty. Dokud není nic zveřejněno, říká to rovnou: není s čím porovnávat, takže aplikace odmítne web otevřít, místo aby se připojila bez ověření.
Nahrajte site.crt tlačítkem Vybrat soubor s certifikátem… nebo ho vložte. Jen certifikát — soubor, který začíná -----BEGIN PRIVATE KEY-----, zůstává na vašem serveru a portál ho odmítne, místo aby ho někam uložil.
Stiskněte Zveřejnit otisk klíče. Portál certifikát přečte, vezme SHA-256 jeho veřejného klíče a zapíše ho do vaší zóny.
Porovnejte ho s vlastní kopií — musí se shodovat:
openssl x509 -in site.crt -noout -pubkey \
| openssl pkey -pubin -outform der | openssl dgst -sha256
Ta sekce je hlavní vchod k obyčejnému záznamu. Táž hodnota leží v seznamu záznamů jako záznam TLSA pod _443._tcp a je tam vidět:
6. Nasměrujte jméno na svůj server
Ve stejném pohledu přidejte záznam A, jehož hodnotou je veřejná adresa vašeho serveru. @ znamená jméno samo.
Teď zóna nese oba záznamy a dohromady jsou vším, co aplikace návštěvníka potřebuje: záznam A říká, kde je váš server, záznam TLSA, jaký klíč musí předložit.
Počítejte s asi deseti minutami, než bude změna vidět všude. V cestě stojí dvě mezipaměti — resolveru a aplikace — po pěti minutách.
7. Zkontrolujte
Portál stáhne váš web tak, jak by to udělal návštěvník, a ohlásí, co by mu bránilo fungovat: klíč, který neodpovídá zveřejněnému, chybějící otisk, hlavičku HSTS, přesměrování na https://, absolutní odkazy na sebe nebo server, který neodpověděl.
Na tomto snímku kontrola odmítá proběhnout: adresa v příkladu je dokumentační a portál nezkoumá nic, co není dosažitelné z internetu — nasměrovat jméno na privátní nebo smyčkovou adresu by z kontroly udělalo sondu do cizí sítě. Se skutečným serverem na skutečné adrese odpoví, že je web v pořádku, nebo pojmenuje přesně, co je špatně.
Dvě kontroly, které zvládnete sami, a jsou to ty nejdůležitější:
# bez SNI — odmítnuto
openssl s_client -connect YOUR_ADDRESS:443 </dev/null
# váš certifikát
openssl s_client -connect YOUR_ADDRESS:443 -servername mysite.lopux </dev/null
Druhá by vám měla podat certifikát, jehož otisk jste zveřejnili. Vezměte otisk jeho klíče stejně jako v §5 a porovnejte: pokud se řetězce liší, každý návštěvník dostane odmítnutí — a pro něj to vypadá přesně jako pokus o podvržení.
8. Co vidí návštěvník
Správně nastavený web se otevře pod vlastním jménem jako každý jiný:
To je lopux.ipvx — vlastní web tohoto projektu. Žije v prostoru jmen stejně, jako v něm bude žít ten váš, a je postavený přesně v tomto tvaru. Klíč, který vydává, odpovídá jeho zveřejněnému otisku — a právě proto ho aplikace otevře bez jediného varování.
Co dostanou různí návštěvníci:
| Návštěvník | Co vidí |
|---|---|
aplikace, jméno v otevřené zóně jako .lopux | obyčejný zámek, všechno funguje |
| aplikace, vlastní kořenové jméno | pokaždé varování prohlížeče o certifikátu — otisk se pod tím stejně ověřuje |
aplikace, http:// v adresním řádku | stránka vypadá prostě; skok k vašemu serveru je stejně šifrovaný a klíč ověřený |
| bez aplikace | nic. Jméno se mimo Lopux-Internet nepřeloží |
Poslední řádek je smysl prostoru jmen, ne jeho omezení. Všimněte si ale řádku nad ním: váš server je obyčejný veřejný stroj a dostat se k němu po adrese může kdokoli. Prostor jmen ho neskrývá a váš certifikát řekne jméno vašeho webu každému, kdo dokončí handshake — přesně proto je tu brána podle SNI z §4.
9. Jak se starat o klíč
Nic tady neodhalí ukradený klíč; systém jen činí vazbu mezi vaším jménem a vaším klíčem závaznou. Ten, kdo má váš klíč, se prokazuje bezchybně, dokud nezveřejníte nový otisk.
- nechte
site.keyčitelný jen pro uživatele webového serveru a mimo adresář, který vydáváte; - udělejte šifrovanou zálohu: ztráta klíče vás stojí výměnu, ne jméno;
- výměna je levná, tak ji udělejte při každém podezření. Zveřejněte nový certifikát před přepnutím: dokud jsou zveřejněné dva otisky, přijímá se kterýkoli z klíčů, a nenastane okamžik,
kdy by web byl nedostupný. Pak přepněte server, počkejte deset minut a starý odstraňte;
- odstranění otisku je odvolání. Není koho žádat ani na co čekat: v okně mezipaměti návštěvník dostane odmítnutí, místo aby uviděl toho, kdo má starý klíč.
10. Když něco nesedí
Aplikace poruchu pojmenuje, místo aby ukázala prázdnou stránku. Co která znamená:
| Co se návštěvník dozví | Co to znamená | Kdo je na tahu |
|---|---|---|
| Pro toto jméno není zveřejněn otisk klíče | zóna nemá záznam TLSA | vy — §5 |
| Tohle není web, za který se vydává | klíč vašeho serveru není ten zveřejněný | vy — vyměnili jste certifikát, aniž byste zveřejnili nový otisk |
| Web neodpověděl | jméno i klíč jsou v pořádku, váš server se neozval | vy — zkontrolujte server a záznam A |
| Tato stránka nemůže fungovat přes obyčejné http | absolutní odkazy https:// na váš vlastní web | vy — udělejte je relativní (§4) |
| Tato aplikace potřebuje aktualizaci, aby web otevřela | aplikace návštěvníka je starší než vaše zóna | on — ať aktualizuje; s vaším webem je vše v pořádku |