Web*_*x10 1 remote-access linux ssh ssh-keys kvm-virtualization
我的 SSH 配置有一个相当奇怪的问题。我在远程访问卡的帮助下设置了我的服务器,并使用 KVM 查看器配置了所有内容。
因此,在通过 KVM 查看器登录服务器时,我仅使用公钥配置了 SSH,并尝试从本地笔记本电脑登录。它工作得很好。
如果我退出 KVM 会话(或在 KVM 会话中与用户一起注销),我将无法再通过 ssh 登录(公钥被拒绝)。SSH 登录仅在用户在某处仍处于登录状态时才有效。
任何提示可能是什么问题?
登录失败的控制台输出(所有个人数据交换):
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 hmac-md5-etm@openssh.com none
debug1: kex: client->server aes128-ctr hmac-md5-etm@openssh.com 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).
成功登录的控制台输出(仅在“活动会话”存在时才可能):
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 hmac-md5-etm@openssh.com none
debug1: kex: client->server aes128-ctr hmac-md5-etm@openssh.com 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 no-more-sessions@openssh.com
debug1: Entering interactive session.
debug1: Sending environment.
debug1: Sending env LANG = de_DE.UTF-8
Welcome to Ubuntu 14.04.1 LTS
当用户的主目录被加密时,在挂载主目录之前ecryptfs
sshd
无法authorized_keys
从用户的主目录中读取文件。
登录时sshd
将用于pam
对用户进行身份验证,pam
并将使用用户输入的密码挂载加密的主目录。
如果您想限制sshd
为仅允许公钥身份验证,这是有问题的。
但是,您也可以将未加密的authorized_keys
文件放在服务器上。这将允许用户使用密钥登录,但由于这不会调用pam
,因此不会挂载主目录,并且在不知道密码的情况下挂载主目录也不起作用。
由于未加密的主目录被加密的主目录隐藏,因此将未加密的authorized_keys
文件放在首位可能有点棘手。底层文件系统的绑定挂载可以帮助解决这个问题。
例如,如果/home
只是根文件系统上的一个目录,则可以执行以下操作:
mkdir /mnt/rootfs
mount --bind / /mnt/rootfs
Run Code Online (Sandbox Code Playgroud)
然后你可以创建 /mnt/rootfs/home/$USER/.ssh/authorized_keys
你可以做的还有更多。由于加密版和未加密版authorized_keys
是两个不同的文件,您可以将不同的内容放入其中。例如,未加密的版本可以调用脚本以挂载加密的主目录:
command="/usr/local/bin/ecryptfs-mount-from-ssh" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDM1Ot12ThbTcPOGpfh7AiRqp3P4BMm3DNo4mDg7gDFPwCmM9rKRHTH0fBVSqkSGlXm84q29bckDukg7vfqkbTpbkP3e2YmTkP6p1J2SoX2QMUnBRRgL9It/ZiAfA2I4QzUrcywVvokO1F2DqcRLy5e5wKTUFfvIm6D2QfBmGbnW2Kkpn16hQyLT1ClXjFC1qXUhazePv0cAtWUCUGjRcLr/ipOphS7eOB46cGhYqtbMkKx0t93ZG4f6jM0o32cYy3RqprpZpTmCeG1gDyG+IlSLBYXYggr72iwTKsTZ9pMDTCBQ8Pb7l317TPOcJzTtDxnpgpGE3x4Vu/Ww+zhsIeT kasperd 2014 May 24
Run Code Online (Sandbox Code Playgroud)
重要的部分是command
在键之前指定的。这将被调用而不是 shell。但只有在使用此特定公钥时才会发生这种情况,并且仅当用户的主目录未安装时才会发生。
如果用户的主目录已经挂载,则该authorized_keys
文件被隐藏并使用加密版本代替。的加密版本authorized_keys
没有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
Run Code Online (Sandbox Code Playgroud)
在上面的例子中,authorized_keys
文件是不带参数调用的,所以第一个if
块被跳过。ecryptfs-mount-private
因此,该命令将询问用户的密码。但这不需要sshd
启用密码身份验证,因此sshd
仅适用于公钥身份验证。
下一个命令将更改为用户的加密主目录(在此之前脚本将在未加密的主目录中运行)。
脚本的最后一部分将运行作为命令参数给出的ssh
命令(如果有),或者如果没有给出命令,则运行用户登录 shell。
一个警告是,这不适用于 X11 转发,因为当 cookie 将被存储时,主目录尚不可用。但是在主目录已经挂载时打开的任何其他会话将能够处理 X11 转发。
使用~/.ssh/rc
反而可能可能解决X11转发问题。这是我还没有研究过的。
第一个if
块有点小技巧,我想出它来允许在不需要密码的情况下挂载用户的主目录。相反,它使用转发ssh-agent
来挂载用户的主目录。这部分带有关于没有任何同行评审的免责声明,因此信任密码学ssh-agent-ecryptfs-decryption.py
完全由您自己承担风险。
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
Run Code Online (Sandbox Code Playgroud)
那么解密是如何工作的呢?首先,脚本提供的参数authorized_keys
是任何随机值。生成的 uuiduuidgen
可以工作。shell 脚本使用 grep 在authorized_keys
文件中查找相关行来提取公钥。
将 base64 编码的公钥以及 uuid 提供给 python 脚本。所使用的公钥正是用户进行身份验证时使用的公钥。python 脚本要求转发代理使用相关公钥对特定消息进行签名(因为签名消息正是ssh-agent
可以做的)。然后使用 base64 对签名的一部分进行编码以生成密码。
此密码用于解密ecryptfs
包装好的密码文件,但主文件使用用户的登录密码进行加密。这个是用 ssh 密钥生成的密码加密的。
归档时间: |
|
查看次数: |
1843 次 |
最近记录: |