使用 logstash logback 编码器加密 json 日志中的字段

Encrypt a field in json log when using logstash logback encoder

在我们的 scala api 中,我们使用 logstash-logback-encoder 创建 json 日志。我们要加密特定字段。屏蔽是不够的,因为如果需要来自日志的值需要解密。实现这一目标的最佳方法是什么? 一种方法可能是创建 JsonGeneratorDecorator 的实现,就像有一个用于屏蔽的实现一样。但是鉴于我们知道要屏蔽哪个字段,是否有更简单的方法来实现这一点?


更新:解决方案

我在回答中使用了@Phil Clay 提供的建议。但是,有一个小问题。 ValueMasker 背后的意图是根据值决定 what/when 掩码。例如,使用 RegEx 匹配所有值 (net.logstash.logback.mask.RegexValueMasker)。由于它们非常通用的用例,ValueMaskers 较少 efficient/performant。但是,我的用例更具体,因为有一个特定的字段需要屏蔽。根据定义,应该使用 FieldMasker 但它不提供值的句柄以允许加密。最后,我创建了一个自定义 ValueMasker 但使用了 net.logstash.logback.mask.FieldNameBasedFieldMasker 中的逻辑,如下所示:

class FieldNameBasedEncryptionMasker extends ValueMasker {

  private var salt: String = ""
  private var fieldNames: Set[String] = Set.empty

  def addFieldName(fieldName: String): Unit =
    fieldNames = fieldNames + fieldName

  def setSalt(saltValue: String): Unit =
    salt = saltValue

  override def mask(context: JsonStreamContext, value: Any): AnyRef = {
    if (context.hasCurrentName && fieldNames.contains(context.getCurrentName) && value
          .isInstanceOf[CharSequence]) {
        // encrypt value  
    } else null
  }
}

这可以在`logback.xml中配置为:

<appender name="stash" class="net.logstash.logback.appender.LogstashSocketAppender">
    <host>$host</host>
    <port>$port</port>
    <encoder class="net.logstash.logback.encoder.LogstashEncoder">
        <customFields>{"app_name":"${LOG_APP_NAME:-undefined}", "app_env":"${LOG_ENV:-local}"}</customFields>
        <jsonGeneratorDecorator class="net.logstash.logback.mask.MaskingJsonGeneratorDecorator">
            <valueMasker class="FieldNameBasedEncryptionMasker">
                <salt>$logging-encryption-salt</salt>
                <fieldName>fieldNameToEncrypt1</fieldName>
                <fieldName>fieldNameToEncrypt2</fieldName>
            </valueMasker>
        </jsonGeneratorDecorator>
    </encoder>
</appender>

您可以创建 net.logstash.logback.mask.ValueMasker 的自定义实现来加密特定字段,而不是返回标准屏蔽值,例如 ****.

然后像这样配置编码器以使用您的自定义屏蔽器:

<encoder class="net.logstash.logback.encoder.LogstashEncoder">
    <jsonGeneratorDecorator class="net.logstash.logback.mask.MaskingJsonGeneratorDecorator">
        <valueMasker class="your.custom.EncryptingMasker"/>
    </jsonGeneratorDecorator>
</encoder>