ssh: нет управления tty: open /dev/tty: нет такого устройства или адреса

При подключении с ПК/Cygwin через SSH (через WiFi) к телефону меня всегда встречает следующее жуткое сообщение:

$ ssh -T root@192.168.1.100 -p 50000
Authenticated with partial success.
root@192.168.1.100's password:
/system/bin/sh: No controlling tty: open /dev/tty: No such device or address
/system/bin/sh: can't find tty fd
/system/bin/sh: warning: won't have full job control
root@android:/ $

Я знаю, что устройство есть, и я также пробовал различные chmodразрешения.

Проблема в том, что я не могу использовать stty(или что-либо связанное с ttys) для установки переменных среды терминала, и поэтому я не могу использовать завершение командной строки TAB или стрелку вверх, чтобы получить последнюю команду или использовать и т. д. CTRL-C/D/ZЯ также пытался играл с разными set -oвариантами, безрезультатно.

Теперь странно то, что этой проблемы вообще нет при использовании локальной оболочки через приложение эмулятора терминала Android, которое, похоже, правильно назначает псевдотерминал с полным контролем над заданиями.

Я искал вверх и вниз, как решить эту проблему, но ничего не нашел. В моем телефоне Samsung используется версия с поддержкой SELinux (AOS 4.2.2), и я получил root-права с помощью CF-Auto-Root (v1.94) и использую последнюю версию ADB. Стандартный mksh и @(#)MIRBSD KSH R40 2011/10/07, следовательно, возможно, не полностью совместим с SEL AOS, но я не могу найти более новый (~ R49) двоичный файл MKSH ARM, чтобы попробовать.


РЕДАКТИРОВАТЬ-1 : я использую SSH-сервер .

РЕДАКТИРОВАТЬ-2 : я только что попробовал SSHelper , который кажется очень хорошим (хотя в 6 раз больше). Но он нестабилен и показывает аналогичные проблемы в веб-журнале:PTY allocation request failed on channel 0

РЕДАКТИРОВАТЬ-3 : После входа в систему (с новым сервером sshd) с помощью: ssh -T dummy@192.168.1.10 -p 2222, я теряю приглашение, но доступ к оболочке все еще в порядке. затем запустив, su -c /system/bin/sh -iверните мне правильное приглашение su #, и проверка set -oдаст:

u0_a202@MSM8960:home # set -o
Current option settings
allexport      off  login          off  nounset        off  verbose        off
bgnice         off  markdirs       off  physical       off  vi             off
braceexpand    on   monitor        on   posix          off  vi-esccomplete off
emacs          on   noclobber      off  privileged     off  vi-tabcomplete on
errexit        off  noexec         off  restricted     off  viraw          off
gmacs          off  noglob         off  sh             off  xtrace         off
ignoreeof      off  nohup          on   stdin          on
interactive    on   nolog          off  trackall       off
keyword        off  notify         off  utf8-mode      off

Но TAB по-прежнему напрямую интерпретируется как символ TAB, а не как завершение командной строки.

РЕДАКТИРОВАТЬ-4 : Это должна быть проблема, связанная с SELinux / SEAndroid , так как когда я отключаю SELinux Enforcing , устанавливая для него Permissive , я теряю возможность SU, но все обычные элементы управления терминалом оболочки работают. Это можно сделать, выполнив: su 0 setenforce 0в любой оболочке, которую вы можете получить, а затем выйдите из системы и снова войдите в систему. Это будет продолжаться до тех пор, пока вы не перезагрузите телефон.

РЕДАКТИРОВАТЬ-5 : Насколько я понимаю, использование этой ssh -tопции используется для принудительного выделения псевдотерминала и прерывания соединения в случае сбоя. Таким образом, происходит сбой, когда pty заблокирован в режиме " Enforcing ", в то время как использование ssh -2принимается с минимальной разницей в ошибках при использовании -vvvдля отладки.

$ ssh -t dummy@192.168.1.10 -p 2222 -vvv
...
dummy@192.168.1.10's password:
debug3: packet_send2: adding 64 (len 51 padlen 13 extra_pad 64)
debug2: we sent a password packet, wait for reply
debug1: Authentication succeeded (password).
Authenticated to 192.168.1.10 ([192.168.1.10]:2222).
debug1: channel 0: new [client-session]
debug3: ssh_session2_open: channel_new: 0
debug2: channel 0: send open
debug1: Requesting no-more-sessions@openssh.com
debug1: Entering interactive session.
debug2: callback start
debug2: fd 3 setting TCP_NODELAY
debug3: packet_set_tos: set IP_TOS 0x10
debug2: client_session2_setup: id 0
debug2: channel 0: request pty-req confirm 1
debug2: channel 0: request shell confirm 1
debug2: callback done
debug2: channel 0: open confirm rwindow 0 rmax 32768
debug2: channel_input_status_confirm: type 100 id 0
PTY allocation request failed on channel 0

Не принято, но этот следующий дает мне оболочку без каких-либо подсказок.

$ ssh -2 dummy@192.168.1.10 -p 2222 -vvv
...
PTY allocation request failed on channel 0
debug2: channel 0: rcvd adjust 2097152
debug2: channel_input_status_confirm: type 99 id 0
debug2: shell request accepted on channel 0
Linux 3.4.0-2340422 armv7l

Такое поведение убеждает меня думать, что оно напрямую связано с блокировкой ptyдоступа SELinux. Но я понятия не имею, как и где это делается.

РЕДАКТИРОВАТЬ-6 : Да, вот оно. Я только что нашел отказ политики SELinux в audit.logфайле: /data/misc/audit/audit.log

audit(1401291488.480:203): avc:  denied  { setattr } for  pid=11441 comm="sshelper_sshd" name="0" dev="devpts" ino=3 scontext=u:r:untrusted_app:s0 tcontext=u:object_r:untrusted_app_devpts:s0 tclass=chr_file VE=SEPF_GT-I9195_4.2.2_0022_M
audit(1401291488.480:203): arch=40000028 syscall=15 per=840000 success=no exit=-13 a0=beffd438 a1=190 a2=27da a3=c0000000 items=1 ppid=8499 pid=11441 auid=4294967295 uid=10202 gid=10202 euid=10202 suid=10202 fsuid=10202 egid=10202 sgid=10202 fsgid=10202 tty=(none) ses=4294967295 comm="sshelper_sshd" exe="/data/data/com.arachnoid.sshelper/bin/sshelper_sshd" subj=u:r:untrusted_app:s0 key=(null)
audit(1401291488.480:203):  cwd="/"
audit(1401291488.480:203): item=0 name="/dev/pts/0" inode=3 dev=00:09 mode=020600 ouid=10202 ogid=10202 rdev=88:00 obj=u:object_r:untrusted_app_devpts:s0

Итак, как это исправить?

Может ли быть какая-то проблема, вызванная sshd на устройстве, которое не может справиться с этим должным образом? Вы пропустили, чтобы включить информацию о том, какой именно. Может, попробовать другой?
@Izzy: добавил ссылку и попробую другую.
Кажется, в последних версиях Android что-то изменилось, что не позволяет ssh получить псевдотерминал (pts).
Я бы не удивился. Каждая новая версия Android поставляется с некоторыми, ммм, «сюрпризами»… Но если причина в этом, другие тоже будут затронуты (подтверждения, пожалуйста?). 4.2.2 уже не "такая новая".
Хм. Единственное, что я могу найти о SELinux для Android. У него есть некоторая информация об изменении политики SELinux, хотя, похоже, это связано с перестройкой некоторой ее части… может быть, связаться с ее разработчиками и попросить о помощи? Кроме того, вы спросили разработчика SSH? (Конечно, переключение на разрешительный режим исправит это.)
Да, я попросил разработчика, но он отсутствует до августа. Если бы я знал, как перестроить политику SELinux, я бы, наверное, так и сделал. Должны быть какие-то инструменты внедрения политик, но я пока не могу найти бинарники.

Ответы (1)

Вы используете ssh -T, что предотвращает выделение tty (4) . Без контроллинга ttyмногое не работает, без него ttyвообще много чего не работает.

Обратите внимание, что ваша первоначальная проблема связана не с отсутствием управляющего tty, а с отсутствием распределения пары pty/tty.

То, что вы здесь имеете, — это в основном строка ввода «редактирование» — в вашем случае не редактирование — на стороне клиента SSH , которая затем передается по ssh на устройство Android.

Попробуйте с ssh -t (нижний регистр t, обратите внимание на разницу). Я могу локально воспроизвести вашу проблему, запустив ssh -T localhost mksh -i, что также приводит к оболочке без какого-либо редактирования строки ввода, поэтому здесь можно решить распределение pty/tty.

Я предполагаю, исходя из правок по вопросу, что он /dev/ptmxсуществует и уже /dev/ptsсмонтирован , и что это проблема SELinux .

Настройка $TERMздесь ничего не решит: она просто указывает программам, использующим termcap или curses (mksh не использует ни того, ни другого), какой физический терминал (или его эмуляция) подключен к устройству tty. mkshиспользует ttyредактирование командной строки, если оно есть, и отключает редактирование командной строки, если его нет.

Вам нужно отредактировать политики SELinux, чтобы сервер SSH мог выделять пару pty/tty (или даже несколько) для каждого соединения.

(Этот ответ был отредактирован, чтобы сложить комментарии к этому и исходному вопросу, а также отразить некоторые изменения в вопросе.)

Да, это было первое, что я сделал, но потом решил использовать, -Tчтобы избежать проблемы с pty, передав переменную TERM вручную. Возможно неправильно? Каждый раз, когда я даю -tпереключатель, ssh принимает пароль, а затем терпит неудачу из-за разрешения на открытие pty с расширением PTY allocation request failed on channel 0. Однако использование -2(ssh2) позволяет мне пройти.
Спасибо за разъяснение. Cygwin не проблема, я использовал его много лет, и он всегда работает так, как ожидалось. Теперь я уверен, что это проблема политики SELinux, поскольку автор SSHelper использовал CyanogenMod для разработки и, следовательно, также не использовал политики SELinux и, вероятно, не реализовал их правильно. (Ни в одном из бесплатных приложений SSHd для Android нет.) Есть идеи, где найти файлы политик и как их редактировать?