Serwery sieciowe w trybie jądra: sprytna optymalizacja czy koszmar bezpieczeństwa?

28

Czytałem wątek Hacker News, w którym jeden użytkownik publikuje link z 2011 roku, wyjaśniając, że IIS jest znacznie szybszy niż większość innych serwerów (* nix). Inny użytkownik odpowiada, wyjaśniając, że IIS uzyskuje tę korzyść dzięki modułowi jądra o nazwie HTTP.sys . Według mojej wiedzy większość innych popularnych serwerów internetowych w 2015 r. Tego nie robi.

Nigdy nie chciałbym pisać serwera WWW w trybie jądra, ponieważ nigdy nie mogłem ufać sobie, że uwolni go od exploitów zabezpieczających (co byłoby mniej poważne, działając w niższym pierścieniu ochronnym).

Z punktu widzenia inżyniera oprogramowania (w przeciwieństwie do klienta serwerów WWW), czy działanie w trybie jądra jest mądrą decyzją dotyczącą wydajności? Czy problemy związane z bezpieczeństwem można złagodzić podczas opracowywania aplikacji do tego stopnia, aby serwer działający w trybie jądra stał się zyskiem netto dla konsumenta?

James Mishra
źródło
5
„Błąd serwera to witryna z pytaniami i odpowiedziami dla administratorów systemu i sieci”. Administratorzy systemów i administratorzy sieci nie piszą serwerów WWW; instalują i konserwują je. Myślę, że kwestia trybu jądra / trybu użytkownika jest o wiele bardziej istotna w czasie programowania niż w czasie instalacji. Nie mam nic przeciwko przeniesieniu pytania w bardziej odpowiednie miejsce, ale wydaje mi się, że błąd serwera nie znajdzie go również w temacie.
James Mishra
Ok, ponownie czytając pytanie, myślę, że można je interpretować jako ogólne pytanie dotyczące architektury oprogramowania, a nie pytanie o zalety i wady istniejących serwerów sieciowych, więc wycofałem mój głos. Ale możesz rozważyć edycję pytania, aby podkreślić ogólny aspekt architektury oprogramowania.
Doc Brown
2
Każdy, kto myśli, że serwer sieciowy w trybie jądra może poprawić wydajność, ponieważ nie musi przełączać kontekstu, powinien przeczytać: Liczby opóźnień, które powinien znać każdy programista . Pełny przełącznik kontekstowy w Linuksie kosztuje około 3000ns ( źródło ), ale wiele wywołań systemowych tak naprawdę nie potrzebuje pełnego przełącznika kontekstowego i może sięgać nawet 50ns, nie mam liczb dla Windows. Jest to gdzieś wzdłuż drugiej / trzeciej kolumny. Wniosek: zminimalizuj żądanie sieciowe i dysk, nie martw się przełącznikami kontekstu.
Lie Ryan,

Odpowiedzi:

24

Http.sys to nie tyle serwer WWW, co serwer proxy. Został zaprojektowany tak, aby pozwolić wielu serwerom internetowym współistnieć na komputerze z systemem Windows, dzięki czemu IIS może uruchamiać witrynę internetową, ale także kilka usług WCF działających z interfejsami http / REST lub SOAP, wszystkie na standardowym porcie 80. (dlatego właśnie nie można uruchomić Apache w systemie Windows bez drobnych problemów, Apache nie został zmodyfikowany do pracy z tym systemem rejestracji, szkoda, że ​​nie został bardziej przejrzysty dla aplikacji i wymaga pewnych dość skomplikowanych modyfikacji, aby się do niego przyczepić).

Działa to tak, że rejestrujesz w nim adres URL i odpowiednią aplikację, a gdy żądanie HTTP jest przesyłane na porcie 80, http.sys je akceptuje, ale następnie przekazuje żądanie do dowolnej zarejestrowanej aplikacji do obsługi tego celu adresu URL.


Wątpię, aby serwer sieciowy działający w trybie jądra miał jakiś sens - nawet jeśli w ten sposób można poprawić wydajność gniazda, aby wykonać jakąkolwiek użyteczną pracę, logika aplikacji będzie nadal wykonywana w przestrzeni użytkownika, więc zawsze jest przejście - właśnie przesunąłem go trochę wzdłuż stosu wywołań.

gbjbaanb
źródło
11
Podstawową zaletą pełnego serwera w trybie jądra jest serwowanie plików statycznych: można tego dokonać bez przełączania do trybu użytkownika. Możliwe jest także buforowanie.
Jules
3
Myślę, że HTTP.sys pochodzi z czasów, w których cykle procesora były znacznie rzadsze ... Nawet w przypadku serwowania małych plików statycznych (co jest najkorzystniejszym przypadkiem w przypadku HTTP.sys) serwer HTTP w trybie użytkownika prawdopodobnie spowodowałby maksymalne obciążenie większości sieci .
usr
4
@usr Http.sys to stosunkowo nowa rzecz, wprowadzona w systemie Windows Server 2003. Jestem prawie pewien, że istnieje, więc możesz uruchomić wiele usług interfejsu API sieci Web nasłuchujących na porcie 80 jednocześnie.
gbjbaanb
2
@ gbjbaanb serwer trybu użytkownika również może na to pozwolić. System Windows ma możliwość współużytkowania pamięci (buforów) i przekazywania uchwytu gniazda do innego procesu.
usr
1
@JamesMishra W mojej głowie tak. Wtedy procesory prawdopodobnie były> 10 razy mniej wydajne. Poza tym tak naprawdę nie było sposobu myślenia o bezpieczeństwie. Dzisiaj to po prostu zły telefon.
usr
14

Http.sys nie jest jedynym dostępnym serwerem sieciowym działającym w trybie jądra: pod Linuksem istnieje także tux . Jak prawidłowo zidentyfikowałeś, bezpieczeństwo jest problemem w tego rodzaju serwerach, co doprowadziło do tego, że tux nie został uwzględniony w głównym jądrze Linux-a (i uważam, że nie był aktualizowany dla nowszych wersji jądra).

Lepszym rozwiązaniem byłoby użycie systemu operacyjnego, który nie polega na ochronie sprzętowej w celu wymuszenia bezpieczeństwa procesu, np. Osobliwości Microsoftu: taki system pozwoliłby na zwiększenie wydajności serwera w trybie jądra bez ryzyka bezpieczeństwa. Niestety od 2015 roku nie są dostępne żadne gotowe do produkcji systemy operacyjne oparte na tej zasadzie, a AFAIK nikt też poważnie nad nimi nie pracuje (projekt Singularity został anulowany).

Jules
źródło
Duży problem związany z podejściem Singularity polega na tym, że oznacza to, że ale JITter może łatwo doprowadzić do eskalacji uprawnień.
CodesInChaos
2
Artykuł w Wikipedii Tux to ciekawa lektura. Tux może przekazywać żądania HTTP dotyczące treści niestatycznej na „prawdziwy” serwer WWW, taki jak Apache, co brzmi jak to, do czego służy Http.sys. Nie wiem, czy Tux był tak wydajny jak Http.sys, ale na podstawie tego, co niewiele przeczytałem, brzmi to tak, jakby deweloperzy jądra Linux nie zgodzili się ostro z decyzją Microsoftu.
James Mishra
10

Http.sys ma niskie ryzyko, ponieważ nie może obsłużyć żadnej poradzi dostarczonej przez firmę zewnętrzną.

Http.sys wykonuje kilka zadań.

  • Działa jako serwer proxy, dzięki czemu wiele procesów może odpowiedzieć na żądanie w różnych częściach przestrzeni nazw HTTP. Odpowiedź gbjbaanb obejmuje to dobrze.

  • Obsługuje pliki statyczne bezpośrednio z pamięci podręcznej plików systemu Windows. Zapewnia to duże przyspieszenie dla małych plików statycznych, ponieważ nie ma przełączników kontekstu.

  • Będzie buforować dane wyjściowe z dowolnej aplikacji, do której przesyła żądanie HTTP i zwraca wynik kasowany. Aplikacja ma pełną kontrolę nad tym, jak długo (jeśli w ogóle) trwa buforowanie.

Http.sys jest zaprojektowany do BARDZO szybkiego wykonywania prostych zadań, jednocześnie przekazując wszystko inne do procesu w przestrzeni użytkownika.

W odpowiedzi na komentarz

„niskie ryzyko, ponieważ nie może uruchamiać żadnego kodu dostarczonego przez firmę zewnętrzną” - tak zawsze mówią i prawie nigdy nie jest to prawdą.

Problem polega na tym, że musisz zaufać Microsoftowi, aby napisał skomplikowany kod jądra, aby zadać to pytanie, w przeciwnym razie zdecydujesz się nie używać systemu Windows do hostingu w ogóle . Http.sys niewiele zwiększa ryzyko błędów jądra, biorąc pod uwagę, jak skomplikowane jest jądro.

Jeśli cokolwiek, Http.sys zmniejsza ryzyko, ponieważ istnieje tak wyraźny podział poniżej „niskiego poziomu” serwisu WWW i kodu aplikacji.

W dobrze zaprojektowanej konfiguracji maszyna (lub serwer wirtualny), na której działa serwer WWW, ma bardzo ograniczony dostęp do reszty sieci, ponieważ stanowi cel wysokiego ryzyka. To bardzo niewiele różni się, jeśli zhakowane zostanie jądro lub serwer sieciowy w trybie użytkownika, ponieważ serwer nie powinien mieć więcej „praw” w sieci, wówczas proces trybu użytkownika serwera WWW musi wykonać swoją pracę.

Ian
źródło
1
Aplikacje trybu użytkownika są często pisane w bezpiecznych językach, co wyklucza większość błędów opartych na uszkodzeniu pamięci (są to zazwyczaj te, które prowadzą do zdalnego wykonania kodu).
CodesInChaos
3
Nie jestem pewien, czy kupię argument, że jeśli ufam Microsoftowi w pisaniu kodu jądra, to jest niewielki skok, aby ufać im, że piszą kod serwera WWW w trybie jądra. Jestem dość naiwny z punktu widzenia bezpieczeństwa informacji, ale wyobrażam sobie, że o wiele łatwiej byłoby uzbroić przepełnienie bufora w Http.sys niż w sterowniku urządzenia lub innej części jądra dalej od Internetu.
James Mishra,