[JAVA] Maskieren Sie vertrauliche Informationen in Protokollnachrichten mit Logback

Überblick

Die Bedingung ist, dass das Maskenziel mit einem regulären Ausdruck extrahiert werden kann, die Zeichenfolge jedoch in den Logback-Einstellungen durch ** % replace ** ersetzt werden kann.

Verwenden Sie die Funktion von regulärer Java-Ausdruck und die Referenz des erfassten Teilstrings. Dann können Sie unter schwierigeren Bedingungen als im obigen Beispiel maskieren. Hier ist ein Beispiel und der tatsächliche Code.

Beispiel

Im folgenden Protokoll werden Benutzer-ID, Token und Ressourcen-ID in * demselben Format * ausgegeben (32 Stellen hexadezimal). Von diesen möchte ich nur ** Token ** maskieren.

Protokollbeispiel


2020-11-14T09:30:52.774+09:00 [main] INFO com.example.Main - UserID: 35f44b06a3cf8dab8355eb8ba5844c73, Token: b9656056c799ab9ba19cebe12b49992b, ResourceID: 945c4f63c61f1bc7ba632fe0ce25aa0d

Logback-Einstellungen


<configuration debug="true">
	<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
		<encoder>
			<pattern>%date{yyyy-MM-dd'T'HH:mm:ss.SSSXXX} [%thread] %level %logger - %message%n</pattern>
		</encoder>
	</appender>

	<root level="INFO">
		<appender-ref ref="STDOUT" />
	</root>
</configuration>

Methode

Wenn Sie den Token-Teil mit einem regulären Ausdruck extrahieren möchten, können Sie in diesem Beispiel "was kurz vor" Token "geschrieben ist" verwenden. (Wenn Sie versuchen, in jeder Situation ein striktes Urteil zu fällen, können Sie nicht einfach reguläre Ausdrücke verwenden.)

Schreiben Sie "% message" wie folgt um.

%replace(%message){'((?i:token).{0,10}?)\b\p{XDigit}{32}\b','$1****'}

Dann wird das Protokoll wie folgt sein. Nur der Token-Teil ist "****", und die anderen haben sich nicht geändert.

2020-11-14T09:43:31.724+09:00 [main] INFO com.example.Main - UserID: 5457645aaa75b97eb9e2c7b0aec79ca6, Token: ****, ResourceID: c194b0155ac7ece290092c1ee2a73948

% replace verwendet Klammern und zwei Argumente [String # replaceAll ()](https://docs.oracle.com/javase/jp/8/docs/api/java/lang/ Sie können sich das genauso vorstellen wie den Empfänger und 2 Argumente von String.html # replaceAll-java.lang.String-java.lang.String-).

Wenn Sie mit regulären Ausdrücken Ihr Bestes geben, können Sie sagen: "Lassen Sie 4 Ziffern vor und nach dem Token."

(Ergänzung) Details zu regulären Ausdrücken

Bei der Konvertierung in das JSON-Format mit Logstash

(Es scheint, dass es in Logstash eine Maskenverarbeitungseinstellung gibt, die jedoch noch nicht untersucht wurde.)

Einstellungen (teilweise)


{
	"timestamp": "%date{yyyy-MM-dd'T'HH:mm:ss.SSSXXX}",
	"thread": "%thread",
	"level": "%level",
	"logger": "%logger",
	"message": "%replace(%message){'((?i:token).{0,10}?)\\b\\p{XDigit}{32}\\b','$1****'}"
}

Log


{"timestamp":"2020-11-14T11:31:38.259+09:00","thread":"main","level":"INFO","logger":"com.example.Main","message":"UserID: c610e22e634ed2ff9f1bb27afc81e638, Token: ****, ResourceID: de343ea6405a8c559043c3e3e84f9bcd"}

(Anhang) Experimenteller Code

Der für dieses Experiment verwendete Code lautet wie folgt.

pom.xml


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>org.example</groupId>
	<artifactId>logback-sample</artifactId>
	<version>1.0-SNAPSHOT</version>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>8</source>
					<target>8</target>
				</configuration>
			</plugin>
		</plugins>
	</build>

	<dependencies>
		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-classic</artifactId>
			<version>1.2.3</version>
		</dependency>
		<dependency>
			<groupId>net.logstash.logback</groupId>
			<artifactId>logstash-logback-encoder</artifactId>
			<version>6.4</version>
		</dependency>
	</dependencies>
</project>

src/main/resources/logback.xml


<configuration debug="true">
	<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
		<encoder>
			<pattern>%date{yyyy-MM-dd'T'HH:mm:ss.SSSXXX} [%thread] %level %logger - %replace(%message){'((?i:token).{0,10}?)\b\p{XDigit}{32}\b','$1****'}%n</pattern>
		</encoder>
	</appender>

	<appender name="STDOUT_JSON" class="ch.qos.logback.core.ConsoleAppender">
		<!-- https://github.com/logstash/logstash-logback-encoder -->
		<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
			<providers>
				<pattern>
					<pattern>
						{
						"timestamp": "%date{yyyy-MM-dd'T'HH:mm:ss.SSSXXX}",
						"thread": "%thread",
						"level": "%level",
						"logger": "%logger",
						"message": "%replace(%message){'((?i:token).{0,10}?)\\b\\p{XDigit}{32}\\b','$1****'}"
						}
					</pattern>
				</pattern>
			</providers>
		</encoder>
	</appender>

	<root level="INFO">
		<appender-ref ref="STDOUT" />
		<appender-ref ref="STDOUT_JSON" />
	</root>
</configuration>

src/main/java/com/example/Main.java


package com.example;

public class Main {
	private static final org.slf4j.Logger log =
			org.slf4j.LoggerFactory.getLogger(Main.class);

	public static void main(String[] args) {
		log.info("UserID: {}, Token: {}, ResourceID: {}", hex(), hex(), hex());
	}

	private static String hex() {
		return new java.util.Random().ints(16, 0, 256)
				.mapToObj(x -> String.format("%02x", x))
				.reduce("", (a, b) -> a + b);
	}
}

Recommended Posts

Maskieren Sie vertrauliche Informationen in Protokollnachrichten mit Logback
Punkt 75: Fügen Sie Fehlererfassungsinformationen in Detailnachrichten ein
Erstellen Sie eine CSR mit erweiterten Informationen in Java
Protokoll mit slf4j + Logback mit Maven in externe Datei ausgeben