Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sshtunnel doesn't recognize private key password

I'm using sshtunnel to connect to connect to a remote server and on to a database from there. Everything is working fine, except that sshtunnel doesn't seem to recognize my ssh_private_key_password unless I've already entered it elsewhere (or more likely I'm making a mistake when providing it).

with SSHTunnelForwarder(
    ('my.server', 22),
    ssh_username="myUsername",
    ssh_pkey="~/.ssh/id_rsa", 
    ssh_private_key_password="myPassword",
    remote_bind_address=("other.server", 3306)
) as server:
{do some stuff}

If I log into "my.server" separately and enter my private key password in the dialog for storage by ssh-agent, and then run the code above, it works as expected.

If I run the code without having already logged into the server at some point earlier, I receive this error: ValueError: No password or public key available! (But the password is there - ssh_private_key_password - no?)

This happens whether ssh_pkey is pointing to the public key or the private key.

What might be happening here? Am I misunderstanding something about the expected arguments for SSHTunnelForwarder? Something more fundamental about the key and password?

like image 987
user3092118 Avatar asked Oct 21 '16 03:10

user3092118


People also ask

Why is my SSH key not working?

Make sure the authorized_keys file and the private key itself have the correct permissions and ownership. Check that key-based authentication is allowed by the server. Make sure the private key is readable by the SSH client. If you're using PuTTY, make sure your SSH keys are properly configured for the session.

Do I need a password with SSH key?

Private keys allow the users to login to SSH without a password. This is considered a safe practice in some cases while also discards the need to remember multiple passwords.

How do I stop SSH from prompting key passphrase?

Use ssh-add to add the keys to the list maintained by ssh-agent. After you add a private key password to ssh-agent, you do not need to enter it each time you connect to a remote host with your public key.

Why does SSH ask for passphrase?

I've found that SSH will prompt for a passphrase if it has trouble reading the private key. I gave it an empty file, and it asked for a passphrase. That means you need to execute ssh -v to see the actual error, usually it is permissions problem, as the key file must have 0600 permissions.


1 Answers

I have worked through this problem.

In my case, my macOS ~/.ssh/id_rsa start with -----BEGIN OPENSSH PRIVATE KEY----- which is not the proper start line.

In fact, the ssh_pkey should be started with -----BEGIN RSA PRIVATE KEY-----. According to the source code of sshtunnel model:

ssh_pkey (str or paramiko.PKey):
    **Private** key file name (``str``) to obtain the public key
    from or a **public** key (:class:`paramiko.pkey.PKey`)

The key is a paramiko.pkey.PKey, that means, the ~/.ssh/id_rsa should be convert to paramiko.pkey correctly.

import paramiko
pkey='~/.ssh/id_rsa'
key=paramiko.RSAKey.from_private_key_file(pkey)

# id_rsa with `-----BEGIN OPENSSH PRIVATE KEY-----`
# raise SSHException: not a valid RSA private key file

So, I generate a new key in a linux OS, with command of ssh-keygen -t rsa, then I authorize access to the key with ssh-copy-id -i ~/.ssh/id_rsa.pub username@jump_server_host -p ssh_port.

ssh-keygen -t rsa
ssh-copy-id -i ~/.ssh/id_rsa.pub username@jump_server_host -p ssh_port

now the ~/.ssh/id_rsa on my linux OS looks like:

-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAuFSEXjLMwyAJ54d5hQQjyIE+4l5pZw7GuYFDgNCzXjl6CNwV
XXXXXXXXXXXXXXX
XXXXXXXXXXXXXXX
XXXXXXXXXXXXXXX
-----END RSA PRIVATE KEY-----

Copy it to my local mac, and test it.

pkey='/path/to/the/new/id_rsa'
key=paramiko.RSAKey.from_private_key_file(pkey) 

# id_rsa with `-----BEGIN RSA PRIVATE KEY-----`
# No SSHException now.

Now, it works without Exception ValueError: No password or public key available!.

with SSHTunnelForwarder(
        ('jump_server_host', jump_ssh_port),  # jump server
        ssh_username='username',
        ssh_pkey="/path/to/new/id_rsa",
        remote_bind_address=('remote_host', remote_ssh_port),  # remote_server
        local_bind_address=('0.0.0.0', 30023)                  # local_bind_port set to 30023, your can select new one 
) as server:
    server.start()
    print(server.local_bind_port)
    server.close() 

It outputs 30023.

like image 140
Ferris Avatar answered Sep 18 '22 10:09

Ferris