Uczyń proces niemożliwym do zabicia w systemie Linux

14

Pracuję nad aplikacją do zarządzania hasłami i ze względów bezpieczeństwa chcę uruchomić proces, którego nie można zabić.

Poza tym nie chcę, aby ten program był demonem, ponieważ muszę czytać ze standardowego wejścia i pisać na nim.

Czy jest na to sposób?

Mohammad Razeghi
źródło
11
„ze względów bezpieczeństwa chcę uruchomić proces, którego nie można zabić”. Tylko uwaga - gdyby było to dozwolone, ludzie mogliby z łatwością ją wykorzystać z niecnych powodów - np. Wystrzelić bombę widełkową, której nie można powstrzymać.
VLAZ
32
To brzmi jak problem XY . Podejrzewam, że cokolwiek naprawdę próbujesz osiągnąć, niemożliwy do zabicia proces nie jest na to sposobem. „Ze względów bezpieczeństwa” jest bardzo niejasne. Co dokładnie chcesz, aby użytkownik nie zrobił? Jaki mają dostęp?
Nate Eldredge,
4
Każdy proces, którego nie da się zabić dla wszystkich celów i celów, jest wirusem.
Naftuli Kay,
3
@NateEldredge: Raczej niech program zignoruje sygnały. To typowy sposób na zrobienie tego; w przeciwnym razie ktoś mógłby wysłać SIGINT lub SIGTSTP bezpośrednio do procesu, omijając terminal.
Noah Spurrier
2
@NoahSpurrier: Wyobrażam sobie sytuację, w której masz użytkownika, który może pisać rzeczy na konsoli, ale nie może w inny sposób wykonać kodu na komputerze (jak kiosk). Skonfigurujesz go tak, aby żaden klawisz, który można wpisać, nie miał nieoczekiwanego efektu. Jeśli potrafią wykonać inny kod, ignorowanie SIGINT i SIGTSTP i SIGQUIT nie pomaga; każdy, kto mógłby wysłać te sygnały bezpośrednio do procesu, może również wysłać SIGKILL lub SIGSTOP, których nie można zignorować.
Nate Eldredge

Odpowiedzi:

41

Dokonać bieg menedżer haseł na podstawie odrębnej użytkownika i uchwyt / ignore / sygnałów sterujących generowanych blokowe ( SIGINT, SIGQUIT, SIGHUP, SIGTSTP, SIGTTIN, i SIGTTOU).

Nie można wysyłać sygnałów do procesów (= kill) działających pod innym użytkownikiem (użytkownikiem, którego zarówno rzeczywisty identyfikator użytkownika, jak i zapisany identyfikator użytkownika różnią się od efektywnego identyfikatora użytkownika), chyba że efektywny identyfikator to 0 (root).

Wszystkie procesy będą nadal możliwe do wywołania przez rootowanie.

Aby uzyskać szczegółowe informacje, zobacz kill (2) .

PSkocik
źródło
15

Jedynym sposobem na unieważnienie procesu jest zaimplementowanie go jako wątku jądra , co nie jest trywialne.

Nadal możesz go zabić, ale byłoby to uszkodzenie dodatkowe związane z zamknięciem systemu operacyjnego.

Możesz także opracować niestandardowy moduł jądra, który ustawi SIGNAL_UNKILLABLEflagę dla twojego procesu. Ta flaga została zaprojektowana tylko dla init(lub systemddowolnego początkowego procesu uruchomienia jądra), które są jedynymi procesami użytkownika chronionymi przed bezwarunkowym zabiciem, ale nic nie zabrania obecności tej flagi dla regularnego procesu.

jlliagre
źródło
1
może to być proces inicjujący
muhmuhten
@muhmuhten Masz rację, init jest procesem przestrzeni użytkownika chronionym przed bezwarunkowym zabiciem. Nie jest jednak przeznaczony do dostosowywania, podczas gdy zdecydowanie istnieje interfejs API dla modułów jądra i wątków.
jlliagre
Aby rozwinąć moją własną odpowiedź, zakładam, że nie masz dostępu do konta root (co, nawiasem mówiąc, sugeruje, że jest to przykład zabawki, projekt kursu lub złośliwe oprogramowanie). Wyklucza to pomysł, że można do tego celu podłączyć moduł jądra. Zauważ też, że flaga SIGNAL_UNKILLABLE nie jest dostępna dla normalnych procesów i wyklucza niektóre ważne normalne operacje (takie jak vforking), dlatego uważałbym to za normalnie niepraktyczny przypadek krawędzi.
GregD
@jlliagre rzeczywiście tak nie jest.
muhmuhten
@dudek Nie do zabicia proces jest już zwykle niepraktycznym przypadkiem na krawędzi.
jlliagre
11

Technicznie nie ma sposobu, aby proces był niemożliwy do zabicia.

Oczywiście dla użytkowników innych niż root mogą zabijać tylko procesy, które mają ten sam identyfikator użytkownika, co oni, więc jeśli możesz tworzyć różne konta, możesz użyć „unikalnego” identyfikatora użytkownika dla procesu, a następnie tylko root może go zabić.

Prostym, ale mniej niezawodnym rozwiązaniem jest przechwycenie przez proces jak największej liczby sygnałów (być może ich zignorowanie). Jest to odpowiednie tylko dla przykładów zabawek lub środowisk nieprzyjmujących przeciwników, ponieważ nie ma sposobu, aby złapać sygnał KILL (sygnał 9), ale w przeciwnym razie możesz uniknąć ich zabicia.

Wreszcie możesz zorganizować odrodzenie procesu, jeśli zostanie zabity. Jest to również delikatne (bardzo delikatne), ale utrudni jego usunięcie. Można tego dokonać za pomocą własnego procesu monitorowania lub inittab. Dla przeciwnika, który wie, co robią, można to łatwo obejść, zabijając wiele procesów jednocześnie.

GregD
źródło
1
Ale (poza inittab) możliwe jest, że proces monitorowania również może zostać zabity, nie?
roaima
Nie, sterowniki urządzeń (moduły jądra) mogą tworzyć procesy, których root nie może zabić.
Noah Spurrier