SSH公钥authentication只适用于之前存在活动会话的情况

我的SSHconfiguration有一个相当奇怪的问题。 我在远程访问卡的帮助下设置了服务器,并使用KVM查看器configuration了所有内容。

所以当通过KVM查看器login到服务器时,我只用pubkeyconfiguration了SSH,并尝试从本地笔记本电脑login。 它工作正常。

如果我退出KVM会话(或在KVM会话中用户注销),我不能通过sshlogin(pubkey denied)。 只要用户在某个地方仍然login,SSHlogin就会起作用。

任何提示可能是什么问题?


用于login失败的控制台输出(所有个人数据交换):

OpenSSH_6.2p2, OSSLShim 0.9.8r 8 Dec 2011 debug1: Reading configuration data /Users/mylocaluser/.ssh/config debug1: Reading configuration data /etc/ssh_config debug1: /etc/ssh_config line 20: Applying options for * debug1: /etc/ssh_config line 103: Applying options for * debug1: Connecting to 100.100.100.100 [100.100.100.100] port 12345. debug1: Connection established. debug1: identity file /Users/mylocaluser/.ssh/id_rsa type 1 debug1: identity file /Users/mylocaluser/.ssh/id_rsa-cert type -1 debug1: identity file /Users/mylocaluser/.ssh/id_dsa type -1 debug1: identity file /Users/mylocaluser/.ssh/id_dsa-cert type -1 debug1: Enabling compatibility mode for protocol 2.0 debug1: Local version string SSH-2.0-OpenSSH_6.2 debug1: Remote protocol version 2.0, remote software version OpenSSH_6.6.1p1 Ubuntu-2ubuntu2 debug1: match: OpenSSH_6.6.1p1 Ubuntu-2ubuntu2 pat OpenSSH* debug1: SSH2_MSG_KEXINIT sent debug1: SSH2_MSG_KEXINIT received debug1: kex: server->client aes128-ctr [email protected] none debug1: kex: client->server aes128-ctr [email protected] none debug1: SSH2_MSG_KEX_DH_GEX_REQUEST(1024<1024<8192) sent debug1: expecting SSH2_MSG_KEX_DH_GEX_GROUP debug1: SSH2_MSG_KEX_DH_GEX_INIT sent debug1: expecting SSH2_MSG_KEX_DH_GEX_REPLY debug1: Server host key: RSA ab:12:23:34:45:56:67:78:89:90:12:23:34:45:56:67 debug1: Host '[100.100.100.100]:12345' is known and matches the RSA host key. debug1: Found key in /Users/mylocaluser/.ssh/known_hosts:36 debug1: ssh_rsa_verify: signature correct debug1: SSH2_MSG_NEWKEYS sent debug1: expecting SSH2_MSG_NEWKEYS debug1: SSH2_MSG_NEWKEYS received debug1: Roaming not allowed by server debug1: SSH2_MSG_SERVICE_REQUEST sent debug1: SSH2_MSG_SERVICE_ACCEPT received debug1: Authentications that can continue: publickey debug1: Next authentication method: publickey debug1: Offering RSA public key: /Users/mylocaluser/.ssh/id_rsa debug1: Authentications that can continue: publickey debug1: Offering RSA public key: /Users/mylocaluser/.ssh/id_rsa2 debug1: Authentications that can continue: publickey debug1: Trying private key: /Users/mylocaluser/.ssh/id_dsa debug1: No more authentication methods to try. Permission denied (publickey).

控制台输出用于成功login(仅当“活动会话”存在时): OpenSSH_6.2p2, OSSLShim 0.9.8r 8 Dec 2011 debug1: Reading configuration data /Users/mylocaluser/.ssh/config debug1: Reading configuration data /etc/ssh_config debug1: /etc/ssh_config line 20: Applying options for * debug1: /etc/ssh_config line 103: Applying options for * debug1: Connecting to 100.100.100.100 [100.100.100.100] port 12345. debug1: Connection established. debug1: identity file /Users/mylocaluser/.ssh/id_rsa type 1 debug1: identity file /Users/mylocaluser/.ssh/id_rsa-cert type -1 debug1: identity file /Users/mylocaluser/.ssh/id_dsa type -1 debug1: identity file /Users/mylocaluser/.ssh/id_dsa-cert type -1 debug1: Enabling compatibility mode for protocol 2.0 debug1: Local version string SSH-2.0-OpenSSH_6.2 debug1: Remote protocol version 2.0, remote software version OpenSSH_6.6.1p1 Ubuntu-2ubuntu2 debug1: match: OpenSSH_6.6.1p1 Ubuntu-2ubuntu2 pat OpenSSH* debug1: SSH2_MSG_KEXINIT sent debug1: SSH2_MSG_KEXINIT received debug1: kex: server->client aes128-ctr [email protected] none debug1: kex: client->server aes128-ctr [email protected] none debug1: SSH2_MSG_KEX_DH_GEX_REQUEST(1024<1024<8192) sent debug1: expecting SSH2_MSG_KEX_DH_GEX_GROUP debug1: SSH2_MSG_KEX_DH_GEX_INIT sent debug1: expecting SSH2_MSG_KEX_DH_GEX_REPLY debug1: Server host key: RSA ab:12:23:34:45:56:67:78:89:90:12:23:34:45:56:67 debug1: Host '[100.100.100.100]:12345' is known and matches the RSA host key. debug1: Found key in /Users/mylocaluser/.ssh/known_hosts:36 debug1: ssh_rsa_verify: signature correct debug1: SSH2_MSG_NEWKEYS sent debug1: expecting SSH2_MSG_NEWKEYS debug1: SSH2_MSG_NEWKEYS received debug1: Roaming not allowed by server debug1: SSH2_MSG_SERVICE_REQUEST sent debug1: SSH2_MSG_SERVICE_ACCEPT received debug1: Authentications that can continue: publickey debug1: Next authentication method: publickey debug1: Offering RSA public key: /Users/mylocaluser/.ssh/id_rsa debug1: Server accepts key: pkalg ssh-rsa blen 279 debug1: Authentication succeeded (publickey). Authenticated to 100.100.100.100 ([100.100.100.100]:12345). debug1: channel 0: new [client-session] debug1: Requesting [email protected] debug1: Entering interactive session. debug1: Sending environment. debug1: Sending env LANG = de_DE.UTF-8 Welcome to Ubuntu 14.04.1 LTS OpenSSH_6.2p2, OSSLShim 0.9.8r 8 Dec 2011 debug1: Reading configuration data /Users/mylocaluser/.ssh/config debug1: Reading configuration data /etc/ssh_config debug1: /etc/ssh_config line 20: Applying options for * debug1: /etc/ssh_config line 103: Applying options for * debug1: Connecting to 100.100.100.100 [100.100.100.100] port 12345. debug1: Connection established. debug1: identity file /Users/mylocaluser/.ssh/id_rsa type 1 debug1: identity file /Users/mylocaluser/.ssh/id_rsa-cert type -1 debug1: identity file /Users/mylocaluser/.ssh/id_dsa type -1 debug1: identity file /Users/mylocaluser/.ssh/id_dsa-cert type -1 debug1: Enabling compatibility mode for protocol 2.0 debug1: Local version string SSH-2.0-OpenSSH_6.2 debug1: Remote protocol version 2.0, remote software version OpenSSH_6.6.1p1 Ubuntu-2ubuntu2 debug1: match: OpenSSH_6.6.1p1 Ubuntu-2ubuntu2 pat OpenSSH* debug1: SSH2_MSG_KEXINIT sent debug1: SSH2_MSG_KEXINIT received debug1: kex: server->client aes128-ctr [email protected] none debug1: kex: client->server aes128-ctr [email protected] none debug1: SSH2_MSG_KEX_DH_GEX_REQUEST(1024<1024<8192) sent debug1: expecting SSH2_MSG_KEX_DH_GEX_GROUP debug1: SSH2_MSG_KEX_DH_GEX_INIT sent debug1: expecting SSH2_MSG_KEX_DH_GEX_REPLY debug1: Server host key: RSA ab:12:23:34:45:56:67:78:89:90:12:23:34:45:56:67 debug1: Host '[100.100.100.100]:12345' is known and matches the RSA host key. debug1: Found key in /Users/mylocaluser/.ssh/known_hosts:36 debug1: ssh_rsa_verify: signature correct debug1: SSH2_MSG_NEWKEYS sent debug1: expecting SSH2_MSG_NEWKEYS debug1: SSH2_MSG_NEWKEYS received debug1: Roaming not allowed by server debug1: SSH2_MSG_SERVICE_REQUEST sent debug1: SSH2_MSG_SERVICE_ACCEPT received debug1: Authentications that can continue: publickey debug1: Next authentication method: publickey debug1: Offering RSA public key: /Users/mylocaluser/.ssh/id_rsa debug1: Server accepts key: pkalg ssh-rsa blen 279 debug1: Authentication succeeded (publickey). Authenticated to 100.100.100.100 ([100.100.100.100]:12345). debug1: channel 0: new [client-session] debug1: Requesting [email protected] debug1: Entering interactive session. debug1: Sending environment. debug1: Sending env LANG = de_DE.UTF-8 Welcome to Ubuntu 14.04.1 LTS

当用ecryptfsencryption用户的主目录时sshd在主目录被挂载之前无法读取用户主目录下的authorized_keys文件。

在login期间, sshd将使用pam对用户进行身份validation,并且pam将使用用户input的密码来挂载encryption的主目录。

如果你想限制sshd只允许公钥authentication,这是有问题的。

但是,您也可以在服务器上放置未encryption的authorized_keys文件。 这将允许用户使用密钥进行login,但是由于这不会调用pam ,所以主目录将不会被挂载,并且在不知道密码的情况下挂载主目录也将不起作用。

由于encryption的主目录隐藏了未encryption的主目录,因此将未encryption的authorized_keys文件置于首位可能会有点棘手。 底层文件系统的绑定挂载可以帮助解决这个问题。

例如,如果/home只是根文件系统上的一个目录,则可以执行如下操作:

 mkdir /mnt/rootfs mount --bind / /mnt/rootfs 

然后你可以创build/mnt/rootfs/home/$USER/.ssh/authorized_keys

你可以做更多。 由于authorized_keys的encryption和未encryption版本是两个不同的文件,因此可以在其中添加不同的内容。 例如,未encryption的版本可以调用脚本来安装encryption的主目录:

 command="/usr/local/bin/ecryptfs-mount-from-ssh" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDM1Ot12ThbTcPOGpfh7AiRqp3P4BMm3DNo4mDg7gDFPwCmM9rKRHTH0fBVSqkSGlXm84q29bckDukg7vfqkbTpbkP3e2YmTkP6p1J2SoX2QMUnBRRgL9It/ZiAfA2I4QzUrcywVvokO1F2DqcRLy5e5wKTUFfvIm6D2QfBmGbnW2Kkpn16hQyLT1ClXjFC1qXUhazePv0cAtWUCUGjRcLr/ipOphS7eOB46cGhYqtbMkKx0t93ZG4f6jM0o32cYy3RqprpZpTmCeG1gDyG+IlSLBYXYggr72iwTKsTZ9pMDTCBQ8Pb7l317TPOcJzTtDxnpgpGE3x4Vu/Ww+zhsIeT kasperd 2014 May 24 

重要的部分是在键之前指定的command 。 这被调用而不是shell。 但是只有在使用这个特定的公钥时才会出现这种情况,并且只有当用户的主目录没有被安装时才会发生。

如果用户的主目录已经挂载,那么这个authorized_keys文件是隐藏的,而是使用encryption的版本。 authorized_keys的encryption版本没有该command ,因此不会运行装入主目录的脚本。

那么,脚本中的内容 这是我的版本:

 #!/bin/bash -e if [ $# = 1 ] then PUBKEY="$( grep "$1" "$HOME/.ssh/authorized_keys" | sed -e 's/.* ssh-rsa //;s/ .*//')" /usr/local/bin/ssh-agent-ecryptfs-decryption.py "$PUBKEY" "$1" | ecryptfs-unwrap-passphrase "$HOME/.ecryptfs-ssh-wrapped/$1" - | ecryptfs-add-passphrase --fnek fi ecryptfs-mount-private cd "$HOME" if [ "$SSH_ORIGINAL_COMMAND" != "" ] then exec /bin/bash -c "$SSH_ORIGINAL_COMMAND" fi exec /bin/bash -l 

在上面的例子中, authorized_keys文件被调用时没有参数,所以第一个if块被跳过。 ecryptfs-mount-private命令将要求用户的密码。 但是这并不要求sshd启用密码authentication,因此只能使用公钥authentication的sshd

下一个命令将更改为用户的encryption主目录(直到该脚本将在未encryption的主目录中运行)。

脚本的最后一部分将运行作为ssh命令参数给定的命令(如果有的话),或者如果没有给出命令,则运行用户loginshell。

一个需要注意的是,这不适用于X11转发,因为主目录尚不可用,当cookie将被存储。 但是在主目录已经挂载的时候打开的任何其他会话都将能够处理X11转发。

改用~/.ssh/rc可以解决X11转发问题。 这是我还没有看过的东西。

第一个if块是一个黑客,我想出来允许无需密码的用户的主目录安装。 而是使用转发的ssh-agent来挂载用户的主目录。 这部分免责声明没有经过同行审查,所以相信ssh-agent-ecryptfs-decryption.py的encryption完全是您自己的风险。

python脚本如下所示:

 #!/usr/bin/env python from sys import argv from os import environ import socket s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) s.connect(environ['SSH_AUTH_SOCK']) def encode_int(v): return ('%08x' % v).decode('hex') def encode_string(s): return encode_int(len(s)) + s def encode_mpint(v): h = '%x' % v if len(h) & 1: h = '0' + h return ('%04x%s' % (len(h) * 4, h)).decode('hex') key_blob = argv[1].decode('base64') msg = 'ecryptfs-decrypt ' + argv[2] s.send(encode_string(chr(13) + encode_string(key_blob) + encode_string(msg) + encode_int(0))) response = s.recv(1024) assert response == encode_string(chr(14) + response[5:]), argv[1] passphrase = response[-48:].encode('base64').replace('\n', '') print passphrase 

那么解密是如何工作的呢? 首先,由authorized_keys提供的脚本参数是任何随机值。 用uuidgen生成的uuid可以工作。 shell脚本使用grep在authorized_keys文件中查找相关行来提取公钥。

这个base64编码的公钥以及uuid被赋给了python脚本。 使用的公钥是用户authentication的公钥。 python脚本使用有问题的公钥(因为签名消息正是ssh-agent可以做的)向转发的代理请求特定消息上的签名。 然后使用base64对部分签名进行编码以生成密码。

此密码用于解密ecryptfs包装的密码文件,但主文件使用用户的login密码encryption。 这个用ssh密钥生成的密码encryption。

我昨天受到了卡斯佩德的想法的启发,我做了这个:

https://github.com/bjornnorman/decryptfs-ssh

我已经试了一下,似乎工作出色。 这使得使用SSH时添加/删除用于无密码解密ecryptfs主文件夹的密钥非常简单。

像kasperd的原创一样,它没有被专家暴露给同行审查 – 但是因为它现在在github上,所以现在任何人都可以参与。

你仍然需要移动你的密钥在你的主文件夹之外,但是这样你至less可以避免令人讨厌的密码login…

请享用!

这是一个简单的解决scheme,但似乎并不高雅。

由于您的主文件夹已encryption,因此只需将authorized_keys文件放在未encryption的位置即可。

那么你需要告诉ssh authorized_keys在哪里。 在/etc/ssh/sshd_config ,追加:

 Match User [your_user_name] AuthorizedKeysFile [new_path_to_authorized_keys] 

注意:请确保将Match放在文件的末尾。 Match保持有效直到文件结尾或其他Match被满足。

现在您可以通过sshlogin,不需要先在本地login。 但是在login后,你需要运行:

 ecrypts-mount-private 

并input您的密码来挂载您的个人文件夹,然后手动cd到您的家中。