Enable IPv6 dualstack support by default (#21340)

Closes #15003
This commit is contained in:
Martin Bartoš 2023-07-03 15:35:33 +02:00 committed by GitHub
parent 51873d6176
commit ee205c8fbc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 80 additions and 13 deletions

View file

@ -357,4 +357,11 @@ Multiple Keycloak CRs may be created in the same namespace and will be managed i
= k8s.keycloak.org/v2alpha1 changes
The condition status field was changed from a boolean to a string for conformance with standard Kubernetes conditions. In the CRD it will temporarily be represented as accepting any content, but it will only ever be a string. Please make sure any of your usage of this field is updated to expect the values "True", "False", or "Unknown", rather than true or false.
The condition status field was changed from a boolean to a string for conformance with standard Kubernetes conditions. In the CRD it will temporarily be represented as accepting any content, but it will only ever be a string. Please make sure any of your usage of this field is updated to expect the values "True", "False", or "Unknown", rather than true or false.
= Keycloak supports IPv4/IPv6 dual stack
Keycloak supports the IPv4/IPv6 dual stack and can be accessible by default via the IPv4 and IPv6 addresses.
In the older versions of Keycloak, the default approach was to use only IPv4 addresses.
For more details, see https://www.keycloak.org/server/configuration-production#_configure_keycloak_server_with_ipv4_or_ipv6[Configure Keycloak Server with IPv4 or IPv6].

View file

@ -36,21 +36,19 @@ Keycloak runs on top of JGroups and Infinispan, which provide a reliable, high-a
To find out more about using multiple nodes, the different caches and an appropriate stack for your environment, see <@links.server id="caching"/>.
== Configure Keycloak Server with IPv6 or IPv4
== Configure Keycloak Server with IPv4 or IPv6
The system properties `java.net.preferIPv4Stack` and `java.net.preferIPv6Addresses` are used to configure the JVM for use with IPv4 or IPv6 addresses.
By default, Keycloak is configured to prefer IPv4 addresses. In order to run with IPv6 addresses,
you need to specify `java.net.preferIPv4Stack=false` (the JVM default) and `java.net.preferIPv6Addresses=true`.
The latter ensures that any hostname to IP address conversions always return IPv6 address variants.
By default, Keycloak is accessible via IPv4 and IPv6 addresses at the same time.
In order to run only with IPv4 addresses, you need to specify the property `java.net.preferIPv4Stack=true`.
The latter ensures that any hostname to IP address conversions always return IPv4 address variants.
These system properties are conveniently set by the `JAVA_OPTS` environment variable. For example, to change the IP stack preference from its default of IPv4 to IPv6, set an environment variable as follows:
These system properties are conveniently set by the `JAVA_OPTS_APPEND` environment variable.
For example, to change the IP stack preference to IPv4, set an environment variable as follows:
[source, bash]
----
export JAVA_OPTS="-Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Dfile.encoding=UTF-8 -Djava.net.preferIPv4Stack=false -Djava.net.preferIPv6Addresses=true"
export JAVA_OPTS_APPEND="-Djava.net.preferIPv4Stack=true"
----
Note that when setting the `JAVA_OPTS` you are replacing the default JVM settings. Make sure to adjust them accordingly to your need.
</@tmpl.guide>

View file

@ -78,7 +78,7 @@ if not "x%JAVA_OPTS%" == "x" (
rem If the memory is not used, it will be freed. See https://developers.redhat.com/blog/2017/04/04/openjdk-and-containers for details.
rem To optimize for large heap sizes or for throughput and better response time due to shorter GC pauses, consider ZGC and Shenandoah GC.
rem Both ZGC and Shenandoah GC seem to be more eager to claim the maximum heap size. Tests showed that ZGC might need additional tuning as it is not as aggressive as ParallelGC in reclaiming dead objects.
set "JAVA_OPTS=-Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.err.encoding=UTF-8 -Dstdout.encoding=UTF-8 -Dstderr.encoding=UTF-8 -XX:+ExitOnOutOfMemoryError -Djava.security.egd=file:/dev/urandom -XX:+UseParallelGC -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=20 -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90"
set "JAVA_OPTS=-Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.err.encoding=UTF-8 -Dstdout.encoding=UTF-8 -Dstderr.encoding=UTF-8 -XX:+ExitOnOutOfMemoryError -Djava.security.egd=file:/dev/urandom -XX:+UseParallelGC -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=20 -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90"
)
@REM See also https://github.com/wildfly/wildfly-core/blob/7e5624cf92ebe4b64a4793a8c0b2a340c0d6d363/core-feature-pack/common/src/main/resources/content/bin/common.sh#L57-L60

View file

@ -89,7 +89,7 @@ if [ "x$JAVA_OPTS" = "x" ]; then
# If the memory is not used, it will be freed. See https://developers.redhat.com/blog/2017/04/04/openjdk-and-containers for details.
# To optimize for large heap sizes or for throughput and better response time due to shorter GC pauses, consider ZGC and Shenandoah GC.
# Both ZGC and Shenandoah GC seem to be more eager to claim the maximum heap size. Tests showed that ZGC might need additional tuning as as it is not as aggressive as ParallelGC in reclaiming dead objects.
JAVA_OPTS="-Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.err.encoding=UTF-8 -Dstdout.encoding=UTF-8 -Dstderr.encoding=UTF-8 -XX:+ExitOnOutOfMemoryError -Djava.security.egd=file:/dev/urandom -XX:+UseParallelGC -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=20 -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90"
JAVA_OPTS="-Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.err.encoding=UTF-8 -Dstdout.encoding=UTF-8 -Dstderr.encoding=UTF-8 -XX:+ExitOnOutOfMemoryError -Djava.security.egd=file:/dev/urandom -XX:+UseParallelGC -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=20 -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90"
else
echo "JAVA_OPTS already set in environment; overriding default settings with values: $JAVA_OPTS"
fi

View file

@ -0,0 +1,62 @@
/*
* Copyright 2023 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.keycloak.it.cli.dist;
import io.quarkus.test.junit.main.Launch;
import org.junit.jupiter.api.Test;
import org.keycloak.it.junit5.extension.DistributionTest;
import org.keycloak.it.junit5.extension.RawDistOnly;
import java.io.IOException;
import java.net.ConnectException;
import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
@DistributionTest(keepAlive = true, defaultOptions = {"--http-enabled=true", "--hostname-strict=false"})
@RawDistOnly(reason = "Containers are immutable")
public class IpStackDistTest {
@Test
@Launch({"start"})
public void dualStackEnabled() {
assertThat(given().when().get("http://localhost:8080").getStatusCode(), is(200));
assertThat(given().when().get("http://127.0.0.1:8080").getStatusCode(), is(200));
assertThat(given().when().get("http://[::1]:8080").getStatusCode(), is(200));
}
@Test
@Launch({"start", "-Djava.net.preferIPv4Stack=true"})
public void ipv4Preferred() throws IOException {
assertThat(given().when().get("http://localhost:8080").getStatusCode(), is(200));
assertThat(given().when().get("http://127.0.0.1:8080").getStatusCode(), is(200));
assertThrows(ConnectException.class, () -> given().when().get("http://[::1]:8080"), "Connection refused must be thrown");
}
@Test
@Launch({"start", "-Djava.net.preferIPv6Addresses=true"})
public void ipv6Prefered() {
assertThat(given().when().get("http://localhost:8080").getStatusCode(), is(200));
assertThat(given().when().get("http://127.0.0.1:8080").getStatusCode(), is(200));
assertThat(given().when().get("http://[::1]:8080").getStatusCode(), is(200));
}
}

View file

@ -34,7 +34,7 @@ import static org.hamcrest.Matchers.matchesPattern;
@WithEnvVars({"PRINT_ENV", "true"})
public class JavaOptsScriptTest {
private static final String DEFAULT_OPTS = "(?:-\\S+ )*-Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true -Dfile.encoding=UTF-8(?: -\\S+)*";
private static final String DEFAULT_OPTS = "(?:-\\S+ )*-Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Dfile.encoding=UTF-8(?: -\\S+)*";
@Test
@Launch({ "start-dev" })