Jekyll2019-02-27T22:37:21+00:00/feed.xmlHiggsThings I find interesting
Install Openshift on a Lab Server2019-02-04T20:00:00+00:002019-02-04T20:00:00+00:00/fuse/openshift/lab/ansible/2019/02/04/openshift-lab<h1 id="introduction">Introduction</h1>
<p>This page details the steps I took to create a RHEL Openshift lab environment for testing various middleware containers. The goal is to create a reproducible environment that will allow for testing and troubleshooting of various combinations of Fuse, AMQ, Kafka, and more.</p>
<h1 id="environment">Environment</h1>
<p>The hardware for the lab server is a single SuperMicro E200-8D. This was chosen for a combination of performance and power efficiency. The server will host at least four RHEL virtual guests, including a DNS server, a master openshift node, and two compute nodes.</p>
<p>Note also that single-developer machines can use minishift to quickly get an openshift environment up and running; this exercise is to install multiple nodes for pedagogical and troubleshooting purposes.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>SuperMicro E200-8D: Intel Xeon D-1528 (6-Core, 12 Threads), 32G DDR4, 512GB M.2 SSD, RHEL 7 - 192.168.1.113
|--RHEL 7 KVM Guest - dns 2GB RAM / 16GB disk - 192.168.1.114
|--RHEL 7 KVM Guest - master 8GB RAM / 80GB disk - 192.168.1.115
|--RHEL 7 KVM Guest - node1 8GB RAM / 80GB disk - 192.168.1.116
+--RHEL 7 KVM Guest - node2 8GB RAM / 80GB disk - 192.168.1.117
</code></pre></div></div>
<p>My local network is 192.168.1.0/24.</p>
<h1 id="set-up-kvm-host">Set up KVM host</h1>
<p>The first step os to set up a base system on top of which the Openshift nodes will be installed. The base system has few requirements; the following is an outline of the repos that are enabled on my base system and the packages I installed.</p>
<ol>
<li>Install rhel 7.x minimal on SuperMicro (bare metal)</li>
<li>Configure network interface for static ip (/etc/sysconfig/network-scripts)
<ul>
<li>192.168.1.113</li>
</ul>
</li>
<li>set hostname
<ul>
<li>kvm.lan</li>
</ul>
</li>
<li>Add rhel subscription <sup id="fnref:1"><a href="#fn:1" class="footnote">1</a></sup></li>
<li>Enable openshift repos on kvm.lan
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>subscription-manager repos \
--enable="rhel-7-server-rpms" \
--enable="rhel-7-server-extras-rpms" \
--enable="rhel-7-server-ose-3.11-rpms" \
--enable="rhel-7-server-ansible-2.6-rpms"
</code></pre></div> </div>
</li>
<li>Update all packages</li>
<li>Install kvm, virtlib, ansible, etc:
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yum install virt-install libvirt-python virt-manager \
virt-install libvirt-client wget git net-tools bind-utils \
yum-utils iptables-services bridge-utils bash-completion \
kexec-tools sos psacct ansible openshift-ansible
</code></pre></div> </div>
</li>
<li>Create storage pool for images
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code> install -d -o qemu -g qemu -m 700 /home/openshift_images
virsh pool-define-as --name openshift_images --type dir --target /home/openshift_images
virsh pool-autostart openshift_images
virsh pool-start openshift_images
</code></pre></div> </div>
</li>
<li>Clone scripts from github<sup id="fnref:2"><a href="#fn:2" class="footnote">2</a></sup>.</li>
<li>Download RHEL server DVD image, kickstart scripts in the associated repo assume location /home/qemu/rhel-server-7.4-x86_64-dvd.iso, but this can be adjusted in ${SCRIPTS}/kickstart/ks-openshift.cfg.</li>
</ol>
<h1 id="edit-ansible-hosts-file">Edit Ansible hosts file</h1>
<p>Edit the ${SCRIPTS}/ansible/hosts-ose-install for appropriate hosts/IP addresses, etc.</p>
<h1 id="set-up-secret-data-for-ansible-scripts">Set up secret data for ansible scripts</h1>
<p>Secret data for the ansible scripts are stored in the ${SCRIPTS}/ansible/group_vars/all/vault.yml file.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ansible-vault create group_vars/all/vault.yml
</code></pre></div></div>
<p>The contents of the vault need to contain the following attributes (add appropriate values). The pool is a valid pool id for the subscription_user:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>secret_ansible_ssh_pass:
secret_subscription_user:
secret_subscription_password:
secret_subscription_pool:
</code></pre></div></div>
<h1 id="create-dns-server">Create dns server</h1>
<p>The DNS server could be externalized to another server or network device. I did find that installing the DNS server on a separate VM reduced problems during install of the openshift environment. It’s not strictly necessary to host the DNS on it’s own VM; it could be co-located with the master server, for instance. From ${SCRIPTS}/kickstart directory, run the following:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>./install-node.sh -u myuser -s dns -i 192.168.1.114 -m 255.255.255.0 -g 192.168.1.1 -n 192.168.1.1 -p openshift_images -x 2048 -y 16 -z 1
</code></pre></div></div>
<p><em>N.B. - the prompted password will be used for both the specified user and root</em></p>
<h1 id="create-ssh-key-for-root-user-on-kvm-host">Create ssh key for root user on kvm host</h1>
<p>The openshift deployer requires passwordless access to the openshift nodes. I set up a ssh key for the kvm host’s root user; that key is distributed to the nodes in the next steps.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh-keygen -t rsa
</code></pre></div></div>
<h1 id="set-up-dns-server">Set up dns server</h1>
<p>The DNS server can now be configured via the ansible script in the ${SCRIPTS}/ansible directory.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>export ANSIBLE_HOST_KEY_CHECKING=False
ansible-playbook -i hosts-ose-install dns-server.yml --vault-id @prompt
</code></pre></div></div>
<h1 id="create-openshift-servers">Create openshift servers</h1>
<p>Use the same script that was used to create the dns server to create the remaining nodes. An alternative would be create one node and clone it.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>./install-node.sh -u myuser -s master -i 192.168.1.115 -m 255.255.255.0 -g 192.168.1.1 -n 192.168.1.114 -p openshift_images -x 8192 -y 96 -z 4
./install-node.sh -u myuser -s node1 -i 192.168.1.116 -m 255.255.255.0 -g 192.168.1.1 -n 192.168.1.114 -p openshift_images -x 8192 -y 96 -z 4
./install-node.sh -u myuser -s node2 -i 192.168.1.117 -m 255.255.255.0 -g 192.168.1.1 -n 192.168.1.114 -p openshift_images -x 8192 -y 96 -z 4
</code></pre></div></div>
<h1 id="configure-openshift-servers-using-custom-ansible-scripts">Configure openshift servers using custom ansible scripts</h1>
<p>This custom script sets up some prerequisites before using the openshift-ansible scripts. In particular, repos are set up, nested virtualization is enabled, useful packages are installed, hostnames are assigned, and root’s public ssh key is distributed to the nodes. Run the following from the ${SCRIPTS}/ansible directory:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ansible-playbook -i hosts-ose-install --vault-id @prompt openshift-prerequisites.yml
</code></pre></div></div>
<h1 id="install-openshift-proper">Install openshift proper</h1>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cd /usr/share/ansible/openshift-ansible/
ansible-playbook -i ${SCRIPTS}/ansible/hosts-ose-install playbooks/prerequisites.yml --vault-id @prompt
</code></pre></div></div>
<p><em>Important! Restart all openshift servers- without a restart of openshift servers, dbus/dnsmasq issues are encountered during installation of cluster. Make sure the following resolves on each node: nslookup cdn.redhat.com</em></p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ansible-playbook -i ${SCRIPTS}/ansible/hosts-ose-install playbooks/deploy_cluster.yml --vault-id @prompt
</code></pre></div></div>
<p>Note: this step takes a long time - 45 mins on my machine!</p>
<h1 id="access-openshift">Access openshift</h1>
<p>Log in to the master node, run</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>oc login -u system:admin
oc get nodes
NAME STATUS ROLES AGE VERSION
master.openshift.local Ready master 21m v1.11.0+d4cacc0
node1.openshift.local Ready compute 8m v1.11.0+d4cacc0
node2.openshift.local Ready infra 8m v1.11.0+d4cacc0
</code></pre></div></div>
<p>Configure authentication as described in the Openshift Docs<sup id="fnref:3"><a href="#fn:3" class="footnote">3</a></sup></p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>provider:
apiVersion: v1
kind: HTPasswdPasswordIdentityProvider
file: /etc/origin/master/htpasswd
</code></pre></div></div>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>touch /etc/origin/master/htpasswd
htpasswd -b /etc/origin/master/htpasswd admin redhat
master-restart api
master-restart controllers
oc adm policy add-cluster-role-to-user cluster-admin admin
oc login -u admin
oc project default
</code></pre></div></div>
<p>The web console can now be accessed: https://master.openshift.local:8443/console/catalog</p>
<h1 id="references">References</h1>
<div class="footnotes">
<ol>
<li id="fn:1">
<p><a href="https://access.redhat.com/labs/registrationassistant/">RHEL Registration</a> <a href="#fnref:1" class="reversefootnote">↩</a></p>
</li>
<li id="fn:2">
<p><a href="https://github.com/sjhiggs/lab-openshift-install">Custom Scripts</a> <a href="#fnref:2" class="reversefootnote">↩</a></p>
</li>
<li id="fn:3">
<p><a href="https://access.redhat.com/documentation/en-us/openshift_container_platform/3.11/html/getting_started/getting-started-configure-openshift">OpenShift Config</a> <a href="#fnref:3" class="reversefootnote">↩</a></p>
</li>
</ol>
</div>Introduction This page details the steps I took to create a RHEL Openshift lab environment for testing various middleware containers. The goal is to create a reproducible environment that will allow for testing and troubleshooting of various combinations of Fuse, AMQ, Kafka, and more.More Fuse and Karaf integration with Keycloak2017-10-09T18:29:00+00:002017-10-09T18:29:00+00:00/fuse/sso/karaf/x509/smartcard/2017/10/09/keycloak-karaf-cli<h1 id="introduction">Introduction</h1>
<p>In a previous post<sup id="fnref:1"><a href="#fn:1" class="footnote">1</a></sup> we integrated Fuse’s web console (Hawtio) with Keycloak for X.509 authentication. This article builds on the previous configuration to integrate Fuse’s command line interface with Keycloak.</p>
<h1 id="environment">Environment</h1>
<p>This exercise was all run locally on my laptop, and all references were set up for localhost.</p>
<ul>
<li>Keycloak 3.2.1.Final</li>
<li>Fuse 6.3.0 R4</li>
<li>Fedora 26 with both Fuse and Keycloak installed</li>
<li>Yubikey Neo with a X.509 certificate issued to the 9A (PIV auth) slot</li>
<li>Firefox with opensc pkcs11 security module</li>
<li>OpenSSL test CA - root and intermediate CA for issuing certs<sup id="fnref:3"><a href="#fn:3" class="footnote">2</a></sup></li>
</ul>
<h1 id="jmxssh-password-integration-with-keycloak">JMX/SSH password integration with Keycloak</h1>
<p>The first step is relatively easy; the direct access configuration for the Demo realm is added to ${KARAF_HOME}/etc/keycloak-direct-access.json:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{
"realm": "demo",
"resource": "ssh-jmx-admin-client",
"ssl-required" : "external",
"auth-server-url" : "http://localhost:8080/auth",
"credentials": {
"secret": "password"
}
}
</code></pre></div></div>
<p>The ${KARAF_HOME}/etc/org.apache.karaf.shell.cfg is edited for:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sshRealm = keycloak
</code></pre></div></div>
<p>The ${KARAF_HOME}/etc/org.apache.karaf.management.cfg is edited for:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>jmxRealm = keycloak
</code></pre></div></div>
<p>Finally, test login:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh -p 8101 -oHostKeyAlgorithms=+ssh-dss admin@localhost
</code></pre></div></div>
<h1 id="what-about-smart-card-x509-authentication-to-the-karaf-cli">What about smart card (X.509) authentication to the Karaf CLI?</h1>
<p>This is easier said than done. The SSH server doesn’t natively support X.509 authentication, and there is no facility in RH-SSO for SSH public key authentication. One idea I have not tried is to do the public key verification (e.g. with a ssh client configured to use the token<sup id="fnref:2"><a href="#fn:2" class="footnote">3</a></sup>) at the Fuse level and then check the user and roles at the Keycloak level.</p>
<h1 id="a-mq-and-keycloak">A-MQ and Keycloak</h1>
<p>This is similar to setting up ssh and jmx for the direct access keycloak configuration. Just configure ${KARAF_HOME}/etc/activemq.xml to use the keycloak jaas realm instead of the default karaf one. An example would look like:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code><jaasAuthenticationPlugin configuration="keycloak" />
<authorizationPlugin>
<map>
<authorizationMap groupClass="org.apache.karaf.jaas.boot.principal.RolePrincipal">
<authorizationEntries>
<authorizationEntry queue=">" read="viewer,admin" write="admin" admin="admin"/>
<authorizationEntry topic=">" read="viewer,admin" write="admin" admin="admin"/>
<authorizationEntry topic="ActiveMQ.Acvisory.>" read="viewer,admin" write="admin" admin="admin"/>
</authorizationEntries>
<tempDestinationAuthorizationEntry>
<tempDestinationAuthorizationEntry read="viewer,admin" write="admin" admin="admin"/>
</tempDestinationAuthorizationEntry>
</authorizationMap>
</map>
</authorizationPlugin>
</code></pre></div></div>
<h1 id="fuse-fabric-and-keycloak">Fuse Fabric and Keycloak</h1>
<p>Here is an example of how to enable Keycloak for Hawtio authentication in a Fuse Fabric environment. This results in the same PIV/X.509 authentication as seen previously<sup id="fnref:1:1"><a href="#fn:1" class="footnote">1</a></sup>.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>fabric:create --wait-for-provisioning
profile-create mykeycloak
profile-edit --repository mvn:org.keycloak/keycloak-osgi-features/3.2.1.Final/xml/features
profile-edit --repository mvn:org.keycloak/keycloak-osgi-features/3.2.1.Final/xml/features mykeycloak
profile-edit --feature keycloak mykeycloak
profile-edit --system hawtio.keycloakEnabled=true mykeycloak
profile-edit --system hawtio.realm=keycloak mykeycloak
profile-edit --system hawtio.rolePrincipalClasses=org.keycloak.adapters.jaas.RolePrincipal,org.apache.karaf.jaas.boot.principal.RolePrincipal mykeycloak
profile-edit --system hawtio.keycloakClientConfig=${karaf.base}/etc/keycloak-hawtio-client.json mykeycloak
container-add-profile root mykeycloak
</code></pre></div></div>
<p>*N.B. - there is a bug<sup id="fnref:4"><a href="#fn:4" class="footnote">4</a></sup> prior to Red Hat JBoss Fuse 6.3 R4 when referencing the json files in the etc directory.</p>
<h1 id="references">References</h1>
<div class="footnotes">
<ol>
<li id="fn:1">
<p><a href="https://sjhiggs.github.io/fuse/sso/x509/smartcard/2017/03/29/fuse-hawtio-keycloak.html">X.509 Auth to Hawtio</a> <a href="#fnref:1" class="reversefootnote">↩</a> <a href="#fnref:1:1" class="reversefootnote">↩<sup>2</sup></a></p>
</li>
<li id="fn:3">
<p><a href="https://jamielinux.com/docs/openssl-certificate-authority/">OpenSSL CA Instructions</a> <a href="#fnref:3" class="reversefootnote">↩</a></p>
</li>
<li id="fn:2">
<p><a href="https://developers.yubico.com/PIV/Guides/SSH_with_PIV_and_PKCS11.html">X.509/PKCS11 and SSH</a> <a href="#fnref:2" class="reversefootnote">↩</a></p>
</li>
<li id="fn:4">
<p><a href="https://issues.jboss.org/browse/ENTESB-6777">ENTESB-6777</a> <a href="#fnref:4" class="reversefootnote">↩</a></p>
</li>
</ol>
</div>Introduction In a previous post1 we integrated Fuse’s web console (Hawtio) with Keycloak for X.509 authentication. This article builds on the previous configuration to integrate Fuse’s command line interface with Keycloak. X.509 Auth to Hawtio ↩X509 Authentication to Red Hat JBoss Fuse with Keycloak2017-03-29T21:11:09+00:002017-03-29T21:11:09+00:00/fuse/sso/x509/smartcard/2017/03/29/fuse-hawtio-keycloak<h1 id="introduction---preview-of-x509-authentication-in-rh-sso">Introduction - preview of X.509 Authentication in RH-SSO</h1>
<p>This page will outline the steps I took to enable client certificate authentication to Red Hat JBoss Fuse 6.3 via Keycloak. This is particularly useful for smartcard/token authentication; in my case I was testing with a Yubikey hosting a PIV applet. This feature will be in future releases of RH-SS0 (currently slated for 7.2), so here is a preview of things to come.</p>
<h1 id="environment">Environment</h1>
<p>This exercise was all run locally on my laptop, and all references were set up for localhost.</p>
<ul>
<li>Keycloak 3.1.0.CR1</li>
<li>Fuse 6.3.0 R1</li>
<li>Fedora 25 with both Fuse and Keycloak installed</li>
<li>Yubikey Neo with a X.509 certificate issued to the 9A (PIV auth) slot</li>
<li>Firefox with opensc pkcs11 security module</li>
<li>OpenSSL test CA - root and intermediate CA for issuing certs <sup id="fnref:3"><a href="#fn:3" class="footnote">1</a></sup></li>
</ul>
<h1 id="compile-the-latest-keycloak">Compile the latest keycloak</h1>
<p>The X.509 auth functionality is pretty recent at the time of writing <sup id="fnref:1"><a href="#fn:1" class="footnote">2</a></sup>. I pulled the latest Keycloak source from github<sup id="fnref:4"><a href="#fn:4" class="footnote">3</a></sup> and created the 3.1.0.CR1 distribution. I created the distribution per the README and installed the <em>distribution/server-dist/target/keycloak-3.1.0.CR1-SNAPSHOT.tar.gz</em> to my <em>/opt/rh/keycloak</em> directory.</p>
<h1 id="configure-keycloak-for-mutual-ssl-authentication">Configure Keycloak for Mutual SSL authentication</h1>
<p>The as-yet unpublished keycloak docs have good instructions on how to set up the SSL and configure keycloak for the X509 authentication<sup id="fnref:6"><a href="#fn:6" class="footnote">4</a></sup>. The Keycloak authenticator will expect a certificate is already present by the time that code is executing, so the Wildfly container needs to be configured to query the client for the certificate.</p>
<p>Copy any server keystores and truststores to the <em>${KEYCLOAK_HOME/standalone/configuration</em> directory and edit <em>${KEYCLOAK_HOME}/standalone/configuration/standalone.xml</em>. The truststore will need to trust certificates from the CA that issued the authentication certificate (the PIV auth cert in my case).</p>
<p>Add a security-realm to <em><security-realms></em> (customized keystore name and password):</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><security-realm</span> <span class="na">name=</span><span class="s">"ssl-realm"</span><span class="nt">></span>
<span class="nt"><server-identities></span>
<span class="nt"><ssl></span>
<span class="nt"><keystore</span> <span class="na">path=</span><span class="s">"server.keystore"</span> <span class="na">relative-to=</span><span class="s">"jboss.server.config.dir"</span> <span class="na">keystore-password=</span><span class="s">"password"</span> <span class="na">alias=</span><span class="s">"server"</span> <span class="na">key-password=</span><span class="s">"password"</span> <span class="nt">/></span>
<span class="nt"></ssl></span>
<span class="nt"></server-identities></span>
<span class="nt"><authentication></span>
<span class="nt"><truststore</span> <span class="na">path=</span><span class="s">"server.truststore"</span> <span class="na">relative-to=</span><span class="s">"jboss.server.config.dir"</span> <span class="na">keystore-password=</span><span class="s">"password"</span> <span class="nt">/></span>
<span class="nt"></authentication></span>
<span class="nt"></security-realm></span>
</code></pre></div></div>
<p>Add a https-listener to the <em><server name=”default-server”></em>:</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><https-listener</span> <span class="na">name=</span><span class="s">"default-ssl"</span> <span class="na">socket-binding=</span><span class="s">"https"</span> <span class="na">security-realm=</span><span class="s">"ssl-realm"</span> <span class="na">verify-client=</span><span class="s">"REQUESTED"</span> <span class="nt">/></span>
</code></pre></div></div>
<p>The keycloak server can now be started and accessed at <em>https://localhost:8443</em>. Create an admin user and log in to the administration console.</p>
<h1 id="install-red-hat-jboss-fuse-63">Install Red Hat JBoss Fuse 6.3</h1>
<p>I unzipped the latest Fuse distribution and then followed the instructions at <sup id="fnref:2"><a href="#fn:2" class="footnote">5</a></sup>. The items that need to be configured as detailed in the instructions are:</p>
<ul>
<li>${KARAF_HOME}/etc/system.properties<sup id="fnref:8"><a href="#fn:8" class="footnote">6</a></sup></li>
<li>copy keycloak-hawtio.json and keycloak-hawtio-client.json to ${KARAF_HOME}/etc/</li>
<li>Edit the keycloak files for the keycloak installation location, if necessary</li>
</ul>
<p>The keycloak-hawtio.json was modified for my installation:</p>
<ul>
<li>Updated http to https</li>
<li>I took a shortcut <strong>for this non-production poc</strong> and used a self-signed cert for SSL in keycloak. I took another shortcut and used <em>disable-trust-manager = true</em> so Fuse would trust the self-signed keycloak SSL cert. In any case, configurable attributes can be found at <sup id="fnref:5"><a href="#fn:5" class="footnote">7</a></sup>.</li>
</ul>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="s2">"realm"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"demo"</span><span class="p">,</span><span class="w">
</span><span class="s2">"resource"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"jaas"</span><span class="p">,</span><span class="w">
</span><span class="s2">"bearer-only"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
</span><span class="s2">"auth-server-url"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"https://localhost:8443/auth"</span><span class="p">,</span><span class="w">
</span><span class="s2">"ssl-required"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"all"</span><span class="p">,</span><span class="w">
</span><span class="s2">"use-resource-role-mappings"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w">
</span><span class="s2">"principal-attribute"</span><span class="p">:</span><span class="w"> </span><span class="s2">"preferred_username"</span><span class="p">,</span><span class="w">
</span><span class="s2">"disable-trust-manager"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<p>The keycloak-hawtio-client.json is what is sent to the end user/client and just needed the http changed to https:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="s2">"realm"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"demo"</span><span class="p">,</span><span class="w">
</span><span class="s2">"resource"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"hawtio-client"</span><span class="p">,</span><span class="w">
</span><span class="s2">"auth-server-url"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"https://localhost:8443/auth"</span><span class="p">,</span><span class="w">
</span><span class="s2">"ssl-required"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"external"</span><span class="p">,</span><span class="w">
</span><span class="s2">"public-client"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<p>The ${KARAF_HOME}/etc/system.properties is updated with the necessary hawtio configurations</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>hawtio.keycloakEnabled=true
hawtio.realm=keycloak
hawtio.keycloakClientConfig=${karaf.base}/etc/keycloak-hawtio-client.json
hawtio.rolePrincipalClasses=org.keycloak.adapters.jaas.RolePrincipal,org.apache.karaf.jaas.boot.principal.RolePrincipal
</code></pre></div></div>
<p><em>N.B. - the keycloakClientConfig requires file:// in later versions of keycloak</em></p>
<p>The Fuse service can now be started (e.g. <em>${KARAF_HOME}/bin/fuse</em>). Finally, install the keycloak JAAS module and adapter.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>JBossFuse:karaf@root> features:addurl mvn:org.keycloak/keycloak-osgi-features/3.0.0.CR1/xml/features
JBossFuse:karaf@root> features:install keycloak-jaas
</code></pre></div></div>
<h1 id="configure-keycloak-flows-and-executions">Configure Keycloak flows and executions</h1>
<p>Add a realm and import the <em>demorealm.json</em> from <sup id="fnref:7"><a href="#fn:7" class="footnote">8</a></sup>. This will set up some pre-configured users and roles (see the documentation on that page). Username password authentication can now be tested by opening a browser and navigating to <em>http://localhost:8181</em> (<strong>the Fuse server was not configured for SSL for this non-production demo</strong>). The Keycloak authentication page should be displayed; log in with one of the demorealm.json users and ensure you are ultimately logged in to the Hawtio admin console.</p>
<p>The last piece is to configure Keycloak to prompt the user for a certificate instead of username/password. This is done by modifying the browser flow for the demo realm. This process, and the configuration of the X.509 execution, is in the keycloak docs. The next couple screenshots show my configuration for this test.</p>
<p><img src="/assets/img/05-keycloak-flow.png" alt="Browser X509 Flow" class="center-image bordered-image" />
<em>Copy the browser flow and edit for X.509 auth</em></p>
<p><img src="/assets/img/06-keycloak-execution-config.png" alt="Configure Execution" class="center-image bordered-image" />
<em>Configure the execution to map cert attributes to user. I chose to map the certificate CN to Keycloak username.</em></p>
<p><img src="/assets/img/08-keycloak-flow-bindings.png" alt="Change binding" class="center-image bordered-image" />
<em>Change the browser binding to use the new X509 browser flow</em></p>
<p><img src="/assets/img/07-user-role-config.png" alt="Configure User" class="center-image bordered-image" />
<em>Configure a user with a username that matches the appropriate cert attribute.</em></p>
<h1 id="authentication-test">Authentication Test</h1>
<p>Let’s see if it all works! When authenticating to hawtio, the end user is redirected to the Keycloak login page. The user is asked to select a certificate, and then the user/cert confirmation page is displayed. Finally, the user is sent back to Fuse/Hawtio and is successfully authenticated with the right roles. Cool!</p>
<p><img src="/assets/img/01-piv-prompt.png" alt="Enter Token PIN" class="center-image" />
<em>Browser prompts for token PIN</em></p>
<p><img src="/assets/img/02-cert-select.png" alt="Select Certificate" class="center-image" />
<em>User selects the appropriate authentication cert</em></p>
<p><img src="/assets/img/03-keycloak-confirm.png" alt="Keycloak Confirm Cert" class="center-image" />
<em>Keycloak form confirmation page is displayed</em></p>
<p><img src="/assets/img/04-fuse-logged-in.png" alt="Fuse Logged In" class="center-image bordered-image" />
<em>We are logged in with the user defined by the CN in the cert</em></p>
<h1 id="future-tests">Future tests</h1>
<p>Items not tested in this demo:</p>
<ul>
<li>Test certs with invalid users</li>
<li>Test “Bad” certificates</li>
<li>Test OCSP</li>
<li>LDAP integration</li>
<li>Hawtio with Kerberos</li>
</ul>
<h1 id="more-keycloak-integration-with-fuse">More Keycloak integration with Fuse</h1>
<p>A follow-up to this post can be found <a href="https://sjhiggs.github.io/fuse/sso/karaf/x509/smartcard/2017/10/09/keycloak-karaf-cli.html">here</a></p>
<h1 id="references">References</h1>
<div class="footnotes">
<ol>
<li id="fn:3">
<p><a href="https://jamielinux.com/docs/openssl-certificate-authority/">OpenSSL CA Instructions</a> <a href="#fnref:3" class="reversefootnote">↩</a></p>
</li>
<li id="fn:1">
<p><a href="https://issues.jboss.org/browse/KEYCLOAK-4335">Keycloak Issue</a> <a href="#fnref:1" class="reversefootnote">↩</a></p>
</li>
<li id="fn:4">
<p><a href="https://github.com/keycloak/keycloak">Keycloak Source</a> <a href="#fnref:4" class="reversefootnote">↩</a></p>
</li>
<li id="fn:6">
<p><a href="https://github.com/keycloak/keycloak-documentation/pull/56/commits/8e505a19beda38698a0ad7523cc1b030c9b115b3">Keycloak docs</a> <a href="#fnref:6" class="reversefootnote">↩</a></p>
</li>
<li id="fn:2">
<p><a href="https://github.com/keycloak/keycloak/tree/master/examples/fuse/fuse-admin">Fuse and Hawtio demo</a> <a href="#fnref:2" class="reversefootnote">↩</a></p>
</li>
<li id="fn:8">
<p><a href="http://www.keycloak.org/docs/latest/securing_apps/topics/oidc/java/fuse/hawtio.html">Keycloak docs - Hawtio</a> <a href="#fnref:8" class="reversefootnote">↩</a></p>
</li>
<li id="fn:5">
<p><a href="http://www.keycloak.org/docs/latest/securing_apps/topics/oidc/java/java-adapter-config.html">Keycloak java adapter attributes</a> <a href="#fnref:5" class="reversefootnote">↩</a></p>
</li>
<li id="fn:7">
<p><a href="https://github.com/keycloak/keycloak/tree/master/examples/fuse">Fuse and Keycloak demo</a> <a href="#fnref:7" class="reversefootnote">↩</a></p>
</li>
</ol>
</div>Introduction - preview of X.509 Authentication in RH-SSO This page will outline the steps I took to enable client certificate authentication to Red Hat JBoss Fuse 6.3 via Keycloak. This is particularly useful for smartcard/token authentication; in my case I was testing with a Yubikey hosting a PIV applet. This feature will be in future releases of RH-SS0 (currently slated for 7.2), so here is a preview of things to come.