ktbyers / netmiko

Multi-vendor library to simplify Paramiko SSH connections to network devices
MIT License
3.55k stars 1.3k forks source link

Automatic Newline b'\n' ConnectHandler #3481

Open Bispo1986 opened 3 weeks ago

Bispo1986 commented 3 weeks ago

SSH Session closed if write channel b'\n'.

Setup

Netmiko 4.3.0

device_type='autodetect' =>(works best with Nokia ISAM devices)

Neu User Workflow step 2 on the Host ***** Failed: Socket is closed

Hello first and foremost. Thanks fo your amazing work on Netmiko.

Now this isn´t a python per si problem, or even the ConnectHandler itself. It´s more a question about the log below:

""" DEBUG:paramiko.transport:userauth is OK INFO:paramiko.transport:Auth banner: b'\n\n' INFO:paramiko.transport:Authentication (password) successful! DEBUG:paramiko.transport:[chan 0] Max packet in: 32768 bytes DEBUG:paramiko.transport:[chan 0] Max packet out: 4096 bytes DEBUG:paramiko.transport:Secsh channel 0 opened. DEBUG:paramiko.transport:[chan 0] Sesch channel 0 request ok DEBUG:paramiko.transport:[chan 0] Sesch channel 0 request ok DEBUG:netmiko:write_channel: b'\n' DEBUG:netmiko:read_channel: DEBUG:paramiko.transport:[chan 0] EOF sent (0) DEBUG:paramiko.transport:EOF in transport thread DEBUG:netmiko:read_channel: Welcome to **** Your password is expired ! enter new password:

DEBUG:netmiko:read_channel: """

Where in normal circunstances i can with device_type=autodetect manage these devices no problem.

This thype of workflow on the other hand, creating new user has an interesting problem with it: "As long as Netmiko automatically writes the channel with b'\n' it isnt possible to deal with the prompts that come right after login. That is because the devices strangely close the session imediatelly if newline (Enter) is given after the login. I tried everything under the sun with device_type=terminal_server and multiple changes on the BaseConnection to try avoiding this netmiko:write_channel: b'\n' on the session but without success. Should i give up (just use Paramiko) or is there something i can do about this with netmiko unknown to me? I need Basically a Session where no newline with be given from netmiko. At least until i manage that prompt for pass expired.

Thanks in advance for your response and support.

ktbyers commented 3 weeks ago

Can you post the Python code that corresponds to the above log file?

Also can you post the full Python exception stack trace?

Bispo1986 commented 3 weeks ago

from netmiko import ConnectHandler, redispatch import re

ssh_net = dict(device_type='autodetect', ip=IP, username=username, password=password, port=port)

connection = ConnectHandler(**ssh_net) node_ip = f'{ssh_net["ip"]}'

This section node_name can be ignored as i am retrieving it from an excel sheet with hostnames and IP Addresses (Pandas)

node_name = ([k for k, v in n_result_df.items() if v == nodeip]) node = node_name[0]

neu_user = input("New User SSH: ").strip() neu_pass = input("New Pass SSH: ").strip()

if neu_user: try:

This first instance works perfectly and does what it should. A temporary pass will be configured together with the new user.

     command = f"configure system security operator {neu_user} password plain:password1234! profile admin no more no confirm-prompt prompt %s:%n%d%c"
     time.sleep(0.5)
     output = connection.send_command_timing(command_string=command, strip_command=False,
                                                    strip_prompt=False)
     parsed_output = f'\n\nStart Time: {now.strftime("%Y-%m-%d  %H:%M")}\nIP: {node_ip}   DSLAM: {node_}\n' + output
     print(parsed_output)
     time.sleep(1)
     connection.disconnect()

except Exception as e: print(f"New User Workflow step 1 on the {node_} Failed: {e}")

So far so good

while True: try:

Here i want it to repeat in case it fails. This is where the problem occurs because the device

       # has this strange behavior where you have to login with the newly created user, but the device
       # asks for new pass still. If by any chance an enter (b'\n') is given before Netmiko enters the new pass,
       #  the session closes.  

      time.sleep(8)
      ssh_net_2 = dict(device_type='terminal_server', ip=node_ip, username=neu_user,
                                 password='password1234!', fast_cli=False, port=22)
      print(ssh_net_2)
      connection_2 = ConnectHandler(**ssh_net_2)

      # This read_output works perfectly. I can see the prompt that appears right after login. 
      read_output = connection_2.read_channel()
      print(read_output)

     # Now before the command is given, there is an automatic "DEBUG:netmiko:write_channel: b'\n'"
     # that closes the session. 
      if 'enter new password:' in read_output:
            connection_2.write_channel(neu_pass + '\n')

      time.sleep(1)
      read_output = connection_2.read_channel()
      print(read_output)
      if 're-enter  password:' in read_output:
            connection_2.write_channel(neu_pass + '\n')
      time.sleep(1)
      read_output = connection_2.read_channel()
      print(read_output)
      time.sleep(1)
      redispatch(connection_2, device_type='autodetect')
      command_ = f'info configure system security operator {neu_user}'
      output_raw = connection_2.send_command(command_, expect_string='>#', read_timeout=30)
      output = re.sub(r"-{2,}|#", "", output_raw)
      parsed_output = f'\n\n\nIP: {node_ip}   DSLAM: {node_}\n' + output
      print(parsed_output)
      time.sleep(2)
      connection_2.disconnect()
      break

except Exception as e: print(f"New User Workflow step 2 on the {node_} failed: {e}") pass

"""All of this is the section that is causing problems. I dont believe it is a Netmiko Problem. I tried with paramiko as well and the same thing occurs where a new line (Enter) will be given in the SSH session and the device closes the Session. So no problems or bugs to report, only to know your insight, if i can do something with Netmiko that avoids a new line being given in the session. At least before the first neu_pass is entered. It would suffice to enter the neu pass before that b'\n'"""

Thanks in advance Kirk for your time. Again it is not a Problem in Netmiko. Just to know your perspective, how would you #solve this kind of problem with Netmiko, if it can be solved. I tried every way possible. without While loop, other device types,

Everything i knew i could try.

LOG: DEBUG:paramiko.transport:userauth is OK INFO:paramiko.transport:Auth banner: b'\n\n' INFO:paramiko.transport:Authentication (password) successful! DEBUG:paramiko.transport:[chan 0] Max packet in: 32768 bytes DEBUG:paramiko.transport:[chan 0] Max packet out: 4096 bytes DEBUG:paramiko.transport:Secsh channel 0 opened. DEBUG:paramiko.transport:[chan 0] Sesch channel 0 request ok DEBUG:paramiko.transport:[chan 0] Sesch channel 0 request ok DEBUG:netmiko:write_channel: b'\n' DEBUG:netmiko:read_channel: DEBUG:paramiko.transport:[chan 0] EOF sent (0) DEBUG:paramiko.transport:EOF in transport thread DEBUG:netmiko:read_channel: Welcome to Device Your password is expired ! enter new password:

DEBUG:netmiko:read_channel:

Bispo1986 commented 3 weeks ago

Hello Kirk. Hope you are doing well.

I was able to do it, with a mix of netmiko and paramiko. The step that needed that new password to be entered and then confirmed works with paramiko:

                client = paramiko.SSHClient()
                client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
                print(f'IP: {node_ip}\nHost: {node_}\nNeu User: {neu_user}\nPass: {neu_pass}')
                ssh_kenn = neu_pass + "\n"
                client.connect(node_ip, 22, neu_user, "test1234!")
                commands = client.invoke_shell()
                commands.send(ssh_kenn)
                commands.send(ssh_kenn)
                output = commands.recv(1000000)
                output = output.decode("utf-8")
                print(output)

That means that i am doing everything through Netmiko and when the scripts needs to login with the new user, paramiko will do the job to at least enter the new pass. The rest, if needed, will be done with Netmiko. I dont see exactly how paramiko dealt with it. Can i log the paramiko session like in Netmiko?

Anyway thanks for your help Kirk and for Netmiko.