LINUX.ORG.RU

Создание ssh соединения через Python

 ,


0

1

Пишу себе тулзу, менеджер соединений ssh. Возник вопрос следующий: у меня есть все данные для входа по ssh, либо посредством пароля, либо используя PEM файл. Как лучше сделать, чтобы из-под питона открывать сессию ssh? При попытках авторизации PEM файлом, я получаю, что у файла нет должных разрешений, а если я делаю os.chmod("file.pem", 600) и даже os.chown("file.pem", os.geteuid(), os.getegid()), я попадаю на ошибку, мол, недостаточно разрешений. Саму сессию в идеале бы открывать командой os.system("ssh -i file.pem user@host -p 22"), куда я подставляю данные. При авторизации через пароль, я просто не могу вставить пароль, потому что ssh предоставляет терминал, и ничего из stdin он не слушает. Как быть? Программа задумывалась для упрощения жизни, но в идеале все должно сводиться к написанию команды и получению заветного терминала.

Есть такой пакет для питона: https://docs.fabfile.org/en/1.12.1/index.html
С помощью него можно делать так:

import fabric
conn = fabric.Connection("linux.org.ru", user="Yarosvet", connect_kwargs={"password": "12345"})
conn.shell()
rupert ★★★★★
()
Последнее исправление: rupert (всего исправлений: 1)
Ответ на: комментарий от rupert

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

Yarosvet
() автор топика

Решил! на помощь пришел pexpect. Код подключения с PEM:

s = pexpect.spawnu(f"ssh {user}@{ip} -p {port} -i {pem_path}")
s.interact()

Код подключения с паролем:

s = pexpect.spawnu(f"ssh {user}@{ip} -p {port}")
s.expect("assword:")
s.send(password + "\r")
s.interact()

Короче, щас сделаю релиз. Если кому нужен менеджер SSH, но от GUI тошнит, а терминальный ни один не подходит - добро пожаловать в мой репоз)

Yarosvet
() автор топика
Последнее исправление: Yarosvet (всего исправлений: 1)
Ответ на: комментарий от Yarosvet

терминальный ни один не подходит - добро пожаловать в мой репоз)

Их что еще и много (консольных менеджеров ssh)? Я без шуток, не в курсе.

Чем обычный openssh клиент может не подходить? Ну, и сомнительно как-то в плане безопасности подобные обвёртки использовать.

lnx4
()
Ответ на: комментарий от vbr

А как в обычном ssh клиенте пароль передать?

Как обычно: набрав ручками; копировать/вставить; крайний плохой вариант - bash на 10-ть строк (и то лучше, чем какой-то менеджер на 100500 строк кода).

Как правильно: ключи придумали 100 лет назад.

lnx4
()
Ответ на: комментарий от lnx4

Как правильно: ключи придумали 100 лет назад.

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

caoutchouckcha
()
Ответ на: комментарий от caoutchouckcha

Если утечёт хеш, 8 символов сбрутить реально. Я бы советовал от 64 битов, это где-то 14 символов, это уже за разумные деньги не сбрутить. Или добить до 96 битов и там — да, уже невозможно.

vbr ★★★
()
Ответ на: комментарий от lnx4

Вы еще не видели мои проекты трехлетней давности) Да согласен дофига у меня мусора получилось в этом коде, но я же не по своей воле, а потому что библиотека для TUI такая кривая. С другой стороны, уже начал на ней писать, да и не переписывать же саму библиотеку.. Быстрее так

Yarosvet
() автор топика
Ответ на: комментарий от vbr

Если утечёт хеш

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

Более того, напомни, какие там в современных дистрибутивах права на shadow файл, из которого ты хеш дергать собрался?

caoutchouckcha
()
Последнее исправление: caoutchouckcha (всего исправлений: 1)
Ответ на: комментарий от caoutchouckcha

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

Не обязательно. К примеру могли утечь старые бэкапы. Или как у меня был кейс, когда я рута получил в девайсе, в которых захардкоден пароль был, но его так и не смог сбрутить. Если бы смог - это мне бы многое облегчило. Девайсы разливаются из одного образа и пароль там одинаковый.

Пароль не просто так хранится там в захешированной правильным образом форме, несмотря на все права на файл.

vbr ★★★
()
Последнее исправление: vbr (всего исправлений: 1)

Судя по твоим ответам в треде, тебе надо не менеджер соединений ssh делать, а просто взять и ssh_config настроить. Или ты непременно хочешь ходить по паролю, но чтобы его за тебя машина помнила?

agentgoblin
()
Ответ на: комментарий от Yarosvet

За типы в коде плюсик, годно

s.expect(«assword:»)

Лол

chmod600_pem

Вот так лучше не делать. А то ходят тут всякие софтины меняют права доступа, потом ищешь что за хрень происходит.

upcFrost ★★★★★
()

узнаю старый добрый ЛОРчик. Человек написал свою софтинку (кому то наверняка полезную), а его тряпками, пропитанными известной жидкостью, отлупили по мордам

SpaceRanger ★★
()
Последнее исправление: SpaceRanger (всего исправлений: 1)
Ответ на: комментарий от SpaceRanger

Скорее, подали кучу идей. К сожалению, бесполезных. Подходило бы мне еще какое-то решение кроме своего менеджера который писал именно я, я может бы и не парился. А теперь вот еще и с питоном париться придется. Либа npyscreen противная, ей нужен питон не моложе 3.6, попытки поставить таковой из исходников ни к чему не привели (зависает на test fault_handlers). Но не в этом дело, питон 3.6 я поставил через pyenv. Дело в том, что он там кривой какой-то, и pyinstaller из под него не работает. А запускать свою прогу руками мне еще ленивее, чем писать каждый раз пароль к серверу. Планировалось скомпилить и запускать одной короткой командой. Что я предпринял: поставил виртуалку с кали, там поставил питон из исходников (там он почему-то отлично установился!). Но вижу все ту же ошибку:

python3.6 -m pyinstaller --onefile main.py
python3.6: error while loading shared libraries: libpython3.6m.so.1.0: cannot open shared object file: No such file or directory

На коренном дебиане это звучало так:

OSError: Python library not found: libpython3.6m.so.1.0, libpython3.6mu.so.1.0, libpython3.6.so, libpython3.6m.so, libpython3.6.so.1.0
    This means your Python installation does not come with proper shared library files.
    This usually happens due to missing development package, or unsuitable build parameters of the Python installation.
Yarosvet
() автор топика
15 сентября 2022 г.
Ответ на: комментарий от vbr

Мы видимо о разном говорили - я про серверы, а ты про некие однотипные железки к которым есть физический доступ. Да, в твоём случае можно shadow слить с соседнего устройства, но все же мы о разном.

caoutchouckcha
()

Опять несколько замечаний к коду.

  1. Эту байду:
__factory = None


def global_init(db_file):
    global __factory

Можно переписать в более коротком и понятном виде используя functools.lru_cache

Стал смотреть дальше, и увидел, что ты не исправил даже самый адский говнокод из предыдущей темы. Так ты станешь великим программистом! Продолжай дальше, за шедевры вроде list(sorted(list)) тебя непременно возьмут на должность не то что сеньора, а CTO в Google. Я даже не буду разжевывать тебе снова, почему это говнокод.

Ещё всё-таки не удержусь и порекомендую почитать, что такое ssh-askpass и зачем он нужен. Хотя… Нет, не читай, твой великолепный рост как разработчика без этого будет идти на порядок быстрее.

emorozov
()
Ответ на: комментарий от caoutchouckcha

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

Это уж не говоря о том, что чувак где-то нашёл десятилетия как заброшенную библиотеку для TUI и заюзал её, а теперь страдает, т.к. она не работает в современных версиях Python, а дальше вряд ли будет лучше.

emorozov
()
Ответ на: комментарий от caoutchouckcha

Вообще, я согласен, нельзя отвечать школьникам так. Всё-таки, юная ранимая психика.

Но меня задело, что в прошлый раз я прошёлся по всему его коду и попытался разжевать основы, но это было совершенно проигнорировано.

Это я ещё даже не начал объяснять про безопасность. Просто указал на неприемлемые недостатки, которые возникли из-за того, что он пишет код не потрудившись даже прочитать Python Tutorial, где многие из его ошибок подробно разжеваны.

Например, list(sorted(list)) возникает от непонимания того, чем являются самые базовые структуры данных в Python, как с ними работать. Самые-самые основы, которые надо изучать в первую очередь, вместо того, чтобы искать, как запихнуть неподдерживаемую библиотеку в современный Python.

emorozov
()
Ответ на: комментарий от caoutchouckcha

:) то-то мне на ssh-порт год долбились подборщики паролей.
и ни одного подборщика ключа чет из них не видел.

pfg ★★★★★
()
Последнее исправление: pfg (всего исправлений: 1)
Ответ на: комментарий от pfg

Посмотри ещё раз, на что ты ответил мне

По-моему, ты ни обычный пароль даже 8-символьный, ни ключ не сбрутишь за какое-то адекватное время.

Можем посчитать, за сколько ты сбрутишь 8-символьный пароль, даже не учитывая что ты не знаешь имя пользователя.

Серьезно, там даже фейл2бан не нужен.

caoutchouckcha
()
Последнее исправление: caoutchouckcha (всего исправлений: 1)
Ответ на: комментарий от caoutchouckcha

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

так что пароли эффективно подбирают по спискам паролей. очень сильно быстрее полного брута 8 символьной произвольной последовательности символов.

удивительно что сей факт тебе надо рассказывать. он приведен во множестве статей и т.д.

ключ аккурат не имеет логики построения, и даже 8 символьный ключ будет надежнее 8 символьного пароля.

pfg ★★★★★
()
Ответ на: комментарий от pfg

Просто скажи, сколько у тебя серверов наружу торчит.

удивительно что сей факт тебе надо рассказывать. он приведен во множестве статей и т.д.

Статьи пишут условные местные фракталы, у которых кроме локалхоста ничего нет.

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

Мой изначальный посыл был в том, что ты не сбрутишь ssh по паролю, даже если (если) знаешь логин.

Да, пароли вида root или toor вероятно сбрутишь.

Не понимаю, о чем спор. Криптографически ты ни ключ, ни нормальный 8 (хотя бы) символьный пароль не сбрутишь

caoutchouckcha
()
Ответ на: комментарий от pfg

ключ аккурат не имеет логики построения, и даже 8 символьный ключ будет надежнее 8 символьного пароля.

С этим я не спорю, само собой. Просто вероятность успешного брута ссш по паролю «слегка» преувеличена.

caoutchouckcha
()
Последнее исправление: caoutchouckcha (всего исправлений: 1)