Ten artykuł zawiera odpowiedzi na często zadawane pytania dotyczące zbierania zrzutów na platformie .NET.
Dlaczego zbieranie zrzutów kończy się niepowodzeniem w systemie Linux?
Aby zaimplementować kolekcję zrzutów, procesy platformy .NET tworzą proces podrzędny o nazwie createdump. Ten proces podrzędny używa interfejsu API systemu Linux ptrace(), a także odczytuje z systemu plików /proc w celu uzyskania dostępu do danych wątku i pamięci zapisanych w pliku zrzutu. Chociaż użycie interfejsu API jest dozwolone przez domyślne ustawienia zabezpieczeń w wielu dystrybucjach systemu Linux, czasami mniej typowa konfiguracja zabezpieczeń odmówi dostępu. Dane wyjściowe z procesu createdump zapisane w konsoli aplikacji są po cenach dumpingowych, takie jak:
[createdump] The process or container does not have permissions or access: open(/proc/1234/mem) FAILED Permission denied (13)
Jednym z powodów odmowy dostępu jest to, że piaskownica zabezpieczeń przechwytuje wywołanie przy użyciu seccomp filtru BPF. W przypadku aplikacji działających w kontenerze korzystających z technologii Open Container Initiative profil seccomp
musi zezwalać na wywołania ptrace
. Na przykład Docker
używa kontenera w środowisku uruchomieniowym kontenera. Podczas inicjowania określa domyślny profil seccomp, który zezwala na ptrace
tylko wtedy, gdy host kontenera ma wersję jądra wyższą niż 4.8 lub czy CAP_SYS_PTRACE
możliwości określono w kontenerze.
Jeśli wywołania nie są przechwytywane, jądro wykonuje różne wbudowane kontrole dostępu. Dokumenty dla ptrace() zawierają szczegółowy opis w pobliżu końca zatytułowany "Sprawdzanie trybu dostępu Ptrace", który opisuje sposób ich wykonania. Uzyskiwanie dostępu do systemu plików /proc używa również odmiany tego samego sprawdzania trybu dostępu ptrace. Poniżej znajduje się skrócone podsumowanie wykonanych kontroli zabezpieczeń i miejsc, w których można odmówić dostępu:
- Proces wywołujący musi mieć ten sam identyfikator użytkownika co proces docelowy lub proces wywołujący musi mieć CAP_SYS_PTRACE. Jeśli żadna z tych wartości nie jest prawdziwa, odmowa dostępu. Ponieważ środowisko uruchomieniowe platformy .NET nie wykonuje żadnych czynności, aby zmienić konto użytkownika podczas uruchamiania pliku createdump, identyfikatory użytkowników powinny być zgodne i ten krok powinien zakończyć się powodzeniem.
- Jeśli element createdump nie ma CAP_SYS_PTRACE (nie jest domyślnie), proces docelowy, który jest po cenach dumpingowych, musi być oznaczony jako "możliwy do zrzutu". Domyślnie większość procesów w systemie Linux jest z możliwością zrzutu, ale to ustawienie można zmienić, wywołując z opcją PR_SET_DUMPABLE. Jeśli dodasz możliwości do procesu przy użyciu narzędzia setcap, może to również spowodować zatrzymanie zrzutu procesu. Aby uzyskać bardziej szczegółowy opis ustawienia możliwego do zrzutu i przyczyn jego wyłączenia, zobacz dokumentacji systemu Linux.
- Wszystkie włączone moduły zabezpieczeń systemu Linux (LSMs) są wyliczane, a każdy z nich musi zatwierdzić dostęp. Niestety, jeśli LSM odmawia dostępu, nie ma jednolitego mechanizmu raportowania systemu Linux, aby wiedzieć, który z nich jest odpowiedzialny. Zamiast tego należy określić, które z nich są włączone w systemie, a następnie zbadać poszczególne elementy. Możesz określić, które maszyny LSM są aktywne, uruchamiając polecenie:
cat /sys/kernel/security/lsm
. Chociaż każdy LSM może być odpowiedzialny, Yama, SELinuxi AppArmor są często istotne.
Aplikacje AppArmor i SELinux mają rozbudowane mechanizmy konfiguracji i raportowania, więc jeśli chcesz dowiedzieć się, jak z nimi pracować, najlepiej jest wyświetlić własną dokumentację każdego projektu. Yama ma tylko jedno ustawienie konfiguracji, które można wyświetlić, uruchamiając polecenie:
cat /proc/sys/kernel/yama/ptrace_scope
To polecenie zwraca liczbę wskazującą bieżące zasady zabezpieczeń Yama ptrace:
- 0: Klasyczne uprawnienia trace.
- 1: Ograniczony ciąg.
- 2: Dołączanie tylko przez administratora.
- 3: Brak dołączenia.
Yama powinien udzielić dostępu do tworzenia w ramach zasad 0 i 1, ale oczekuje się, że dostęp zostanie odrzucony w ramach zasad 2 i 3. Zasady 3 zawsze odmawia dostępu, a zasady 2 nie działają domyślnie, ponieważ createdump zwykle nie ma możliwości CAP_SYS_PTRACE.
Dlaczego pobieram zrzuty tylko w systemie Linux, jeśli system dotnet-dump lub mój proces awarii jest uruchomiony z podwyższonym poziomem uprawnień?
Niektóre systemy oparte na systemie Linux są konfigurowane przy użyciu zasad zabezpieczeń, które wymagają dowolnego procesu zbierania zrzutu, aby mieć możliwość CAP_SYS_PTRACE. Zwykle procesy nie mają tej możliwości, ale uruchomienie podwyższonego poziomu uprawnień jest jednym ze sposobów jej włączenia. Aby uzyskać pełny opis wpływu zasad zabezpieczeń systemu Linux na zbieranie zrzutów, zobacz "Dlaczego zbieranie zrzutów kończy się niepowodzeniem w systemie Linux?".
Dlaczego nie mogę zbierać zrzutów podczas uruchamiania wewnątrz kontenera?
W przypadku aplikacji działających w ramach dowolnej technologii Open Container Initiative profil seccomp
musi zezwalać na wywołania ptrace(). Na przykład Docker
używa kontenera w środowisku uruchomieniowym kontenera. Podczas inicjowania środowiska uruchomieniowego określa domyślny profil seccomp, który zezwala ptrace
tylko wtedy, gdy host kontenera ma wersję jądra wyższą niż 4,8 lub czy określono CAP_SYS_PTRACE
możliwości.
Aby uzyskać pełny opis wpływu zasad zabezpieczeń systemu Linux na zbieranie zrzutów, zobacz pytanie "Dlaczego zbieranie zrzutów kończy się niepowodzeniem w systemie Linux?".
Dlaczego nie mogę zbierać zrzutów w systemie macOS?
W systemie macOS użycie ptrace
wymaga prawidłowego uprawnienia hosta procesu docelowego. Aby uzyskać informacje o minimalnych wymaganych uprawnieniach, zobacz Domyślne uprawnienia.
Gdzie mogę dowiedzieć się więcej na temat sposobu wykorzystania zrzutów w celu ułatwienia diagnozowania problemów w mojej aplikacji platformy .NET?
Oto kilka dodatkowych zasobów:
Jak mogę rozwiązać problem "Nie można znaleźć żadnej zgodnej wersji platformy"
W systemie Linux zmienna środowiskowa DOTNET_ROOT
musi wskazywać prawidłowy folder po ustawieniu. Gdy wskazuje inną wersję platformy .NET, dotnet-dump
zawsze generuje ten błąd. Jeśli zmienna środowiskowa DOTNET_ROOT
nie jest ustawiona, zostanie wygenerowany inny błąd ("Aby uruchomić tę aplikację, musisz zainstalować platformę .NET").