Я должен сохранить закрытый ключ в файле?

Это кажется на удар пределов ресурса. Взгляд pam_limits.so и /etc/security/limits.conf. Они позволяют администратору устанавливать явные пределы для ресурсов, которые может использовать пользователь так, чтобы один пользователь не мог пожиратель ресурсов все системные ресурсы. Если Apache поразит ограниченное, указанное этим, то он возвратит ошибку как вышеупомянутый даже при том, что существует много ресурсов, которые могут использовать другие пользователи. Существует также limit или ulimit команда в большинстве оболочек, но я не думаю, что это - проблема.

7
14.02.2013, 18:39
4 ответа

Если Вы хотите использовать существующие инструменты как ssh/ssh-agent необходимо обеспечить ключ как файл.

Другой, возможно, более выполнимое решение состоит в том, чтобы или непосредственно реализовать a ssh клиент в рамках Вашего приложения и зависит от сторонних библиотек, таких как JSch или расширяется также ssh/ssh-agent непосредственно получить и дешифровать ключ от Вашей базы данных.

4
27.01.2020, 20:16

Файлы являются основным способом обмениваться данными между приложениями. Это не должен быть дисковый файл. Это может быть файл на временном хранении или канале. Можно подать файл ключей к ssh-add на его стандартном входе пока файл ключей не является защищенным паролем ¹ (и так как файл ключей хранился зашифрованный, нет никакой причины его, чтобы быть защищенной паролем на вершине).

С другой стороны, ничего не делайте, представляют себе и пишут файл в поддержанную памятью файловую систему такой как /run (или /dev/shm или /tmp или безотносительно Ваших предложений распределения).

С другой стороны, имейте в наличии файл секретных ключей без внешнего шифрования, но поместите пароль на него. Используйте долгий, случайным образом сгенерированный пароль и сохраните тот пароль в базе данных.

¹ Экспериментально, ssh-add дроссели на защищенных паролем файлах ключей, которые не seekable, таковы как именованные каналы.

4
27.01.2020, 20:16

Извините, не ответ, но слишком долго для комментария, который я думаю, существует.

Важная вещь - то, чего Вы пытаетесь достигнуть путем хранения ключа в зашифрованной базе данных.

Взломщик, который может получить доступ к временному файлу секретных ключей, сможет считать память ssh клиентского процесса также (и следовательно добираться до ключевых данных так или иначе), потому что оба из этих данных должны иметь в основном те же права доступа - пытающийся скрыться, файл, кажется, не заставляет его больше защитить.

При использовании различных пользователей для дб, веб-приложения и соединения SSH, путем хранения ключа в дб, дешифрования его в веб-приложении и питания его к ssh, Вы просто открываете векторы потенциальной атаки путем распространения ключа на всем протяжении процесса. При использовании всего одного пользователя для всех них (дб, приложение, ssh), Вы ничего не получаете за исключением сложности кода.

Единственное преимущество, кажется, более легкая передача системы к другому хосту и потенциальному усилению в случае, если данные дб украдены, но веб-приложение (какой AFAIU содержит алгоритм дешифрования и пароль), нет. Но это, вероятно?

Тем не менее, если Вы хотите защитить ключ, можно также использовать внутреннее шифрование ssh ключей и загрузить их в ssh-агент при запуске сервиса (не забудьте удалять его, когда это останавливается!). Но снова помните, что ssh-агент сохраняет ключи в памяти незашифрованными, таким образом, это может потенциально быть считано. Все снова и снова: действительно ли это - проблема, которую Вы пытаетесь решить?

Если просто необходимо защитить коммуникацию между двумя машинами, stunnel могло бы быть лучше полезным, чем ssh.

И наконец для вопроса: что касается (портативного) OpenSSH, пишущий простой патч, который позволил бы ssh считать ключ из другого процесса как sshd делает с AuthorizedKeysCommand опция должна быть довольно простой.

3
27.01.2020, 20:16
  • 1
    я ценю то, что Вы говорите, и Вы правы бросить вызов моим предположениям и спросить, какая проблема - я решение; однако, Ваш ответ слишком характерен для среды вокруг моего вопроса (веб-приложение и дб) и (как Вы говорите), действительно не отвечает на сам вопрос. –  kojiro 14.02.2013, 21:11
  • 2
    Несомненно, я просто хотел записать это для дальнейшего использования. Скорее часто я видел, что люди (mis) используют ssh в ситуациях, где что-то еще было бы более оптимальным вариантом (я не говорю, что это - Ваш случай). И мудрый безопасностью часто забывает то, что должно быть его главными проблемами. –  peterph 14.02.2013, 23:32

Я пытался решить эту проблему, поскольку я создавал пары ключей и сохранял их в база данных с 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 , но он создан так, что только владелец имеет разрешения на него, и он удаляется, когда вы завершаете работу агента.

2
27.01.2020, 20:16

Теги

Похожие вопросы