ConnectAuthError when trying to connect to SRX with SSH private key with passphrase and SSH-agent
Hello,
I need some help to troubleshoot why connecting with SSH key with passphrase is not working with SSH agent. If I understand correctly if I have setup access to SRX with SSH keys and using SSH agent then junos-eznc should be able to read that information and connect to device.
Connection to SRX 4200 with version Junos: 21.4R3-S4.9 From ubuntu 22.04 with python 3.10 and junos-eznc 2.7.1
This is what I have in my .ssh/config file:
host 10.35.255.1
IdentityFile ~/.ssh/privatekey
host *
KexAlgorithms=+"diffie-hellman-group1-sha1,diffie-hellman-group14-sha1"
PubkeyAcceptedAlgorithms=+"ssh-rsa"
HostKeyAlgorithms=+"ssh-rsa"
Ciphers=+"aes128-cbc,3des-cbc,aes192-cbc,aes256-cbc"
ServerAliveInterval=300
ServerAliveCountMax=2
AddKeysToAgent yes
If I connect from command line it doesn't ask password and connects
rilves@raimondadmin:~$ ssh 10.35.255.1 -p 830 -s netconf
<!-- No zombies were killed during the creation of this user interface -->
<!-- user rilves, class j-super-user-local -->
<hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
If I try with the following python code
from pprint import pprint
from jnpr.junos import Device
with Device(host='10.35.255.1', user='rilves') as dev:
pprint( dev.facts )
I get following error:
rilves@raimondadmin:~$ python3 test.py
Traceback (most recent call last):
File "/home/rilves/.local/lib/python3.10/site-packages/jnpr/junos/device.py", line 1371, in open
self._conn = netconf_ssh.connect(
File "/home/rilves/.local/lib/python3.10/site-packages/ncclient/manager.py", line 187, in connect
return connect_ssh(*args, **kwds)
File "/home/rilves/.local/lib/python3.10/site-packages/ncclient/manager.py", line 139, in connect_ssh
session.connect(*args, **kwds)
File "/home/rilves/.local/lib/python3.10/site-packages/ncclient/transport/ssh.py", line 359, in connect
self._auth(username, password, key_filenames, allow_agent, look_for_keys)
File "/home/rilves/.local/lib/python3.10/site-packages/ncclient/transport/ssh.py", line 494, in _auth
raise AuthenticationError(repr(saved_exception))
ncclient.transport.errors.AuthenticationError: SSHException('encountered EC key, expected OPENSSH key')
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/rilves/test.py", line 5, in <module>
with Device(host='10.35.255.1', user='rilves') as dev:
File "/home/rilves/.local/lib/python3.10/site-packages/jnpr/junos/device.py", line 1476, in __enter__
self.open()
File "/home/rilves/.local/lib/python3.10/site-packages/jnpr/junos/device.py", line 1392, in open
raise EzErrors.ConnectAuthError(self)
jnpr.junos.exception.ConnectAuthError: ConnectAuthError(10.35.255.1)
Everything works if I provide "passwd: " in the python script aswell. But would like to have key authentication. Do I need to create OPENSSH key or could this be any other error and it just not getting my key for some reason ?
Thanks for help!
Alright I did some more reading and checked out the first error line code "device.py" And from that file I found this
# we want to enable the ssh-agent if-and-only-if we are
# not given a password or an ssh key file.
# in this condition it means we want to query the agent
# for available ssh keys
allow_agent = bool(
(self._auth_password is None) and (self._ssh_private_key_file is None)
)
It seems that SSH agent only works when you don't give SSH key file and password defined anywhere. So I tested and removed my .ssh/config file and then the python code works and connects to device.
Is this expected behavior? Is it possible to set this in python to script to still have .ssh/config file the same? Also if the key password is not yet in the SSH agent after new session it would also break. Shouldn't it still check the SSH key from .ssh/config and then ask for password if not in SSH agent already ?
I am using an SSH key with a passphrase which is cached by my local SSH agent. I was getting something similar, errors like this:
Traceback (most recent call last):
File "/home/myuser/.local/lib/python3.10/site-packages/jnpr/junos/device.py", line 1390, in open
self._conn = netconf_ssh.connect(
File "/home/myuser/.local/lib/python3.10/site-packages/ncclient/manager.py", line 187, in connect
return connect_ssh(*args, **kwds)
File "/home/myuser/.local/lib/python3.10/site-packages/ncclient/manager.py", line 139, in connect_ssh
session.connect(*args, **kwds)
File "/home/myuser/.local/lib/python3.10/site-packages/ncclient/transport/ssh.py", line 359, in connect
self._auth(username, password, key_filenames, allow_agent, look_for_keys)
File "/home/myuser/.local/lib/python3.10/site-packages/ncclient/transport/ssh.py", line 494, in _auth
raise AuthenticationError(repr(saved_exception))
ncclient.transport.errors.AuthenticationError: PasswordRequiredException('private key file is encrypted')
I was opening the device as follows:
device = Device(dev_name, username=os.getlogin(), ssh_config=args.sshconfig, port=22)
The ssh config file I was passing is very basic:
Host *
User myusername
IdentityFile ~/.ssh/id_ed25519
ProxyCommand /usr/bin/nc -X 5 -x localhost:10801 %h %p
If I manually hack my local device.py file and set allow_agent = True then everything works ok.
If I leave device.py as it is and remove the 'IdentityFile' line from the ssh config file it still fails.
I tried adding ssh_private_key_file=None and passwd=None when creating the device object, so allow_agent would naturally evaluate to true, but that didn't work for some reason.
I modified device.py file and removed private key file check from allow_agent and then everything works fine when key is still passed in .ssh/config file So I changed this:
allow_agent = bool(
(self._auth_password is None) and (self._ssh_private_key_file is None)
)
to this:
allow_agent = bool(
(self._auth_password is None)
)
I modified device.py file and removed private key file check from allow_agent and then everything works fine when key is still passed in .ssh/config file So I changed this:
allow_agent = bool( (self._auth_password is None) and (self._ssh_private_key_file is None) )to this:
allow_agent = bool( (self._auth_password is None) )
Hi @Raimond56, Thanks for sharing the information. let me replicate this issue on our lab setup and verify.
Thanks Chidanand
Hi @Raimond56,
Thanks for providing the details.
I am not able to replicate this issue with latest PyEZ code (pip install git+https://github.com/Juniper/py-junos-eznc.git).
Could you please check and let us know, if we are missing any steps.
eval "$(ssh-agent -s)"
ssh-keygen -t rsa -b 4096
ssh-add ~/.ssh/id_rsa
ssh-copy-id -i ~/.ssh/id_rsa.pub [email protected]
vi ~/.ssh/config
host xx.xx.xx.xx
IdentityFile ~/.ssh/id_rsa
host *
KexAlgorithms=+"diffie-hellman-group1-sha1,diffie-hellman-group14-sha1"
HostKeyAlgorithms=+"ssh-rsa"
Ciphers=+"aes128-cbc,3des-cbc,aes192-cbc,aes256-cbc"
ServerAliveInterval=300
ServerAliveCountMax=2
AddKeysToAgent yes
PyEZ script:
from pprint import pprint
from jnpr.junos import Device
with Device(host='xx.xx.xx.xx', user='regress') as dev:
pprint( dev.facts )
(venv) regress@masterhost:~/pyez_issues$ python test.py
{'2RE': True,
'HOME': '/var/home/regress',
'RE0': {'last_reboot_reason': 'Router rebooted after a normal shutdown.',
'mastership_state': 'master',
'model': 'RE-VMX',
'status': 'OK',
'up_time': '9 days, 16 hours, 41 minutes, 58 seconds'},
'RE1': {'last_reboot_reason': None,
'mastership_state': 'Present',
'model': None,
'status': None,
'up_time': None},
Thanks & Regards Chidanand
Hi @chidanandpujar thank you for looking at this issue!
I have set up a fresh Debian 12 VM to test this. The regular ssh agent is loaded on boot:
debian@debian12:~$ ssh-agent -s
SSH_AUTH_SOCK=/tmp/ssh-IuNk6wdCTHQ2/agent.3364; export SSH_AUTH_SOCK;
SSH_AGENT_PID=3365; export SSH_AGENT_PID;
echo Agent pid 3365;
debian@debian12:~$
debian@debian12:~$ eval "$(ssh-agent -s)"
Agent pid 3381
My ssh config file is set to connect to one of our routers via a socks5 proxy running on another host on my network:
debian@debian12:~$ cat ./.ssh/config
Host cr1-esams.wikimedia.org
User cmooney
IdentityFile ~/.ssh/id_ed25519
ProxyCommand /usr/bin/nc -X 5 -x 192.168.240.106:10801 %h %p
I can add my ed25519 ssh key to the local agent with 'ssh-add':
debian@debian12:~$ ssh-add ./.ssh/id_ed25519
Enter passphrase for ./.ssh/id_ed25519:
Identity added: ./.ssh/id_ed25519 (cathal@wikilap)
debian@debian12:~$
After this I can ssh to the router fine, it picks up the key from the ssh agent, and proxies as required based on the config file:
debian@debian12:~$ ssh cr1-esams.wikimedia.org
Last login: Thu Jul 17 11:02:52 2025 from 2a02:ec80:300:2:185:15:59:36
--- JUNOS 23.4R2-S3.9 Kernel 64-bit JNPR-12.1-20240604.39c9257_buil
{master}
[email protected]>
I have the latest PyEz installed from the url you posted above, and have this Python file:
debian@debian12:~$ cat test_pyez.py
#!/usr/bin/python3
from jnpr.junos import Device
from pprintpp import pprint as pp
junos_dev = Device('cr1-esams.wikimedia.org', username='cmooney', ssh_config='/home/debian/.ssh/config', port=22)
junos_dev.open()
pp(junos_dev.facts)
When I run this I get an error saying the private key file is encrypted:
debian@debian12:~$ ./test_pyez.py
Traceback (most recent call last):
File "/home/debian/.local/lib/python3.11/site-packages/jnpr/junos/device.py", line 1390, in open
self._conn = netconf_ssh.connect(
^^^^^^^^^^^^^^^^^^^^
File "/home/debian/.local/lib/python3.11/site-packages/ncclient/manager.py", line 187, in connect
return connect_ssh(*args, **kwds)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/debian/.local/lib/python3.11/site-packages/ncclient/manager.py", line 139, in connect_ssh
session.connect(*args, **kwds)
File "/home/debian/.local/lib/python3.11/site-packages/ncclient/transport/ssh.py", line 359, in connect
self._auth(username, password, key_filenames, allow_agent, look_for_keys)
File "/home/debian/.local/lib/python3.11/site-packages/ncclient/transport/ssh.py", line 494, in _auth
raise AuthenticationError(repr(saved_exception))
ncclient.transport.errors.AuthenticationError: PasswordRequiredException('Private key file is encrypted')
If I modify the 'allow_agent' variable on this line so it simply says allow_agent = True then the connection works:
debian@debian12:~$ ./test_pyez.py
{'2RE': True,
'HOME': '/var/home/cmooney',
'RE0': {'last_reboot_reason': '0x2000:hypervisor reboot',
'mastership_state': 'master',
'model': 'RE-S-2X00x6',
'status': 'OK',
'up_time': '64 days, 2 hours, 2 minutes, 18 seconds'},
@chidanandpujar actually looking at the code and the setup I tried something else. I removed this line from my ~/.ssh/config file:
IdentityFile ~/.ssh/id_ed25519
And then with the unmodified device.py file the connection actually worked. So I think the and (self._ssh_private_key_file is None) part of that conditional is the problem.
On my normal system I have many SSH keys for access to different systems though. So I need the IdentityFile line in my ssh config to tell ssh what key to use for the given device, but I need it to be loaded from the agent then as it has a passphrase.
Hi @topranks , Thanks for the sharing the details. Let me replicate this issue on test setup and verify the fix mentioned.
Thanks Chidanand
Thanks! In terms of the correct fix I'm not sure what is best. Perhaps another option when connecting to the device could be added like "force_agent" or something, which if set would always use the agent, even if self._ssh_private_key_file is not null?
Hey @chidanandpujar thanks for looking into this
Did you have passphrase configured for your private key aswell?
I tested again in clean python3 venv I run pip install git+https://github.com/Juniper/py-junos-eznc.git Then run the script and it results in same error.
I run the same script as before
from pprint import pprint
from jnpr.junos import Device
with Device(host='10.35.255.1', user='rilves') as dev:
pprint( dev.facts )
And I have this in .ssh/config file:
host 10.35.255.*
IdentityFile ~/.ssh/privatekey
host *
KexAlgorithms=+"diffie-hellman-group1-sha1,diffie-hellman-group14-sha1"
PubkeyAcceptedAlgorithms=+"ssh-rsa"
HostKeyAlgorithms=+"ssh-rsa"
Ciphers=+"aes128-cbc,3des-cbc,aes192-cbc,aes256-cbc"
ServerAliveInterval=300
ServerAliveCountMax=2
AddKeysToAgent yes
If I remove IdentifyFile from .ssh/config file the script works. But if it is there it does not.
@topranks Thanks for testing aswell!
As topranks said I am also not sure what the best fix could be, but for my deployment currently works if I remove
and (self._ssh_private_key_file is None) from device.py.
Hi @Raimond56, Thanks for sharing the information.
Thanks & Regards Chidanand