Aplikowanie zmiennych sysctl przy pomocy udev'a
Spis treści
Kernele linux'owe mają dość sporo opcji, które możemy zmienić przy pomocy pliku /etc/sysctl.conf .
Niby nic nadzwyczajnego ale co w przypadku tych zmiennych, które muszą być ustawione, z tym, że
moduł, który stworzy odpowiednie ścieżki w katalogu /proc/sys/ , nie został załadowany z jakichś
względów przy starcie systemu? Zmienne te nie zostaną ustawione, a w logu pojawi się komunikat
informujący nas o nieodnalezieniu określonego pliku. Okazuje się, że jesteśmy w stanie aplikować
określone ustawienia sysctl w momencie ładowania określonych modułów i temu mechanizmowi się
przyjrzymy bliżej w tym wpisie.
Komunikaty zwracane przez systemd-sysctl
Przeglądając log systemowy, doszukałem się kilku komunikatów, których treść jest podobna do tej poniższej linijki::
# journalctl --no-tail -b -u systemd-sysctl
...
systemd-sysctl[430]: Couldn't write '30' to 'net/netfilter/nf_conntrack_icmpv6_timeout', ignoring: No such file or directory
...
Problem udało się rozwiązać i winne były dwa moduły, konkretnie nf_conntrack_ipv4 oraz
nf_conntrack_ipv6 , które nie ładowały się przy starcie systemu -- no bo nie było ich wpisanych do
pliku /etc/modules . Te dwa moduły były ładowane w późniejszej fazie startu systemu ale
ustawienia, które powinny zostać zaaplikowane, zostały zwyczajnie zignorowane.
Możemy naturalnie wpisać wszystkie niezbędne moduły (te, których wartości są określone w pliku
sysctl.conf) do pliku /etc/modules . Chodzi o to, że w systemd mamy dwie usługi odpowiedzialne
za ustawianie zmiennych kernela: systemd-modules-load.service , która ładuje moduły oraz
systemd-sysctl.service , która nakłada ustawienia z pliku sysctl.conf . Druga z nich ma wyraźnie
określoną zależność After=systemd-modules-load.service , dlatego też wszystkie moduły muszą być
pierw załadowane, by te zmienne mogły zostać zaaplikowane. Nie zawsze jest to jednak idealne
rozwiązanie.
Reguły udev'a dla określonych modułów
Co w przypadku gdy nie chcemy ładować wszystkich modułów przy starcie systemu? Przecie część z nich
możemy ładować w trakcie jego pracy, oczywiście, jeśli zachodzi taka potrzeba. W takim przypadku
musimy skorzystać z udev'a i napisać regułkę, która w chwili ładowania takiego modułu ustawi
określone dla niego opcje. W manualu
sysctl.d jest przykład takiej
reguły i ja na jej podstawie stworzyłem plik /etc/udev/rules.d/99-sysctl.rules o poniższej
treści:
ACTION=="add", SUBSYSTEM=="module", KERNEL=="nf_conntrack", \
RUN+="/lib/systemd/systemd-sysctl --prefix=/net/netfilter"
ACTION=="add", SUBSYSTEM=="module", KERNEL=="nf_conntrack_ipv4", \
RUN+="/lib/systemd/systemd-sysctl --prefix=/net/netfilter"
ACTION=="add", SUBSYSTEM=="module", KERNEL=="nf_conntrack_ipv6", \
RUN+="/lib/systemd/systemd-sysctl --prefix=/net/netfilter"
Opcja ACTION oraz SUBSYSTEM zawsze pozostaje bez zmian. Z kolei na pozycji KERNEL wpisujemy
nazwę modułu, tego, który zwykle ładowany jest przy pomocy modprobe lub też może zostać
wyświetlony via lsmod . W RUN następuje wywołanie odpowiedniego narzędzia dostarczanego przez
systemd z opcją --prefix, która odpowiada za lokalizację plików modułu w katalogu /proc/sys/ . W
tym przypadku, konfiguracja powyższych modułów znajduje się pod /proc/sys/net/netfilter/ , zatem
wszystkie wpisy w /etc/sysctl.conf odwołujące się do net.netfilter będą aplikowane przy
ładowaniu tych modułów.