This is the second part of a two-part blog series that shows how to set up a “sandbox” environment of Global Federated Identity and Privilege Management (GFIPM) components using open source software and Docker containers:
- Part I provides some background on GFIPM, Security Assertion Markup Language (SAML), and open source software available to implement GFIPM/SAML
- Part II shows how to use Docker to deploy these open source components in a sandbox environment
GFIPM Components as Docker Containers
This diagram shows four Docker containers that implement the components presented in Part I:
- apacheds: An LDAP directory with some demo/test users
- idp: Shibboleth 3 identity provider
- portal: Apache httpd with Shibboleth 2.5.5 service provider, delegating certain http requests to Tomcat
- tomcat: Apache Tomcat 8, with a simple web application installed that displays assertions received from the IDP/SP via http headers
Note: We have added a SAML Discovery Service (also known as a “where are you from”, or “WAYF”) service to the sandbox, and configured the portal (service provider) to forward requests to this service so the user can select the IDP he/she wishes to use to authenticate. This occurs as part of Step #3 in the diagram above. This container’s information is:
- samlds: Shibboleth Discovery Service 1.2.1
Installing Docker and Creating a Docker Machine
Docker runs natively on Linux (and, soon, Windows Server, in 2016), but a “wrapper” toolset called Docker Machine enables us to work with Docker containers on MacOS and Windows. So assuming you are not running on Linux, the first step is to install Docker Toolbox, which includes Docker Machine and the Oracle VirtualBox environment in which it runs. There are separate instructions for downloading Docker Toolbox on MacOS and Windows.
After installing Docker Toolbox, open a terminal window (MacOS) or command prompt (Windows) and type
docker --version to verify the setup:
Docker version 1.9.0, build 76d6bc9
To continue with this setup, we need Docker version 1.9.0 or higher.
Next, we need to create a Docker Machine instance to host our Docker environment. Docker Machine will “wrap” this environment to make it look like Docker is running natively on our Mac or Windows platform:
–virtualbox-memory 2048 –virtualbox-hostonly-nicpromisc allow-all ojb-machine
Running pre-create checks…
Waiting for machine to be running, this may take a few minutes…
Machine is running, waiting for SSH to be available…
Detecting operating system of created instance…
Provisioning created instance…
Copying certs to the local machine directory…
Copying certs to the remote machine…
Setting Docker configuration on the remote daemon…
To see how to connect Docker to this machine, run: docker-machine env ojb-machine
$: eval $(docker-machine env ojb-machine)
Since its early days, Docker has included basic networking capabilities, allowing containers to communicate over TCP/IP and expose ports outside of the host. Recently, the community has evolved more robust networking mechanisms to address the shortcomings of the original Docker networking capabilities. One of these mechanisms is Weave. Weave creates a sort of virtual Ethernet switch among a set of containers, and can also route traffic between that switched network and the host–and beyond. It also provides name resolution services via DNS.
Note: Currently, weave only runs on Unix platforms, such as MacOS and Linux. It does not run on Windows. As such, if you are following along on a Windows host, execute the remaining commands in this post in the Docker Machine (except where noted) rather than on Windows. To do that, log into the Docker Machine by typing
docker-machine ssh ojb-machine. At the conclusion of the demo, log out of the Docker Machine by typing
First, install weave:
$: sudo chmod a+x /usr/local/bin/weave
Note: to execute the above commands on MacOS or Linux (but not on the Docker Machine host), the account under which you are logged in must be in the “sudoers” group, and you will need to provide the superuser password.
Then launch weave:
$: eval $(weave env)
$: weave expose
These commands start the weave network, specifying that the top-level domain of machines in the network will be ojbc.local. (This can be anything you want; you’ll just need to adjust the remainder of the tutorial if you change to something different, and you’ll also need to change the configuration files in each of the Docker containers, which refer to one another by full domain name.) The
weave expose command instructs weave to route traffic to all machines on the weave network through to the host.
Install and Run Containers
The next step is to actually install the sandbox images and run the containers, which can be accomplished in one step per image:
$: docker run -d –name=idp ojbc/idp
$: docker run -d –name=samlds ojbc/samlds
$: docker run -d –name=portal ojbc/portal
$: docker run -d –name=apacheds ojbc/apacheds
Note: You will see slightly different output if you have not previously pulled the four images. You will also see different hashes created for each container.
You can make sure everything is working by executing the command
weave status dns. You should see each container with an associated IP address in the 10.32.0.0 network.
Set Up Routing and DNS on the Host
To be able to access the containers from your host machine, you will need to set up some static network routes, and to enable your host OS to recognize the names in the ojbc.local domain, you’ll need to add the weave proxy as a DNS server.
To set up the static routes, execute the following two commands:
$: route add -net 172.17.0.0/16 $(docker-machine ip ojb-machine)
Note: On Windows, execute these commands in your Windows environment, not on the Docker Machine host. Also, remove the “-net” option from each command, and replace the $(docker-machine ip ojb-machine) part with the output of the command
docker-machine ip ojb-machine (since the Windows command shell does not do the $(…) replacement).
The first route uses the Docker Machine as a gateway to route traffic directly to the weave network (the containers). The second route is necessary for the Docker Machine gateway to route traffic to the weave proxy DNS server, which weave deploys on the Docker “bridge” network native on the Docker Machine. Essentially, these are two private networks that exist on the Docker Machine host, and these routes simply tell your native OS how to access them (via the Docker Machine host as a gateway/router).
After setting up the static routes, you should be able to ping any of the individual containers. For instance, if tomcat is at 10.32.0.2, then you should be able to do:
PING 10.32.0.2 (10.32.0.2): 56 data bytes
64 bytes from 10.32.0.2: icmp_seq=0 ttl=63 time=0.324 ms
64 bytes from 10.32.0.2: icmp_seq=1 ttl=63 time=0.533 ms— 10.32.0.2 ping statistics —
2 packets transmitted, 2 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.324/0.428/0.533/0.105 ms
To set up DNS on MacOS, add an entry to the resolver config as follows:
$: sudo rm -f /etc/resolver/ojbc.local && echo “nameserver 172.17.0.1” | sudo tee -a /etc/resolver/ojbc.local
In addition, if you are on MacOS X Yosemite, you need to turn on support for .local domains by running:
sudo discoveryutil mdnsactivedirectory yes.
On Windows, add 172.17.0.1 as an additional DNS server under Network Preferences.
After completing this section, you should be able to ping any of the containers by name–e.g.,
Access the Secure Portal
The final step is to access the URL https://portal.ojbc.local/ojb-web-util/index.jsp. Because the containers ship with self-signed certificates, your browser will display warnings about unsecure certificates/connections. After clicking through the warnings, you will be presented with the Discovery Service’s IDP selection page. In the sandbox, there is only one IDP set up (OJBC); select it. The Discovery Service will then redirect you to the IDP’s login page, at which you can authenticate with the user “demouser1” and the password “password”. The IDP will then redirect your request back to the portal, which will pass it off to the app server. The Java Server Page in the app server will offer four links:
Click the first link to bring up a page that simply formats the HTTP headers and the contents of the SAML assertion passed along from the IDP. Of course, in a “real” web application, the application would use the contents of the assertion (in particular, the attributes) to make access control decisions or personalize the user’s experience.
Congratulations – you now have a local sandbox GFIPM federation running in Docker!
All of the Docker images used in this tutorial are available in the OJBC’s Docker Hub area. Feel free to pull and use them. You can use these to set up your own local federation for testing, or extend the images for production use (being sure to secure them–they are not hardened as-is). You can also use the Dockerfiles and contexts, available under the Reciprocal Public License, in the OJBC’s GitHub area, as the basis for your own GFIPM images.
The OJBC staff team is happy to provide tips and guidance on implementation of GFIPM in general, and use of these containers in particular. Feel free to contact us!