Не удается передать пароль для sudo su — имя пользователя с использованием комбинации Powershell + plink.exe

Контекст проекта

В настоящее время я работаю в очень ограничительной рабочей среде. Я знаю обо всех хороших практиках, связанных с SSH: ключи, ssh-agent и т. д., к сожалению, по разным причинам я не хотел бы сейчас вдаваться в подробности, я вынужден работать в очень строгих условиях.

Я осознаю «качество» рабочей среды, и если вы будете читать дальше, пожалуйста, постарайтесь относиться к этому вопросу как к чисто техническому вопросу и, возможно, даже как к технической задаче (в основном не спрашивайте о политике, стоящей за текущей ситуацией :)).


Контекст:

Виртуальная машина Windows с очень ограниченным набором доступных инструментов. Ограничено отсутствием доступа к Интернету и отсутствием разрешения на установку чего-либо стороннего (дополнительных инструментов, библиотек и т. д.).

Итак, что у меня есть в наличии:

  • Putty (включая plink.exe в качестве SSH-клиента командной строки)
  • Powershell 2.0

Используя эти инструменты, я хотел бы автоматизировать очень ограниченный рабочий процесс SSH, который в большинстве случаев выглядит следующим образом:

  • Вход по SSH на основе пароля с использованием личной учетной записи (ключи SSH не разрешены)

  • только sudo su - application_account для доступа к учетной записи приложения (нет доступа к /etc/sudoers, нет доступа к дополнительным командам sudoers, я могу только su для учетной записи приложения)

  • скрипты должны запрашивать пароль при каждом выполнении

Я получил работающую настройку автоматизации с Python + Fabric + автоматизацией подсказок, которая делала почти все, что я хотел. К сожалению, по разным причинам эта установка находится в «серой зоне» и может быть занесена в черный список.

Итак, теперь я пытаюсь использовать только инструменты, доступные в виртуальной машине, в настоящее время Powershell + plink.exe. К сожалению, я не могу перейти к последнему этапу автоматизации, запуску sudo su - application_account.

Я пробовал все, что мог придумать, почти все, основанное на использовании System.Diagnostics.Process для запуска plink.exe, а затем:

Либо перенаправьте стандартный ввод и отправьте серию команд, включая ответы на такие запросы:

$process.StandardInput.WriteLine($password)

Или отправьте пароль с помощью heredocs:

a)

# One-line heredoc.
echo $password | sudo su - application_account<<< ls

b)

# Multi-line heredoc.
echo $password | sudo -S su - <<END
ls
END

c) или почти любую комбинацию, включающую параметры sudo, такие как -k, -S, форматы heredoc и т. д.

Или используйте параметр -m plink.exe, чтобы создать файл, содержащий список команд, включая выполнение sudo su heredoc.

Или пытаетесь использовать входные данные на основе событий.

...

И многие, многие другие.

Я также не могу контролировать процесс, если я перенаправляю весь ввод/вывод (если я перенаправляю и блокировку процесса, и отладка действительно сложна, поскольку у меня нет тонны инструментов на виртуальной машине, и я не понимаю, почему она блокируется ).

Или sudo просто не принимает ввод пароля в качестве последнего шага смертельного удара.

Неужели невозможно контролировать plink.exe в таком ограничительном контексте? Должен заметить, что без доступа к учетной записи приложения автоматизация аккаунта невозможна (т.е. простая персональная автоматизация пользователя по SSH достигнута давно и ее недостаточно).

Меня интересуют возможные решения с использованием Powershell или любых других инструментов, которые поставляются непосредственно с Windows, в качестве рекомендаций по отладке установки. В принципе, как я мог понять, почему процесс блокируется. Или любая идея, которая не требует изменения административных настроек где-либо или установки дополнительных инструментов/приложений/библиотек.

В довершение ко всему, мой пароль содержит специальные символы, которые, похоже, не нравятся оболочке (я думаю). Любые рекомендации по их экранированию в Powershell/bash?

Изменить - код, который я использую прямо сейчас:

$procInfo = New-Object System.Diagnostics.ProcessStartInfo
$procInfo.RedirectStandardInput = $true
$procInfo.FileName="C:\Tools\PuTTY\plink.exe"
$procInfo.Arguments = "-t $sshHost"
$procInfo.UseShellExecute = $false

$process = New-Object System.Diagnostics.Process
$process.StartInfo = $procInfo
[void]$process.Start()

Start-Sleep -m 1000
$process.StandardInput.WriteLine($sshUser)
Start-Sleep -m 1000
$process.StandardInput.WriteLine($password)
Start-Sleep -m 1000
$process.StandardInput.WriteLine("sudo su - $applicationUser")
Start-Sleep -m 5000
$process.StandardInput.WriteLine($password)

person oblio    schedule 27.02.2017    source источник
comment
$process.StandardInput.WriteLine($password) с plink -t, вероятно, единственное жизнеспособное решение в вашей среде. Расскажите нам подробнее о проблемах, с которыми вы столкнулись при использовании этого подхода.   -  person Martin Prikryl    schedule 28.02.2017
comment
@Martin Prikryl Мне отказывают в доступе от sudo. Я повторно использую тот же $password, что и WriteLine, в ssh, и логин ssh работает, так что пароль хороший. Но когда я снова WriteLine, чтобы передать пароль sudo, я получаю $ Извините, попробуйте еще раз. Я предполагаю, что у меня есть специальные символы в пароле (вещи из !@#$%^&*()_+), и во второй раз на входе происходит какая-то интерпретация оболочки, но я не уверен как я могу лучше всего избежать пароля. Я пробовал -replace, но, похоже, мне не повезло. Например, он не заменяет все экземпляры.   -  person oblio    schedule 28.02.2017
comment
Я не думаю, что вам нужна специальная обработка специальных символов в пароле. В любом случае, попробовать сначала с простым паролем — хорошее начало. Вы пытались ввести пароль для sudo вручную в интерактивном терминале?   -  person Martin Prikryl    schedule 28.02.2017
comment
Да, это работает. Powershell, запустите plink, введите пароль, sudo su - application_account, введите пароль, все работает. Просто powershell + WriteLine($password) для sudo su - application_account не работает :(   -  person oblio    schedule 28.02.2017
comment
Покажите нам свой полный код.   -  person Martin Prikryl    schedule 28.02.2017
comment
@Martin Prikryl Я добавил код в качестве редактирования вопроса.   -  person oblio    schedule 28.02.2017
comment
Вы пробовали $process.StandardInput.Write(($password + "`n"))? В случае, если окончания строки Windows сломают его?   -  person Martin Prikryl    schedule 28.02.2017
comment
Может быть, даже для $process.StandardInput.Write("sudo su - $applicationUser`n") — на случай, если его LF просочится в пароль.   -  person Martin Prikryl    schedule 28.02.2017
comment
Пробовал, не повезло, использовал $password`n и sudo su - $applicationUser`n. У меня связанный с этим вопрос: после sudo я получаю доступ к консоли, т.е. вижу подсказку. Это похоже на то, что plink был фоновым, я вижу второе приглашение sudo, которое вы получаете после того, как оно отказывается от первого пароля.   -  person oblio    schedule 28.02.2017
comment
@Martin Prikryl Неважно, вы были правы, я допустил ошибку при вводе символа конца строки. Это сработало. ИМО, вы можете опубликовать комментарий как ответ :)   -  person oblio    schedule 28.02.2017


Ответы (1)


Вероятно, это последовательность Windows EOL, которую испускает WriteLine, которая плохо сочетается с sudo. Попробуйте явно использовать CR (*nix EOL):

$process.StandardInput.Write("sudo su - $applicationUser`n")
$process.StandardInput.Write(($password + "`n"))
person Martin Prikryl    schedule 28.02.2017