Dlaczego dostaję komunikat „ekran się kończy” bez rootowania?

23

Zainstalowałem screen na Fedorze 19. Kiedy testuję komendę jako root zdalnie przez SSH, działa ona idealnie. Na przykład, jeśli wejdę, screennowy emulator terminala zostanie uruchomiony i czeka na polecenia. Mogę go odłączyć itp. Jednak gdy próbuję zrobić to samo, gdy jestem zalogowany zdalnie przez SSH jako standardowy użytkownik, polecenie natychmiast się kończy. Jedyna wiadomość, którą widzę, to [screen is terminating].

Czy ktoś już miał ten problem? Czy jest to związane ze złymi uprawnieniami?

Aktualizacja:

$ strace -e trace=file screen
execve("/usr/bin/screen", ["screen"], [/* 23 vars */]) = 0
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libtinfo.so.5", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libutempter.so.0", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libcrypt.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libpam.so.0", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libfreebl3.so", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libaudit.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
open("/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib/locale/UTF-8/LC_CTYPE", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
access("/home/steam/.nethackrc", F_OK)  = -1 ENOENT (No such file or directory)
readlink("/proc/self/fd/0", "/dev/pts/0", 4095) = 10
stat("/dev/pts/0", {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
lstat("/dev/pts/0", {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
open("/var/run/utmp", O_RDONLY)         = 3
open("/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 3
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libnss_files.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 3
open("/etc/shadow", O_RDONLY|O_CLOEXEC) = -1 EACCES (Permission denied)
readlink("/proc/self/fd/0", "/dev/pts/0", 4095) = 10
stat("/dev/pts/0", {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
stat("/dev/pts/0", {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
lstat("/dev/pts/0", {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
stat("/var/run/screen", {st_mode=S_IFDIR|0775, st_size=60, ...}) = 0
Directory '/var/run/screen' must have mode 777.
+++ exited with 1 +++

Próbowałem zmienić uprawnienia na 777, ale kiedy wykonuję screen, otrzymuję:

Katalog „/ var / run / screen” musi mieć tryb 775.

Dlatego cofnąłem moje zmiany.

Laurent
źródło
Jakie jest polecenie?
ewwhite
Najprostszy: „screen”. Przykład nagrałem
Czy przypadkiem korzystasz z serwera VPS lub hostowanego?
ewwhite
Jest to serwer hostowany
strace -e trace=file screenaby sprawdzić, czy nie powiedzie się podczas dostępu do pliku. Lub używa tmuxjako obejścia, działa tak samo, z tym że używa ^ b zamiast ^ a.
Emmanuel,

Odpowiedzi:

5

Przerzucanie między „must have 777” a „must have 775” jest spowodowane przez strace.

screenjest zwykle programem setuid lub setgid. Zyskuje dodatkowe uprawnienia po uruchomieniu, co służy do tworzenia plików gniazd i / lub modyfikowania utmp.

Podczas śledzenia procesu setuid i setgid są wyłączone. Proces śledzenia, kontrolowany przez mniej uprzywilejowanego użytkownika, może przejąć śledzony proces, więc musi działać bez dodatkowych uprawnień, aby uniknąć nadania pierwotnemu użytkownikowi zbyt dużej mocy.

screen wykrywa, czy jest uruchamiany z uprawnieniami setuid, setgid, czy nie, i odpowiednio dostosowuje swoje oczekiwania dotyczące uprawnień do katalogu.

Tworzy to klasę problemów, z którymi nie można łatwo debugować strace.

Ale jeśli jesteś rootem, istnieje obejście! Jeśli proces śledzenia działa jako root, wówczas śledzony proces może normalnie uzyskać uprawnienia. Oto co robisz:

  1. Otwórz 2 nowe terminale
  2. W pierwszym terminalu zaloguj się do komputera zdalnego jako root
  3. W drugim terminalu zaloguj się do zdalnego komputera jako zwykły użytkownik
  4. Służy psdo uzyskania PID procesu powłoki normalnego użytkownika w drugim terminalu
  5. W pierwszym terminalu uruchom strace -f -p SHELLPID
  6. Na drugim terminalu uruchom ekran i zobacz, jak się nie udaje
  7. W pierwszym terminalu masz teraz dziennik śledzenia, którego potrzebujesz, aby dowiedzieć się, co naprawdę jest nie tak.

Kluczowym dodatkiem do stracepolecenia jest -fopcja, która nakazuje śledzić procesy potomne. Potrzebujesz go do śledzenia ekranu, który będzie potomkiem procesu powłoki określonego za pomocą -p.

Lubię też używać -ffi określać plik wyjściowy za pomocą -o, jak w

strace -ff -o /tmp/screentrace -p SHELLPID

który utworzy osobny plik wyjściowy dla każdego procesu potomnego. Następnie czytasz je, less /tmp/screentrace*a wynik jest zazwyczaj czystszy niż to, co dostajesz za pomocą jednego -f.

AKTUALIZACJA

Teraz, gdy widziałem dane wyjściowe strace, nie wiem dokładnie, co poszło źle, ale ten wiersz jest najbardziej zaskakującą rzeczą w śladzie:

chown("/dev/pts/2", 1002, 5)            = -1 EPERM (Operation not permitted)

Kilka linijek wcześniej stworzył pty, które okazało TIOCGPTNsię być numerem 2.

open("/dev/ptmx", O_RDWR)               = 5
...
ioctl(5, TIOCGPTN, [2])                 = 0
stat("/dev/pts/2", {st_mode=S_IFCHR|0600, st_rdev=makedev(136, 2), ...}) = 0

Ale nie udało się tego zmienić. Nie wiem, dlaczego ten chown zawiódł, ale niepowodzenie chownu daje prawdopodobny powód, dla którego ekran się poddał. Możesz uzyskać nieco więcej informacji, dodając -vdo opcji śledzenia i patrząc na statpóźniej, TIOCGPTNaby zobaczyć, kto jest właścicielem /dev/pts/wpisu.


źródło
Dziękuję za szczegółową procedurę. Próbowałem przyjrzeć się wynikowi wygenerowanemu przez strace, ale nie mogę zrozumieć, co jest nie tak. Dalej jest związek z treścią trzech plików generowanych przez strace: pastebin.com/raw.php?i=aeqDwTBX każdy pomysł jest mile widziane :)
Laurent
2

Z możliwych przyczyn tego błędu - niepoprawne zasady selinux, ale według redhat bugtracker takie błędy zostały naprawione w Fedorze 17/18.

Aby obejść ten problem, możesz zmienić SCREENDIRw sobie zmienną ~/.bashrcna coś podobnego $HOME/.screen.

Alexander Kudrevatykh
źródło
Próbowałem, ale to nie rozwiązuje problemu.
Laurent
1

Kiedy napotkałem ten komunikat o błędzie. Musiałem dostosować swoje uprawnienia w następujący sposób:

chmod 2775 /usr/bin/screen

I to rozwiązało problem dla mnie. 2 jest bardzo ważne dla prawidłowych uprawnień dostępu.

Przeczytaj więcej na temat SUID, SGID, Sticky Bit, ACL i ich wpływu na dostęp.

Roric
źródło
działa u + s. To nie jest miłe, ale w tej chwili nie widzę innych rozwiązań.
Antti Rytsölä
0

Komenda ekranowa była już uruchomiona. Więc go zakończyłem i przepisałem polecenie. Tak, nie jest to całkiem dobra rozdzielczość jak inne, ale zajmuje to mniej czasu.

Po prostu ps i znajdź pid, zabij PID i ponownie uruchom komendę screen ponownie.

Jeśli korzystasz z wielu poleceń ekranowych, upewnij się, że zakończyłeś prawidłowy proces związany z twoim terminalem.

Shree Harsha
źródło
0

Znalazłem ten problem rozwiązany po skomentowaniu następującego wiersza w / etc / fstab i ponownym uruchomieniu:

devpts         /dev/pts        devpts  defaults        0       0
Uto Dev
źródło
0

Upewnij się, że nikt inny nie screenkorzysta z tego urządzenia

Można to osiągnąć za pomocą /superuser/97844/how-can-i-determine-what-process-has-a-file-open-in-linux :

sudo lsof /dev/ttyS0

A potem zabij ten proces, jeśli tak jest.

Z jakiegoś powodu, pod tym warunkiem, sudo screenmoże nadal uzyskiwać dostęp do urządzenia, ale wtedy to połączenie będzie brakowało znaków, które są konsumowane przez drugi screen.

Upewnij się, że użytkownik ma uprawnienia do odczytu i zapisu do pliku

Np. W Ubuntu chcesz dodać użytkownika do dialoutgrupy: /ubuntu//a/133244/52975

Ciro Santilli
źródło