EduGAIN Connectivity Check Service - ECCS
- Introduction
- Check Performed on the IdPs
- Limitations
- Disable Checks
- On-line interface
- Requirements Hardware
- Requirements Software
- HOWTO Install and Configure
- ECCS API Server (UWSGI)
- ECCS API JSON
- Utility for web interface
- Utility for developers
- Authors
Introduction
The purpose of the eduGAIN Connectivity Check is to identify eduGAIN Identity Providers (IdP) that are not properly configured. In particular it checks if an IdP properly loads and consumes SAML2 metadata which contains the eduGAIN Service Providers (SP). The check results are published on the public eduGAIN Connectivity Check web page (### NOT-AVAILABLE-YET ###). The main purpose is to increase the service overall quality and user experience of the eduGAIN interfederation service by making federation and Identity Provider operators aware of configuration problems.
The check is performed by sending a SAML authentication request to each eduGAIN IdP and then follow the various HTTP redirects. The expected result is a login form that allows users to authenticate (typically with username/password) or an error message of some form. For those Identity Providers that output an error message, it can be assumed that they don't consume eduGAIN metadata properly or that they suffer from another configuration problem. There are some cases where the check will generate false positives, therefore IdPs can be excluded from checks as is described below.
The Identity Providers are checked once per day. Therefore, the login requests should not have any significant effect on the log entries/statistics of an Identity Provider. Also, no actual login is performed because the check cannot authenticate users due to missing username and password for the IdPs. Only Identity Providers are checked but not the Service Providers.
Check Performed on the IdPs
The check executed by the service follows these steps:
-
It retrieves the eduGAIN IdPs from eduGAIN Operator Team database via a JSON interface
-
For each IdP that is was not manually disabled by the eduGAIN Operations Team, the check creates a Wayfless URL for each SP involved and retrieves the IdP login page. It expects to find the HTML form with a username and password field. Therefore, no complete login will happen at the Identity Provider because the check stops at the login page. The SPs used for the check are "SP Demo provided by GARR" (https://sp-demo.idem.garr.it/shibboleth) from IDEM GARR AAI and the "AAI Viewer Interfederation Test" (https://attribute-viewer.aai.switch.ch/interfederation-test/shibboleth) from SWITCHaai. These SPs might change in the future if needed. The SAML authenticatin request is not signed. Therefore, authentication request for any eduGAIN SP could be created because the SP's private key is not needed.
Limitations
There are some situations where the check cannot work reliably. In those cases it is possible to disable the check for a particular IdP. The so far known cases where the check might generate a false negative are:
- IdP does not support HTTP or HTTPS with at least SSLv3 or TLS1 or newer (these IdPs are insecure anyway)
- IdP is part of a Hub & Spoke federation (some of them manually have to first approve eduGAIN SPs)
- IdP does not use web-based login form (e.g. HTTP Basic Authentication or X.509 login)
Disable Checks
In cases where an IdP cannot be reliably checked, it is necessary to create or enrich the robots.txt
file on the IdP's web root with:
User-agent: ECCS
Disallow: /
If an IdP is not able to create its own robots.txt
file under the web root directory, it can be disabled by setting the dictionary IDPS_DISABLED_DICT
into eccs_properties.py
with a line in the form:
'':''
On-line interface
The test eduGAIN Connectivity Check web pages is available at: https://technical-test.edugain.org/eccs
The tool uses following status for IdPs:
- ERROR (red):
- The IdP's response contains an HTTP Error or the web page returned does not look like a login page.
- Invalid-Form: considers those IdPs that do not load a standard username/password login page and do not return messages like "No return endpoint available for relying party" or "No metadata found for relying party".
- Timeout: considers those IdPs that do not load a standard username/password login page within 60 seconds.
- Connection-Error: considers those IdPs that are not reachable due to a connection problem. View the "Page Source" value to discover which problem the IdP has.
- IdP-Error: considers those IdPs that the web page returned does not contain a Login Form and reports an unspecified error such as "An error occured". This has been seen on Micrsoft ADFS based IdPs
- The IdP most likely does not consume the eduGAIN metadata correctly.
A typical case that falls into this category is when an IdP returns a message "No return endpoint available for relying party" or "No metadata found for relying party":
- No-eduGAIN-Metadata
- The IdP has a problem with its SSL certificate:
- SSL-Error
- The IdP's response contains an HTTP Error or the web page returned does not look like a login page.
- OK (green):
- The IdP most likely correctly consumes eduGAIN metadata and returns a valid login page. This is no guarantee that login on this IdP works for all eduGAIN services but if the check is passed for an IdP, this is probable.
- DISABLED (white)
- The IdP is excluded because it cannot be checked reliably. The "Page Source" column, when an entity is disabled, shows the reason of the disabling.
Requirements Hardware
- OS: Debian 9, CentOS 7.8 (tested)
- HDD: 10 GB
- RAM: 4 GB
- CPU: >= 2 vCPU (suggested)
- ARCH: 64 Bit
Requirements Software
- Apache Server + WSGI
- Python 3 (tested with v3.9.1)
- Selenim + Google Chrome Web Brower (tested with v91.0.4472.164)
- Chromedriver (tested with v91.0.4472.101)
- Git
HOWTO Install and Configure
Download ECCS Repository
cd $HOME ; git clone https://gitlab.geant.org/edugain/eccs.git
Install Python 3
CentOS 7 requirements
-
Update the system packages:
sudo yum -y update
-
Install the YUM utils:
sudo yum install yum-utils
-
Install needed packages to build python:
sudo yum-builddep python3
-
Install Git:
sudo yum -y install git
Debian requirements
-
Update the system packages:
sudo apt update ; sudo apt upgrade -y
-
Install needed packages to build python3:
sudo apt-get build-dep python3
-
Install Git:
sudo apt install git
Install
-
Download the last version of Python 3 from https://www.python.org/downloads/source/ into your home:
wget https://www.python.org/ftp/python/3.9.1/Python-3.9.1.tgz -O $HOME/eccs/Python-3.9.1.tgz
-
Extract Python source package:
cd $HOME/eccs/
tar xzf Python-3.9.1.tgz
-
Build Python from the source package:
cd $HOME/eccs/Python-3.9.1
./configure --prefix=$HOME/eccs/python
make
-
Install Python 3 under
$HOME/eccs/python
:make install
$HOME/eccs/python/bin/python3 --version
This will install python3 under your $HOME/eccs directory.
-
Remove useless things:
rm -Rf $HOME/eccs/Python-3.9.1 $HOME/eccs/Python-3.9.1.tgz
Install Google Chrome needed by Selenium
-
Debian (64 bit):
cd $HOME/eccs
sudo wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo apt install ./google-chrome-stable_current_amd64.deb
-
CentOS (64 bit):
cd $HOME/eccs
sudo wget https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm
sudo yum install ./google-chrome-stable_current_x86_64.rpm
Install the Chromedriver
-
Find out which version of Chromium you are using:
- Debian 9 (stretch):
-
google-chrome -version
=> Google Chrome 91.0.4472.164
-
- CentOS 7.8:
-
google-chrome -version
=> Google Chrome 91.0.4472.164
-
- Debian 9 (stretch):
-
Take the Chrome version number, remove the last part, and append the result to URL "
https://chromedriver.storage.googleapis.com/LATEST_RELEASE_
". For example, with Chrome version 73.0.3683.75, you'd get a URL "https://chromedriver.storage.googleapis.com/LATEST_RELEASE_73.0.3683
". -
Use the URL created in the last step to discover the version of ChromeDriver to use. For example, the above URL will get your a file containing "73.0.3683.68".
-
Use the version number retrieved from the previous step to construct the URL to download ChromeDriver. With version
72.0.3626.68
, the URL would be "https://chromedriver.storage.googleapis.com/index.html?path=73.0.3683.68/" -
Download the Chromedriver and extract it with:
cd $HOME/eccs
wget https://chromedriver.storage.googleapis.com/73.0.3683.68/chromedriver_linux64.zip
unzip chromedriver_linux64.zip
rm chromedriver_linux64.zip google-chrome-stable_current_amd64.deb
Note: After the initial download, it is recommended that you occasionally go through the above process again to see if there are any bug fix releases.
ECCS Script
Install and Configure the Virtual Environment
cd $HOME/eccs
./python/bin/python3 -m pip install virtualenv
$HOME/eccs/python/bin/virtualenv --python=$HOME/eccs/python/bin/python3 eccs-venv
$HOME/eccs/eccs-venv/bin/python3 -m pip install --upgrade pip
-
source eccs-venv/bin/activate
(deactivate
to exit Virtualenv)python3 -m pip install -r requirements.txt
Configure ECCS
-
Configure ECCS properties:
cp $HOME/eccs/eccs_properties.py.template $HOME/eccs/eccs_properties.py
-
vim $HOME/eccs/eccs_properties.py
(and change it upon your needs)
-
Change
PATH
by adding the virtualenv Pythonbin
dir:-
CentOS:
-
vim $HOME/.bash_profile
-
Add the following lines at the tail:
# set PATH for ECCS if [ -d "$HOME/eccs" ]; then PATH="$HOME/eccs/eccs-venv/bin:$PATH" fi
-
source $HOME/.bash_profile
-
-
Debian:
-
vim $HOME/.bash_profile
-
Add the following lines at the tail:
# set PATH for ECCS if [ -d "$HOME/eccs" ]; then PATH="$HOME/eccs/eccs-venv/bin:$PATH" fi
-
source $HOME/.bash_profile
-
-
-
Configure ECCS cron job for the local user:
-
crontab -e
SHELL=/bin/bash 0 4 * * * /bin/bash $HOME/eccs/cleanAndRunEccs.sh > $HOME/eccs/logs/eccs-cron.log 2>&1
-
Execute
cd $HOME/eccs
-
./cleanAndRunEccs.py
(to run a full and clean check) -
./runEccs.py
(to run a full check on the existing inputs) -
./runEccs.py --idp <IDP-ENTITYID>
(to run check on a single IdP) -
./runEccs.py --test
(to run a full check without effects) -
./runEccs.py --idp <IDP-ENTITYID> --test
(to run check on a single IdP without effects) -
./runEccs.py --idp <IDP-ENTITYID> --replace
(to run check on a single IdP and replace, or add, a result)
If something prevent the good execution of the ECCS's check, the logs/failed-cmd.sh
file will be not empty at the end of the execution.
The "--test" parameter will not change the result of ECCS, but will write the output on the logs/stdout_idp_YYYY-MM-DD.log
,logs/stderr_idp_YYYY-MM-DD.log
and logs/failed-cmd-idp.sh
files if the argument "--test" will be used.
ECCS API Server (uWSGI)
Install
- Install requirements:
- Debian:
sudo apt-get install libpcre3 libpcre3-dev libapache2-mod-proxy-uwsgi build-essentials python3-dev unzip
- CentOS:
sudo yum install mod_proxy_uwsgi unzip
- Configure SElinux to enable ECCS:
sudo semanage fcontext -a -t httpd_sys_content_t $HOME/eccs/eccs.conf
sudo restorecon -v $HOME/eccs/eccs.conf
sudo semanage fcontext -a -t httpd_sys_content_t $HOME/eccs/html(/.*)?
sudo restorecon -R -v "$HOME/eccs/html/"
sudo setsebool -P httpd_can_network_connect 1
- Debian:
Configure
-
Add the systemd service to enable ECCS API:
cd $HOME/eccs
cp eccs.ini.template eccs.ini
cp eccs.service.template eccs.service
-
vim eccs.ini
(and change "uid
", "gid
" and "base
" values opportunely) -
vim eccs.service
(and change "User
","Group
","WorkingDirectory
","RuntimeDirectory
","ExecStart
" values opportunely) sudo cp $HOME/eccs/eccs.service /etc/systemd/system/eccs.service
sudo systemctl daemon-reload
sudo systemctl enable eccs.service
sudo systemctl start eccs.service
-
Configure Apache for ECCS web side:
- Debian:
sudo cp $HOME/eccs/eccs-debian.conf /etc/apache2/conf-available/eccs.conf
sudo a2enconf eccs.conf
-
sudo chgrp www-data $HOME ; sudo chmod g+rx $HOME
(Apache needs permission to access the $HOME dir) sudo systemctl restart apache2.service
- CentOS:
sudo cp $HOME/eccs/eccs-centos.conf /etc/httpd/conf.d/eccs.conf
-
sudo chgrp apache $HOME ; sudo apache g+rx $HOME
(Apache needs permission to access the $HOME dir) sudo systemctl restart httpd.service
- Debian:
-
Restart API WSGI server each day to update the datetime:
crontab -e
SHELL=/bin/bash 0 3 * * * /usr/bin/touch $HOME/eccs/eccs.ini
Utility
To perform a restart after an API change use the following command:
touch $HOME/eccs/eccs.ini
ECCS API JSON
-
/api/eccsresults
(Return the results of the last check ready for ECCS web interface) -
/api/eccsresults?<parameter1>=<value1>&<parameter2>=<value2>
:-
date=2020-02-20
(select date) -
idp=https://idp.example.org/idp/shibboleth
(select a specific idp) -
status=
(select specific ECCS status)- 'OK'
- 'ERROR'
- 'DISABLED'
-
check_result=
OK
Timeout
Invalid-Form
Connection-Error
IdP-Error
No-eduGAIN-Metadata
SSL-Error
DISABLED
-
reg_auth=https://reg.auth.example.org
(select a specific Registration Authority) -
format=simple
(retrieve results in a simple format)
-
/api/fedstats
-
/api/fedstats?reg_auth=https://reg.auth.example.org
:
Utility for web interface
The available dates are provided by the first and the last file created into the output/
directory,
remember to change its path into web/eccs.php
file.
Clean old results
To clean the ECCS results from files older than last 7 days use (modify it on your needs):
-
crontab -e
SHELL=/bin/bash 0 10 * * * /bin/bash $HOME/eccs/clean7daysOldFiles.sh > $HOME/eccs/logs/clean7daysOldFiles.log 2>&1
User interface
The eduGAIN Connectivity Check Service web page is available at https://technical-test.edugain.org/eccs
User interface parameters
Parameter name | Example |
---|---|
date |
date=2020-02-20 |
reg_auth |
reg_auth=https://reg.auth.example.org |
idp |
idp=https://idp.example.org/idp/shibboleth |
status |
status=ERROR |
check_result |
check_result=Timeout |
Example:
https://technical-test.edugain.org/eccs?reg_auth=http://www.idem.garr.it/&check_result=SSL-Error
Utility for developers
ECCS API Development Server
cd $HOME/eccs ; ./api.py
Authors
Original Author
- Marco Malavolti (marco.malavolti@garr.it)