Почему я получаю «экран заканчивается» без рута?

23

Я установил экран на Fedora 19. Когда я тестирую команду как root удаленно через SSH, она работает отлично. Например, если я ввожу screenновый терминал, эмулятор запускается и ждет команды. Я могу отсоединить его и т. Д. Однако, когда я пытаюсь сделать то же самое, когда я удаленно вошел в систему через SSH как обычный пользователь, команда немедленно завершается. Единственное сообщение, которое я вижу, это [screen is terminating].

У кого-то уже была эта проблема? Это связано с плохими разрешениями?

Обновить:

$ 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 +++

Я пытался изменить разрешения на 777, но затем, когда я выполняю screen, я получаю:

Каталог '/ var / run / screen' должен иметь режим 775.

Поэтому я отменил свои изменения.

Laurent
источник
Какая команда?
13
Самый простой: «экран». Я записал пример на shelr.tv/records/525179c7966080791000005f
Вы случайно не используете VPS или хост-сервер?
13
Это хост-сервер
strace -e trace=file screenпроверить, не удается ли при доступе к файлу. Или использует tmuxв качестве обходного пути, он работает так же, за исключением того, что он использует ^ b вместо ^ a.
Эммануэль

Ответы:

5

Переключение между «должен иметь режим 777» и «должен иметь режим 775» вызвано strace.

screenобычно это программа setuid или setgid. При выполнении он получает дополнительные привилегии, которые используются для создания файлов сокетов и / или изменения utmp.

Когда процесс отслеживается, setuid и setgid отключены. Процесс трассировки, контролируемый менее привилегированным пользователем, может взять на себя отслеживаемый процесс, поэтому он должен работать без своих дополнительных привилегий, чтобы не дать исходному пользователю слишком много полномочий.

screen определяет, выполняется ли он с привилегиями setuid, привилегиями setgid или нет, и соответствующим образом корректирует свои ожидания в отношении прав доступа к каталогу.

Так что это создает класс проблем, которые не могут быть легко отлажены strace.

Но если вы root, есть обходной путь! Если процесс трассировки выполняется от имени пользователя root, то отслеживаемый процесс может получить привилегии в обычном режиме. Итак, вот что вы делаете:

  1. Откройте 2 новых терминала
  2. В первом терминале войдите на удаленную машину как пользователь root
  3. Во втором терминале войдите на удаленный компьютер как обычный пользователь
  4. Используется psдля получения PID процесса оболочки обычного пользователя во втором терминале.
  5. В первом терминале запустите strace -f -p SHELLPID
  6. Во втором терминале запустите экран и посмотрите, как он провалится
  7. В первом терминале у вас теперь есть страйс-лог, который вам нужен, чтобы узнать, что действительно не так.

Ключевым дополнением к straceкоманде является -fпараметр, который указывает ей отслеживать дочерние процессы. Он нужен для отслеживания экрана, который будет дочерним по отношению к процессу оболочки, который вы указали -p.

Я также хотел бы использовать -ffи указать выходной файл с помощью -o, как в

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

который создаст отдельный выходной файл для каждого дочернего процесса. После этого вы читаете их, less /tmp/screentrace*и результат, как правило, чище, чем тот, который вы получаете, используя один -f.

ОБНОВИТЬ

Теперь, когда я увидел вывод strace, я не знаю точно, что пошло не так, но эта строка - самая удивительная вещь в трассировке:

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

Несколькими строками ранее он создал pty, который, как выяснилось, TIOCGPTNбыл номером 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

Но это не было в состоянии подавить это. Я не знаю, почему этот chown потерпит неудачу, но ошибка chown действительно дает правдоподобную причину, по которой экран сдался. Вы можете получить немного больше информации, добавив -vопции strace и посмотрев statпосле, TIOCGPTNчтобы увидеть, кому принадлежит /dev/pts/запись.


источник
Спасибо за подробную процедуру. Я пытался посмотреть на вывод, сгенерированный strace, но я не могу понять, что не так. Здесь и далее ссылка с содержимым трех файлов, созданных strace: pastebin.com/raw.php?i=aeqDwTBX, любая идея приветствуется :)
Laurent
2

Одна из возможных причин этой ошибки - неправильные политики selinux, но, по словам redhat bugtracker, такие ошибки были исправлены в fedora 17/18.

В качестве обходного пути вы можете изменить переменную SCREENDIRв вас ~/.bashrcчто-то вроде $HOME/.screen.

Александр Кудреватых
источник
Я пытался, но это не решает проблему.
Лоран
1

Когда я столкнулся с этим сообщением об ошибке. Я должен был отрегулировать свои разрешения следующим образом:

chmod 2775 /usr/bin/screen

И это решило проблему для меня. 2 очень важно для правильных разрешений доступа.

Вы должны прочитать больше о SUID, SGID, Sticky Bit, ACL и как они влияют на доступ.

Рорик
источник
U + S работает. Это нехорошо, но я не вижу других решений в данный момент.
Антти Рыцёля
0

Команда экрана уже запущена. Поэтому я прекратил это и набрал команду заново. Да, это не очень хорошее разрешение, как у других, но для этого требуется меньше времени.

Просто ps и найдите pid, убейте PID и продолжайте снова набирать команду на экране.

Если вы запускаете несколько экранных команд, убедитесь, что вы завершили правильный процесс, связанный с вашим терминалом.

Шри Харша
источник
0

Я обнаружил, что эта проблема решена после комментирования следующей строки в / etc / fstab и перезагрузки:

devpts         /dev/pts        devpts  defaults        0       0
Уто Дев
источник
0

Убедитесь, что никто другой screenне использует это устройство

Это может быть достигнуто с помощью /superuser/97844/how-can-i-determine-what-process-has-a-file-open-in-linux :

sudo lsof /dev/ttyS0

А затем убить этот процесс, если это так.

По какой-то причине при этом условии sudo screenвсе еще может получить доступ к устройству, но тогда это соединение пропустит символы, которые потребляются другим screen.

Убедитесь, что у пользователя есть права на чтение и запись в файл

Например, в Ubuntu вы хотите добавить пользователя в dialoutгруппу: /ubuntu//a/133244/52975

Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
источник