结构,fabfile,fab:paramiko.ssh_exception.SSHException:无现有会话

问题描述

cf_key是我的私人ssh密钥。请看一下我的回溯和代码,看看我在做什么错。我已经编辑了实际的服务器名称,并将其替换为“”。看起来像“密钥不能用于签名”。我的钥匙怎么了?

我执行了以下命令:fab doit 'cf_key' refresh 'dev'并收到此错误

maintenance on
Exception: key cannot be used for signing
Traceback (most recent call last):
  File "/home/michael/projects/campaignfinances/venv/lib/python3.6/site-packages/paramiko/transport.py",line 2109,in run
    handler(self.auth_handler,m)
  File "/home/michael/projects/campaignfinances/venv/lib/python3.6/site-packages/paramiko/auth_handler.py",line 298,in _parse_service_accept
    sig = self.private_key.sign_ssh_data(blob)
  File "/home/michael/projects/campaignfinances/venv/lib/python3.6/site-packages/paramiko/agent.py",line 418,in sign_ssh_data
    raise SSHException("key cannot be used for signing")
paramiko.ssh_exception.SSHException: key cannot be used for signing

Traceback (most recent call last):
  File "/home/michael/projects/campaignfinances/venv/bin/fab",line 8,in <module>
    sys.exit(program.run())
  File "/home/michael/projects/campaignfinances/venv/lib/python3.6/site-packages/invoke/program.py",line 384,in run
    self.execute()
  File "/home/michael/projects/campaignfinances/venv/lib/python3.6/site-packages/invoke/program.py",line 566,in execute
    executor.execute(*self.tasks)
  File "/home/michael/projects/campaignfinances/venv/lib/python3.6/site-packages/invoke/executor.py",line 129,in execute
    result = call.task(*args,**call.kwargs)
  File "/home/michael/projects/campaignfinances/venv/lib/python3.6/site-packages/invoke/tasks.py",line 127,in __call__
    result = self.body(*args,**kwargs)
  File "/home/michael/projects/campaignfinances/fabfile.py",line 51,in refresh
    conn.run('sudo ln -sf /home/django/sites/{0}.campaignfinances.org/src/project/templates/maintenance.html {0}-maintenance.html'.format(server))
  File "<decorator-gen-3>",line 2,in run
  File "/home/michael/projects/campaignfinances/venv/lib/python3.6/site-packages/fabric/connection.py",line 29,in opens
    self.open()
  File "/home/michael/projects/campaignfinances/venv/lib/python3.6/site-packages/fabric/connection.py",line 634,in open
    self.client.connect(**kwargs)
  File "/home/michael/projects/campaignfinances/venv/lib/python3.6/site-packages/paramiko/client.py",line 446,in connect
    passphrase,File "/home/michael/projects/campaignfinances/venv/lib/python3.6/site-packages/paramiko/client.py",line 764,in _auth
    raise saved_exception
  File "/home/michael/projects/campaignfinances/venv/lib/python3.6/site-packages/paramiko/client.py",line 740,in _auth
    self._transport.auth_publickey(username,key)
  File "/home/michael/projects/campaignfinances/venv/lib/python3.6/site-packages/paramiko/transport.py",line 1570,in auth_publickey
    raise SSHException("No existing session")
paramiko.ssh_exception.SSHException: No existing session

fabfile.py

###################################################################
#
# Usage:
# fab doit(path_to_ssh_key) refresh('dev|staging')
# fab doit(path_to_ssh_key) maintenanceon('dev|staging')
# fab doit(path_to_ssh_key) maintenanceoff('dev|staging')
#
# fab doit(path_to_ssh_key) productionrefresh
#
# Example: fab doit('c:\users\tom\.ssh\id_rsa.pem') maintenanceon('dev')
#
# If you use a passphrase then add --prompt-for-passphrase
####################################################################
from fabric import task,Connection


@task
def doit(ctx,keypath):
    ctx.user = 'django'
    ctx.host = '<servername>'
    ctx.connect_kwargs.key_filename = ''.format(keypath)


@task
def maintenanceon(ctx,server):
    conn = Connection(ctx.host,ctx.user,connect_kwargs=ctx.connect_kwargs)
    # create ln to maintenance file
    print('maintenance on')
    with conn.cd('/usr/share/Nginx/html/'):
        conn.run('sudo ln -sf /home/django/sites/{0}.<servername>/src/project/templates/maintenance.html {0}-maintenance.html'.format(server))


@task
def maintenanceoff(ctx,connect_kwargs=ctx.connect_kwargs)
    # create ln to maintenance file
    print('maintenance off')
    with conn.cd('/usr/share/Nginx/html/'):
        conn.run('sudo unlink {}-maintenance.html'.format(server))


@task
def refresh(ctx,server):
    env_command = '. /home/django/sites/{0}.<servername>.com/{0}/bin/activate'.format(server)

    conn = Connection(ctx.host,connect_kwargs=ctx.connect_kwargs)

    # set to maintenance mode
    with conn.cd('/usr/share/Nginx/html/'):
        print('maintenance on')
        conn.run('sudo ln -sf /home/django/sites/{0}.<servername>.com/src/project/templates/maintenance.html {0}-maintenance.html'.format(server))
    # refresh install
    with conn.cd('/home/django/sites/{}.<servername>.com/src/'.format(server)):
        print('git pull')
        conn.run('git pull')
    # check requirements
    with conn.cd('/home/django/sites/{}.<servername>.com/src/requirements/'.format(server)):
        print('pip-sync')
        conn.run(env_command + '&&' + 'pip-sync {}.txt'.format(server))
    # run migrations and collectstatic
    with conn.cd('/home/django/sites/{}.<servername>.com/src/project/'.format(server)):
        print('migrate')
        conn.run(env_command + '&&' + 'python manage.py migrate')
        print('collecstatic')
        conn.run(env_command + '&&' + 'python manage.py collectstatic --no-input')
    # restart server
    print('restart server')
    conn.sudo('systemctl restart {}.service'.format(server),pty=True)

    # maintenance mode off
    with conn.cd('/usr/share/Nginx/html/'):
        print('maintenance off)')
        conn.run('sudo unlink {}-maintenance.html'.format(server))


@task
def productionrefresh(ctx):
    env_command = '. /home/django/sites/www.<servername>.com/www/bin/activate'

    conn = Connection(ctx.host,connect_kwargs=ctx.connect_kwargs)

    # set to maintenance mode
    with conn.cd('/usr/share/Nginx/html/'):
        print('Set to maintenance mode')
        conn.run('sudo ln -sf /home/django/sites/www.<servername>.com/src/project/templates/maintenance.html prod-maintenance.html')
    # refresh install
    with conn.cd('/home/django/sites/www.<servername>.com/src/'):
        print('Git pull')
        conn.run('git pull')
    # check requirements
    with conn.cd('/home/django/sites/www.<servername>.com/src/requirements/'):
        print('pip-sync production.txt')
        conn.run(env_command + '&&' + 'pip-sync production.txt')
    # run migrations and collectstatic
    with conn.cd('/home/django/sites/www.<servername>.com/src/project/'):
        print('python manage.py migrate')
        conn.run(env_command + '&&' + 'python manage.py migrate')
        print('python manage.py collectstatic')
        conn.run(env_command + '&&' + 'python manage.py collectstatic --no-input')
    # restart server
    print('restart production service')
    conn.sudo('systemctl restart production.service',pty=True)
    # maintenance mode off
    with conn.cd('/usr/share/Nginx/html/'):
        print('maintenance off')
        conn.run('sudo unlink prod-maintenance.html')


@task
def productioncollect(ctx):
    env_command = '. /home/django/sites/www.<servername>.com/www/bin/activate'

    conn = Connection(ctx.host,connect_kwargs=ctx.connect_kwargs)
    with conn.cd('/home/django/sites/www.<servername>.com/src/project/'):
        conn.run(env_command + '&&' + 'python manage.py collectstatic --no-input')

解决方法

您可以使用带有该密钥的openssh客户端SSH到服务器吗?输出表明您的密钥不能用于签名,这是我从未见过的。

另外,测试密钥对于这样的签名有效:

redkrieg@cortex-0:~$ echo "signme" > testfile
redkrieg@cortex-0:~$ ssh-keygen -Y sign -f cf_key -n testsigning testfile
Signing file testfile
Write signature to testfile.sig

确保之后,testfile.sig中包含SSH SIGNATURE块。