diff --git a/SUMMARY.adoc b/SUMMARY.adoc index 7ab048cfe4..78ba824229 100755 --- a/SUMMARY.adoc +++ b/SUMMARY.adoc @@ -25,10 +25,16 @@ {% if book.community %} . link:topics/mongo.adoc[Mongo DB Setup] {% endif %} - . link:topics/cache.adoc[Server Cache] + . link:topics/network.adoc[Network Setup] + .. link:topics/network/bind-address.adoc[Bind Addresses] + .. link:topics/network/ports.adoc[Socket Port Bindings] + .. link:topics/network/https.adoc[HTTPS/SSL Setup] + .. link:topics/network/outgoing.adoc[Outgoing HTTP Requests] . link:topics/clustering.adoc[Clustering] + . link:topics/cache.adoc[Server Cache Configuration] {% if book.community %} -. link:topics/proxy.adoc[Keycloak Security Proxy] + . link:topics/proxy.adoc[Keycloak Security Proxy] {% endif %} + . link:topics/migration.adoc[Upgrading and Migrating] diff --git a/book.json b/book.json index a277afeeb1..17294e0256 100755 --- a/book.json +++ b/book.json @@ -22,6 +22,14 @@ "datasource": { "name": "JBoss EAP Administration and Configuration Guide", "link": "https://access.redhat.com/documentation/en-US/JBoss_Enterprise_Application_Platform/6.4/html/Administration_and_Configuration_Guide/chap-Datasource_Management.html" + }, + "network": { + "name": "JBoss EAP Administration and Configuration Guide", + "link": "https://access.redhat.com/documentation/en-US/JBoss_Enterprise_Application_Platform/6.4/html/Administration_and_Configuration_Guide/chap-Network_and_Port_Configuration.html#Configure_interfaces" + }, + "socket": { + "name": "JBoss EAP Administration and Configuration Guide", + "link": "https://access.redhat.com/documentation/en-US/JBoss_Enterprise_Application_Platform/6.4/html/Administration_and_Configuration_Guide/sect-Socket_Binding_Groups.html" } }, "caching": { diff --git a/document-attributes.adoc b/document-attributes.adoc deleted file mode 100755 index 2b5779488a..0000000000 --- a/document-attributes.adoc +++ /dev/null @@ -1,3 +0,0 @@ -:attributes: yes - -Include worked! diff --git a/topics/network.adoc b/topics/network.adoc new file mode 100755 index 0000000000..9f08ab53ac --- /dev/null +++ b/topics/network.adoc @@ -0,0 +1,20 @@ +[[_network]] + +== Network Setup + +{{book.project.name}} can run out of the box, with some 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. The SSO protocols that {{book.project.name}} uses all require +SSL/HTTPS or otherwise these protocols have some serious vulnerabilities. HTTPS/SSL is not configured out of the box. +Finally, {{book.project.name}} +may often need to make secure SSL 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. + + + + + + + + + diff --git a/topics/network/bind-address.adoc b/topics/network/bind-address.adoc new file mode 100755 index 0000000000..dc6bdfdda6 --- /dev/null +++ b/topics/network/bind-address.adoc @@ -0,0 +1,51 @@ +=== Bind Addresses + +By default {{book.project.name}} 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 {{book.project.name}} 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 actually quite easy and can be done on the command line with either the _standalone.sh_ or +_domain.sh_ boot scripts discussed in the <> chapter. + +[source] +---- +$ standalone.sh -b 192.168.0.5 +---- + +The +-b+ switch tells the boot script the IP bind address for any public interfaces. + +Alternatively, you can edit the profile configuration of your deployment if you do not want to specify this IP address +every time you boot the server. Open up the profile configuration file (_standalone.xml or _domain.xml_ depending on your +<> and look for the interfaces XML block. + +[source,xml] +---- + + + + + + + + +---- + +The +public+ interface corresponds to subsystems creating sockets that are available publically. An example of one +of these subsystems is the web layer which serves up the authentication endpoints of {{book.project.name}}. The +management+ +interface corresponds to sockets opened up by the management layer of the {{book.appserver.name}}. Specifically the sockets +which allow you to use the +jboss-cli.sh+ command line interface and the {{book.appserver.name}} 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 overriden on the command line by setting a Java system property, i.e.: + +[source] +---- +$ domain.sh -Djboss.bind.address=192.168.0.5 +---- + ++-b+ is actually just a convenience function for this. 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's a lot more nifty options when setting up +interface+ definitions. See the link:{{book.appserver.network.link}}[the network interface] + chapter of the {{book.appserver.network.name}}. diff --git a/topics/network/https.adoc b/topics/network/https.adoc new file mode 100755 index 0000000000..854f7df037 --- /dev/null +++ b/topics/network/https.adoc @@ -0,0 +1,189 @@ +=== Setting up HTTPS/SSL + +WARNING: {{book.project.name}} is not set up by default to handle SSL/HTTPS. + It is highly recommended that you either enable SSL on the {{book.project.name}} server itself or on a reverse proxy in front of the {{book.project.name}} server. + +{{book.project.name}} can run out of the box without SSL/HTTPS so long as you stick to private IP addresses like localhost, 127.0.0.1, 10.0.x.x, 192.168.x.x, and 172..16.x.x. +If you try to access {{book.project.name}} out of the box via a non-private IP address you will get an error. + +This default behavior is defined by the SSL/HTTPS mode of each {{book.project.name}} realm. This is discussed in more detail in the +link:{{book.adminguide.link}}[{{book.adminguide.name}}], but let's give some context and a brief overview of these modes. + +external:: + {{book.project.name}} can run out of the box without SSL so long as you stick to private IP addresses like localhost, 127.0.0.1, 10.0.x.x, 192.168.x.x, and 172..16.x.x. + If you try to access {{book.project.name}} from a non-private IP adress you will get an error. + +none:: + {{book.project.name}} does not require SSL. This should really only be used in development when you are playing around with things. + +all:: + {{book.project.name}} requires SSL for all IP addresses. + +==== Enable HTTPS/SSL with a Reverse Proxy + +It is believed that most deployments of {{book.project.name}} will be clustered and will use a reverse proxy or load balancer +in front of {{book.project.name}} server instances. + +To enable SSL/HTTPS in this deployment scenario, follow the documentation for your reverse proxy first, before doing any {{book.project.name}} setup. +It is important that you make sure the proxy sets the `X-Forwarded-For` and `X-Forwarded-Proto` headers on the requests made to {{book.project.name}}. +Next you need to enable `proxy-address-forwarding` on the {{book.project.name}} http connector in {{book.project.name}} configuration +Assuming that your reverse proxy doesn't use port 8443 for SSL you also need to configure what port http traffic is redirected to. + +. Open _standalone.xml_, _standalone-ha.xml_, or _domain.xml_ file (depends on your <>). + +. First add `proxy-address-forwarding` and `redirect-socket` to the `http-listener` element: + +[source] +---- + + ... + + ... + +---- + +Then add a new `socket-binding` element to the `socket-binding-group` element: + +[source] +---- + + + ... + + ... + +---- + +Also remember that when running in <> what +socket-binding-group+ +you modify depends on how you have your server groups configured. + +==== Enabling SSL/HTTPS for the {{book.project.name}} Server + +If you are not using a reverse proxy or load blancer to handle HTTPS traffic for you, you'll need to enable HTTPS +for the {{book.project.name}} server. This involves + +. Obtaining or generating a keystore that contains the private key and certificate for SSL/HTTP traffic +. Configuring the {{book.project.name}} server to use this keypair and certificate. + +===== 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 you are deploying the Keycloak Server to. + +====== Self Signed Certificate + +In development, you will probably not have a third party signed certificate available to test a {{book.project.name}} deployment so you'll need to generate a self-signed on. +Generate one is very easy to do with the `keytool` utility that comes with the Java jdk. + + +[source] +---- + +$ 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 +---- + +You should answer `What is your first and last name ?` question with the DNS name of the machine you're installing the server on. +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 http://cacert.org[cacert.org]. +You'll have to do a little set up first before doing this though. + +The first thing to do is generate a Certificate Request: + +[source] +---- + +$ keytool -certreq -alias yourdomain -keystore keycloak.jks > keycloak.careq +---- + +Where `yourdomain` is a DNS name for which this certificate is generated for. +Keytool generates the request: + +[source] +---- + +-----BEGIN NEW CERTIFICATE REQUEST----- +MIIC2jCCAcICAQAwZTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAk1BMREwDwYDVQQHEwhXZXN0Zm9y +ZDEQMA4GA1UEChMHUmVkIEhhdDEQMA4GA1UECxMHUmVkIEhhdDESMBAGA1UEAxMJbG9jYWxob3N0 +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr7kck2TaavlEOGbcpi9c0rncY4HhdzmY +Ax2nZfq1eZEaIPqI5aTxwQZzzLDK9qbeAd8Ji79HzSqnRDxNYaZu7mAYhFKHgixsolE3o5Yfzbw1 +29Rvy+eUVe+WZxv5oo9wolVVpdSINIMEL2LaFhtX/c1dqiqYVpfnvFshZQaIg2nL8juzZcBjj4as +H98gIS7khql/dkZKsw9NLvyxgJvp7PaXurX29fNf3ihG+oFrL22oFyV54BWWxXCKU/GPn61EGZGw +Ft2qSIGLdctpMD1aJR2bcnlhEjZKDksjQZoQ5YMXaAGkcYkG6QkgrocDE2YXDbi7GIdf9MegVJ35 +2DQMpwIDAQABoDAwLgYJKoZIhvcNAQkOMSEwHzAdBgNVHQ4EFgQUQwlZJBA+fjiDdiVzaO9vrE/i +n2swDQYJKoZIhvcNAQELBQADggEBAC5FRvMkhal3q86tHPBYWBuTtmcSjs4qUm6V6f63frhveWHf +PzRrI1xH272XUIeBk0gtzWo0nNZnf0mMCtUBbHhhDcG82xolikfqibZijoQZCiGiedVjHJFtniDQ +9bMDUOXEMQ7gHZg5q6mJfNG9MbMpQaUVEEFvfGEQQxbiFK7hRWU8S23/d80e8nExgQxdJWJ6vd0X +MzzFK6j4Dj55bJVuM7GFmfdNC52pNOD5vYe47Aqh8oajHX9XTycVtPXl45rrWAH33ftbrS8SrZ2S +vqIFQeuLL3BaHwpl3t7j2lMWcK1p80laAxEASib/fAwrRHpLHBXRcq6uALUOZl4Alt8= +-----END NEW CERTIFICATE REQUEST----- +---- + +Send this ca request to your CA. +The CA will issue you a signed certificate and send it to you. +Before you import your new cert, you must obtain and import the root certificate of the CA. +You can download the cert from CA (ie.: root.crt) and import as follows: + +[source] +---- + +$ keytool -import -keystore keycloak.jks -file root.crt -alias root +---- + +Last step is import your new CA generated certificate to your keystore: + +[source] +---- + +$ keytool -import -alias yourdomain -keystore keycloak.jks -file your-certificate.cer +---- + +===== Configure {{book.project.name}} to Use the Keystore + +Now that you have a Java keystore with the appropriate certificates, you need to configure your {{book.project.name}} installation to use it. +First step is to move the keystore file to the _configuration_ directory of your deployment and to edit the _standalone.xml_, _standalone-ha.xml_ or _domain.xml_ file to use +the keystore and enable HTTPS. (See <>). + +In the standalone or domain configuration file, search for the `security-realms` element and add: + +[source] +---- + + + + + + + + +---- + +Find the element `server name="default-server"` (it's a child element of `subsystem xmlns="urn:jboss:domain:undertow:`) and add: + +[source] +---- + + + + + ... + +---- diff --git a/topics/network/outgoing.adoc b/topics/network/outgoing.adoc new file mode 100755 index 0000000000..35bd16b67a --- /dev/null +++ b/topics/network/outgoing.adoc @@ -0,0 +1,115 @@ +=== Outgoing HTTP Requests + +The {{book.project.name}} server often needs to invoke non-browser HTTP requests on the applications and services it secures. +The auth server manages these outgoing connections by maintaining an HTTP client connection pool. There are a few settings +of which you should be aware of. These settings live in the file _keycloak-server.json_ _keycloak-server.json_ file that corresponds to your <> + +By default the setting is like this: + +[source,json] +---- +"connectionsHttpClient": { + "default": {} +}, +---- +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:: + _Not supported yet, but we will support in future versions. Password for the client's key. + This is _REQUIRED_ if `client-keystore` is set. + +[[_truststore]] +==== Outgoing HTTPS Request Truststore + +When {{book.project.name}} connects out to remote HTTP endpoints over secure https connection, it has to validate the other 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. + +How certificates are validated is also configured in the _keycloak-server.json_ file that corresponds to your <>. + +`standalone/configuration/keycloak-server.json`. +By default truststore provider is not configured, and any https connections fall back to standard java truststore configuration as described in https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html[ + Java's JSSE Reference Guide] - using `javax.net.ssl.trustStore system property`, otherwise `cacerts` file that comes with java is used. + +Truststore is used when connecting securely to identity brokers, LDAP identity providers, when sending emails, and for backchannel communication with client applications. +Some of these facilities may - in case when no trusted certificate is found in your configured truststore - fallback to using the JSSE provided truststore. +The default JavaMail API implementation used to send out emails behaves in this way, for example. + +You can add your truststore configuration by using the following template: + +[source] +---- + +"truststore": { + "file": { + "file": "path to your .jks file containing public certificates", + "password": "password", + "hostname-verification-policy": "WILDCARD", + "disabled": false + } +} +---- + +Possible configuration options are: + +file:: + The value is the file 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. + Truststore file should only contain public certificates of your secured hosts. + This is _REQUIRED_ if `disabled` is not true. + +password:: + Password for the truststore. + This is _REQUIRED_ if `disabled` is not true. + +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. + +disabled:: + If true (default value), truststore configuration will be ignored, and certificate checking will fall back to JSSE configuration as described. + If set to false, you must configure `file`, and `password` for the truststore. + +You can use _keytool_ to create a new truststore file and add trusted host certificates to it: + +[source] +---- + +$ keytool -import -alias HOSTDOMAIN -keystore truststore.jks -file host-certificate.cer +---- + diff --git a/topics/network/ports.adoc b/topics/network/ports.adoc new file mode 100755 index 0000000000..41ae8c324d --- /dev/null +++ b/topics/network/ports.adoc @@ -0,0 +1,57 @@ +=== Socket Port Bindings + +The ports for each socket also have a pre-defined default that can be overriden at the command line or within configuration. +To illustrate this configuration, let's pretend you are running in <> and +open up the _.../standalone/configuration/standalone.xml_. Search for +socket-binding-group+. + +[source,xml] +---- + + + + + + + + + + + + +---- + ++socket-bindings+ define actual socket connections that will be open by the server that covers both the +interface+ (bind address) +that will be used as wel as the port. The ones you will be most interested in are + +http:: + Defines the port used by {{book.project.name}} HTTP connections +https:: + Defines the port used by {{book.project.name}} HTTPS connections +ajp:: + The Apache HTTPD server is often used with _mod-cluster_ as a load balancer. AJP is the protocol that is used. + This socket binding defines the port used for the AJP protocol. +management-http:: + Defines the HTTP connection used by {{book.appserer.name}} CLI and web console. + +When running in <> locking 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 +[source,xml] +---- + + + ... + + + + ... + + + +---- + +NOTE: There's a lot more nifty options when setting up +socket-binding-group+ definitions. See the link:{{book.appserver.socket.link}}[the socket binding group] + chapter of the {{book.appserver.socket.name}}. +