keycloak-aplcache

Merge pull request #743 from stianst/master KEYCLOAK-730

10/6/2014 8:58:57 AM

Details

diff --git a/docbook/reference/en/en-US/master.xml b/docbook/reference/en/en-US/master.xml
index 39515ef..3487d3c 100755
--- a/docbook/reference/en/en-US/master.xml
+++ b/docbook/reference/en/en-US/master.xml
@@ -32,6 +32,7 @@
                 <!ENTITY ExportImport SYSTEM "modules/export-import.xml">
                 <!ENTITY ServerCache SYSTEM "modules/cache.xml">
                 <!ENTITY SecurityVulnerabilities SYSTEM "modules/security-vulnerabilities.xml">
+                <!ENTITY Clustering SYSTEM "modules/clustering.xml">
                 ]>
 
 <book>
@@ -121,6 +122,7 @@ This one is short
     &ExportImport;
     &ServerCache;
     &SecurityVulnerabilities;
+    &Clustering;
     &Migration;
 
 </book>
diff --git a/docbook/reference/en/en-US/modules/clustering.xml b/docbook/reference/en/en-US/modules/clustering.xml
new file mode 100755
index 0000000..613316f
--- /dev/null
+++ b/docbook/reference/en/en-US/modules/clustering.xml
@@ -0,0 +1,217 @@
+<chapter id="clustering">
+    <title>Clustering</title>
+
+    <para>To improve availability and scalability Keycloak can be deployed in a cluster.</para>
+
+    <para>It's fairly straightforward to configure a Keycloak cluster, the steps required are:
+        <itemizedlist>
+            <listitem>
+                <para>
+                    Configure a shared database
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    Configure Infinispan
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    Enable realm and user cache invalidation
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    Enable distributed user sessions
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    Start in HA mode
+                </para>
+            </listitem>
+        </itemizedlist>
+    </para>
+
+    <section>
+        <title>Configure a shared database</title>
+        <para>
+            Keycloak doesn't replicate realms and users, but instead relies on all nodes using the same
+            database. This can be a relational database or Mongo. To make sure your database doesn't become a single
+            point of failure you may also want to deploy your database to a cluster.
+        </para>
+    </section>
+
+    <section>
+        <title id="cluster-configure-infinispan">Configure Infinispan</title>
+        <para>
+            Keycloak uses <ulink url="http://www.infinispan.org/">Infinispan</ulink> caches to share information between nodes.
+        </para>
+        <para>
+            For realm and users Keycloak uses a invalidation cache. An invalidation cache doesn't share any data, but simply
+            removes stale data from remote caches. This reduces network traffic, as well as preventing sensitive data (such as
+            realm keys and password hashes) from being sent between the nodes.
+        </para>
+        <para>
+            User sessions supports either distributed caches or fully replicated caches. We recommend using a distributed
+            cache.
+        </para>
+        <para>
+            To configure the required Infinspan caches open <literal>standalone/configuration/standalone-ha.xml</literal> and add:
+<programlisting>
+<![CDATA[
+<subsystem xmlns="urn:jboss:domain:infinispan:2.0">
+    <cache-container name="keycloak" jndi-name="infinispan/Keycloak" start="EAGER">
+        <invalidation-cache name="realms" mode="SYNC"/>
+        <invalidation-cache name="users" mode="SYNC"/>
+        <distributed-cache name="sessions" mode="SYNC" owners="1" />
+    </cache-container>
+    ...
+</subsystem>
+]]>
+</programlisting>
+        </para>
+        <para>
+            For more advanced options refer to the
+            <ulink url="http://docs.jboss.org/author/display/WFLY8/Infinispan+Subsystem">Infinispan Subsystem</ulink>
+            and
+            <ulink url="http://www.infinispan.org/docs/6.0.x/user_guide/user_guide.html">Infinispan</ulink>
+            documentation.
+        </para>
+        <para>
+            Next open <literal>standalone/configuration/keycloak-server.json</literal> and add:
+<programlisting>
+"connectionsInfinispan": {
+    "default" : {
+        "cacheContainer" : "java:jboss/infinispan/Keycloak"
+    }
+}
+</programlisting>
+        </para>
+    </section>
+
+    <section>
+        <title>Enable realm and user cache invalidation</title>
+        <para>
+            To reduce number of requests to the database Keycloak caches realm and user data. In cluster mode
+            Keycloak uses an Infinispan invalidation cache to make sure all nodes re-load data from the database
+            when it is changed. Using an invalidation cache instead of a replicated cache reduces the network traffic
+            generated by the cluster, but more importantly prevents sensitive data from being sent.
+        </para>
+        <para>
+            To enable realm and user cache invalidation open <literal>keycloak-server.json</literal> and change
+            the <literal>realmCache</literal> and <literal>userCache</literal> providers to <literal>infinispan</literal>:
+<programlisting>
+"realmCache": {
+    "provider": "infinispan"
+},
+
+"userCache": {
+    "provider": "infinispan"
+}
+</programlisting>
+        </para>
+    </section>
+
+    <section>
+        <title>Enable distributed user sessions</title>
+        <para>
+            To help distribute the load of user sessions Keycloak uses an Infinispan distributed cache. A distributed
+            cache splits user sessions into segments where each node holds one or more segment. It is possible
+            to replicate each segment to multiple nodes, but this is not strictly necessary since the failure of a node
+            will only result in users having to log in again. If you need to prevent node failures from requiring users to
+            log in again, set the <literal>owners</literal> attribute to 2 or more for the <literal>sessions</literal> cache
+             (see <link linkend='cluster-configure-infinispan'>Configure Infinispan</link>).
+        </para>
+        <para>
+            To enable the Infinispan user sessions provider open <literal>keycloak-server.json</literal> and change the
+            userSessions provider to <literal>infinispan</literal>:
+<programlisting>
+"userSessions": {
+    "provider": "infinispan"
+}
+</programlisting>
+        </para>
+    </section>
+
+    <section>
+        <title>Start in HA mode</title>
+        <para>
+            To start the server in HA mode, start it with:
+            <programlisting># bin/standalone --server-config=standalone-ha.xml</programlisting>
+        </para>
+        <para>
+            Alternatively you can copy <literal>standalone/config/standalone-ha.xml</literal> to <literal>standalone/config/standalone.xml</literal>
+            to make it the default server config.
+        </para>
+    </section>
+
+    <section>
+        <title>Enabling cluster security</title>
+        <para>
+            By default there's nothing to prevent unauthorized nodes from joining the cluster and sending potentially malicious
+            messages to the cluster. However, as there's no sensitive data sent there's not much that can be achieved.
+            For realms and users all that can be done is to send invalidation messages to make nodes load data from the
+            database more frequently. For user sessions it would be possible to modify existing user sessions, but creating
+            new sessions would have no affect as they would not be linked to any access tokens. There's not to much that
+            can be achieved by modifying user sessions. For example it would be possible to prevent sessions from expiring,
+            by changing the creation time. However, it would for example have no effect adding additional permissions to the
+            sessions as these are rechecked against the user and application when the token is created or refreshed.
+        </para>
+        <para>
+            In either case your cluster nodes should be in a private network, with a firewall protecting them from outside
+            attacks. Ideally isolated from workstations and laptops. You can also enable encryption of cluster messages,
+            this could for example be useful if you can't isolate cluster nodes from workstations and laptops on your private
+            network. However, encryption will obviously come at a cost of reduced performance.
+        </para>
+        <para>
+            To enable encryption of cluster messages you first have to create a shared keystore (change the key and store passwords!):
+<programlisting>
+<![CDATA[
+# keytool -genseckey -alias keycloak -keypass <PASSWORD> -storepass <PASSWORD> \
+ -keyalg Blowfish -keysize 56 -keystore defaultStore.keystore -storetype JCEKS
+]]>
+</programlisting>
+        </para>
+        <para>
+            Copy this keystore to all nodes (for example to standalone/configuration). Then configure JGroups to encrypt all
+            messages by adding the <literal>ENCRYPT</literal> protocol to the JGroups sub-system (this should be added after
+            the <literal>pbcast.GMS</literal> protocol):
+<programlisting>
+<![CDATA[
+<subsystem xmlns="urn:jboss:domain:jgroups:2.0" default-stack="udp">
+    <stack name="udp">
+        ...
+        <protocol type="pbcast.GMS"/>
+        <protocol type="ENCRYPT">
+            <property name="key_store_name">
+                ${jboss.server.config.dir}/defaultStore.keystore
+            </property>
+            <property name="key_password">PASSWORD</property>
+            <property name="store_password">PASSWORD</property>
+            <property name="alias">keycloak</property>
+        </protocol>
+        ...
+    </stack>
+    <stack name="tcp">
+        ...
+        <protocol type="pbcast.GMS"/>
+        <protocol type="ENCRYPT">
+            <property name="key_store_name">
+                ${jboss.server.config.dir}/defaultStore.keystore
+            </property>
+            <property name="key_password">PASSWORD</property>
+            <property name="store_password">PASSWORD</property>
+            <property name="alias">keycloak</property>
+        </protocol>
+        ...
+    </stack>
+    ...
+</subsystem>
+]]>
+</programlisting>
+            See the <ulink url="http://www.jgroups.org/manual/index.html#ENCRYPT">JGroups manual</ulink> for more details.
+        </para>
+    </section>
+
+</chapter>
diff --git a/docbook/reference/en/en-US/modules/server-installation.xml b/docbook/reference/en/en-US/modules/server-installation.xml
index aadfba8..9e595a1 100755
--- a/docbook/reference/en/en-US/modules/server-installation.xml
+++ b/docbook/reference/en/en-US/modules/server-installation.xml
@@ -122,7 +122,7 @@ keycloak-war-dist-all-&project.version;/
         </para>
     </section>
     <section>
-        <title>Configuring the Server</title>
+        <title id="configure-server">Configuring the Server</title>
         <para>
             Although the Keycloak Server is designed to run out of the box, there's some things you'll need
             to configure before you go into production.  Specifically: