Chapter 8. Setting up the network

The default installation of Red Hat Single Sign-On can run with some networking limitations. For one, all network endpoints bind to localhost so the auth server is really only usable on one local machine. For HTTP based connections, it does not use default ports like 80 and 443. HTTPS/SSL is not configured out of the box and without it, Red Hat Single Sign-On has many security vulnerabilities. Finally, Red Hat Single Sign-On may often need to make secure SSL and HTTPS connections to external servers and thus need a trust store set up so that endpoints can be validated correctly. This chapter discusses all of these things.

8.1. Bind addresses

By default Red Hat Single Sign-On binds to the localhost loopback address 127.0.0.1. That’s not a very useful default if you want the authentication server available on your network. Generally, what we recommend is that you deploy a reverse proxy or load balancer on a public network and route traffic to individual Red Hat Single Sign-On server instances on a private network. In either case though, you still need to set up your network interfaces to bind to something other than localhost.

Setting the bind address is quite easy and can be done on the command line with either the standalone.sh or domain.sh boot scripts discussed in the Choosing an Operating Mode chapter.

$ standalone.sh -b 192.168.0.5

The -b switch sets the IP bind address for any public interfaces.

Alternatively, if you don’t want to set the bind address at the command line, you can edit the profile configuration of your deployment. Open up the profile configuration file (standalone.xml or domain.xml depending on your operating mode) and look for the interfaces XML block.

    <interfaces>
        <interface name="management">
            <inet-address value="${jboss.bind.address.management:127.0.0.1}"/>
        </interface>
        <interface name="public">
            <inet-address value="${jboss.bind.address:127.0.0.1}"/>
        </interface>
    </interfaces>

The public interface corresponds to subsystems creating sockets that are available publicly. An example of one of these subsystems is the web layer which serves up the authentication endpoints of Red Hat Single Sign-On. The management interface corresponds to sockets opened up by the management layer of the JBoss EAP. Specifically the sockets which allow you to use the jboss-cli.sh command line interface and the JBoss EAP web console.

In looking at the public interface you see that it has a special string ${jboss.bind.address:127.0.0.1}. This string denotes a value 127.0.0.1 that can be overridden on the command line by setting a Java system property, i.e.:

$ domain.sh -Djboss.bind.address=192.168.0.5

The -b is just a shorthand notation for this command. So, you can either change the bind address value directly in the profile config, or change it on the command line when you boot up.

Note

There are many more options available when setting up interface definitions. For more information, see the network interface in the JBoss EAP Configuration Guide.

8.2. Socket port bindings

The ports opened for each socket have a pre-defined default that can be overridden at the command line or within configuration. To illustrate this configuration, let’s pretend you are running in standalone mode and open up the …​/standalone/configuration/standalone.xml. Search for socket-binding-group.

    <socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
        <socket-binding name="management-http" interface="management" port="${jboss.management.http.port:9990}"/>
        <socket-binding name="management-https" interface="management" port="${jboss.management.https.port:9993}"/>
        <socket-binding name="ajp" port="${jboss.ajp.port:8009}"/>
        <socket-binding name="http" port="${jboss.http.port:8080}"/>
        <socket-binding name="https" port="${jboss.https.port:8443}"/>
        <socket-binding name="txn-recovery-environment" port="4712"/>
        <socket-binding name="txn-status-manager" port="4713"/>
        <outbound-socket-binding name="mail-smtp">
            <remote-destination host="localhost" port="25"/>
        </outbound-socket-binding>
    </socket-binding-group>

socket-bindings define socket connections that will be opened by the server. These bindings specify the interface (bind address) they use as well as what port number they will open. The ones you will be most interested in are:

http
Defines the port used for Red Hat Single Sign-On HTTP connections
https
Defines the port used for Red Hat Single Sign-On HTTPS connections
ajp
This socket binding defines the port used for the AJP protocol. This protocol is used by Apache HTTPD server in conjunction mod-cluster when you are using Apache HTTPD as a load balancer.
management-http
Defines the HTTP connection used by JBoss EAP CLI and web console.

When running in domain mode setting the socket configurations is a bit trickier as the example domain.xml file has multiple socket-binding-groups defined. If you scroll down to the server-group definitions you can see what socket-binding-group is used for each server-group.

domain socket bindings

    <server-groups>
        <server-group name="load-balancer-group" profile="load-balancer">
            ...
            <socket-binding-group ref="load-balancer-sockets"/>
        </server-group>
        <server-group name="auth-server-group" profile="auth-server-clustered">
            ...
            <socket-binding-group ref="ha-sockets"/>
        </server-group>
    </server-groups>

Note

There are many more options available when setting up socket-binding-group definitions. For more information, see the socket binding group in the JBoss EAP Configuration Guide.

8.3. HTTPS/SSL

Warning

Red Hat Single Sign-On is not set up by default to handle SSL/HTTPS. It is highly recommended that you either enable SSL on the Red Hat Single Sign-On server itself or on a reverse proxy in front of the Red Hat Single Sign-On server.

This default behavior is defined by the SSL/HTTPS mode of each Red Hat Single Sign-On realm. This is discussed in more detail in the Server Administration Guide, but let’s give some context and a brief overview of these modes.

external requests
Red Hat Single Sign-On can run out of the box without SSL so long as you stick to private IP addresses like localhost, 127.0.0.1, 10.x.x.x, 192.168.x.x, and 172.16.x.x. If you don’t have SSL/HTTPS configured on the server or you try to access Red Hat Single Sign-On over HTTP from a non-private IP adress you will get an error.
none
Red Hat Single Sign-On does not require SSL. This should really only be used in development when you are playing around with things.
all requests
Red Hat Single Sign-On requires SSL for all IP addresses.

The SSL mode for each realm can be configured in the Red Hat Single Sign-On admin console.

8.4. Enabling HTTPS/SSL for the Red Hat Single Sign-On server

If you are not using a reverse proxy or load balancer to handle HTTPS traffic for you, you’ll need to enable HTTPS for the Red Hat Single Sign-On server. This involves

  1. Obtaining or generating a keystore that contains the private key and certificate for SSL/HTTP traffic
  2. Configuring the Red Hat Single Sign-On server to use this keypair and certificate.

8.4.1. Creating the Certificate and Java Keystore

In order to allow HTTPS connections, you need to obtain a self signed or third-party signed certificate and import it into a Java keystore before you can enable HTTPS in the web container where you are deploying the Red Hat Single Sign-On Server.

8.4.1.1. Self Signed Certificate

In development, you will probably not have a third party signed certificate available to test a Red Hat Single Sign-On deployment so you’ll need to generate a self-signed one using the keytool utility that comes with the Java JDK.

$ keytool -genkey -alias localhost -keyalg RSA -keystore keycloak.jks -validity 10950
    Enter keystore password: secret
    Re-enter new password: secret
    What is your first and last name?
    [Unknown]:  localhost
    What is the name of your organizational unit?
    [Unknown]:  Keycloak
    What is the name of your organization?
    [Unknown]:  Red Hat
    What is the name of your City or Locality?
    [Unknown]:  Westford
    What is the name of your State or Province?
    [Unknown]:  MA
    What is the two-letter country code for this unit?
    [Unknown]:  US
    Is CN=localhost, OU=Keycloak, O=Test, L=Westford, ST=MA, C=US correct?
    [no]:  yes

When you see the question What is your first and last name ?, supply the DNS name of the machine where you are installing the server. For testing purposes, localhost should be used. After executing this command, the keycloak.jks file will be generated in the same directory as you executed the keytool command in.

If you want a third-party signed certificate, but don’t have one, you can obtain one for free at cacert.org. However, you first need to use the following procedure.

Procedure

  1. Generate a Certificate Request:

    $ keytool -certreq -alias yourdomain -keystore keycloak.jks > keycloak.careq

    Where yourdomain is a DNS name for which this certificate is generated. Keytool generates the request:

    -----BEGIN NEW CERTIFICATE REQUEST-----
    MIIC2jCCAcICAQAwZTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAk1BMREwDwYDVQQHEwhXZXN0Zm9y
    ZDEQMA4GA1UEChMHUmVkIEhhdDEQMA4GA1UECxMHUmVkIEhhdDESMBAGA1UEAxMJbG9jYWxob3N0
    MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr7kck2TaavlEOGbcpi9c0rncY4HhdzmY
    Ax2nZfq1eZEaIPqI5aTxwQZzzLDK9qbeAd8Ji79HzSqnRDxNYaZu7mAYhFKHgixsolE3o5Yfzbw1
    29RvyeUVe+WZxv5oo9wolVVpdSINIMEL2LaFhtX/c1dqiqYVpfnvFshZQaIg2nL8juzZcBjj4as
    H98gIS7khql/dkZKsw9NLvyxgJvp7PaXurX29fNf3ihG+oFrL22oFyV54BWWxXCKU/GPn61EGZGw
    Ft2qSIGLdctpMD1aJR2bcnlhEjZKDksjQZoQ5YMXaAGkcYkG6QkgrocDE2YXDbi7GIdf9MegVJ35
    2DQMpwIDAQABoDAwLgYJKoZIhvcNAQkOMSEwHzAdBgNVHQ4EFgQUQwlZJBA+fjiDdiVzaO9vrE/i
    n2swDQYJKoZIhvcNAQELBQADggEBAC5FRvMkhal3q86tHPBYWBuTtmcSjs4qUm6V6f63frhveWHf
    PzRrI1xH272XUIeBk0gtzWo0nNZnf0mMCtUBbHhhDcG82xolikfqibZijoQZCiGiedVjHJFtniDQ
    9bMDUOXEMQ7gHZg5q6mJfNG9MbMpQaUVEEFvfGEQQxbiFK7hRWU8S23/d80e8nExgQxdJWJ6vd0X
    MzzFK6j4Dj55bJVuM7GFmfdNC52pNOD5vYe47Aqh8oajHX9XTycVtPXl45rrWAH33ftbrS8SrZ2S
    vqIFQeuLL3BaHwpl3t7j2lMWcK1p80laAxEASib/fAwrRHpLHBXRcq6uALUOZl4Alt8=
    -----END NEW CERTIFICATE REQUEST-----
  2. Send this CA request to your Certificate Authority (CA).

    The CA will issue you a signed certificate and send it to you.

  3. Obtain and import the root certificate of the CA.

    You can download the cert from CA (in other words: root.crt) and import as follows:

    $ keytool -import -keystore keycloak.jks -file root.crt -alias root
  4. Import your new CA generated certificate to your keystore:

    $ keytool -import -alias yourdomain -keystore keycloak.jks -file your-certificate.cer

8.4.2. Configuring Red Hat Single Sign-On to use the keystore

Now that you have a Java keystore with the appropriate certificates, you need to configure your Red Hat Single Sign-On installation to use it. Use the configuration procedure that applies to your installation:

8.4.2.1. JBoss Security Legacy

Procedure

  1. Edit the standalone.xml, standalone-ha.xml, or host.xml file to use the keystore and enable HTTPS.
  2. Either move the keystore file to the configuration directory of your deployment or the file in a location you choose and provide an absolute path to it.

    If you are using absolute paths, remove the optional relative-to parameter from your configuration (See operating mode).

  3. Create a batch file named sso_legacy.cli in the bin directory of JBoss EAP.
  4. Add the following content to the batch file:

    # Start batching commands
    
    batch
    
    /core-service=management/security-realm=UndertowRealm:add()
    /core-service=management/security-realm=UndertowRealm/server-identity=ssl:add(keystore-path=keycloak.jks, keystore-relative-to=jboss.server.config.dir, keystore-password=secret)
    /subsystem=undertow/server=default-server/https-listener=https:write-attribute(name=security-realm, value=UndertowRealm)
    
    # Run the batch commands
    
    run-batch
  5. Start the Red Hat Single Sign-On server.
  6. Change to the bin directory of JBoss EAP.
  7. Run the following script.

    $ sh jboss-cli.sh --connect --file=sso_legacy.cli
    
    The batch executed successfully
    process-state: reload-required
  8. Restart the Red Hat Single Sign-On server so that the sso_legacy.cli changes take effect.

8.4.2.2. Elytron TLS v1.2

Procedure

  1. Create a batch file named sso.cli in the bin directory of JBoss EAP.
  2. Add the following content to the batch file:

    # Start batching commands
    
    batch
    
    # Add the keystore, key manager and ssl context configuration in the elytron subsystem
    
    /subsystem=elytron/key-store=httpsKS:add(relative-to=jboss.server.config.dir,path=keycloak.jks,credential-reference={clear-text=secret},type=JKS)
    /subsystem=elytron/key-manager=httpsKM:add(key-store=httpsKS,credential-reference={clear-text=secret})
    /subsystem=elytron/server-ssl-context=httpsSSC:add(key-manager=httpsKM,protocols=["TLSv1.2"])
    
    # Change the undertow subsystem configuration to use the ssl context defined in the previous step for https
    
    /subsystem=undertow/server=default-server/https-listener=https:undefine-attribute(name=security-realm)
    /subsystem=undertow/server=default-server/https-listener=https:write-attribute(name=ssl-context, value=httpsSSC)
    
    # Run the batch commands
    
    run-batch
  3. Start the Red Hat Single Sign-On server.
  4. Change to the bin directory of JBoss EAP.
  5. Run the following script.

    $ sh jboss-cli.sh --connect --file=sso.cli
    
    The batch executed successfully
    process-state: reload-required
  6. Restart the Red Hat Single Sign-On server so that the sso.cli changes take effect.

For more information on configuring TLS, refer to the WildFly documentation.

8.4.2.3. Elytron TLS 1.3

Procedure

  1. Create a batch file named sso.cli in the bin directory of JBoss EAP.
  2. Add the following content to the batch file:

    batch
    
    # Add the keystore, key manager and ssl context configuration in the elytron subsystem
    /subsystem=elytron/key-store=httpsKS:add(relative-to=jboss.server.config.dir,path=keycloak.jks,credential-reference={clear-text=secret},type=JKS)
    /subsystem=elytron/key-manager=httpsKM:add(key-store=httpsKS,credential-reference={clear-text=secret})
    
    
    /subsystem=elytron/server-ssl-context=httpsSSC:add(key-manager=httpsKM,protocols=["TLSv1.3"])
    /subsystem=elytron/server-ssl-context=httpsSSC:write-attribute(name=cipher-suite-names,value=TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256)
    
    # Change the undertow subsystem configuration to use the ssl context defined in the previous step for https
    
    /subsystem=undertow/server=default-server/https-listener=https:undefine-attribute(name=security-realm)
    /subsystem=undertow/server=default-server/https-listener=https:write-attribute(name=ssl-context, value=httpsSSC)
    
    # Run the batch commands
    
    run-batch
  3. Start the Red Hat Single Sign-On server.
  4. Change to the bin directory of JBoss EAP.
  5. Run the following script.

    $ sh jboss-cli.sh --connect --file=sso.cli
    
    The batch executed successfully
    process-state: reload-required
  6. Restart the Red Hat Single Sign-On server so that the sso.cli changes take effect.

For more information on configuring TLS, refer to the WildFly documentation.

8.5. Outgoing HTTP requests

The Red Hat Single Sign-On server often needs to make non-browser HTTP requests to the applications and services it secures. The auth server manages these outgoing connections by maintaining an HTTP client connection pool. There are some things you’ll need to configure in standalone.xml, standalone-ha.xml, or domain.xml. The location of this file depends on your operating mode.

HTTP client Config example

<spi name="connectionsHttpClient">
    <provider name="default" enabled="true">
        <properties>
            <property name="connection-pool-size" value="256"/>
        </properties>
    </provider>
</spi>

Possible configuration options are:

establish-connection-timeout-millis
Timeout for establishing a socket connection.
socket-timeout-millis
If an outgoing request does not receive data for this amount of time, timeout the connection.
connection-pool-size
How many connections can be in the pool (128 by default).
max-pooled-per-route
How many connections can be pooled per host (64 by default).
connection-ttl-millis
Maximum connection time to live in milliseconds. Not set by default.
max-connection-idle-time-millis
Maximum time the connection might stay idle in the connection pool (900 seconds by default). Will start background cleaner thread of Apache HTTP client. Set to -1 to disable this checking and the background thread.
disable-cookies
true by default. When set to true, this will disable any cookie caching.
client-keystore
This is the file path to a Java keystore file. This keystore contains client certificate for two-way SSL.
client-keystore-password
Password for the client keystore. This is REQUIRED if client-keystore is set.
client-key-password
Password for the client’s key. This is REQUIRED if client-keystore is set.
proxy-mappings
Denotes proxy configurations for outgoing HTTP requests. See the section on Proxy Mappings for Outgoing HTTP Requests for more details.
disable-trust-manager
If an outgoing request requires HTTPS and this config option is set to true you do not have to specify a truststore. This setting should only be used during development and never in production as it will disable verification of SSL certificates. This is OPTIONAL. The default value is false.

8.5.1. Proxy mappings for outgoing HTTP requests

Outgoing HTTP requests sent by Red Hat Single Sign-On can optionally use a proxy server based on a comma delimited list of proxy-mappings. A proxy-mapping denotes the combination of a regex based hostname pattern and a proxy-uri in the form of hostnamePattern;proxyUri, e.g.:

.*\.(google|googleapis)\.com;http://www-proxy.acme.com:8080

To determine the proxy for an outgoing HTTP request the target hostname is matched against the configured hostname patterns. The first matching pattern determines the proxy-uri to use. If none of the configured patterns match for the given hostname then no proxy is used.

If the proxy server requires authentication, include the proxy user’s credentials in this format username:password@. For example:

.*\.(google|googleapis)\.com;http://user01:pas2w0rd@www-proxy.acme.com:8080

The special value NO_PROXY for the proxy-uri can be used to indicate that no proxy should be used for hosts matching the associated hostname pattern. It is possible to specify a catch-all pattern at the end of the proxy-mappings to define a default proxy for all outgoing requests.

The following example demonstrates the proxy-mapping configuration.

# All requests to Google APIs should use http://www-proxy.acme.com:8080 as proxy
.*\.(google|googleapis)\.com;http://www-proxy.acme.com:8080

# All requests to internal systems should use no proxy
.*\.acme\.com;NO_PROXY

# All other requests should use http://fallback:8080 as proxy
.*;http://fallback:8080

This can be configured via the following jboss-cli command. Note that you need to properly escape the regex-pattern as shown below.

echo SETUP: Configure proxy routes for HttpClient SPI

# In case there is no connectionsHttpClient definition yet
/subsystem=keycloak-server/spi=connectionsHttpClient/provider=default:add(enabled=true)

# Configure the proxy-mappings
/subsystem=keycloak-server/spi=connectionsHttpClient/provider=default:write-attribute(name=properties.proxy-mappings,value=[".*\\.(google|googleapis)\\.com;http://www-proxy.acme.com:8080",".*\\.acme\\.com;NO_PROXY",".*;http://fallback:8080"])

The jboss-cli command results in the following subsystem configuration. Note that one needs to encode " characters with &quot;.

<spi name="connectionsHttpClient">
    <provider name="default" enabled="true">
        <properties>
            <property
            name="proxy-mappings"
            value="[&quot;.*\\.(google|googleapis)\\.com;http://www-proxy.acme.com:8080&quot;,&quot;.*\\.acme\\.com;NO_PROXY&quot;,&quot;.*;http://fallback:8080&quot;]"/>
        </properties>
    </provider>
</spi>

8.5.2. Using standard environment variables

Alternatively, it is possible to use standard environment variables to configure the proxy mappings, that is HTTP_PROXY, HTTPS_PROXY and NO_PROXY variables.

The HTTP_PROXY and HTTPS_PROXY variables represent the proxy server that should be used for all outgoing HTTP requests. Red Hat Single Sign-On does not differ between the two. If both are specified, HTTPS_PROXY takes the precedence regardless of the actual scheme the proxy server uses.

The NO_PROXY variable is used to define a comma separated list of hostnames that should not use the proxy. If a hostname is specified, all its prefixes (subdomains) are also excluded from using proxy.

Take the following example:

HTTPS_PROXY=https://www-proxy.acme.com:8080
NO_PROXY=google.com,login.facebook.com

In this example, all outgoing HTTP requests will use https://www-proxy.acme.com:8080 proxy server except for requests to for example login.google.com, google.com, auth.login.facebook.com. However, for example groups.facebook.com will be routed through the proxy.

Note

The environment variables can be lowercase or uppercase. Lowercase takes precedence. For example if both HTTP_PROXY and http_proxy are defined, http_proxy will be used.

If proxy mappings are defined using the subsystem configuration (as described above), the environment variables are not considered by Red Hat Single Sign-On. This scenario applies in case no proxy server should be used despite having for example HTTP_PROXY environment variable defined. To do so, you can specify a generic no proxy route as follows:

<spi name="connectionsHttpClient">
    <provider name="default" enabled="true">
        <properties>
            <property name="proxy-mappings" value=".*;NO_PROXY"/>
        </properties>
    </provider>
</spi>

8.5.3. Outgoing HTTPS request truststore

When Red Hat Single Sign-On invokes on remote HTTPS endpoints, it has to validate the remote server’s certificate in order to ensure it is connecting to a trusted server. This is necessary in order to prevent man-in-the-middle attacks. The certificates of these remote server’s or the CA that signed these certificates must be put in a truststore. This truststore is managed by the Red Hat Single Sign-On server.

The configuration of the trustore is always done by the Red Hat Single Sign-On truststore SPI. The instructions in this section apply if the keystore was configured bye the JBoss Security Legacy or Elytron TLS.

The truststore is used when connecting securely to identity brokers, LDAP identity providers, when sending emails, and for backchannel communication with client applications.

Warning

By default, a truststore provider is not configured, and any https connections fall back to standard java truststore configuration as described in Java’s JSSE Reference Guide. If there is no trust established, then these outgoing HTTPS requests will fail.

You can use keytool to create a new truststore file or add trusted host certificates to an existing one:

$ keytool -import -alias HOSTDOMAIN -keystore truststore.jks -file host-certificate.cer

The truststore is configured within the standalone.xml, standalone-ha.xml, or domain.xml file in your distribution. The location of this file depends on your operating mode. You can add your truststore configuration by using the following template:

<spi name="truststore">
    <provider name="file" enabled="true">
        <properties>
            <property name="file" value="path to your .jks file containing public certificates"/>
            <property name="password" value="password"/>
            <property name="hostname-verification-policy" value="WILDCARD"/>
        </properties>
    </provider>
</spi>

Possible configuration options for this setting are:

file
The path to a Java keystore file. HTTPS requests need a way to verify the host of the server they are talking to. This is what the trustore does. The keystore contains one or more trusted host certificates or certificate authorities. This truststore file should only contain public certificates of your secured hosts. This is REQUIRED if any of these properties are defined.
password
Password of the keystore. This is REQUIRED if any of these properties are defined.
hostname-verification-policy
WILDCARD by default. For HTTPS requests, this verifies the hostname of the server’s certificate. ANY means that the hostname is not verified. WILDCARD Allows wildcards in subdomain names i.e. *.foo.com. STRICT CN must match hostname exactly.