Управление зашифрованными секретами в приложениях Service Fabric

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

Использование зашифрованных секретов в приложении Service Fabric состоит из трех этапов:

  • настройка шифрования секретов и сертификата шифрования;
  • указание зашифрованных секретов в приложении;
  • расшифровка зашифрованных секретов из кода службы.

Настройка шифрования секретов и сертификата шифрования

Настройка сертификата шифрования и его использование для шифрования секретов отличается в Windows и Linux.

Указание зашифрованных секретов в приложении

Предыдущий шаг описывает, как зашифровать секрет с помощью сертификата и создать строку в формате base-64 для использования в приложении. Эта строка в формате base-64 может быть указана как зашифрованный параметр в файле Settings.xml службы или как зашифрованная переменная среды в ServiceManifest.xml службы.

Укажите зашифрованный параметр в файле конфигурации Settings.xml службы. При этом атрибуту IsEncrypted необходимо задать значение true.

<?xml version="1.0" encoding="utf-8" ?>
<Settings xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2011/01/fabric">
  <Section Name="MySettings">
    <Parameter Name="MySecret" IsEncrypted="true" Value="I6jCCAeYCAxgFhBXABFxzAt ... gNBRyeWFXl2VydmjZNwJIM=" />
  </Section>
</Settings>

Укажите зашифрованную переменную среды в файле ServiceManifest.xml службы. При этом атрибуту Type необходимо задать значение Encrypted.

<CodePackage Name="Code" Version="1.0.0">
  <EnvironmentVariables>
    <EnvironmentVariable Name="MyEnvVariable" Type="Encrypted" Value="I6jCCAeYCAxgFhBXABFxzAt ... gNBRyeWFXl2VydmjZNwJIM=" />
  </EnvironmentVariables>
</CodePackage>

Секреты также следует добавить в приложение Service Fabric, указав сертификат в манифесте приложения. Добавьте элемент SecretsCertificate в файл ApplicationManifest.xml и укажите отпечаток требуемого сертификата.

<ApplicationManifest … >
  ...
  <Certificates>
    <SecretsCertificate Name="MyCert" X509FindType="FindByThumbprint" X509FindValue="[YourCertThumbrint]"/>
  </Certificates>
</ApplicationManifest>

Примечание

При активации приложения, для которого указан SecretsCertificate, служба Service Fabric найдет соответствующий сертификат и предоставит удостоверению, с которым выполняется приложение, полные права доступа к закрытому ключу сертификата. Service Fabric также будет отслеживать изменения сертификата и повторно применять соответствующие разрешения. Для обнаружения изменений для сертификатов, объявленных по общему имени, Service Fabric выполняет периодическую задачу, которая находит все совпадающие сертификаты, и сравнивает их с кэшированным списком отпечатков. Обнаружение нового отпечатка означает, что сертификат по этому субъекту продлен. Задача выполняется один раз в минуту на каждом узле кластера.

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

Включение секретов приложений в экземпляры приложений

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

Использование переопределяемых параметров в Settings.xml

Файл конфигурации Settings.xml позволяет применять переопределяемые параметры, которые можно предоставить при создании приложения. Вместо предоставления параметру значения используйте атрибут MustOverride :

<?xml version="1.0" encoding="utf-8" ?>
<Settings xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2011/01/fabric">
  <Section Name="MySettings">
    <Parameter Name="MySecret" IsEncrypted="true" Value="" MustOverride="true" />
  </Section>
</Settings>

Чтобы переопределить значения в файле Settings.xml, объявите параметр override для службы в файле ApplicationManifest.xml:

<ApplicationManifest ... >
  <Parameters>
    <Parameter Name="MySecret" DefaultValue="" />
  </Parameters>
  <ServiceManifestImport>
    <ServiceManifestRef ServiceManifestName="Stateful1Pkg" ServiceManifestVersion="1.0.0" />
    <ConfigOverrides>
      <ConfigOverride Name="Config">
        <Settings>
          <Section Name="MySettings">
            <Parameter Name="MySecret" Value="[MySecret]" IsEncrypted="true" />
          </Section>
        </Settings>
      </ConfigOverride>
    </ConfigOverrides>
  </ServiceManifestImport>

Теперь при создании экземпляра приложения можно указать значение в качестве параметра приложения . Для облегчения интеграции в процессе сборки создание экземпляра приложения можно выполнить с помощью сценария PowerShell или написать на языке C#.

При использовании PowerShell параметр передается в команду New-ServiceFabricApplication в виде хэш-таблицы:

New-ServiceFabricApplication -ApplicationName fabric:/MyApp -ApplicationTypeName MyAppType -ApplicationTypeVersion 1.0.0 -ApplicationParameter @{"MySecret" = "I6jCCAeYCAxgFhBXABFxzAt ... gNBRyeWFXl2VydmjZNwJIM="}

При использовании языка C# параметры приложения указываются в ApplicationDescription как NameValueCollection:

FabricClient fabricClient = new FabricClient();

NameValueCollection applicationParameters = new NameValueCollection();
applicationParameters["MySecret"] = "I6jCCAeYCAxgFhBXABFxzAt ... gNBRyeWFXl2VydmjZNwJIM=";

ApplicationDescription applicationDescription = new ApplicationDescription(
    applicationName: new Uri("fabric:/MyApp"),
    applicationTypeName: "MyAppType",
    applicationTypeVersion: "1.0.0",
    applicationParameters: applicationParameters)
);

await fabricClient.ApplicationManager.CreateApplicationAsync(applicationDescription);

Расшифровка зашифрованных секретов из кода службы

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

// Access decrypted parameters from Settings.xml
ConfigurationPackage configPackage = FabricRuntime.GetActivationContext().GetConfigurationPackageObject("Config");
bool MySecretIsEncrypted = configPackage.Settings.Sections["MySettings"].Parameters["MySecret"].IsEncrypted;
if (MySecretIsEncrypted)
{
    SecureString MySecretDecryptedValue = configPackage.Settings.Sections["MySettings"].Parameters["MySecret"].DecryptValue();
}

// Access decrypted environment variables from ServiceManifest.xml
// Note: you do not have to call any explicit API to decrypt the environment variable.
string MyEnvVariable = Environment.GetEnvironmentVariable("MyEnvVariable");

Дальнейшие действия