Secret management что это
Модуль PowerShell Secret Management: безопасное хранение и использование паролей
Microsoft недавно выпустила крайне интересный PowerShell модуль SecretManagement. Данный модуль можно использовать для безопасного хранения и использования сохраненных паролей в ваших PowerShell скриптах. Данный модуль условно состоит из двух составляющих: SecretStore vault – собственно дефолтное хранилище паролей, и движок SecretManagement, который позволяет работать с хранилищами паролей. Поддерживается как встроенное хранилище (SecretStore vault), так и внешние инструменты для хранения паролей, например: KeePass, LastPass, HashiCorp Vault, Azure Key Vault, Bitwarden, Windows Credential Manager и т.д. С помощью SecretsManagement вы можете сохранить любые пароли и извлечь их в любой момент. Можно хранить не только пароли, но и лицензионные ключи, ключи доступа, и любую другую конфиденциальную информацию (поддерживаются типы объектов Hashtable, Byte, String, SecureString и PSCredential).
В этой статье мы покажем, как использовать модуль Secret Management в ваших скриптах PowerShell для хранения и извлечения учетных данных, а также пример интеграции с KeePass.
Установка модуля Secret Management
Модуль SecretsManagement требует наличие установленного Windows PowerShell версии 5.1 или PowerShell Core.
Для установки модуля Secrets Management с помощью менеджера пакетов NuGet, выполните команду:
Чтобы установить хранилище паролей SecretStore, предлагаемой Microsoft по умолчанию, выполните команду:
Чтобы вывести список доступных командлетов в модулях, используйте команды:
Создаем хранилище паролей (SecretStore Vault)
Сначала нужно создать локальное хранилище паролей. Я назову его MyDomainPassdb и назначу в качестве хранилища паролей по умолчанию.
Вы можете создавать и использовать как локальные, так и удаленные хранилища паролей.
Следующая команда выведет список зарегистрированных хранилищ паролей для текущего пользователя:
Задайте мастер пароль для доступа к хранилищу паролей:
По умолчанию доступ к хранилищам паролей определяется следующими настройками:
К сожалению, модуль Secret Management нельзя использовать для сервисных MSA/gMSA аккаунтов, т.к. для них не создаются профили.
Управление сохранёнными паролями с помощью модуля Secret Management
Чтобы добавить строку типа SecureString в хранилище паролей используется командлет Set-Secret. Нужно указать имя хранилища и название записи:
Укажите пароль, который нужно сохранить в базу.
Вывести список записей в хранилище паролей можно так:
В большинстве случаев для работы в сетях Windows вам нужно сохранять в хранилище паролей не просто пароль, а пару – учетная запись и пароль. В этом случае нужно сохранить эту пару в виде объекта PSCredential. Также может быть удобно добавить метаданные с описанием сохраненной записи.
Если вы не хотите вводить имя учетной записи в окне Get-Credential, можно указать ее так:
Вести список сохранённых паролей и их описание можно так:
Get-SecretInfo | Ft Name, Metadata
Как использовать сохраненные пароли в скриптах PowerShell?
Теперь вы можете использовать сохраненные пароли в своих скриптах и командах PowerShell. Например, у одного из заказчиков из соображений безопасности и защиты административных учетных записей для каждого администратора нарезали с десяток учетных записей (под разные сервисы/задачи). Использовать одинаковые пароли запрещено, выполняется регулярный аудит паролей. Вводить пароли каждый раз для них довольно утомительно.
С помощью модуля SecretManagement можно безопасно сохранить пароли в локальный файл и вызывать их при необходимости.
Например, для подключения к удалённому компьютеру и запуска команды через PowerShell Remoting, можно использовать такой код:
Аналогичным образом можно упростить доступ к Exchange/Office365:
Или просто получить значение имени и пароля в переменную:
Получаем доступ к паролям в KeePass из PowerShell
Вы можете использовать модуль SecretManagement для доступа к другим популярным хранилкам паролей. Рассмотрим, как получить доступ к сохраненным паролям в файле KeePass (*.kdbx).
Сначала нужно установить модуль SecretManagement для взаимодействия с KeePass:
Затем зарегистрируйте хранилище KeePass в своем профиле пользователя:
Чтобы проверить доступ к файлу KeePass, выполните команду:
Укажите мастер пароль для доступа к файлу KeePass. Если вы указали правильный пароль, команда должна вернуть True.
Теперь можно вывести список сохраненных паролей в базе KeePass.
Чтобы сохранить новые пароль в KeePass:
Аналогичным образом вы можете подключить любое другое популярное решение для хранения паролей и использовать его в PowerShell.
Возможности AWS Secrets Manager
Безопасное хранение конфиденциальных данных
AWS Secrets Manager выполняет шифрование конфиденциальных данных при хранении с помощью принадлежащих пользователю ключей шифрования, которые хранятся в AWS Key Management Service (KMS). При извлечении конфиденциальных данных Secrets Manager дешифрует их и передает по безопасному соединению TLS в локальную среду пользователя. По умолчанию Secrets Manager не записывает конфиденциальные данные в постоянное хранилище и не кэширует их. Управлять доступом к конфиденциальным данным можно с помощью точно настроенных политик сервиса AWS Identity and Access Management (IAM) и политик на основе ресурсов. Кроме того, элементам конфиденциальной информации можно присваивать отдельные теги и управлять доступом на основе тегов. Например, конфиденциальной информации, используемой в рабочей среде, можно присвоить тег Prod, а затем прописать политику IAM для предоставления доступа к этой конфиденциальной информации только при поступлении запросов из корпоративной ИТ-сети.
Автоматическая ротация конфиденциальных данных без нарушения работы приложений
Благодаря AWS Secrets Manager можно осуществлять ротацию конфиденциальных данных по расписанию или по требованию с помощью консоли Secrets Manager, AWS SDK или интерфейса командной строки AWS. К примеру, для ротации пароля БД при сохранении его в Secrets Manager необходимо указать тип БД, периодичность ротации и данные главного пользователя для доступа к БД. Secrets Manager по умолчанию поддерживает ротацию данных пользователей для доступа к БД, размещенной на Amazon RDS и Amazon DocumentDB, и кластерам, размещенным на Amazon Redshift. Чтобы осуществлять ротацию других конфиденциальных данных, можно расширить функциональные возможности Secrets Manager, изменив предоставленные образцы функций Lambda. Например, можно выполнять ротацию обновляемых токенов OAuth, которые используются для авторизации приложений, или паролей для БД MySQL, размещенной локально. После замены жестко заданных учетных данных на соответствующий код пользователи и приложения извлекают нужные данные посредством вызова API Secrets Manager, что позволяет автоматизировать ротацию конфиденциальных данных без прерывания работы приложений.
Автоматическая репликация конфиденциальных данных в несколько регионов AWS
С помощью AWS Secrets Manager можно автоматически реплицировать конфиденциальные данные в несколько регионов AWS, чтобы обеспечить соответствие вашим уникальным требованиям к аварийному восстановлению и межрегиональной избыточности. С помощью консоли Secrets Manager, AWS SDK, AWS CLI или AWS CloudFormation вы можете указать регионы AWS, в которых нужно создать реплики конфиденциальных данных, и Secrets Manager безопасно создаст региональные реплики для чтения, устраняя необходимость в обслуживании сложного решения, предназначенного для этой цели. Теперь можно предоставить вашим межрегиональным приложениям доступ к реплицированным конфиденциальным данным в требуемых регионах, а Secrets Manager будет синхронизировать их с основным экземпляром конфиденциальных данных.
Программное извлечение конфиденциальных данных
Хранить и извлекать конфиденциальные данные можно с помощью консоли AWS Secrets Manager, AWS SDK, интерфейса командной строки AWS или AWS CloudFormation. Чтобы извлечь конфиденциальные данные, необходимо просто заменить в приложениях данные для доступа, указанные как текст, на специальный код, позволяющий извлекать эти данные программно с помощью API Secrets Manager. Secrets Manager предоставляет образцы кода для вызова API Secrets Manager, которые также доступны на странице ресурсов по AWS Secrets Manager. Можно настроить адреса Amazon Virtual Private Cloud (VPC) таким образом, чтобы трафик между VPC и Secrets Manager не выходил за пределы сети AWS. Кроме того, можно использовать библиотеки кэширования на стороне клиента Secrets Manager для оптимизации доступности и уменьшения задержки при использовании конфиденциальных данных.
Аудит и мониторинг использования конфиденциальных данных
AWS Secrets Manager позволяет осуществлять аудит и мониторинг конфиденциальных данных благодаря интеграции с сервисами AWS для ведения журналов, мониторинга и уведомлений. Например, после включения AWS CloudTrail для соответствующего региона AWS можно проверить, когда выполняется хранение или ротация конфиденциальных данных, просмотрев журналы AWS CloudTrail. Аналогичным образом можно настроить Amazon CloudWatch, чтобы с помощью Amazon Simple Notification Service получать сообщения электронной почты, если конфиденциальные данные не используются в течение определенного периода времени, или настроить Amazon CloudWatch Events, чтобы получать push-уведомления при ротации конфиденциальных данных сервисом Secrets Manager.
Соответствие требованиям
С помощью AWS Secrets Manager можно управлять секретами для рабочих нагрузок, на которые распространяется действие Руководства по соблюдению требований к безопасности Министерства обороны США для облачных вычислений (DoD CC SRG IL2, DoD CC SRG IL4 и DoD CC SRG IL5), Федеральной программы управления рисками и авторизацией (FedRAMP), Акта о передаче и защите данных учреждений здравоохранения США (HIPAA), Программы зарегистрированных экспертов по оценке систем информационной безопасности (IRAP), Отчета об аудиторской проверке стороннего поставщика сервисов (OSPAR), стандартов ISO/IEC 27001, ISO/IEC 27017, ISO/IEC 27018 и ISO 9001, Стандарта безопасности данных индустрии платежных карт (PCI-DSS) или System and Organization Control (SOC). Просмотрите подробные сведения о программе соответствия AWS и отчет в AWS Artifact.
Ознакомьтесь с примерами расчета стоимости и рассчитайте свои расходы.
Получите мгновенный доступ к уровню бесплатного пользования AWS.
Начните разработку с использованием сервиса AWS Secrets Manager в Консоли AWS.
Безопасное использование секретов: шаблон для использования HashiCorp Vault
HashiCorp Vault — это инструмент с открытым исходным кодом, который обеспечивает безопасный и надежный способ хранения и распространения секретов, таких как ключи API, токены доступа и пароли. Программное обеспечение, такое как Vault, может быть критически важным при развертывании приложений, требующих использования секретов или конфиденциальных данных.
Согласно недавнему исследованию ученых из Университета штата Северная Каролина, более 100 000 общедоступных репозиториев GitHub содержат открытые секреты приложений непосредственно в исходном коде. Это исследование — от частных токенов API до криптографических ключей — просканировало только около 13% общедоступных репозиториев GitHub — показывает, что надлежащая защита секретов приложений является одним из наиболее часто игнорируемых методов защиты информации в программном обеспечении.
Хотя масштабы воздействия удивительны, важно отметить, что эта проблема затрагивает не только проекты с открытым исходным кодом. Даже частные репозитории исходного кода могут раскрывать секреты, если они не защищены должным образом. Возьмем, к примеру, нарушение безопасности в Buffer Inc. в 2013 году. То, что начиналось как незаконный доступ к собственному исходному коду Buffer, привело к утечке учетных данных Twitter API компании, что в конечном итоге привело к рассылке спама в учетных записях Twitter бесчисленных клиентов.
Я не собираюсь угнетать Buffer прямо сейчас. Компании взламывают каждый день, и Buffer дал первоклассный ответ. Их нефильтрованная прозрачность и информирование об инцидентах послужили интересным примером важности управления секретами как основного принципа информационной безопасности. Но это также поднимает вопрос о том, как лучше всего управлять секретами в растущей, масштабируемой организации.
Введение в HashiCorp Vault
Я большой поклонник HashiCorp. Их подход к инструментам DevOps, не зависящий от поставщика, предоставляет отличные портативные решения, которые абстрагируются от отдельных поставщиков облачных услуг и фокусируются на решении реальных проблем. Их инструмент управления секретами, Vault, не исключение.
В то время как каждый отдельный поставщик облачных услуг имеет собственное решение для управления секретами, Vault является независимым от поставщика решением, которое позволяет централизованно управлять и обеспечивать доступ к секретам приложений без учета базового механизма секретов или методов аутентификации.
Установка Vault
Прежде чем мы сможем начать работу с Vault, нам сначала нужно его установить. Как и все продукты HashiCorp, Vault кроссплатформенный, с поддержкой macOS, Windows, Linux, Solaris и даже BSD. Вы даже можете запустить его на Raspberry Pi.
Запуск сервера
После установки Vault нам нужно запустить наш сервер. В этой статье я буду работать только с сервером разработки Vault. Однако важно отметить, что сервер разработки невероятно небезопасен и хранит все данные в памяти, а это означает, что при его перезапуске все будет потеряно. По словам самих HashiCorp:
Сервер разработки следует использовать для экспериментов с функциями Vault, такими как: различные методы аутентификации, механизмы секретов, устройства аудита и т. д.
Как видите, на экран выводится много данных, с которыми вы можете поиграть. Прежде всего следует отметить, что сервер разработки по умолчанию не запускается как демон (и в целях тестирования, никогда не должен запускаться как демон). Следовательно, если вы хотите взаимодействовать с сервером, вы должны сначала открыть второе окно терминала и экспортировать предоставленную переменную среды VAULT_ADDR, чтобы команда Vault хранилища знала, с каким сервером она должна взаимодействовать.
Также важно отметить значения Unseal Key и Root Token. Хотя мы коснемся того, что делать с Root Token в следующем разделе, понимание запечатывания / распечатывания Vault имеет решающее значение для правильного развертывания Vault в производственной среде.
Расшифровка и аутентификация
В производственной среде сервер Vault запускается в закрытом состоянии. Это означает, что Vault знает, где находятся данные, но не знает, как их расшифровать. На сервере разработки Vault по умолчанию не запечатан (unsealed). Однако, если вы решите запечатать его, вы получите ключ распечатки (Unseal Key), чтобы распечатать (unseal) его. Незапечатанный Vault остается в этом состоянии до тех пор, пока оно не будет повторно запечатано или сам сервер не будет перезапущен.
При первом запуске производственного сервера Vault важно его инициализировать. Этот процесс сгенерирует ключи шифрования и начальный корневой токен, и его можно будет запустить только с новыми хранилищами без каких-либо данных:
Вход в систему
Хранение секретов
В то время как Vault HashiCorp можно использовать для безопасного хранения практически любых данных, наиболее распространенным вариантом использования Vault является хранилище ключей и значений для секретов приложений. После проверки подлинности хранение секретов становится невероятно простым благодаря команде vault kv put :
Например, давайте посмотрим, что произойдет, если мы введем новое значение для того же секрета:
Видите, как был увеличен ключ метаданных версии? Это означает, что наше исходное значение должно поддерживаться в дополнение к новым значениям, что обеспечивает отличный журнал аудита того, какие секреты были изменены и когда.
Извлечение секретов
Хранение секретов — это только половина дела. Другая половина — извлекать эти секреты. В нашем примере выше давайте сначала посмотрим, как получить весь список секретов:
Как видите, хотя технически мы помещаем два секрета, отслеживается только один ключ, потому что эти два секрета на самом деле являются всего лишь двумя версиями одного секрета. Чтобы получить его, выполните команду vault kv get с секретным пространством имен и ключом:
Ценность секретов с управлением версиями невероятна, поскольку они позволяют внутренним службам привязаться к различным секретным версиям, что дает возможность постепенно развиваться, выпускать (release) и откатывать изменения приложений, не опасаясь потери важных данных.
Удаление секретов
Это помечает данные как удаленные ( deleted ) и предотвращает их извлечение в обычных запросах GET, но фактически не удаляет данные:
Чтобы данные действительно были удалены без возможности восстановления, необходимо использовать команду destroy:
Вместо того, чтобы просто пометить данные как удаленные и ограничить доступ к ним, команда destroy удалит их полностью, что сделает невозможным последующее извлечение:
Копаем глубже в HashiCorp Vault
Vault — сложный инструмент, и управление такими секретами — это лишь малая часть того, что можно с его помощью сделать. Хотя тонкости Vault выходят далеко за рамки этой статьи, давайте коснемся лишь нескольких других концепций, которые делают Vault таким мощным.
Secrets engines
Хранилище ключей и значений по умолчанию в Vault является примером механизма секретов (в частности, механизма под названием kv ). По своей сути алгоритм секретов — это абстрактный механизм хранения секретных данных. Это означает, что вместо механизма хранения на основе ключа-значения можно использовать более целевые механизмы хранения. Например, механизм секретов базы данных может использоваться для динамического генерирования учетных данных базы данных ( database ) на основе настроенных ролей для MySQL и MariaDB, что позволяет производить автоматическую ротацию учетных данных root или даже временные учетные данные для доступа по запросу.
Методы аутентификации
В дополнение к стандартному методу аутентификации на основе токенов Vault поддерживает ряд дополнительных методов аутентификации для лучшей поддержки ваших вариантов использования. Отличным примером этого является метод проверки подлинности GitHub, который можно использовать для автоматического предоставления доступа к Vault разработчикам, принадлежащим к определенной организации GitHub — и даже к определенной группе внутри организации GitHub — с использованием только токена личного доступа. Для более крупных организаций решения единого входа на уровне предприятия, такие как LDAP или Okta, могут использоваться для аутентификации пользователей в Vault.
Авторизация
Авторизация всегда идет рука об руку с аутентификацией. Хотя предоставить глобальный доступ с помощью GitHub или аутентификации на основе токенов несложно, это почти никогда не бывает полным решением. Благодаря политике Vault может быть реализован метод авторизации в стиле RBAC, предоставляющий разным пользователям и группам CRUD-подобный доступ к различным аспектам самого хранилища. В сочетании с одним из более продвинутых методов аутентификации это может стать невероятно мощным инструментом для детального контроля доступа в большой организации.
За пределами Vault
Каким бы мощным ни было Vault, настроить его правильно довольно сложно. Хотя размер и объем различных методов проверки подлинности и механизмов секретов ясно показывают, сколько вы можете сделать с Vault, может быть сложным осмыслить основы управления секретами в контексте информационной безопасности исходного кода. Благодаря впечатляюще большому количеству как официальных, так и общественных библиотек API, получение секретов безопасным способом невероятно просто, и если вы стремитесь стать опытным пользователем Vault, собственная учебная программа Vault HashiCorp – отличный способ для начала изучения.
Помимо безопасности приложений и инфраструктуры, вам нужен план быстрого реагирования на инциденты. Ознакомьтесь с нашим бесплатным руководством «От реактивного к упреждающему: 6 способов трансформации вашего мониторинга и реагирования на инциденты» для создания прозрачных рабочих процессов управления инцидентами с высокой степенью совместной работы.
Автоматизируем поиск секретов в git и ansible
Знаете ли вы что хранится в вашем git репозитории? Нет ли среди сотен коммитов паролей от продуктовых серверов, попавших туда по ошибке?
А что если ansible скрипт при публикации упадет и засветит пароли в логе?
Рассказываю о том как мы попробовали автоматизировать такие проверки и что из этого получилось.
Привет, Хабр!
Меня зовут Олег, я работаю в достаточно крупном для РФ банке, в подразделении «IT для IT».
Недавно к нам обратились друзья из внедрения (OPS) с просьбой помочь им автоматизировать процесс приемки изменений в скрипты деплоя (ansible) и конфигурации приложений на промышленных средах.
Исторически у нас есть 2 git хранилища (на самом деле больше, но это не так важно), в одном команды хранят свой код, в другом хранятся скрипты деплоя, конфигурации приложений итд, в общем все что относится к OPS составляющей.
Так вот, исходя из принятого процесса скрипты и конфигурации для промышленных сред хранятся в master ветке и при вливании в нее нужен апрув от OPS.
Пароли в git? Серьезно?
Да, к сожалению серьезно. Конечно же для таких вещей нужно использовать системы secret management, такие как HashiCorp Vault, CyberArk Conjur итд.
Но процесс покупки и внедрения тут сложный и долгий, а работать нужно сейчас.
Число команд, проектов и деплоев растет постоянно и ребята уже просто не могли анализировать то количество pull request которое к ним приходило.
Значит, будем автоматизировать!
Что анализируем?
Совместно с коллегами выявили 3 основных вектора утечки пароля, которые их интересовали и встречались наиболее часто:
Пароль в открытом виде
Передача параметров в shell или command таски ansible
Чтобы этого избежать можно использовать environment, например:
Тогда в вывод наши credentials не попадут. Еще можно указывать атрибут no_log.
Неосторожное использование withCredentials
У нас используется Jenkins, в котором для работы с credentials используется конструкция withCredentials. С помощью нее внутри pipeline можно получить credential, сохранить его в переменные и использовать, например для подключения к какой нибудь сторонней системе. Jenkins при этом будет маскировать в логе значение этих переменных.
Однако, если мы сделаем, например так:
То несмотря на то, что мы не увидим в логе путь к файлу, мы увидим его содержимое. Так же, можно сохранить переменную secretFile в другую и спокойно вывести ее в лог вне конструкции withCredentials.
Перед тем как рассказывать дальше отмечу что все эти проверки направлены на поиск неосторожного, необдуманного использования инструментов. Я конечно же отдаю себе отчет что от злонамеренных действий это не спасет (для этого у банка есть другие структуры).
Ищем пароли
Казалось что поиск паролей в открытом виде это какая то плевая задача. У нас в арсенале есть не только SonarQube но и Checkmarx. Уж они точно должны уметь решать эти задачи.
Но при внимательном рассмотрении оказывается что правило достаточно простое, оно проверяет попадает ли название переменной под определенный паттерн. Исходник, если интересно тут.
Изучив что есть на рынке пришли к выводу что будем смотреть в сторону opensource утилит. Запрос в google «find secrets in git» выдает нам примерно такие варианты:
Попробовав их все мы остановились на Gitleaks, вот почему:
Проводит анализ на основе regexp, которые можно расширять;
Умеет учитывать энтропию при анализе;
Легко задавать исключения;
В пилоте показал лучший результат.
Кроме того в правиле можно указывать требуемую энтропию, например:
В переводе на человеческий это означает: «Если мы встречаем строку кода, которая соответствует регулярному выражению, и эта строка попадает в пределы энтропии от 4,5 до 4,7, то это пароль»
Я не буду заниматься переводом документации, все прекрасно описано тут.
Конечно мы немного затюнили правила под себя, так же мы поправили вывод, чтобы найденные gitleaks пароли не светились в логах (чтобы борясь с компрометацией мы не компрометировали пароли).
Проверяем ansible
Двигаемся дальше, итак, мы хотим находить вот такие playbook, потому что не хотим случайно засветить в логах Jenkins наши креды.
Хорошо что мы этого не сделали, а вспомнили про Ansible Lint.
Это официальный линтер для Ansible, который имеет «из коробки» кучу полезных проверок, но нас интересует не это.
Нам были нужны вот эти 2 фичи:
Возможность писать свои правила;
Автоматическое сканирование и поиск playbook. Не нужно передавать конкретные файлы на проверку, можно запустить линтер в папке и он сам найдет их.
Для нашей проверки мы используем matchtask, на вход которого поступает каждый найденный task, который мы можем анализировать.
К сожалению я не могу здесь привести код именно нашего таска, но он похож на этот пример (полностью тут):
Итак, после проверки Gitleaks запускается Ansible Lint, который в режиме автоматического сканирования прогоняет наше правило. Другие правила мы отключили, т.к. не можем навязывать командам использование линтера (хотя и рекомендует всем).
Проверяем withCredentials
Напоминаю о проблеме, например вот такой код в Jenkinsfile выведет в лог содержимое секретного файла, что скорее всего будет утечкой (хотя и замаскирует путь к нему).
А вот тут нас ждал провал.
Jenkinsfile это по сути groovy, который можно разобрать на Abstract Syntax Tree и анализировать. Мы использовали AstBuilder чтобы получить дерево, научились находить withCredentials, анализировать его параметры и находить их использование внутри withCredentials. Например, код выше мы научились анализировать и реагировать на него.
Однако в жизни все сложнее, например я могу записать secretFile в глобальную переменную и использовать где-то в другом stage, могу записать secretFile в какой то временный файл итп итд.
Когда код скрипта приблизился к 1000 строк стало понятно что его уже сейчас пора рефакторить, плюс логики получается так много что впору выделять под развитие отдельную команду, поэтому пока что эту проверку и ее развитие мы отложили.
Что в результате?
Мы провели внутренний пилот, в который попало 1000 pull request. Порядка 3% были ложные срабатывания gitleaks, в некоторых случаях были найдены реальные секреты, опасные скрипты ansible.
В целом схема показала себя работоспособной, коллеги из OPS довольны и уже включают эти проверки на остальные репозитории.
В конце так же хочу поделится интересными проектами, которые использовать в этой работе не удалось: