Dlaczego Port-Share sprawia, że wszyscy odwiedzający witrynę wyglądają jak localhost
Backend widzi skok przekierowania, nie przeglądarkę. Sprawdź, gdzie ginie adres źródłowy, a następnie zdecyduj, który komponent może za niego ręczyć.
Każdy wiersz dziennika dostępu pokazuje ten sam adres loopback, podczas gdy strona sama się wczytuje, a certyfikat jest poprawnie weryfikowany. Nic nie jest zepsute w sensie niedostępności i właśnie dlatego ten stan trwa miesiącami. Zepsuło się przypisanie: backend sieciowy zapisuje adres skoku, który przekazał połączenie, a każda późniejsza decyzja, która ufała dziennikowi, odziedziczyła tę samą błędną odpowiedź.
Poniższe kontrole idą od kabla do środka. Zatrzymaj się na pierwszej, która wyjaśnia widoczną wartość, ponieważ każdy kolejny krok zakłada, że poprzednie są już prawdziwe. Żadna z nich nie wymaga zgadywania konfiguracji frontendu.
Śledź dwa połączenia, nie linię dziennika
Port-Share multipleksuje dwa protokoły na jednym nasłuchu TCP. OpenVPN sprawdza pierwsze bajty połączenia przychodzącego, zatrzymuje je, gdy wygląda jak jego własny protokół, a wszystko inne przekazuje do drugiego celu. Ten cel to zwykle serwer WWW na tym samym hoście, więc zaakceptowane gniazdo serwera WWW ma proces OpenVPN jako partnera.
ss -ltnp 'sport = :443'
ss -tnp 'dport = :8080'
Pierwsze polecenie pokazuje, kto jest właścicielem publicznego nasłuchu. Drugie pokazuje połączenia docierające do portu backendu, a adres ich partnera to ten, który wydrukuje dziennik dostępu. Jeśli tym partnerem jest loopback, dziennik jest dokładny, a informacja zginęła o warstwę wcześniej. Zmiana nazwy pola w dzienniku lub włączenie modułu IP klienta nie odzyska adresu, którego połączenie nigdy nie niosło.
To jest kontrola, która rozstrzyga wszystko inne. Jeśli partnerem backendu jest adres przeglądarki, współdzielenie portu nie jest twoim problemem, a format dziennika jest.
Przekazywanie transportu nie jest wstrzykiwaniem nagłówka
Przekaźnik przesuwa bajty. Nie parsuje HTTP, więc nie może wstawić nagłówka do żądania, którego nigdy nie czyta jako żądania, ani nic dodać do strumienia TLS, który przepuszcza nietknięty. Moduł oczekujący nagłówka proxy będzie nadal czekał na taki, którego żaden komponent nie produkuje.
Oryginalny adres mogą nieść dwa mechanizmy i oba wymagają zgody po obu stronach. Protokół PROXY dodaje mały nagłówek na początku połączenia, a backend musi być skonfigurowany, by go oczekiwać; backend, który go nie oczekuje, potraktuje te bajty jako początek żądania i zawiedzie w mylący sposób. Zaufane nagłówki proxy, takie jak X-Forwarded-For, działają, gdy proxy rozumiejące HTTP je ustawia, a backendowi mówi się, które pary mogą je potwierdzać.
Żaden z nich nie jest automatyczny i żaden nie jest domyślnie bezpieczny. Backend, który wierzy każdemu przychodzącemu przekazanemu nagłówkowi, pozwala klientowi wybrać własny adres, co zamienia niedokładność dziennika w obejście kontroli dostępu. Uruchom demonstrację raz na hoście testowym, zanim zaufasz jakiemukolwiek nagłówkowi na ścieżce produkcyjnej.
curl -sS -H 'X-Forwarded-For: 127.0.0.1' https://site.example.com/health
grep -F '127.0.0.1' /var/log/nginx/access.log | tail -n 3
Opcjonalny katalog mapowania źródeł
Współdzielenie portu ma opcjonalny argument katalogu, który zapisuje mapowanie między oryginalnym adresem źródłowym a połączeniem przekazującym, na platformach, gdzie funkcja jest zaimplementowana. Oczekuje się, że strona internetowa będzie konsultować to mapowanie; nie jest to nagłówek i nie jest wstrzykiwane do żądania.
Ten projekt warto znać, ponieważ wyjaśnia, dlaczego niektóre wdrożenia zgłaszają prawdziwe adresy, a inne nie, przy pozornie identycznej konfiguracji frontendu. Różnica jest po stronie odbierającej i zwykle mieszka w module lub łatce, której większość pakowanych serwerów WWW nie włącza domyślnie. Przeczytaj dokumentację swojego serwera WWW, aby poznać dokładny hook, który oferuje, i potwierdź, że moduł jest załadowany, zamiast tego zakładać.
Jeśli pójdziesz tą drogą, traktuj to jako integrację z dwóch połówek: mapowanie zapisywane przez przekaźnik i wyszukiwanie wykonywane przez backend. Zweryfikuj oba i potwierdź, że katalog przeżywa restart i nie rośnie nieograniczenie na zajętym nasłuchu.
Zdecyduj, który komponent ręczy za adres
Przed zmianą konfiguracji nazwij komponent, któremu wolno twierdzić adres klienta, oraz komponenty, którym wolno w to wierzyć. Jedna zapisana odpowiedź zapobiega zwykłemu dryfowi, w którym trzy różne warstwy ufają każda innemu źródłu.
Trzy projekty pokrywają większość potrzeb. Trzymaj publiczny nasłuch i nasłuch sieciowy oddzielnie, aby serwer WWW widział prawdziwe pary i nie istniał problem przypisania. Postaw z przodu odwrotne proxy rozumiejące HTTP, zakończ lub przeanalizuj żądanie tam i pozwól mu ustawić przekazany nagłówek dla backendu, który ufa tylko temu proxy. Albo zachowaj współdzielenie portu i zaakceptuj, że dzienniki pokazują skok, a reguły dostępu są pisane wobec tożsamości aplikacji, a nie adresu.
Nie działa traktowanie przekazanego adresu loopback jako dowodu, że żądanie powstało na tej maszynie. Ten wniosek jest dokładnie odwrotny: adres jest obecny właśnie dlatego, że lokalny komponent utworzył połączenie. Reguła napisana w ten sposób wpuszcza każdego, kto może dotrzeć do nasłuchu.
Testuj regułę, nie stronę
Ładująca się strona dowodzi, że ścieżka przekazywania działa, i nic nie mówi o przypisaniu. Testuj konsumenta adresu: regułę dostępu, limit szybkości, wpis audytu, wyszukiwanie geograficzne.
curl -sS -o /dev/null -w '%{http_code}\n' https://site.example.com/
tail -n 5 /var/log/nginx/access.log
grep -c '' /var/log/nginx/access.log
Porównaj autoryzowane żądanie zewnętrzne z zapisami zarówno frontendu, jak i backendu i potwierdź, że reguła, która powinna odmawiać, nadal odmawia, a ta, która powinna dopuszczać, nadal dopuszcza. Jeśli wiersz dziennika jest poprawny, ale reguła nadal zachowuje się tak, jakby wszyscy byli lokalni, reguła czyta inne pole niż to, które poprawiłeś.
Zakończ, zapisując łańcuch przypisania w notatkach wdrożeniowych: który nasłuch, który przekaźnik, który nagłówek lub mapowanie i który backend jest skonfigurowany, by mu ufać. Następna osoba czytająca wiersz dziennika będzie potrzebować wszystkich czterech, a brak tej notatki jest tym, co sprawia, że to samo zgłoszenie otwiera się ponownie rok później. Trzymaj ją obok konfiguracji, a nie w wątku czatu.