Konto
PL

Wszystkie instrukcje

Własna strona na nazwie .lopux

Masz nazwę w Lopux-Internecie; ta instrukcja stawia za nią prawdziwą stronę, dostępną dla każdego, kto używa aplikacji. Jeśli nazwy jeszcze nie masz — najpierw ją zajmij.

Zakłada, że potrafisz uruchomić serwer WWW i nic ponadto. Wszystko, co jest specyficzne dla Lopux-Internetu, jest tutaj: dlaczego certyfikat jest samopodpisany, co musi działać obok Twojej strony i które dwa rekordy sprawiają, że nazwa działa.

Zrzuty ekranu pokazują angielski interfejs. Portal mówi w sześciu językach — wybierz swój przyciskiem EN w prawym górnym rogu.

1. Czego potrzebujesz i co się nie nada

Maszyna, na której to Ty panujesz nad TLS na porcie 443. VPS, serwer dedykowany, komputer w domu z osiągalnym adresem. To całe wymaganie i jest ono prawdziwe.

Platformy zarządzane tego nie udźwigną, z dwóch niezależnych powodów. Vercel, Netlify, Cloudflare Pages, większość PaaS: dodajesz własną domenę, a certyfikat zdobywają i podają oni. Cała rzecz polega tu na tym, że Twój serwer dowodzi posiadania klucza, który opublikowałeś Ty — platforma podająca własny klucz takiego dowodu nie przeprowadzi, a aplikacja odwiedzającego odrzuci stronę i będzie miała rację. Nazwy zresztą i tak nie przyjmą: konfiguracja własnej domeny weryfikuje własność przez zwykły DNS, w którym mysite.lopux nie istnieje i istnieć nie będzie.

CDN z przodu też nie pomaga — kończy TLS u siebie, czyli ten sam problem.

Platformy pozwalające wgrać własny certyfikat razem z kluczem zadziałałyby mechanicznie, ale wtedy ta strona może podszywać się pod Twoją witrynę przed każdym odwiedzającym, po cichu, i nic w tej konstrukcji tego nie wykryje. Potraktuj to jak to, czym jest: oddanie komuś swojego klucza prywatnego.

2. Dlaczego certyfikat jest samopodpisany

Żaden urząd certyfikacji nie może wystawić certyfikatu na nazwę w Lopux-Internecie. Nie dlatego, że to trudne, tylko dlatego, że nie wolno: urząd może wystawiać wyłącznie na nazwy pod zwykłym korzeniem DNS, a te nazwy leżą celowo poza nim.

Zamiast prosić obcego o poręczenie, publikujesz odcisk własnego klucza w strefie swojej nazwy, a aplikacja każdego odwiedzającego porównuje serwer, do którego dotarła, z tym rekordem. To rekord jest tu instancją rozstrzygającą.

Pod jednym względem jest to ostrzejsze niż urząd certyfikacji: przy urzędzie certyfikat na Twoją nazwę mogłyby wystawić setki organizacji i każdej by uwierzono. Tutaj działa wyłącznie klucz, który opublikowałeś Ty.

3. Zrób certyfikat

Dziesięć lat, bez hasła, i każda nazwa, którą obsługujesz, wymieniona w 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"

Trzy rzeczy o tym poleceniu:

odnawiania, nigdy. Dziesięć lat to po prostu dłużej, niż będzie Cię to obchodzić;

które gdziekolwiek wypychasz;

z Twoim serwerem, dostaje go i odczytuje z niego nazwę. Jedna nazwa, bez organizacji i adresu e-mail.

4. Co działa obok Twojej strony

Twoja strona mówi zwykłym HTTP i nigdy nie widzi certyfikatu. Przed nią stoi nginx, który kończy TLS opublikowanym kluczem i przekazuje żądanie do środka.

Ten front istnieje, bo źródło w Lopux-Internecie potrzebuje kilku ustawień odwrotnych do tego, co daje zwykły „utwardzony nginx", a każde z nich psuje się w sposób, który w przeglądarce wygląda dobrze:

ZasadaCo kosztuje pomyłka
żadnego HSTS — i zdejmij go, jeśli strona wysyła własnynagłówek przypina przeglądarkę do https:// dla tej nazwy, co trwale psuje tryb zwykłego http://, który odwiedzający ma, zanim cokolwiek zainstaluje
żadnego przekierowania na https:// — i powiedz stronie, że żądanie już przyszło po TLSinaczej framework wystawi to przekierowanie sam i zepsuje ten sam tryb od środka
odrzucaj uzgadnianie, w którym SNI to nie Twoja nazwaskaner przechodzący po adresach zbierze Twój certyfikat, a w certyfikacie jest Twoja nazwa
tylko 443aplikacje pukają w 443 i nigdzie indziej; port 80 nie obsługuje nikogo, kto przyszedł przez Lopux-Internet
terminy na uzgadnianie i na odczytjedno połączenie, które się otwiera i milczy, potrafi zablokować serwer. Publiczny adres zbiera takie w ciągu minut
front trzyma klucz, a skok do środka idzie zwykłym HTTPten skok nie może więc opuszczać maszyny: nie publikuj na zewnątrz portu samej strony

Oto ten nginx w całości. Podmień nazwę, ścieżki i adres zaplecza:

map $http_upgrade $connection_upgrade { default upgrade; '' close; }
server_tokens off;

# nie Twoja nazwa: zamknięte drzwi, przed certyfikatem
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;   # klucz, którego odcisk publikujesz
    ssl_certificate_key /etc/ssl/site.key;
    ssl_protocols       TLSv1.2 TLSv1.3;     # samopodpisany: nie ma czego zszywać

    client_header_timeout 10s;   # ograniczają uzgadnianie — patrz niżej
    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;   # Twoja strona, HTTP, nie na zewnątrz
        proxy_http_version 1.1;
        proxy_set_header Host              $host;
        proxy_set_header X-Forwarded-Proto https;   # zasada 2: bez przekierowania
        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 pułapka w tych terminach, przez którą nginx po prostu nie wstanie: ssl_handshake_timeout nie istnieje w module http nginx — należy do stream. W http uzgadnianie ogranicza client_header_timeout i to właśnie ta wartość wykonuje tu tę pracę.

O bramce SNI warto powiedzieć osobno, bo robi coś mniej oczywistego niż chowanie się przed skanerami. Bez niej serwer podaje ten sam certyfikat — a więc to samo ostrzeżenie przeglądarki — dwóm odwiedzającym w przeciwstawnych sytuacjach: temu, którego aplikacja porównała Twój klucz z rekordem, zanim ruszył choć jeden bajt strony, i temu, kto wpisał Twój adres IP, gdzie nie sprawdzono niczego. Bramka usuwa ten drugi przypadek. Nie zamienia ostrzeżenia w weryfikację: kto zna Twoją nazwę, wpisze ją sobie do własnego hosts i przyjdzie niesprawdzony dokładnie jak wcześniej.

Jedna zasada dotycząca samych stron, łatwo ją przeoczyć: używaj odnośników względnych. /about, a nie https://mysite.lopux/about. Odwiedzający w trybie zwykłego http:// nie przejdzie po bezwzględnym odnośniku https:// do Twojej własnej strony, a Lopux-Internet celowo nie przepisuje Twoich stron. Odnośniki do innych witryn to Twoja sprawa i nic im nie jest.

5. Opublikuj odcisk klucza

Otwórz swoją nazwę w portalu i przewiń do sekcji Certyfikaty. Dopóki nic nie jest opublikowane, mówi to wprost: nie ma z czym porównać, więc aplikacja odmówi otwarcia strony, zamiast łączyć się bez weryfikacji.

Sekcja „Certyfikaty", jeszcze bez publikacji

Wgraj site.crt przyciskiem Wybierz plik certyfikatu… albo wklej go. Tylko certyfikat — plik zaczynający się od -----BEGIN PRIVATE KEY----- zostaje na Twoim serwerze, a portal go odrzuci, zamiast gdzieś zapisać.

Certyfikat wklejony w pole, pod nim przycisk publikacji

Naciśnij Opublikuj odcisk klucza. Portal odczyta certyfikat, weźmie SHA-256 jego klucza publicznego i zapisze wynik w Twojej strefie.

Opublikowany odcisk i potwierdzenie, jaki klucz rozpoznano

Porównaj go z własną kopią — muszą się zgadzać:

openssl x509 -in site.crt -noout -pubkey \
  | openssl pkey -pubin -outform der | openssl dgst -sha256

Ta sekcja to frontowe drzwi do zwykłego rekordu. Ta sama wartość leży na liście rekordów jako rekord TLSA pod _443._tcp i tam ją widać:

Rekord TLSA na zwykłej liście rekordów

6. Skieruj nazwę na swój serwer

W tym samym widoku dodaj rekord A, którego wartością jest publiczny adres Twojego serwera. @ oznacza samą nazwę.

Formularz rekordu A z adresem serwera

Teraz strefa niesie oba rekordy i razem są one wszystkim, czego potrzebuje aplikacja odwiedzającego: rekord A mówi, gdzie jest Twój serwer, a TLSA — jaki klucz musi on okazać.

Oba rekordy na liście: TLSA i A

Załóż jakieś dziesięć minut, zanim zmiana będzie widoczna wszędzie. Po drodze stoją dwie pamięci podręczne — resolwera i aplikacji — po pięć minut każda.

7. Sprawdź

Portal pobiera Twoją stronę tak, jak zrobiłby to odwiedzający, i mówi, co przeszkodziłoby jej działać: klucz niezgodny z opublikowanym, brakujący odcisk, nagłówek HSTS, przekierowanie na https://, bezwzględne odnośniki do siebie albo serwer, który nie odpowiedział.

Sprawdzenie informuje, że adres nie jest publiczny

Na tym zrzucie sprawdzenie odmawia wykonania: adres w przykładzie jest adresem dokumentacyjnym, a portal nie zagląda tam, gdzie nie da się dotrzeć z internetu — skierowanie nazwy na adres prywatny lub pętli zwrotnej zamieniłoby sprawdzenie w sondowanie czyjejś sieci. Przy prawdziwym serwerze pod prawdziwym adresem odpowiada, że ze stroną wszystko w porządku, albo nazywa dokładnie, co jest nie tak.

Dwa sprawdzenia, które możesz zrobić sam, i to właśnie one liczą się najbardziej:

# bez SNI — odmowa
openssl s_client -connect YOUR_ADDRESS:443 </dev/null

# Twój certyfikat
openssl s_client -connect YOUR_ADDRESS:443 -servername mysite.lopux </dev/null

Drugie powinno podać Ci certyfikat, którego odcisk opublikowałeś. Weź odcisk jego klucza tak samo jak w §5 i porównaj: jeśli ciągi się różnią, każdy odwiedzający dostaje odmowę, a dla niego wygląda to dokładnie jak próba podszycia się.

8. Co widzi odwiedzający

Dobrze ustawiona strona otwiera się pod własną nazwą, jak każda inna:

Strona lopux.ipvx otwarta pod własną nazwą

To lopux.ipvx — własna strona tego projektu. Żyje w przestrzeni nazw tak samo, jak będzie żyła Twoja, i jest postawiona dokładnie w tym kształcie. Klucz, który podaje, zgadza się z jej opublikowanym odciskiem — i właśnie dlatego aplikacja otwiera ją bez słowa ostrzeżenia.

Co dostają różni odwiedzający:

OdwiedzającyCo widzi
aplikacja, nazwa w otwartej strefie takiej jak .lopuxzwykła kłódka, wszystko działa
aplikacja, własna nazwa korzeniowaza każdym razem ostrzeżenie przeglądarki o certyfikacie — odcisk i tak jest sprawdzany pod spodem
aplikacja, http:// w pasku adresustrona wygląda skromnie; skok do Twojego serwera i tak jest szyfrowany, a klucz sprawdzony
bez aplikacjinic. Nazwa nie rozwiązuje się poza Lopux-Internetem

Ostatni wiersz to sens przestrzeni nazw, a nie jej ograniczenie. Zwróć jednak uwagę na wiersz wyżej: Twój serwer to zwykła publiczna maszyna i każdy może do niego trafić po adresie. Przestrzeń nazw go nie ukrywa, a Twój certyfikat podaje nazwę Twojej strony każdemu, kto dokończy uzgadnianie — po to właśnie jest bramka SNI z §4.

9. Jak dbać o klucz

Nic tutaj nie wykryje kradzieży klucza; system czyni jedynie wiążącym powiązanie Twojej nazwy z Twoim kluczem. Ten, kto ma Twój klucz, uwierzytelnia się bez zarzutu, dopóki nie opublikujesz nowego odcisku.

10. Kiedy coś jest nie tak

Aplikacja nazywa usterkę, zamiast pokazywać pustą stronę. Co znaczy każda z nich:

Co słyszy odwiedzającyCo to znaczyCzyj ruch
Dla tej nazwy nie opublikowano odcisku kluczaw strefie nie ma rekordu TLSATwój — §5
To nie jest strona, za którą się podajeklucz Twojego serwera nie jest tym opublikowanymTwój — zmieniłeś certyfikat, nie publikując nowego odcisku
Strona nie odpowiedziałanazwa i klucz są w porządku, serwer się nie odezwałTwój — sprawdź serwer i rekord A
Ta strona nie może działać po zwykłym httpbezwzględne odnośniki https:// do Twojej własnej stronyTwój — zrób je względnymi (§4)
Ta aplikacja potrzebuje aktualizacji, żeby otworzyć tę stronęaplikacja odwiedzającego jest starsza niż Twoja strefajego — niech zaktualizuje; z Twoją stroną wszystko dobrze

Wszystkie instrukcje