Setting up Alfresco Content Services with docker-compose is really fast and easy. Run docker-compose up and away you go.
But, what if you need to have Kerberos SSO enabled as well?
Read on to discover how to setup Kerberos SSO when using docker-compose.
Note: The docker-compose deployment method is only supported for PoC, demos, and testing scenarios (at the time of writing). You should not use docker-compose for production environment.
This post doesn’t cover setting up a KDC, for example Microsoft AD.
If you wanted to save some time and have Microsoft AD setup for you, have a look at my Vagrant_Machines github Repo. The benifit of using a vagrant AD machine is that you can always redeploy both the AD machine and the docker-compose images to get back to a working environment with a single command.
The complete code for this post can be found here.
Environment Configuration
Here is my environment configuration:
Microsoft Domain Controller: dc01.example.com
Domain name: example.com
ACS server: acs1
Kerberos User Account: acs1
The Steps
The high level steps are:
Project Structure
In the bellow directory structure you can see that each custom docker image is created within it’s own sub directory. One for Repository and one for Share.
docker-compose ├── config │ ├── alfresco // customisation for alfresco-content-repository │ │ ├── Dockerfile │ │ └── kerberos_files // environment specific files share │ │ ├── alfresco.keytab │ │ ├── java.login.config │ │ └── krb5.conf │ └── share // customisation for alfresco-share │ ├── Dockerfile │ └── kerberos_files // environment specific files for share │ ├── java.login.config.share │ ├── krb5.conf │ ├── share-config-custom.xml │ └── share.keytab └── docker-compose.yml
Let’s jump in and create the environment specific files, I've purposely linked to the file on my github repo rather then copy and paste the content to keep the post a bit more concise and easy to follow
Environment Specific Files
In the project structure above, all the files specific to the custom images are contianed within config/<IMAGE_NAME>/kerberos_files. Any modifications to the names or structure of the above project will likely require a corresponding change in the the custom images Dockerfile.
Keytab
Create the keytab file as per the official documentation.
As the Repository and Share web applications will be running from the same server, acs1 in my case, you can reuse the same keytab file when building the custom images. For clarity, I renamed the keytab file to reflect they are being used in different containers, which is why you see keytab.alfresco and keytab.share in each image's kerberos_files directory.
Using the above environment configuration parameters, I created my keytab file using the following command (^ is the Powershell equvialent of \ in a bash shell):
ktpass -princ HTTP/acs1.example.com@EXAMPLE.COM ^ -pass ComplexPassw0rd ^ -mapuser EXAMPLE\httpacs1 ^ -crypto all ^ -ptype KRB5_NT_PRINCIPAL ^ -out c:\tmp\httpacs1.keytab ^ -kvno 0
Take note of the following when you run the command as you will need them later on
Principle: HTTP/acs1.example.com
Password: ComplexPassw0rd
Kerberos REALM name: EXAMPLE.COM
If you are deploying Microsoft AD using my Vagrant machine, you will find a keytab file is created for you automatically. Check out how to make this work for your ACS server here.
java.login.config
The offical configuration for the java.login.config file can be found here.
In my setup, I created two slightly different java.login.config files, one for the custom Alfresco Repository Image and one for the custom Share Image. This isn't strictly mandatory as you can reuse the same file for each docker image, with the obvious concern that the Alfresco Repository Container does not need a ShareHTTP JAAS configuration section.
krb5.conf
We create a krb5.conf file using the information collected while creating a keytab and from the Environment Configuration. As the custom Alfresco Repository Image and custom Share Image will use the same Kerberos configuraiton, the files in each image's build is exsactly the same.
Note: The realm name EXAMPLE.COM, this must be CAPITALISED. In the below, I directly reference my domain controller dc01.example.com.
share-config-custom.xml
As we are using docker containers for Share, we need make sure we change any links that point to a repository api from localhost to the Alfresco Repository Container's. The quickest way I found to do this is by taking a stock share-config-custom.xml file and performing a find and replace for the string localhost, replacing with the name of the repository docker service name.
In my share-config-custom.xml file, I replaced localhost with alfresco as per my docker-compose.yml configuration.
There are some additional sets listed on the official documentation that must be followed, for example, enabling and configuring the Kerberos section and uncommenting some sections.
Create Dockerfile’s
We now need to create our custom images which will inject the files we have created. As the Repository and Share are running in different containers, we will need each to have it’s own Dockerfile. This does require a bit docker wizardry, but nothing too complex.
The key points to note are:
The two Dockerfiles can be found here and here
Looking at these in detail we see that the files are copied into the image:
COPY kerberos_files/krb5.conf /etc COPY kerberos_files/alfresco.keytab /etc COPY kerberos_files/java.login.config /usr/java/default/conf/security
Then we secure the keytab file's permissions and enable java.login.config file:
RUN chown -R root:root /usr/java/default/conf/security /etc/krb5.conf /etc/*.keytab && \ echo "login.config.url.1=file:/usr/java/default/conf/security/java.login.config" >> /usr/java/default/conf/security/java.security
For the most part, the Dockerfile used for our custom Share image is much the same, the only additional step is that we must copy in our share-config-custom.xml file as per the line here.
Configure docker-compose.yml
There are many ways to do this part. You could for example create your docker images with docker first and then specify these images within docker-compose. For simplicity, I am building my images using docker-compose. As mentioned above, this is only intended for setting up a test or demo environment.
The following lines have been added to the docker-compose.yml file to allow docker-compose to build images from our Dockerfiles. (the paths are relative so make sure you run docker-compose from the docker-compose directory):
For the Repository
Alfresco container_name: alfresco622-kerberos hostname: alfresco622 build: context: ./config/alfresco
For Share:
Share container_name: share622-kerberos hostname: share622 build: context: ./config/share
Domain Controller name resolution
The following has also been added to aid with name resolution. If you do add this to your docker-compose file, make sure to adjust for your environment.
extra_hosts: - "dc01.example.com:192.168.100.25" - "dc01:192.168.100.25"
Ldap and Kerberos Java Properties
We must also setup configuration for ldap sync properties and Kerberos properties on the repository service. In my lab I’ve used the following additional Java properties to configure both ldap sync and Kerberos (make sure you adjust these for your environment):
-Dldap.authentication.allowGuestLogin=false -Dldap.authentication.userNameFormat=%s@example.com -Dldap.authentication.java.naming.provider.url=ldap://192.168.100.25:389 -Dldap.authentication.defaultAdministratorUserNames=joe.bloggs -Dldap.authentication.active=false -Dsynchronization.autoCreatePeopleOnLogin=false -Dldap.synchronization.active=true -Dldap.synchronization.java.naming.security.principal=alfresco.ldap@example.com -Dldap.synchronization.java.naming.security.credentials=C0mplexPassword -Dldap.synchronization.groupSearchBase=OU=Alfresco-Groups,DC=example,DC=com -Dldap.synchronization.userSearchBase=OU=Alfresco-Users,DC=example,DC=com -Dkerberos.authentication.realm=EXAMPLE.COM -Dkerberos.authentication.user.configEntryName=Alfresco -Dkerberos.authentication.defaultAdministratorUserNames=joe.bloggs,vagrant -Dkerberos.authentication.http.configEntryName=AlfrescoHTTP -Dkerberos.authentication.http.password=C0mplexPassword -Dkerberos.authentication.sso.enabled=true -Dauthentication.chain=kerberos1:kerberos,alfrescoNtlm1:alfrescoNtlm,ldap1:ldap-ad
The official documentation describes both the ldap properties and the Kerberos properties that must be configured. You can also configure these options from the Admin Console if you wanted to.
Run docker-compose
As we added the ability to build images directly into our docker-compose file, we can use the following to start this service
Docker-compose up --build -d
On subsequent runs when no build configuration changes have been made, you can omit the --build option.
That's it! If you managed to get everything configured, you have your Kerberos enabled cookie cutter template docker-compose that you can use for any dockerised version of Alfresco. Happy Kerberos-ing
Troubleshooting
Kerberos can be a pretty tricky authenitcation mechanisum to setup. If you do get stuck make sure you double check each and every setting you have configured.
You can also use docker logs <CONTAINER_ID | CONTAINER_NAME > to view the Repository or Share logs.