Monitoring Java Application Security with JDK Tools and JFR Events
AnaMariaMihalceanu1
85 views
33 slides
Jun 04, 2024
Slide 1 of 33
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
About This Presentation
Slides for JNation 2024
Size: 3.19 MB
Language: en
Added: Jun 04, 2024
Slides: 33 pages
Slide Content
Monitoring Java Application
Security with JDK Tools and JFR
Events
Hello! I am Ana
Agenda
JFR Security Events Overview
Observing JDK Security Properties
Monitoring TLS Protocol
Analysing X.509 certificates
Continuous Monitoring in the Cloud
Goal
JFR Security Events Overview
JDK Flight Recorder(JFR) Events
When running a Java application, JFR can collect events that occur in the JVM.
JFR Events express the state of the application and underlying JVM.
For profiling, store event data in a .jfr file.
TimestampDurationThreadIDStack
Trace IDEvent Specific Payload
JFR Event Components
Event
ID
JFR Security Events
NameGoalBackported
To
Enabled By
Default*
jdk.SecurityPropertyModificationRecordscalls to Security.setProperty(String
key, String value).
Oracle JDK 11.0.5
and 8u231 No
jdk.TLSHandshakeKeeps track of TLS handshake activity.Oracle JDK 11.0.5
and 8u231 No
jdk.X509CertificateRecords details of X.509 Certificates.Oracle JDK 11.0.5
and 8u231 No
jdk.X509ValidationRecords details of X.509 certificates
negotiated in successful X.509 validation.
Oracle JDK 11.0.5
and 8u231 No
jdk.InitialSecurityPropertyFor insights on initial JDK security properties.Oracle JDK 17.0.7
and 11.0.20 Yes
jdk.SecurityProviderServiceRecords service provider method invocations.JDK 17.0.8, 11.0.22
and 8u391No
* In default.jfc and profile.jfc shipped within a JDK
Observing JDK Security
Properties
Ways to Observe Initial Security Properties
Initial security properties set statically in the$JAVA_HOME/conf/security file.
Dynamically set security properties via java.security.Security methods.
Log the initial security properties.
java -Djava.security.debug=properties
Record jdk.InitialSecurityProperty JFR event.
Enable JFR recording java -XX:StartFlightRecording:settings=default,duration=60s
Or start a flight recording by connecting to the running application from JDK Mission Control.
How to Trace Security Properties
Changes?
Broad View Over JDK Security Properties
Inspect the recording with jcmd or JDK Mission Control.
Start a JFR recording when launching the application.
java -XX:StartFlightRecording:settings=default,duration=60s
Havejdk.SecurityPropertyModification enabled in JFR configuration.
$JAVA_HOME/bin/jfr configure jdk.SecurityPropertyModification#enabled=true
Extra Tips to Observe Security Properties (1)
Configure more JFR events by adding a space between each setting.
Setup jdk.SecurityPropertyModification when launching the JVM.
Set more JFR events when launching the JVM, separated by comma.
$JAVA_HOME/bin/jfr configure event1#enabled=true event2#enabled=false
java -XX:StartFlightRecording:settings=default,+jdk.SecurityPropertyModification#enabled=true
java -XX:StartFlightRecording:settings=default,+event1#enabled=true,+event2#enabled=false
Extra Tips to Observe Security Properties (2)
Configure each JFR event from JDK Mission Control (JMC)
Inspect the evolution of captured events in JMC.
Event Browser > Java Development Kit > Security
Create a connection to a running JVM (this time -XX:StartFlightRecording is not mandatory).
In JMC menu, selectFile > Connection... > [Select one running JVM] > Start Flight Recording
Configure each JDK Security event.
Why Is TLS Important?
Message integrity: identify the unauthorized modification of data during transit.
Authenticity: ability to identify a user/system before communicating information.
certificate authorities/digital certificates
Confidentiality: protect sensitive data/information from unauthorized users.
encryption/decryption
certificate authorities/digital certificates
Capture TLS Protocol Information
Use a network protocol analyzer tool.
Attach the tool to the network interface where the JVM communicates.
Look for "Server Hello" record to determine TLS version used on a particular socket.
A Java developer friendly way: inspect debug logs.
java -Djavax.net.debug=ssl:handshake
Configure jdk.TLSHandshakeJFR event to get essential TLS information.
Capture TLS Protocol Details with JDK Tools
Runjfr configurecommand in a terminal window.
jfr configure jdk.TLSHandshake#enabled=true
jdk.TLSHandshake#stackTrace=true
Switchjdk.TLSHandshake options to true in JFR configuration file.
Start a recording whilejdk.TLSHandshakeis enabled as well.
java -XX:StartFlightRecording:settings=default,duration=60s,
+jdk.TLSHandshake#enabled=true,+jdk.TLSHandshake#stackTrace=true
Local Demo Setup Overview
Running TicTacToe locally
Monitor with JDK tools
Spring Boot application
with JDK 22
KeystoreTruststore
Client Certificate#local.ext file
authorityKeyIdentifier=keyid,issue
r
basicConstraints=CA:FALSE
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
DNS.2 = springboot
IP.1 = 127.0.0.1
Importance of X.509 Certificates
Bind an identity to a public key using a digital signature.
Enable secure communication and transaction between two parties.
Establish trust based on a series of fields:
version
serial number
signature (algorithm ID and parameters)
issuer name
validity period
subject name
subject public key (and associated algorithm ID)
View Certificate Details
# use keytool to query certificates in JDK truststore
$JAVA_HOME/bin/keytool -cacerts -list –v
# use keytool to query certificates in a keystore
keytool -v -list -keystore /path/to/keystore
# print verbose X.509 certificate information
java -Djava.security.debug=certpath -Djavax.net.debug=all
Enable Details about X.509 Certificates in JFR
# enable jdk.X509Certificate, jdk.X509Validationevents in your JFR configuration file
<event name="jdk.X509Certificate">
<setting name="enabled">true</setting>
<setting name="stackTrace">true</setting>
</event>
<event name="jdk.X509Validation">
<setting name="enabled">true</setting>
<setting name="stackTrace">true</setting>
</event>
# or runjfr configurecommand in a terminal window
$JAVA_HOME/bin/jfr configure jdk.X509Certificate#enabled=true jdk.X509Validation#enabled=true
# or enable JFR events on application launch
java -XX:StartFlightRecording:settings=default,jdk.X509Certificate#enabled=true,
+jdk.X509Validation#enabled=true
Capture Certificate Details with jcmd and JFR
Execute a diagnostic command via jcmd.
.
jcmd llvmid JFR.start duration=60s filename=/tmp/cert.jfr
Run your application with -XX:StartFlightRecording flag and have
jdk.X509Certificate and jdk.X509Validationoptions enabled.
Show recorded details about X.509 Certificates.
$JAVA_HOME/bin/jfr print --events jdk.X509Certificate /tmp/cert.jfr
Continuous Monitoring in the
Cloud
Streaming JFR Events
JDK Flight Recorder provides rich, structured data, and API support to event
streams.
Since JDK 16, you can transfer recorded events programmatically, as they occur,
over the network using javax.management.MBeanServerConnection.
Until JDK 16, developers could monitor a Java process on a remote host and
control what is recorded via JDK Mission Control.
Monitor a Remote Host with MBeanServerConnection
String host = "com.example";
int port = 7091;
String url = "service:jmx:rmi:///jndi/rmi://" + host + ":" + port + "/jmxrmi";
JMXServiceURL u = new JMXServiceURL(url);
JMXConnector c = JMXConnectorFactory.connect(u);
MBeanServerConnection connection = c.getMBeanServerConnection();
try (RemoteRecordingStream stream = new RemoteRecordingStream(connection)) {
stream.enabled("jdk.X509Certificate").withStackTrace();
stream.onEvent("jdk.X509Certificate", System.out::println),
stream.start();
}
Stream JFR Events Actively, Within Process
CompositeMeterRegistry metricsRegistry = Metrics.globalRegistry;
try (var es = EventStream.openRepository()) {
es.onEvent("jdk.X509Validation", recordedEvent -> { Gauge.builder("jdk.X509Validation", recordedEvent,
e -> e.getLong("validationCounter")) .description("X509 Certificate Validation Gauge")
.register(metricsRegistry); });
es.start();} catch (IOException e) { throw new RuntimeException("Couldn't process event", e);
}
Evolving the Demo Setup
Oracle CloudRun podman compose with TicTacToe in Oracle Cloud Instance
Monitor with JDK tools
Spring Boot application
with JDK 22Keystore
Player
Monitoring tool
(Prometheus)Configuration
Volume
Volume
Java Management Service
Let’s play and observe!
Stay Tuned For More!
Inside.javaDev.javayoutube.com/java
Useful links
•Monitoring Java Application Security with JDK tools and JFR Events: https://dev.java/learn/security/monitor/
•Stack Walker ep 2 on JFR https://inside.java/2023/05/14/stackwalker-02/
•Introduction to JDK Mission Control: https://youtu.be/7-RKyp05m8M
•JMC9 – What’s new?: https://youtu.be/KzWwGSRxIi4
•Continuous monitoring with JDK Flight Recorder: https://www.infoq.com/presentations/monitoring-jdk-jfr/
•Code used during demo: https://github.com/ammbra/tictactoe
•OCI Instance installation: https://www.anamihalceanu.com/post/building-a-cloud-compute-instance-with-java-concepts
•Compose files in OCI: https://docs.oracle.com/en/learn/podman-compose/index.html#confirm-podman-compose-is-working
•More articles on Java Management Service: https://inside.java/tag/cloud
•Gunnar Morling’s article on custom JFR events: https://www.morling.dev/blog/rest-api-monitoring-with-custom-jdk-flight-
recorder-events/