id: Гость   вход   регистрация
текущее время 14:35 28/03/2024
Владелец: SATtva (создано 27/01/2015 17:51), редакция от 18/03/2015 21:51 (автор: SATtva) Печать
Категории: софт, gnupg, openpgp, инфобезопасность, стандарты, свободный софт, разграничение доступа
создать
просмотр
редакции
ссылки

GPG Remote


Оглавление документа:

Постановка проблемы


Использование GnuPG в сетевой среде всегда несёт риск того, что противник, способный скомпрометировать какое-либо из клиентских приложений (email-клиент, IM-клиент и т.п.), сможет с лёгкостью извлечь закрытые ключи, выполнив gpg --export-secret-keys. Смарткарты являются общепринятым решением данной проблемы, но сами они, в свою очередь, являются специализированными устройствами, которые 1) не всегда могут быть доступны пользователю либо 2) могут быть недоверяемы по тем или иным причинам.

Предлагаемое решение


GPG Remote — это клиент-серверное приложение, переносящее операции с закрытыми ключами GnuPG на удалённый сервер, исполняемый в безопасной доверенной системе. Сервер отфильтровывает клиентский ввод в соответствии с заданными правилами и запускает GnuPG, выступая посредником между программой и клиентом.


GPG Remote позволяет разделить процесс исполнения GnuPG между клиентом-фронтэндом и сервером-бекэндом. Клиентская часть приложения эмулирует консольный интерфейс GnuPG: принимает аргументы командной строки и данные, передаваемые пользователем через стандартный ввод (STDIN). Затем производится парсинг консольных аргументов и определение файлов, которые пользователь хотел передать GnuPG для обработки. Из этих данных формируется пакет запроса, который передаётся серверу.


Сервер работает в доверенной среде, его задача — выполнить gpg безопасным образом. Этой цели служит белый список консольных опций gpg, согласно которому сервер отфильтровывает полученные от клиента аргументы командной строки (прежде всего, команды типа --export-secret-keys). Клиентские файлы сохраняются во временную директорию, а их пути в аргументах командной строки соответствующим образом заменяются. Наконец, сервер вызывает gpg, а вывод программы (состоящий из потоков STDERR и STDOUT, кода завершения программы, а также сгенерированных файлов) посылается обратно клиенту.

Установка


Убедитесь, что на системах, где вы планируете запускать клиентскую и серверную части приложения, установлен Python 3.3.x или выше. Клиентский и серверный модули не имеют внешних зависимостей, их можно разместить в произвольных директориях.


Для запуска клиента GPG Remote в качестве замены системному gpg необходимо переименовать скрипт gpgremote_client.py в /usr/bin/gpg либо поставить символическую ссылку с указанного пути на файл скрипта. Если клиентский и серверный компоненты запускаются на одной системе, убедитесь, чтобы связки ключей GnuPG были доступны (на чтение и запись) только пользователю, из-под которого запускается сервер.


Если требуется поддержка удалённого ввода парольных фраз (при запуске клиента и сервера на отдельных системах), сделайте следующее:


  1. Убедитесь, что на клиенте установлено стандартное приложение pinentry.
  2. Установите на клиентскую и серверную системы библиотеку pyassuan.
  3. Корректно настройте и запустите gpg-agent на серверной системе. При запуске gpg-agent укажите в опции --pinentry-program путь к pinentry.py из дистрибутива GPG Remote (для дополнительной информации см. man gpg-agent).

Для поддержки "тревожных" команд (см. одноимённый раздел ниже) установите на серверной системе Python-модуль pbkdf2.

Настройка


Клиент считывает свои настройки (в частности, хост и порт сервера) из файла gpgremote_client.conf, находящегося в директории ~/.gnupg. Этот путь можно переопределить с помощью переменной окружения GNUPGHOME.


По умолчанию, сервер берёт свои настройки из файла gpgremote_server.conf, также находящегося в директории ~/.gnupg (если этот путь не был переопределён с помощью переменной окружения GNUPGHOME), однако с помощью опции -c/--config можно указать другой путь и имя файла конфигурации. Большинство других параметров сервера также можно изменить из командной строки (используйте -h/--help для вывода всех опций, доступных для запуска сервера).

Белый список


Вторая часть серверных настроек — это белый список опций gpg, находящийся в файле whitelist.conf в одной директории с конфигурационным файлом. Его формат достаточно прост, но правильная настройка имеет критически важное значение для безопасности сервера (см. раздел "Меры безопасности"):


  1. Строки, не начинающиеся со знака тире, игнорируются.
  2. Каждая строка содержит один набор опций.
  3. Набор может быть представлен одной опцией в короткой (с одним тире) или в длинной форме (с двумя тире), либо разделёнными пробелом несколькими опциями в короткой или длинной форме (в произвольном порядке).
  4. Если набор содержит слова, не начинающиеся с тире, то они имеют следующее значение:
    • Слово в квадратных скобках является произвольным параметром — опции в данном наборе считаются параметеризуемыми.
    • Слово без квадратных скобок является разрешённым значением параметра — опции в данном наборе считаются параметеризуемыми и могут принимать параметр только в указанном значении. Если требуется разрешить несколько значений параметра, их необходимо привести в этой же строке через пробел (поддерживаются кавычки и экранирование пробелов).
    • Слово #NO_FILES в квадратных скобках устанавливает для данного набора опций флаг "без файлов" — программа не будет рассматривать переданные аргументы командной строки в качестве имён файлов (см. раздел "Меры безопасности").

Одноразовые пароли


Одноразовые пароли (OTP) — это дополнительная мера безопасности для защиты закрытых ключей. После её активации при использовании закрытого ключа пользователь должен будет ввести короткий случайный пароль (из заранее сгенерированного списка) наряду с основной парольной фразой. Поскольку для каждой операции такой пароль уникален, это препятствует использованию закрытого ключа со стороны противника, даже если он перехватит парольную фразу и попытается воспользоваться ключом через GPG Remote. (Обратите внимание: для поддержки данной функции необходимо использовать pinentry.py из состава GPG Remote. См. выше раздел "Установка".)


Для использования данной функции, активируйте её в файле настроек сервера или опцией --otp при запуске сервера. После этого вызовите сервер с опцией --gen-otp и укажите, какое число одноразовых паролей требуется сгенерировать. Чем длиннее будет список, тем реже его надо будет обновлять, но и тем больше операций сможет совершить противник, если этот список окажется скомпрометирован. Обратите внимание, что в любой момент можно сгенерировать новый список паролей, и все пароли, которые оставались в предыдущем списке, будут аннулированы; после генерации нового списка перезапуск сервера не требуется.


Если функция OTP включена, то при каждом запросе парольной фразы необходимо будет ввести также и одноразовый пароль — его нужно дописать непосредственно к концу парольной фразы (не отделяя пробелом или какими-либо иными знаками). Введённый пароль тут же аннулируется: так, если пользователь допустит опечатку в парольной фразе закрытого ключа, то при следующей попытке её ввода потребуется ввести уже следующий одноразовый пароль. Когда список паролей окажется пуст, какие-либо операции с закрытыми ключами станут недоступны, пока не будет сгенерирован новый список.


Учтите, что кэширование парольных фраз в gpg-agent обходит механизм OTP: пока парольная фраза закэширована, ключ может применяться без всяких запросов к пользователю.

"Тревожные" команды


Существует возможность настройки произвольного количества так называемых "тревожных", или экстренных, команд. Эти команды (в сущности, shell-команды любого вида) исполняются на стороне сервера, если в диалог pinentry введена определённая парольная фраза. (Обратите внимание: для поддержки данной функции необходимо использовать pinentry.py из состава GPG Remote. См. выше раздел "Установка".)


Правила для "тревожных" команд задаются специальными пунктами в конфигурационном файле сервера. Имя правила должно быть уникальным и начинаться с префикса panic_. Значение правила должно состоять из защитного токена и следующей далее через пробел shell-команды или нескольких команд в обычном виде (иными словами, без кавычек, экранирования и т.п.) либо специальной команды (см. ниже). Защитный токен представляет собой PBKDF2-хэш от парольной фразы, которая должна вызывать срабатывание правила. Чтобы получить такой токен, запустите сервер с опцией --gen-token и введите парольную фразу и, если нужно, число итераций хэширования.


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


При исполнении shell-команд им, помимо прочих, передаются следующие переменные окружения:


  • GPG_REMOTE_PID: ID серверного процесса GPG Remote.
  • GPG_REMOTE_KEYRINGS: Разделённый пробелами список путей к не пустым связкам ключей gpg.

Вместо shell-команд "тревожные" правила могут содержать следующие специальные команды. Имейте в виду, что правило может содержать только одну специальную команду:


  • STOP: Штатно останавливает сервер GPG Remote. Сервер отправляет клиенту сообщение о неопределённой ошибке, завершает обработку оставшихся параллельных запросов, удаляет все временные данные, полученные от клиента, и останавливает программу.
  • KILL: Немедленно прерывает работу сервера GPG Remote. Сервер посылает себе системный сигнал SIGKILL без выполнения каких-либо завершающих процедур.

Обратите внимание, что gpg-agent считывает закрытый ключ в память до того, как вызывает pinentry, поэтому использование команд rm/wipe для экстренного стирания связок ключей не приведёт к немедленному уничтожению ключа — для этого также необходимо остановить серверный процесс GPG Remote (с помощью специальных команд STOP или KILL), чтобы не дать ему отправить результат работы gpg обратно клиенту. В тех случаях, когда в этом есть потребность, используйте возможность последовательного выполнения нескольких правил (путём назначения им одинаковых токенов безопасности или парольных фраз).

Меры безопасности


Аутентификация/шифрование канала связи лежит за пределами данного приложения. Для организации безопасной клиент-серверной коммуникации пользователь может использовать SSH- или VPN-туннелирование.


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


Учтите, что даже если модифицирующие связку ключей опции (такие как --delete-key или --import) не внесены в белый список, у клиента всё равно сохранится возможность добавлять открытые и закрытые ключи на связку, просто передавая их через стандартный ввод (обрабатываемый программой gpg по контексту). Если такие действия нежелательны, администратору сервера следует запускать сервер из-под пользователя, не имеющего прав записи в файлы связок gpg. Имейте в виду, что стандартные файлы связок всегда можно переопределить с помощью опций --no-default-keyring, --keyring и --secret-keyring.


Другая потенциальная угроза серверу заключается в риске утечки его локальных файлов. При наивной реализации пользователь мог бы попросить сервер выполнить gpg -o – --enarmor [путь к локальному файлу], и сервер, не задумываясь, передал бы содержимое этого файла через STDIN. Чтобы этого избежать, сервер проверяет, чтобы число аргументов командной строки, в которых могут содержаться имена файлов, равнялось количеству файлов, полученных от клиента в пакете запроса. (Все эти сложности необходимы, т.к. если бы сервер просто отказывался выполнять запросы, включающие пути к существующим локальным файлам, возникала бы утечка информации о содержимом файловой системы сервера.) В то же время, для такого механизма необходима корректная настройка белого списка сервера в плане обозначения опций с параметрами: если опция может принимать параметры, её набор должен содержать указатель параметра (произвольный или разрешённый), в противном случае сервер может оказаться уязвим к описанной атаке.


Обратите внимание, что ряд консольных опций gpg (в частности, --list-keys, --list-sigs и др.) могут принимать произвольное количество нефайловых аргументов. Для учёта такого случая набор опций в белом списке может содержать специальное ключевого слово [#NO_FILES]. Если клиентский запрос будет включать опцию из такого набора, сервер удалит из запроса опции -o/--output и не станет возвращать клиенту какие бы то ни было файлы.


Получаемые от клиента файлы (которые могут содержать открытый текст секретных данных) сервер сохраняет во временную директорию. По умолчанию это системная директория для временных файлов (как правило, /tmp), но если такая директория по какой-либо причине является небезопасной, её путь можно переопределить с помощью переменной окружения TEMP или опции --temp при запуске сервера. (Обратите внимание, что файлы сохраняются не непосредственно в temp-директорию, а во временные подкаталоги в ней, создаваемые с правами доступа 0700, т.е. доступные только для пользователя, под которым запущен сервер GPG Remote.)


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


Клиент имеет возможность вызвать у сервера отказ в обслуживании, посылая ему чрезмерно объёмные запросы. Для предотвращения такого сценария следует использовать параметры ограничения ресурсов сервера: size_limit, threads и queue. Первый ограничивает объём клиентского пакета запроса и, как следствие, объём потребляемой памяти. Второй устанавливает ограничение на число процессорных потоков, выделяемых на обработку запросов (каждый запрос обрабатывается одним потоком). Учтите, что максимальный объём ОЗУ, требуемый серверу, составляет примерно S * T * 2, где S — лимит на объём пакета и T — число потоков (т.е. при заданных по умолчанию S=1 ГБ и T=2 максимальный объём ОЗУ может составить 4 ГБ). Наконец, значение queue — это количество запросов, которые могут встать в очередь на обработку. Если это значение выше числа потоков, то оставшиеся запросы будут ожидать завершения активных. Ожидающие запросы не потребляют дополнительных ресурсов, за исключением открытого сокета для соединения.


При использовании удалённого ввода парольных фраз, они никогда не попадают в память долгоживущего серверного процесса GPG Remote. Тем не менее, введённая парольная фраза остаётся в памяти клиентского модуля вплоть до завершения вызова gpg, и на протяжении этого времени она остаётся уязвима к своппингу ОЗУ. Убедитесь, чтобы swap-раздел ОС был зашифрован, отключен или примите иные адекватные меры предосторожности.


Одноразовые пароли (OTP) являются механизмом контроля доступа, применяемым на уровне логики GPG Remote. Данный механизм не затрагивает какой бы то ни было криптографический материал, и от него не следует ожидать обеспечения особых криптографических свойств, таких как PFS.


Если на сервере настроены "тревожные" правила, и при этом в токенах безопасности используется большое число итераций, противник потенциально будет способен определить этот факт по задержке, с которой gpg возвращает вывод, поскольку введённая парольная фраза будет сравниваться с каждым из уникальных токенов. Также выполнение тех или иных "тревожных" правил может быть выявлено, если исполняемая команда требует значительного времени для завершения.

Технические сведения


Коммуникационный протокол представляет собой простейший двухшаговый запрос-ответ. Формат пакета для обоих направлений показан ниже.

<len_p> | <len_j> | JSON(<header>, <type>, <fields>, <files_meta>) | [binary]

  • len_p (8 bytes): Общая длина пакета.
  • len_j (8 bytes): Длина JSON-пакета.
  • header (list): Токен аутентификации auth (опционально) и версия приложения version.
  • type (str): Идентификатор пакета.
  • fields (list): Произвольный набор полей.
  • files_meta (dict): Отображение путь_файла->длина_файла.
  • binary (bytes): Конкатенированное содержимое файлов (опционально).

Если используется токен аутентификации, он должен быть представлен в виде свёртки HMAC-SHA256 (в шестнадцатеричной нотации) всех метаданных в JSON-пакете. Токен вычисляется следующим образом: элементы метаданных (за исключением элемента auth) помещаются в вышеуказанном порядке в плоский список, кодируются в JSON-строку, которая передаётся в контекст функции HMAC. В настоящее время аутентификация применяется только для IPC-сообщений между сервером и pinentry. По этой причине аутентификация binary-пакета не производится.


Удалённый ввод парольных фраз реализован на основе специализированного приложения-прокладки pinentry и выполняется по следующему протоколу (участник pinentry в нижеследующем описании — это специализированное приложение pinentry, если не указано иное):


  1. server>gpg-agent: устанавливает в переменной окружения PINENTRY_USER_DATA (передаваемой через весь стек вызова gpg > gpg-agent > pinentry) сведения для установления IPC-канала, в том числе имя IPC-сокета и сеансовый ключ аутентификации.
  2. gpg-agent>pinentry: вызывает pinentry, передавая переменную окружения PINENTRY_USER_DATA и инициализирует Assuan-протокол.
  3. server>pinentry: передаёт по IPC-каналу (UNIX-сокету) открытый сетевой сокет клиентского соединения непосредственно процессу pinentry.
  4. pinentry>client: по предоставленному сетевому соединению посылает клиенту необходимые данные (текстовые строки и опции запуска, полученные от gpg-agent на этапе 2) для вызова стандартного приложения pinentry.
  5. client: вызывает стандартное приложение pinentry и получает пользовательский ответ (в виде ответа Assuan-протокола).
  6. client>pinentry: пересылает пользовательский ответ.
  7. pinentry: выполняет "тревожные" команды, если введённая парольная фраза вызвала срабатывание каких-либо из них.
  8. pinentry>gpg-agent: воспроизводит пользовательский ответ в начатом на этапе 2 Assuan-протоколе.

При вводе неверной парольной фразы цикл 2-8 повторяется по запросу gpg-agent.


Стоит отметить, что, хотя доступ к UNIX-сокету IPC-интерфейса (используемого для связи между сервером и процессом pinentry) не ограничивается средствами ОС (чтобы имелась возможность запуска сервера и gpg-agent под разными пользователями), сервер производит проверку аутентичности поступающих сообщений с помощью сеансового ключа аутентификации, который он передаёт pinentry на первом этапе протокола.


Список одноразовых паролей (OTP) хранится на сервере в открытом виде. Каждая строка файла списка представляет собой разделённый двоеточием идентификационный номер и непосредственно строку пароля


Токен безопасности для "тревожных" правил представляет собой вывод PBKDF2[SHA-1, HMAC] с эффективным предельным объёмом энтропии 256 бит. Длина значения соли составляет 64 бита. Формат токена — это строка разделённых двоеточиями и Base62-кодированных элементов: число итераций (в байтовом представлении), соль, хэш PBKDF2.


Значение порта сервера по умолчанию (29797) было получено в Python следующим образом:

int.from_bytes(b'gpgremote', 'big') % 2 ** 16

(В то же время, было замечено, что при такой процедуре значение имеют только последние байты b'te'.)

Проблемы и ограничения


  • Интерактивные консольные операции (такие как генерация и редактирование ключа и т.п.) не поддерживаются.

  • Клиент не поддерживает чтение ввода из TTY, данные могут быть переданы только через пайп в STDIN.

  • Передача файловых дескрипторов и иные продвинутые виды IPC для взаимодействия с вызываемым процессом gpg не поддерживаются.

  • Переменные окружения клиента не передаются вызываемому процессу gpg. Если требуется вызов gpg с определённым окружением (к примеру, LANG), необходимо запустить сервер GPG Remote с данными переменными.

  • При использовании GnuPG 2.x без специализированного приложения Pinentry из состава GPG Remote операции с защищёнными закрытыми ключами приведут к вызову на стороне сервера стандартного диалога Pinentry, который заблокирует процесс gpg, не давая ему корректно завершиться. Если клиент и сервер GPG Remote запускаются на одной системе, то такое поведение может быть даже желательным (однако убедитесь, что значения conn_timeout у клиента и gpg_timeout у сервера достаточно велики, чтобы пользователь успел ввести парольную фразу), в противном случае администратору сервера следует предпринять меры для отключения gpg-agent на стороне сервера (например, путём перехода на версию GnuPG 1.4.x или с помощью запуска gpg-agent с опцией --batch).

Планы


  • Снизить потребление памяти.

 
На страницу: 1, 2, 3, 4 След.
Комментарии [скрыть комментарии/форму]
— Гость (28/01/2015 19:08)   <#>
Кое-где тильды в тексте съелись. SATtva, если вам нужно набрать тильду, пишите две: ~~/.gnupg.
— SATtva (29/01/2015 11:56)   профиль/связь   <#>
комментариев: 11558   документов: 1036   редакций: 4118
Вот спасибо, мил человек, а то ж я не знал. :)
— Гость (29/01/2015 13:37)   <#>
Если ещё какие вопросы по разметке будут, обращайтесь. Всего не обещаю, но чем смогу, помогу.
— SATtva (30/01/2015 10:33)   профиль/связь   <#>
комментариев: 11558   документов: 1036   редакций: 4118
Посмотрел, с какой стороны лучше зайти к реализации парольных фраз. Так как поток данных при запросе парольной фразы идёт по схеме gpg <> gpg-agent <> pinentry, то, чтобы делать по уму, а не грязными хаками, следует реализовать на сервере кастомный pinentry, задача которого только в том, чтобы переадресовать запрос обратно клиенту, который, в свою очередь, запустит стандартный pinentry, а введённые пользователем данные отдаст на сервер.

Ситуация осложняется тем, что все компоненты GnuPG используют для коммуникации специальный протокол (Assuan), и кастомный pinentry должен уметь на нём общаться. К счастью, один добрый человек уже озаботился этим вопросом и написал Python-реализацию libassuan и даже собственную pinentry.

При правильной реализации удастся даже снизить риск, указанный в моём прежнем замечании (в конце комментария) относительно небезопасности хранения данных в памяти Python-процесса, т.к. единственный долгоживущий процесс — сервер — сам даже не будет видеть пользовательский пароль. Определённая опасность остаётся только на стороне клиента — этот процесс видит пароль и висит в памяти до получения результата от сервера.
— unknown (30/01/2015 11:10)   профиль/связь   <#>
комментариев: 9796   документов: 488   редакций: 5664

У вас было изначально именно так. Я исправил. :)
— SATtva (30/01/2015 11:22)   профиль/связь   <#>
комментариев: 11558   документов: 1036   редакций: 4118
Старик Фрейд доволен. :)
— Гость (31/01/2015 10:38)   <#>

Он от чего-то защищает? Вспомнил свой старый топик «Агент-прослойка для безопасной работы с ключами в UNIX», так что спасибо вам за реализацию. По ссылке:

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

Помогут ли эти костыли от кражи приватного ssh-ключа?
Такие решения возможны только на уровне обфускации и игры в прятки. Принципиально это невозможно.
Обычный юзер же не может читать память произвольного процесса, даже запущенного им самим. Разве не так?

Кто из нас прав, я или unknown?

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

Как работают хранители паролей? Чем обеспечивается безопасность при взломе профиля? Что мешает злонамеренному коду перехватить пароль на открытие базы хранителя паролей?
Работают так, что система пользователя считается безопасной. Если у Вас там рассадник троянов, то поможет разве что отдельный ноутбук без подключения к сети.

Все эти вопросы об одном и том же. Какова модель угрозы, и от чего мы собственно защищаемся?

Возьмём традиционный gpg с pinentry. Периодически юзер вводит пассфразу. Значит, периодически запущенный фоново троян её может перехватывать:

Под скомпрометированным пользователем доверять нельзя ничему.
Справедливо.

Есть ли какое-то коцептуальное отличие случая «gpg+pinentry+пассфраза» от «PGP-ключ лежит на диске нешифрованным (ограничиваемся только дисковым шифрованием)»? Или это всё очередное самоуспокоение? Понятно, что с gpg-remote всё должно быть лучше.

Единственно, поддерживать она будет только gpg, но не gpgme.

А добавить поддержку gpgme — это насколько сложно будет? Мой джаббер-клиент на неё завязан, и это не лечится. ☹
— SATtva (31/01/2015 11:18, исправлен 31/01/2015 11:33)   профиль/связь   <#>
комментариев: 11558   документов: 1036   редакций: 4118

В принципе или конкретно в случае GPG Remote? На стороне сервера — позволяет сделать так, чтобы пароль не болтался в его, сервера, памяти. На стороне клиента это просто элемент стандартного GnuPG-окружения, так-то пароль можно и через обычный питоновский input() запрашивать.



Один процесс не может читать память другого параллельного процесса (ну, почти: есть ptrace и прочая). Обычный пользователь не может читать память процессов, запущенных другим пользователем. Нарушение этих условий требует наличия дыры в ядре.



Если под одним пользователем на одной системе, то, в пределе, без разницы.


Что Вы зациклились на pinentry? Это просто фиговинка для ввода пароля, в её гуишной версии (есть ещё на ncurses) есть какая-то простая защита от X-сниффинга, но я бы на это сильно не полагался. Необходимость её использования в том, что на неё завязан gpg-agent, плюс её кастомная реализация — рекомендуемый разработчиками GnuPG способ для создания собственных механизмов передачи паролей в gpg. Если б не pinentry, добавление поддержки паролей в GPG Remote вышло бы ужасно грязным и не факт, что вообще смогло бы вменяемо работать.



Нереал, это же динамическая библиотека, чтобы её эмулировать, нужно полностью скопировать API и завернуть это всё в ELF. То есть это повышает сложность проекта сразу минимум на порядок.

— Гость (31/01/2015 14:29)   <#>

В принципе, т.е. без gpg-remote.


Да, это очевидное утверждение.


Ну так вот и хотелось бы немного понятных деталей. Под юзером USER1 запещно два процесса. Как сильно один может влезать на другой? Например, под одним выполняется троянский демон, а второй переиодически запрашивает пассфразу (pinentry) или просто хранит в памяти закешированный приватный PGP-ключ (какой-нибудь джаббер-клиент с конвенциональным gpg).

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


У меня к ней личные счёты.


Наверно, речь идёт не о pinentry, как о GUI'нюшке на gtk, а о её internals?


Жаль, но аргумент понятен. Значит, с mcabber'ом gpg-remote не подружить: надо либо патчить первый, переводя его на традиционный gpg (малореально, затрат много), либо делать поддержку gpgme в gpg-remote (тоже нереально). ☹ Некуда бедному крестьянину податься. Т.е. закрыть дыру в самом уязвимом приложении, работающем с PGP-ключами, через gpg-remote не получится, хотя когда-то были надежды на этот счёт.
— SATtva (31/01/2015 15:36)   профиль/связь   <#>
комментариев: 11558   документов: 1036   редакций: 4118

Преимущество в компартментации и изоляции кода: из монолитного трудноотлаживаемого комбайна приложение разбивается на независимые компоненты с чётко очерченными функциями (libgcrypt реализует низкоуровневые криптографические операции, gpg — операции с протоколом и форматом OpenPGP, gpg-agent — операции с закрытыми ключами, pinentry — сугубо пользовательский интерфейс), взаимодействующие с помощью простого командного протокола. Всем хочется получить безопасное приложение, вот это, очевидно, необходимая цена.


Непосредственно читать чужую память нельзя, у каждого процесса своё выделенное виртуальное адресное пространство, за доступом к которой следит ОС. Системные вызовы типа ptrace позволяют аттачиться к другим процессам данного пользователя (на этом принципе основана работа дебаггеров), но на его применение в конкретных ОС могут налагаться дополнительные ограничения, см. ссылку выше.


Незашифрованный ключ не хранится в памяти джаббер-клиента (да и вообще никакой ключ). Когда джаббер-клиенту нужно выполнить какую-нибудь криптооперацию, он вызывает gpg (или gpgme, не суть важно) и передаёт ему нужные данные, а тот уже запрашивает у клиента пароль через pinentry (если он не закэширован в gpg-agent) и выполняет операцию. Скомпрометированный джаббер-клиент может вытащить ключ, запросив gpg --export-secret-key (чего мы пытаемся избежать с помощью GPG Remote), но тогда ему таки потребуется извращаться с перехватом пароля, либо попытаться прочитать закэшированный пароль из процесса gpg-agent (если он запущен от того же пользователя и ОС позволит), либо попытаться прочитать криптоключ из процесса gpg (с теми же условиями).


В сущности, pinentry — небольшой Assuan-сервер, который должен поддерживать ряд команд, на которые рассчитывает gpg-agent. В какую обёртку завёрнут этот сервер, есть ли вообще у него какой-то пользовательский интерфейс, совершенно всё равно.
— Гость (31/01/2015 16:44)   <#>

Если копнуть глубже, то, пожалуй, незачем читать пассфразу из чужого процесса — проще поменять конфиги так, что очередной раз вместо правильного pinentry/gpg/gpg-agent запустится свой прикормленный троянский. В этом плане, если gpg-remote не используется, pinentry и gpg-agent никак не помогут от кражи ключа. Можно ещё надеяться на разные уловки, которые противник не сможет преодолеть, но концептуально вроде так: скомпрометированный джаббер-клиент всегда сможет вытащить ключ, как ни старайся (без gpg-remote).
— SATtva (31/01/2015 16:55)   профиль/связь   <#>
комментариев: 11558   документов: 1036   редакций: 4118
Это вполне очевидно: компрометация среды конкретного пользователя фатальна для конфиденциальных данных этого пользователя. Тут как с PFS: всё, что проходило через эту среду до компрометации, может считаться безопасным (в идеале), но всё, что попадёт после, гарантированно способно утечь.
— Гость (31/01/2015 17:41)   <#>
Да, но это такая своеобразная максима. Если её брать за основу, то pinentry и прочие извращения ненужны. Однако, люди с ними возятся, значит, их интересуют более тонкие градации того, что считать безопасным, а что нет. Ну, типа «от такого рода/типа компрометации оно спасает, и от такого рода зловредов, а вот от таких — уже нет». Собственно, я именно поэтому выше задал вопрос о модели угрозы, т.е. о том, что считается дозволенным, а что нет для противника, от которого защищаемся.

Есть ли какой-то кем-то проведённый внятный анализ, так сказать, «отцеживания градаций безопасности потенциально скомпрометированного юзера»? К какому тут классу относится разделение всего на gpg, gpg-agent и pinentry? А то получается, что вроде как это лучше, но если глубже копнуть, то тоже ломается. Есть ли какая-то осязаемая мера «насколько лучше»? Вроде раз хуже оно всё равно не делает, можно смириться, тут вопрос лишь в том, стоит ли получаемая дополнительная безопасность трудозатрат на настройку этого комбайна, да ещё с учётом его ограничений для usability (пассфразу надо вводить чаще и т.д.).
— Гость (31/01/2015 17:45)   <#>
SATtva, у вас есть желание в перспективе сделать deb/rpm-пакет/ебилд для gpg-remote и протолкнуть его в репы дистров, чтобы устанавливалось всё стандартно?
— SATtva (31/01/2015 17:52)   профиль/связь   <#>
комментариев: 11558   документов: 1036   редакций: 4118

Плюсую.


Это вещи из разряда secure software engineering best practices, т.е. "делайте так, и ваша жизнь наладится в коде будет меньше багов, а те, что есть, с меньшей вероятностью смогут скомпрометировать систему". Насчёт того, существуют ли какие-то количественные научно обоснованные оценки, мне неизвестно (но подозреваю, что они есть).


Если правильно настраивать — не надо. :Р
На страницу: 1, 2, 3, 4 След.
Ваша оценка документа [показать результаты]
-3-2-1 0+1+2+3