Это кажется на удар пределов ресурса. Взгляд pam_limits.so и /etc/security/limits.conf
. Они позволяют администратору устанавливать явные пределы для ресурсов, которые может использовать пользователь так, чтобы один пользователь не мог пожиратель ресурсов все системные ресурсы. Если Apache поразит ограниченное, указанное этим, то он возвратит ошибку как вышеупомянутый даже при том, что существует много ресурсов, которые могут использовать другие пользователи. Существует также limit
или ulimit
команда в большинстве оболочек, но я не думаю, что это - проблема.
Если Вы хотите использовать существующие инструменты как ssh
/ssh-agent
необходимо обеспечить ключ как файл.
Другой, возможно, более выполнимое решение состоит в том, чтобы или непосредственно реализовать a ssh
клиент в рамках Вашего приложения и зависит от сторонних библиотек, таких как JSch или расширяется также ssh
/ssh-agent
непосредственно получить и дешифровать ключ от Вашей базы данных.
Файлы являются основным способом обмениваться данными между приложениями. Это не должен быть дисковый файл. Это может быть файл на временном хранении или канале. Можно подать файл ключей к ssh-add
на его стандартном входе пока файл ключей не является защищенным паролем ¹ (и так как файл ключей хранился зашифрованный, нет никакой причины его, чтобы быть защищенной паролем на вершине).
С другой стороны, ничего не делайте, представляют себе и пишут файл в поддержанную памятью файловую систему такой как /run
(или /dev/shm
или /tmp
или безотносительно Ваших предложений распределения).
С другой стороны, имейте в наличии файл секретных ключей без внешнего шифрования, но поместите пароль на него. Используйте долгий, случайным образом сгенерированный пароль и сохраните тот пароль в базе данных.
¹ Экспериментально, ssh-add
дроссели на защищенных паролем файлах ключей, которые не seekable, таковы как именованные каналы.
Извините, не ответ, но слишком долго для комментария, который я думаю, существует.
Важная вещь - то, чего Вы пытаетесь достигнуть путем хранения ключа в зашифрованной базе данных.
Взломщик, который может получить доступ к временному файлу секретных ключей, сможет считать память ssh клиентского процесса также (и следовательно добираться до ключевых данных так или иначе), потому что оба из этих данных должны иметь в основном те же права доступа - пытающийся скрыться, файл, кажется, не заставляет его больше защитить.
При использовании различных пользователей для дб, веб-приложения и соединения SSH, путем хранения ключа в дб, дешифрования его в веб-приложении и питания его к ssh, Вы просто открываете векторы потенциальной атаки путем распространения ключа на всем протяжении процесса. При использовании всего одного пользователя для всех них (дб, приложение, ssh), Вы ничего не получаете за исключением сложности кода.
Единственное преимущество, кажется, более легкая передача системы к другому хосту и потенциальному усилению в случае, если данные дб украдены, но веб-приложение (какой AFAIU содержит алгоритм дешифрования и пароль), нет. Но это, вероятно?
Тем не менее, если Вы хотите защитить ключ, можно также использовать внутреннее шифрование ssh ключей и загрузить их в ssh-агент при запуске сервиса (не забудьте удалять его, когда это останавливается!). Но снова помните, что ssh-агент сохраняет ключи в памяти незашифрованными, таким образом, это может потенциально быть считано. Все снова и снова: действительно ли это - проблема, которую Вы пытаетесь решить?
Если просто необходимо защитить коммуникацию между двумя машинами, stunnel
могло бы быть лучше полезным, чем ssh.
И наконец для вопроса: что касается (портативного) OpenSSH, пишущий простой патч, который позволил бы ssh
считать ключ из другого процесса как sshd
делает с AuthorizedKeysCommand
опция должна быть довольно простой.
Я пытался решить эту проблему, поскольку я создавал пары ключей и сохранял их в база данных с Python. Ниже приведены некоторые шаги, которые я в итоге использовал, а именно запуск ssh-agent
и взаимодействие с ним. Это на Python, но, по-видимому, вы могли бы перевести его на что-нибудь еще. Еще одна особенность заключается в том, что ни один из них не использует shell = True
, поэтому они более безопасны от атак с использованием инъекций.
import subprocess
import os
sockfile = '/some/place.sock'
agent = subprocess.Popen(['ssh-agent',
'-D', # foreground mode
'-a', sockfile, # bind address (socket file)
])
subprocess.check_call(['ssh-add',
'-D', # delete all identities from the agent
],
env={'SSH_AUTH_SOCK': sockfile},
)
Это запускает ssh-agent
, предназначенный только для нашей программы, и очищает его (я считаю, что он загружает в него мои пользовательские ключи, хотя не уверен). Переменная среды SSH_AUTH_SOCK
обычно устанавливается ssh-agent
(но это мы делали вручную), мы загружаем данные в другие программы.
Затем мы используем ssh-add
, чтобы передать ему закрытый ключ (здесь он хранится в dr.private_key
в виде строки, но мне нужно сериализовать его, поэтому я кодирую его как ASCII).
adder = subprocess.Popen(['ssh-add',
'-', # read key from stdin
],
env={'SSH_AUTH_SOCK': sockfile},
stdin=subprocess.PIPE,
)
adder.communicate(dr.private_key.encode('ascii'))
retval = adder.wait()
assert retval == 0 # added successfully
Теперь, когда я использую какое-либо приложение, использующее SSH, например Git, я рекомендую использовать тот же сокет агента SSH:
gitp = subprocess.Popen(
['git', '-C', os.path.abspath('../some-repo') ,'fetch'],
env={'SSH_AUTH_SOCK': sockfile},
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
)
print(gitp.communicate()[0].decode('ascii'))
, и он отлично работает. Единственный «временный файл» - это сокет, используемый ssh-agent
, но он создан так, что только владелец имеет разрешения на него, и он удаляется, когда вы завершаете работу агента.