Kernel

Zablokowanie możliwości ładowania modułów kernela na Debian linux

Kernele oferowane przez różne dystrybucje linux'a, np. Debian czy Ubuntu, są tak budowane by możliwie jak największa ilość sprzętu na takim jądrze operacyjnym nam zadziałała bez zbędnego przerabiania systemu. Takie podejście sprawia, że nowo nabyty przez nas sprzęt możemy od razu podłączyć do komputera, a stosowne moduły po rozpoznaniu urządzenia zostaną załadowane do pamięci operacyjnej, przez co my będziemy mogli wejść w interakcję z takim kawałkiem elektroniki. Problem w tym, że kernel ma bardzo dużo tych modłów. Dużo modułów, to więcej kodu, a więcej kodu to więcej błędów, które na poziomie jądra mogą być bardzo opłakane w skutkach. Z zagrożeniem, jakie niosą moduły zewnętrzne (te spoza drzewa kernela linux), można sobie poradzić podpisując kernel kluczami od firmware EFI/UEFI. W takim przypadku załadowanie niepodpisanego modułu już się nie powiedzie. Niemniej jednak, dystrybucyjne kernele mają całą masę modułów do różnorakiego sprzętu, które na etapie budowania kernela są podpisywane, co otwiera im drogę do bycia załadowanymi w naszym systemie nawet jeśli nie posiadamy urządzeń, które by użytek z tych modułów robiły. Przydałoby się zatem zabezpieczyć możliwość ładowania modułów kernela w taki sposób, by jedynie administrator systemu miał możliwość określenia jakie moduły i na którym etapie pracy systemu mogą one zostać załadowane.

Automatyczny restart połączenia LTE na routerze WiFi z OpenWRT

Od już dłuższego czasu (będzie parę lat) korzystam z internetu LTE zamiast tradycyjnego połączenia przewodowego. Głównie ze względu na fakt, że w mojej okolicy nie ma praktycznie żadnych szanujących się ISP, z którymi warto by wejść w interakcję i podpisać z nimi jakąś sensową umowę. Poza tym, dla osób mojego pokroju, które cenią sobie mobilność, internet stacjonarny i tak jest mało praktyczny. Dlatego w moim domowym routerze mam wgrany firmware OpenWRT umożliwiający zainstalowanie na tym urządzeniu odpowiedniego oprogramowania obsługującego modemy LTE podłączane przez port USB. Połączenie sieciowe ze światem zwykle działa prawidłowo ale z jakiegoś powodu jest ono zrywane. Zwykle taka sytuacja ma miejsce w środku nocy (czasami parokrotnie), zwłaszcza gdy przekroczę limit danych i do końca okresu rozliczeniowego muszę przemęczyć się z lejkiem 1 mbit/s. Gdy ten lejek jest aplikowany, to zwykle odpalam sobie torrent'a, tak by pobrać najnowsze obrazy ISO tej czy innej dystrybucji linux'a. Niemniej jednak, jak mi net rozłączą, to nie załączy się on ponownie sam z siebie. Modem Huawei E3372s-153 w wersji NON-HiLink zdaje się pracować poprawnie, bo świeci się na nim dioda sugerująca, że połączenie z internetem jest nawiązane. Dlatego też postanowiłem w końcu ten problem rozwiązać raz na zawsze i mieć przy tym nieco spokojniejszy sen.

Chroot do 32-bit systemu ARM z poziomu 64-bit linux'owego hosta

Eksperymentując ostatnio z moją maszynką Raspberry Pi 4B, zaszła potrzeba, by zejść do systemu RasPiOS/Raspbian przy pomocy mechanizmu chroot. Problem w tym, że system wyrzuca komunikat: chroot: failed to run command ‘/bin/bash’: Exec format error . Niby wszystko jest na swoim miejscu ale ta widoczna wyżej wiadomość nie chce zniknąć uniemożliwiając tym samym dalszą zabawę z RPI. Okazało się, że winna jest tutaj architektura CPU. Mój laptop działa pod kontrolą 64-bitowego Intel'owskiego procesora (x64, x86-64, AMD64), na którym uruchomiony jest również 64-bitowy Debian linux. Z kolei Raspberry Pi ma 64-bitowy procesor ARM (ARMv8-A) działający pod kontrolą 32-bitowego systemu operacyjnego. Te dość spore rozbieżności sprawiają, że nie damy rady skorzystać z chroot, przynajmniej nie bez zaprzęgnięcia do tego celu emulatora QEMU.

Energy Performance Bias (EPB) i jego wpływ na wydajność CPU Intela pod linux

Przeglądając ostatnio log systemowy, zauważyłem, że pojawia się w nim komunikat kernel: ENERGY_PERF_BIAS: Set to 'normal', was 'performance' . Co prawda korzystam z laptopa i cokolwiek związane z energią ustawione w trybie wydajności nie zawsze zdaje się być optymalnym rozwiązaniem ale też moja maszyna zwykle jest podpięta do źródła zasilania i przydałoby się, by była ona skonfigurowana właśnie bardziej w stronę profilu wydajności niż oszczędności energii. Ten powyższy komunikat informuje nas zaś, że system zmienił ustawienia z performance (tryb wydajności) na normal (jakiś bliżej nieokreślony tryb normalny). Chodzi naturalnie o ustawienia trybu pracy procesora Intel. Postanowiłem zatem poszukać informacji na temat tego czym jest ten cały Energy Performance Bias (EPB) i jak go skonfigurować w odpowiedni sposób pod linux.

Zastosowanie KSM w maszynach wirtualnych QEMU/KVM

Użytkownicy linux'a, którzy korzystają z mechanizmu wirtualizacji QEMU/KVM, wiedzą, że takie maszyny wirtualne potrafią zjadać dość sporo pamięci operacyjnej. Im więcej takich maszyn zostanie uruchomionych w obrębie danego hosta, tym większe ryzyko, że nam tego RAM'u zwyczajnie zabraknie. Można oczywiście ratować się dokupieniem dodatkowych modułów pamięci ale też nie zawsze taki zabieg będzie możliwy, zwłaszcza w przypadku domowych stacji roboczych pokroju desktop/laptop. Szukając rozwiązania tego problemu natrafiłem na coś, co nazywa się Kernel Samepage Merging. W skrócie, KSM to mechanizm, który ma na celu współdzielenie takich samych stron pamięci operacyjnej przez kilka procesów. W ten sposób można (przynajmniej teoretycznie) dość znacznie obniżyć zużycie RAM, zwłaszcza w przypadku korzystania na maszynach wirtualnych z tych samych systemów operacyjnych. Przydałoby się zatem ocenić jak bardzo KSM wpłynie na wykorzystanie pamięci i czy będzie z niego jakiś większy użytek zarówno przy korzystaniu z maszyn wirtualnych, czy też w codziennym użytkowaniu komputera.

Konfiguracja HugePages pod maszyny wirtualne QEMU/KVM

W linux rozmiar stron pamięci operacyjnej RAM ma domyślnie 4096 bajtów (4 KiB). Maszyny wirtualne QEMU/KVM mają to do siebie, że wykorzystują dość spore zasoby pamięci (wile GiB), przez co mały rozmiar strony może niekorzystnie wpływać na wydajność systemów gościa. Chodzi generalnie o to, że rozrostowi ulega tablica stron, której przeszukiwanie jest czasochłonną operacją. By temu zaradzić, wymyślono TLB (Translation Lookaside Buffer), który ulokowany jest albo w CPU albo gdzieś pomiędzy CPU i główną pamięcią operacyjną. TLB to mały ale za to bardzo szybki cache. W przypadku systemów z duża ilością pamięci RAM, niewielki rozmiar TLB sprawia, że odpowiedzi na zapytania nie są brane z cache, tylko system wraca do przeszukiwania normalnej tablicy stron zlokalizowanej w pamięci RAM (TLB miss). Taka sytuacja jest bardzo kosztowna, spowalnia cały system i dlatego trzeba jej unikać. Na szczęście jest mechanizm HugePages, który pozwala na zwiększenie rozmiaru strony pamięci z domyślnych 4 KiB do 2 MiB lub nawet do 1 GiB w zależności od właściwości głównego procesora. W tym artykule postaramy się skonfigurować HugePages na potrzeby maszyn wirtualnych dla systemu Debian Linux.

Wirtualizacja QEMU/KVM (libvirt) na Debian Linux

Prawdopodobnie dla większości użytkowników linux'a, wirtualizacja kojarzy się w zasadzie z jednym oprogramowaniem, tj. VirtualBox. Niby strona VBox'a podaje, że jest on na licencji GPL-2 ale w Debianie nie ma go w głównym repozytorium (jest on obecny w sekcji contrib ). Problem z VirtualBox'em jest taki, że wymaga on kompilatora Open Watcom, który już wolnym oprogramowaniem nie jest. VBox też nie jest jedynym oprogramowaniem, które na linux można wykorzystać w roli hiperwizora do obsługi maszyn wirtualnych. Jest o wiele lepsze rozwiązanie, mianowicie QEMU, które jest w stanie zrobić użytek z maszyny wirtualnej kernela (Kernel Virtual Machine, KVM) i realizować dokładnie to samo zadanie, które zwykł ogarniać VirtualBox. Wirtualizacja na bazie QEMU/KVM jest w pełni OpenSource, co ucieszy pewnie fanów wolnego i otwartego oprogramowania, choć zarządzanie maszynami wirtualnymi odbywa się za sprawą konsoli. Oczywiście, osoby które korzystają z VirtualBox'a zdają sobie sprawę, że to narzędzie oferuje graficzny menadżer maszyn wirtualnych (Virtual Machine Manager, VMM), który usprawnia i znacznie ułatwia zarządzanie wirtualnymi maszynami. Jeśli GUI jest dla nas ważnym elementem środowiska pracy i nie uśmiecha nam się konfigurować maszyn wirtualnych przy pomocy terminala, to jest i dobra wiadomość dla takich osób, bo istnieje virt-manager , który jest dość rozbudowanym menadżerem maszyn wirtualnych pozwalającym na ich tworzenie, konfigurowanie i zarządzanie nimi przy wykorzystaniu graficznego interfejsu użytkownika. W tym artykule postaramy się skonfigurować naszego Debiana w taki sposób, by przygotować go do pracy z maszynami wirtualnymi posługując się qemu/libvirt/virt-manager .

Czym jest linux kernel driver binding

Bawiąc się ostatnio QEMU/KVM na swoim laptopie z zainstalowanym Debianem natrafiłem na ciekawe zagadnienie związane z wirtualizacją, tj. z PCI passthrough. Nie chodzi mi tutaj o samą technikę PCI passthrough ale o dobór sterowników do urządzeń działających pod kontrolą linux. Każdy sprzęt, który ma działać w systemie, musi mieć załadowany w pamięci RAM stosowny moduł kernela. Te moduły zwykle są ładowane automatycznie podczas pracy systemu, np. gdy podłączamy nowy sprzęt do komputera (można też te moduły ładować i ręcznie via modprobe ). Gdy nasz linux z jakiegoś powodu dobierze niewłaściwy (z naszego punktu widzenia) moduł dla jakiegoś urządzenia, to możemy to urządzenie odłączyć od komputera, a moduł bez problemu wyładować, po czym dokonać stosownych poprawek w systemie. Problem zaczyna się w sytuacji, gdy mamy do czynienia ze sprzętem, którego nie da się od komputera fizycznie odłączyć, np. wbudowana w płytę główną karta dźwiękowa, czy też wbudowana grafika bezpośrednio w CPU. Podobnie sprawa wygląda w przypadku wkompilowania modułów na stałe w kernel -- jak wyładować moduł, którego się nie da wyładować? By w takich sytuacjach zmienić przypisany urządzeniu sterownik trzeba dodać parę plików w katalogach /etc/modules-load.d/ / /etc/modprobe.d/ oraz zrestartować maszynę, tak by podczas fazy boot kernel dobrał sprzętowi pożądane przez nas moduły i ich konfigurację. Niemniej jednak, istnieje prostszy sposób na zmianę sterownika działającego w systemie sprzętu i to bez potrzeby fizycznego restartowania maszyny. Chodzi o mechanizm ręcznego przypisywania urządzeń do konkretnych sterowników (manual driver binding and unbinding).

Moduł LKRG (Linux Kernel Runtime Guard)

Jakiś czas temu opisywałem moduł TPE (Trusted Path Execution) dla kernela linux, który jest w stanie dość znacznie poprawić bezpieczeństwo naszego systemu. Ostatnio jednak natknąłem się na moduł LKRG (Linux Kernel Runtime Guard), którego to zadaniem jest stać na straży samego jądra operacyjnego i chronić je w czasie rzeczywistym przed różnego rodzaju zagrożeniami poprzez wykrywanie eksploitów wykorzystujących luki w jego mechanizmach bezpieczeństwa. Jako, że ja bardzo lubię zbroić swojego Debiana, to postanowiłem się przyjrzeć nieco bliżej temu całemu LKRG i sprawdzić jego użyteczność. Trzeba jednak wiedzieć, że LKRG jest dostarczany w formie osobnego modułu zamiast łaty na kernel, przez co trzeba będzie także postarać się o automatyzację pewnych rzeczy, m.in. procesu budowania modułu przy aktualizacji kernela via DKMS.

Jak załadować firmware karty WiFi przed initrd/initramfs

Każdy kto ma laptopa wyposażonego w kartę WiFi, czy też ogólnie komputer posiadający bezprzewodową sieciówkę, ten prawdopodobnie spotkał się z błędem podobnym do tego: Direct firmware load for iwlwifi-6000g2a-6.ucode failed with error -2 . W tym przypadku sprawa dotyczyła karty Intel Corporation Centrino Advanced-N 6205 [Taylor Peak] działającej w oparciu o moduł kernela iwlwifi . W takich przypadkach zwykle wystarczy zainstalować firmware od określonego modułu i po kłopocie. No i faktycznie w Debianie jest dostępny pakiet firmware-iwlwifi , który zawiera ten potrzebny plik iwlwifi-6000g2a-6.ucode . Problem jednak w tym, że instalacja paczki z firmware niekoniecznie może nam pomóc. Ten powyższy przykład nie jest odosobniony i czasami pliki z firmware muszą być dostępne w chwili ładowania kernela do pamięci RAM czy też na etapie initramfs/initrd. W takim przypadku zainstalowanie paczki z firmware w naszym linux'ie nic nam nie da, bo pliki rezydują na niezamontowanym jeszcze dysku. Jak zatem wybrnąć z tej wydawać by się było patowej sytuacji?