У меня довольно странная проблема с моей конфигурацией SSH. Я настроил свой сервер с помощью карты удаленного доступа и настроил все с помощью программы просмотра KVM.
Итак, во время входа на сервер через KVM Viewer я настроил SSH только с помощью pubkey и попытался войти в систему с моего локального ноутбука. Работало нормально.
Если я выхожу из сеанса KVM (или выхожу из системы с пользователем в сеансе KVM), я больше не могу войти через ssh (pubkey запрещен). Вход по 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
file в первую очередь может быть немного сложным. В этом может помочь привязка базовой файловой системы.
Если например /home
это просто каталог в корневой файловой системе, вы можете сделать следующее:
mkdir /mnt/rootfs
mount --bind / /mnt/rootfs
И тогда вы можете создать /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
Важная часть - это command
указан перед ключом. Это вызывается вместо оболочки. Но это происходит только тогда, когда используется этот конкретный открытый ключ, и только если домашний каталог пользователя не смонтирован.
Если домашний каталог пользователя уже смонтирован, это 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
В приведенном выше примере authorized_keys
файл вызывается без аргументов, поэтому первый if
блок пропускается. В ecryptfs-mount-private
таким образом команда запросит пароль пользователя. Но для этого не требуется sshd
включить аутентификацию по паролю, и таким образом будет работать на sshd
только с аутентификацией с открытым ключом.
Следующая команда перейдет в зашифрованный домашний каталог пользователя (до тех пор скрипт будет выполняться внутри незашифрованного домашнего каталога).
Последняя часть скрипта выполнит команду, заданную как аргумент для ssh
команда, если она есть, или оболочка входа пользователя, если команда не была дана.
Одно предостережение заключается в том, что это не работает с пересылкой X11, потому что домашний каталог еще не доступен, когда cookie будет сохранен. Но любой другой сеанс, открытый в то время, когда домашний каталог уже смонтирован, сможет обрабатывать пересылку X11.
С помощью ~/.ssh/rc
вместо этого может решить проблему пересылки X11. Это то, что я еще не изучал.
Первый if
block - это своего рода хитрость, которую я придумал, чтобы можно было смонтировать домашний каталог пользователя без пароля. Вместо этого используется перенаправленный 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
Так как же работает расшифровка? Прежде всего, аргумент сценария, предоставленный authorized_keys
- любое случайное значение. UUID, созданный с помощью uuidgen
может работать. Сценарий оболочки использует команду grep для поиска соответствующей строки в authorized_keys
файл для извлечения открытого ключа.
Открытый ключ в кодировке base64, а также uuid передаются скрипту python. Используемый открытый ключ - это именно тот ключ, с помощью которого пользователь прошел аутентификацию. Сценарий python запрашивает у перенаправленного агента подпись в конкретном сообщении с использованием рассматриваемого открытого ключа (поскольку подписывание сообщений - это именно то, что ssh-agent
сможет сделать). Затем часть подписи кодируется с помощью base64 для создания пароля.
Этот пароль используется для расшифровки ecryptfs
обернутый файл паролей, но основной файл зашифрован с использованием пароля для входа пользователя. Он зашифрован паролем, сгенерированным из ключа ssh.
Вчера меня так вдохновила идея Касперда, что я сделал следующее:
https://github.com/bjornnorman/decryptfs-ssh
Я уже немного попробовал, и, кажется, работает блестяще. Это упрощает добавление / удаление ключей для дешифрования домашних папок ecryptfs без пароля при использовании SSH ...
Как и оригинал kasperd, он не был подвергнут экспертной оценке экспертами, но поскольку он находится на github, теперь любой может принять участие. :)
Вам все равно придется перемещать ключи за пределы вашей домашней папки, но с этим вы, по крайней мере, можете избежать неприятного входа в систему с паролем ...
Наслаждайтесь!
Вот простое решение, но оно не выглядит элегантным.
Поскольку ваша домашняя папка зашифрована, просто поставьте authorized_keys
файл в незашифрованном месте.
Затем вам нужно указать ssh, где authorized_keys
является. В /etc/ssh/sshd_config
, добавить:
Match User [your_user_name]
AuthorizedKeysFile [new_path_to_authorized_keys]
ПРИМЕЧАНИЕ. Обязательно установите Match
в конце файла. В Match
остается в силе до конца файла или другого Match
встречается.
Теперь вы можете войти в систему через ssh, и вам не нужно сначала входить в систему локально. Но после входа в систему по ssh вам нужно запустить:
ecrypts-mount-private
и введите свой пароль, чтобы смонтировать вашу домашнюю папку, а затем cd
домой вручную.