У меня есть несколько брандмауэров Juniper SSG, которыми мне нужно управлять, и я хотел бы иметь возможность отправлять им команды из некоторых сценариев мониторинга. Я настроил доступ по SSH с помощью открытых ключей, и я могу автоматически входить в брандмауэры.
Когда я запускаю SSH в интерактивном режиме, все работает нормально:
$ssh <firewall IP>
FIREWALL-> <command>
<command output>
FIREWALL-> exit
Connection to <firewall IP> closed.
$
Но когда я пытаюсь запустить команду из командной строки, она не работает:
$ssh <firewall IP> <command>
$
Это, конечно, отлично работает при отправке команды удаленному компьютеру Linux:
$ssh <linux box IP> <command>
<command output>
$
Почему это происходит? В чем разница между запуском SSH в интерактивном режиме и указанием команды для запуска в командной строке SSH?
Он также отлично работает с маршрутизатором Cisco. Похоже, что только эти межсетевые экраны Juniper ведут себя так.
Судя по выходным данным отладки SSH, похоже, что соединение установлено правильно, но модуль Juniper отвечает EOF при отправке команды, а вместо этого ящик Linux отвечает фактическим выходом команды:
Linux:
debug1: Authentication succeeded (publickey).
debug1: channel 0: new [client-session]
debug2: channel 0: send open
debug1: Entering interactive session.
debug2: callback start
debug2: client_session2_setup: id 0
debug1: Sending command: uptime
debug2: channel 0: request exec confirm 0
debug2: callback done
debug2: channel 0: open confirm rwindow 0 rmax 32768
debug2: channel 0: rcvd adjust 131072
debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
16:44:44 up 25 days, 1:06, 3 users, load average: 0.08, 0.02, 0.01
debug2: channel 0: rcvd eof
debug2: channel 0: output open -> drain
debug2: channel 0: obuf empty
debug2: channel 0: close_write
debug2: channel 0: output drain -> closed
debug2: channel 0: rcvd close
debug2: channel 0: close_read
debug2: channel 0: input open -> closed
debug2: channel 0: almost dead
debug2: channel 0: gc: notify user
debug2: channel 0: gc: user detached
debug2: channel 0: send close
debug2: channel 0: is dead
debug2: channel 0: garbage collecting
debug1: channel 0: free: client-session, nchannels 1
debug1: Transferred: stdin 0, stdout 0, stderr 0 bytes in 0.1 seconds
debug1: Bytes per second: stdin 0.0, stdout 0.0, stderr 0.0
debug1: Exit status 0
Можжевельник:
debug1: Authentication succeeded (publickey).
debug1: channel 0: new [client-session]
debug2: channel 0: send open
debug1: Entering interactive session.
debug2: callback start
debug2: client_session2_setup: id 0
debug1: Sending environment.
debug1: Sending env LANG = en_US.UTF-8
debug2: channel 0: request env confirm 0
debug1: Sending command: get system
debug2: channel 0: request exec confirm 0
debug2: callback done
debug2: channel 0: open confirm rwindow 2048 rmax 1024
debug2: channel 0: rcvd eof
debug2: channel 0: output open -> drain
debug2: channel 0: obuf empty
debug2: channel 0: close_write
debug2: channel 0: output drain -> closed
debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
debug2: channel 0: rcvd close
debug2: channel 0: close_read
debug2: channel 0: input open -> closed
debug2: channel 0: almost dead
debug2: channel 0: gc: notify user
debug2: channel 0: gc: user detached
debug2: channel 0: send close
debug2: channel 0: is dead
debug2: channel 0: garbage collecting
debug1: channel 0: free: client-session, nchannels 1
debug1: Transferred: stdin 0, stdout 0, stderr 0 bytes in 0.2 seconds
debug1: Bytes per second: stdin 0.0, stdout 0.0, stderr 0.0
debug1: Exit status 1
SSH не выделяет псевдо-TTY, когда вы указываете команду для запуска. Попробуйте добавить опцию «-t», чтобы переопределить это.
Как кто-то прокомментировал, попробуйте добавить -t или даже -tt, чтобы заставить его. Похожая проблема была предположительно исправлена этим временным решением.
На самом деле у меня есть проблема, связанная с этим, за исключением меня, она работает из CLI, но не работает через cron.
Передача команды в командной строке - это не то же самое, что ввод команд в оболочке. В первом случае оболочке необходимо проанализировать аргументы, а во втором - прочитать строки из стандартного ввода.
Если это тупая (или ограниченная, если вы предпочитаете называть ее) интерактивная оболочка, вполне возможно, что она не была закодирована для поддержки обеих (я видел такое поведение на практике). Однако, поскольку оболочка явно поддерживает типизированные команды, вам, вероятно, повезет больше, если вы просто отправите все команды на его стандартный ввод. Как это:
echo command | ssh ...
это работает на SRX240:
( echo 'sh conf|d s|n'; echo 'quit' ) | ssh root@192.168.1.1 "cli"
Это можно улучшить, если использовать bash heredoc, чтобы вы могли просто вставить в него полные операторы, но этот пример пока должен вас в достаточной степени направить.