Skip to content

Adding SAML Authentication and HTTPS to MC Hub

lefreud edited this page Mar 5, 2021 · 1 revision

This guide discusses how you can restrict access to the MC Hub web application by using an authentication server running on CentOS 7. To do so, we will be using an Apache server with Shibboleth Service Provider V3. It also goes through the installation and automatic renewal of SSL certificates for HTTPS using Certbot.

Useful definitions

Requirements

  • CentOS 7 x86-64 instance
  • clouds.yaml file with application credentials from OpenStack

1. Register your SAML Service Provider

In order to enable Single Sign-On with SAML, you need to register as a Service Provider to your Identity Provider.

If your are creating a new, unregistered Service Provider, you need to follow these steps. Otherwise, you can skip this part and go to the next section.

  1. Contact the administrator of your organization's Identity Provider.
  2. Create a unique Service Provider Entity ID. A good way to create a unique ID is to use the hostname you will be using to host your app, for example mcui.calculquebec.cloud.
  3. Ask for the location of the IdP's SAML metadata file. This will be used when creating the shibboleth2.xml configuration file.
  4. Tell the administrator the SAML attributes you need from every user connecting to your Service Provider (e.g. First Name, Last Name, Email, Organization Roles). These will be used later when creating attribute-map.xml.
  5. When the setup of your MC Hub server is done, you will need to send the link to your own metadata file location to the IdP administrator in order to register your service provider. The metadata file url should look like http://<sp-hostname>/Shibboleth.sso/Metadata.

2. Install the dependencies

  1. Install a text editor of your choice.

    sudo yum install vim
  2. Add the Docker repository to yum.

    The installation steps are taken from Docker Docs: Install Docker Engine on CentOS.

    Uninstall any old versions installed.

    sudo yum remove docker \
                    docker-client \
                    docker-client-latest \
                    docker-common \
                    docker-latest \
                    docker-latest-logrotate \
                    docker-logrotate \
                    docker-engine

    Set up the Docker repository.

    sudo yum install -y yum-utils
    sudo yum-config-manager \
        --add-repo \
        https://download.docker.com/linux/centos/docker-ce.repo
  3. Add the Shibboleth repository to yum.

    Create a shibboleth.repo file and open it in a text editor.

    sudo vim /etc/yum.repos.d/shibboleth.repo
    

    Copy and paste the following configuration and save the file.

    [shibboleth]
    name=Shibboleth (CentOS_7)
    type=rpm-md
    mirrorlist=https://shibboleth.net/cgi-bin/mirrorlist.cgi/CentOS_7
    gpgcheck=1
    gpgkey=https://download.opensuse.org/repositories/security:/shibboleth/CentOS_7/repodata/repomd.xml.key
    enabled=1
    
  4. Update yum packages.

    sudo yum update -y
    
  5. Install the required packages.

    sudo yum install -y httpd.x86_64 mod_ssl shibboleth.x86_64 docker-ce docker-ce-cli containerd.io
    

    This will install the Apache server, Shibboleth Service Provider, for SSO authentication and Docker, in order to run the MC Hub web application

3. Configure Shibboleth Service Provider

  1. Add the proper keys and certificates to your configuration. If this is the first time you setup this Service Provider, you can skip this step and use the keys and certificates generated by Shibboleth on installation.

    Remove the keys automatically generated by Shibboleth.

    sudo rm /etc/shibboleth/*.pem
    

    Copy and paste your key files in their respective locations.

    sudo vim /etc/shibboleth/sp-encrypt-key.pem
    sudo vim /etc/shibboleth/sp-encrypt-cert.pem
    sudo vim /etc/shibboleth/sp-signing-key.pem
    sudo vim /etc/shibboleth/sp-signing-cert.pem
    
  2. Edit the default attribute map with your own attributes.

    Delete the default attribute-map.xml and create a new one in a text editor.

    sudo rm /etc/shibboleth/attribute-map.xml
    sudo vim /etc/shibboleth/attribute-map.xml
    

    Then, add the following lines. The attributes should correspond to what the Identity Provider and you have agreed on.

    <Attributes xmlns="urn:mace:shibboleth:2.0:attribute-map" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <Attribute name="urn:oid:1.3.6.1.4.1.47174.1.1.1.8" id="ccServiceAccess"/>
        <Attribute name="urn:oid:1.3.6.1.4.1.5923.1.1.1.1" id="eduPersonAffiliation"/>
        <Attribute name="urn:oid:1.3.6.1.4.1.5923.1.1.1.6" id="eduPersonPrincipalName"/>
        <Attribute name="urn:oid:2.5.4.42" id="givenName"/>
        <Attribute name="urn:oid:2.5.4.4" id="surname"/>
        <Attribute name="urn:oid:0.9.2342.19200300.100.1.3" id="mail"/>
    </Attributes>
  3. Download the IdP's metadata file.

    Replace https://idp.mit.c3.ca/idp/shibboleth with the URL where your IdP hosts the SAML metadata file.

    sudo curl -o /etc/shibboleth/idp-metadata.xml "https://idp.mit.c3.ca/idp/shibboleth"
    
  4. Modify the default Shibboleth configuration file. Set the environment variables to values adapted to your organization.

    Set the Entity ID of the IdP.

    export IDENTITY_PROVIDER_ENTITY_ID="https://idp.mit.c3.ca/idp/shibboleth"

    Set the Entity ID you chose for the SP.

    export SERVICE_PROVIDER_ENTITY_ID="mcui.calculquebec.cloud"

    Set the support contact.

    export SHIBBOLETH_SUPPORT_CONTACT="admin@example.com"

    Apply the modifications to the configuration.

    sudo sed -e "s|https://idp.example.org/idp/shibboleth|${IDENTITY_PROVIDER_ENTITY_ID}|g" \
        -e "s|https://sp.example.org/shibboleth|${SERVICE_PROVIDER_ENTITY_ID}|g" \
        -e "s|root@localhost|${SHIBBOLETH_SUPPORT_CONTACT}|g" \
        -i /etc/shibboleth/shibboleth2.xml

    Open the resulting configuration file.

    sudo vim /etc/shibboleth/shibboleth2.xml
    

    Then, add the following line to the configuration, just before the </ApplicationDefaults> closing tag.

    <MetadataProvider type="XML" validate="true" path="idp-metadata.xml"/>
  5. Test the Shibboleth configuration to see if there is any problem.

    sudo LD_LIBRARY_PATH=/opt/shibboleth/lib64 shibd -t

    The output should end with the following:

    overall configuration is loadable, check console or log for non-fatal problems
    

4. Configure the Apache server

  1. Remove the welcome.conf Apache example configuration.

    sudo rm /etc/httpd/conf.d/welcome.conf
    
  2. Add a virtual host on port 80. This step is required only if you want to setup HTTPS.

    sudo vim /etc/httpd/conf/httpd.conf

    Add the following code at the end of the configuration file. Change mcui.calculquebec.cloud for the hostname you are using.

    <VirtualHost *:80>
        DocumentRoot "/var/www/html"
        ServerName mcui.calculquebec.cloud
    </VirtualHost>
  3. Modify the default Shibboleth Apache module configuration file.

    sudo rm /etc/httpd/conf.d/shib.conf
    sudo vim /etc/httpd/conf.d/shib.conf
    

    Then, paste the following configuration. In this case, unauthenticated users will be redirected to the SSO login page for all routes (except those starting with /Shibboleth.sso). For authenticated users, the Apache server acts as a reverse proxy, forwarding all requests to 127.0.0.1:5000. You can choose a different port number if you wish.

    IMPORTANT: Make sure to block access to you application's http port (in this case 5000) to incoming connections from other IPs than 127.0.0.1. Otherwise, anyone can bypass the authentication and access the application directly.

    # https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPApacheConfig
    
    # RPM installations on platforms with a conf.d directory will
    # result in this file being copied into that directory for you
    # and preserved across upgrades.
    
    # For non-RPM installs, you should copy the relevant contents of
    # this file to a configuration location you control.
    
    #
    # Load the Shibboleth module.
    #
    LoadModule mod_shib /usr/lib64/shibboleth/mod_shib_24.so
    
    #
    # Turn this on to support "require valid-user" rules from other
    # mod_authn_* modules, and use "require shib-session" for anonymous
    # session-based authorization in mod_shib.
    #
    ShibCompatValidUser Off
    
    #
    # Ensures handler will be accessible.
    #
    <Location /Shibboleth.sso>
    AuthType None
    Require all granted
    </Location>
    <IfModule mod_alias.c>
    <Location /shibboleth-sp>
        AuthType None
        Require all granted
    </Location>
    Alias /shibboleth-sp/main.css /usr/share/shibboleth/main.css
    </IfModule>
    
    #
    # Configure the module for content.
    #
    # You MUST enable AuthType shibboleth for the module to process
    # any requests, and there MUST be a require command as well. To
    # enable Shibboleth but not specify any session/access requirements
    # use "require shibboleth".
    #
    <Location / >
        AuthType shibboleth
        ShibUseHeaders On
        ShibRequestSetting requireSession 1
        require shib-session
    
        # Reverse proxy configuration
        ProxyPreserveHost On
        ProxyPass http://127.0.0.1:5000/
        ProxyPassReverse http://127.0.0.1:5000/
    </Location>
  4. Allow HTTPD scripts to connect to the network with the reverse proxy. This should be disallowed by default by SELinux.

    sudo /usr/sbin/setsebool -P httpd_can_network_connect 1
    

5. Configure the services to run automatically on boot

Configure systemd to start the required services on boot. This includes the Apache server, Shibboleth and Docker.

sudo systemctl enable httpd
sudo systemctl enable shibd
sudo systemctl enable docker

6. Configure the MC Hub container

  1. Start the Docker service.

    sudo systemctl start docker
    
  2. Prepare MC Hub's working directory.

    Create a new directory. You can name it whatever you want. This directory can be located anywhere. In this case, it is ~/mcui.

    mkdir ~/mcui

    Copy the content of your clouds.yaml file.

    cd ~/mcui
    vim clouds.yaml
    # Paste your clouds.yaml file content

    If you are using Google Cloud as a DNS provider, do the following steps.

    1. Create a service account that has permissions to manage the DNS settings (if you don't already have one). The account should have the DNS Administrator role.
    2. Create a new keypair and download it, in JSON format.
    3. Copy the JSON key file to the root of the repository in a file named gcloud-key.json.
    vim gcloud-key.json
    

    Create the configuration.json file and set the proper configuration. Read the section on the JSON Configuration for more information.

    vim configuration.json

    Create a directory named clusters_backup and give it the proper permissions. This is required for the bind mount to work properly.

    mkdir clusters_backup
    sudo chmod -R 777 clusters_backup
  3. Run the Docker image of MC Hub.

    Run fredericfc/magic_castle-ui. Change v5.0.1 for the latest version of MC Hub in the following command.

    If you are not using the Google Cloud DNS provider, remove the line --mount "type=bind,source=$(pwd)/gcloud-key.json,target=/home/mcu/credentials/gcloud-key.json" \.

    sudo docker run -p 5000:5000 \
      --restart always \
      --mount "type=volume,source=database,target=/home/mcu/database" \
      --mount "type=bind,source=$(pwd)/gcloud-key.json,target=/home/mcu/credentials/gcloud-key.json" \
      --mount "type=bind,source=$(pwd)/clouds.yaml,target=/home/mcu/.config/openstack/clouds.yaml" \
      --mount "type=bind,source=$(pwd)/clusters_backup,target=/home/mcu/clusters" \
      --mount "type=bind,source=$(pwd)/configuration.json,target=/home/mcu/configuration.json" \
        fredericfc/magic_castle-ui:v5.0.1
    

    The --restart always option will restart automatically the container, including when the host system reboots.

    For debugging purposes, you can use mendhak/http-https-echo. This image contains a basic server that outputs the content of the requests, including the headers created by Shibboleth.

7. Run the Apache server

After doing this setup, you can start the shibd daemon and httpd daemon. Then, you will be able to connect to MC Hub with SAML authentication.

You can also simply sudo reboot and the daemons and container will be launched automatically.

  1. Run Shibboleth.

    sudo systemctl start shibd
    
  2. Run the Apache server.

    sudo systemctl start httpd
    
  3. Navigate to the server's public IP or hostname.

    Verify that you are being redirected to the IdP and login with your credentials.

  4. Test the logout by going to <hostname>/Shibboleth.sso/Logout and going back to the home page. You should be redirected to the SAML login automatically.

8. Add HTTPS support

Follow the Certbot instructions for setting up HTTPS and automatic certificate renewal here: https://certbot.eff.org/lets-encrypt/centosrhel7-apache