3.3.4. LinOTP Server configuration background#
Note
This section contains deeper background information about server configuration. If you installed LinOTP via the virtual appliance or Debian packages, you probably do not need to read this.
You only need to read this chapter, if you installed LinOTP manually or want to adapt your LinOTP setup very specifically.
LinOTP Server configuration#
Token database#
During the installation a database connection is configured by the package linotp. It is assumed that the MariaDB server is installed.
The configuration of the database and its connection is done automatically.
If you want to use an alternative you have to configure the database connection in:
/etc/linotp/linotp.cfg or
/etc/linotp/conf.d/*
The attribute DATABASE_URI is used for configuration.
The DATABASE_URI starts with the driver/module to be selected for the database. This is followed by the user with database access and password, and ends with the database hostname and the database name itself.
If the configuration is adapted accordingly the tool linotp can create the database with tables and give the user the rights.
Our example shows the configuration of a PostgreSQL database for LinOTP.
The simple SQLite database may be well used for installations up to 100 tokens. This file based sql database can only be accessed locally. Being a simple file, it can be easily backed up but it features no additional access settings. Nevertheless all sensitive data are encrypted with the encKey file. But keep in mind, that this file is located on the same machine like the SQLite database file. You might have a dedicated database department that is running databases like Oracle or MS SQL. Please note, that LinOTP makes use of the SQLAlchemy framework. You may find the supported databases here at http://www.sqlalchemy.org/docs/dialects/index.html.
You will then need to change the sqlalchemy.url in your linotp.cfg
file.
For PostgreSQL change it to:
DATABASE_URI = "postgresql://linotpuser:linotppass@localhost/linotp_db"
Be assured that you set up the encKey before creating the database tables. The database tables are then created by calling:
linotp init database
A more detailed setup description for running LinOTP with Oracle or DB2 can be found at section Database connection.
RADIUS token communication#
Starting with LinOTP 2.4 you can also define RADIUS Tokens, that forward the authentication request to another RADIUS
server. This can be another OTP backend or any other RADIUS server. In the file linotp.cfg
you can
define a parameters for this:
RADIUS_NAS_IDENTIFIER=LinOTP
The RADIUS_NAS_IDENTIFIER is the NAS_Identifier that is send within the RADIUS Auth Request. All other parameters are configured in the RADIUS token itself.
Please see the section Enroll RADIUS Token for further information on this.
linotp server#
To get a quick result easily you may use the LinOTP command line tool and start a linotp development server with the following command:
linotp run
This will start a linotp server for you but is not suitable for production.
Note
you need to init a token database upfront (see Token database)
Note
you need add some linotp administrators (see Authentication)
Apache web server#
Note
TODO: This part is outdated and needs to be updated to work with LinOTP 3.
To enable encryption and authentication for the LinOTP Server LinOTP can run in a web server. LinOTP will run as WSGI [1] and thus you can use any web server that supports WSGI. This section describes how to setup your Apache to serve LinOTP in an encrypted and authenticated manner.
Install apache2,
install libapache2-mod-wsgi [2],
enable mod-wsgi and mod-ssl with your Apache:
a2enmod wsgi a2enmod ssl
4. With LinOTP an example Apache configuration was installed to /usr/share/doc/linotp/examples/apache2-linotp2
.
You can copy this file to /etc/apache2/sites-available/linotp2
.
Activate this configuration by:
a2ensite linotp2
You may disable any other default site:
a2dissite
This is the Debian package name. Might be different!
In the following section we discuss the Apache configuration file, which you might want to adapt to your needs.
Apache configuration file#
This example configuration applies to Apache version 2.4.
The configuration file starts with the VirtualHost definition:
<VirtualHost _default_:443>
ServerAdmin webmaster@localhost
Security-relevant HTTP headers are set:
Header always edit Set-Cookie ^(.*)$ $1;secure
Header always set X-Frame-Options "DENY"
Header always set X-XSS-Protection "1; mode=block"
Header always set Strict-Transport-Security "max-age=315360000; includeSubDomains"
Header always set X-Content-Type-Options "nosniff"
Header always set X-Permitted-Cross-Domain-Policies "none"
For security, server access rights are denied globally and only given where necessary:
<Directory />
AllowOverride None
Require all denied
</Directory>
LinOTP documentation:
<Directory /usr/share/doc/linotpdoc/html>
Require all granted
</Directory>
Alias /doc/html /usr/share/doc/linotpdoc/html
LinOTP WSGI application link:
<Directory /etc/linotp2>
<Files linotpapp.wsgi>
Require all granted
</Files>
</Directory>
WSGIScriptAlias / /etc/linotp2/linotpapp.wsgi
The WSGIScriptAlias binds the linotpapp.wsgi
script to the web server root. You only should change the location
of the linotpapp.wsgi
script, but you should not change the web server root path to something other than /
,
because all supported LinOTP clients assume that LinOTP can be reached there.
For efficiency, LinOTP will be run in a separate set of WSGI daemon processes rather than as part of Apache itself:
# The daemon is running as user 'linotp'
# This user should have access to the encKey database encryption file
WSGIDaemonProcess linotp processes=1 threads=15 display-name=%{GROUP} user=linotp
WSGIProcessGroup linotp
WSGIPassAuthorization On
Note, that the user=<user> needs to have write access to the log file specified in linotp.ini
(default /var/log/linotp/
) and read access to the encKey
file specified in linotp.ini
.
Next we group the different LinOTP web interfaces and APIs (represented by their URL paths), based on the access level they should allow.
- /manage, /system, /license, /audit and /admin
/manage is a web interface that uses the APIs provided by /system, /license, /audit and /admin.
These interfaces allow the management and configuration of LinOTP and should be restricted to admin-grade users. They are secured with JSON Web Tokens (JWT) and require setting up a local administrator account. The easiest way to achieve this is to use the LinOTP CLI commands; please refer to the respective man page, linotp-local-admins(1).
There is no need to set up additional server-level security features, so the respection section in the configuration may look like this:
<LocationMatch /(manage|system|license|audit|admin)> # The authentication for administration requests is done from within the LinOTP application </LocationMatch>
- /gettoken
This interface is used to retrieve a list of OTP values. By default, no one is allowed to use the interface and access must be explicitly granted, as it exposes highly sensitive information:
<Location /gettoken> Require all denied </Location>
To allow access only from a certain location, you can use the “Require ip” statement:
<Location /gettoken> Require ip 10.10.10.10 </Location>
/selfservice and /userservice
These interfaces are provided to end users for managing their methods of authentication. The web interface at /selfservice uses the /userservice API, which authenticates the user against a user identity source defined in LinOTP by configuring a user ID resolver.
As this mechanism provides user authentication, there is no need to configure additional security measures:
<LocationMatch /(selfservice|userservice)> # The authentication of the selfservice is done from within the application </LocationMatch>Please ensure that these two interfaces have the same access settings and can be reached by token users.
/validate
This interface is used to validate multi factor authentication attempts.
The PAM authentication module
pam_linotp
and the RADIUS authentication modulerlm_linotp2
are using this interface and you should therefore encrypt the communication between modules and interface with SSL.You may also want to setup additional security steps. For example, you may restrict the IP addresses that are allowed to contact this interface, which can be achieved with a configuration like:
<Location /validate> Order deny,allow Deny from all Allow from 192.168.1.17 </Location>By default, however, there are no additional protection measures, so the configuration template should look like this:
<Location /validate> # No Authentication </Location>
If you are using client certificate authentication you can restrict access for certain client certificates using the SSLRequire directive. For a guideline on how to setup SSL and to issue certificates see section Issuing Certificate Authority:
ErrorLog /var/log/apache2/error.log
LogLevel warn
# Do not use %q! This will reveal all parameters, including setting PINs and Keys!
# Using SSL_CLIENT_S_DN_CN will show you, which administrator did what task
LogFormat "%h %l %u %t %>s \"%m %U %H\" %b \"%{Referer}i\" \"%{User-agent}i\" \
\"%{SSL_CLIENT_S_DN_CN}x\""" LinOTP2
CustomLog /var/log/apache2/ssl_access.log LinOTP2
# SSL Engine Switch:
# Enable/Disable SSL for this virtual host.
SSLEngine on
# If both key and certificate are stored in the same file, only the
# SSLCertificateFile directive is needed.
SSLCertificateFile /etc/ssl/certs/linotpserver.pem
SSLCertificateKeyFile /etc/ssl/private/linotpserver.key
Lastly, error responses can be defined. By default, we only configure the code 500 document:
ErrorDocument 500 "<h1>Internal Server Error</h1> …"
</VirtualHost>
Note
The example uses the SSL certificate linotpserver.pem. If you do not have a certificate authority that provides you with a proper certificate, you may create a new self signed test certificate. If you are running LinOTP on the Smart Virtual Appliance, follow the tutorial in Change the server SSL certificate.
Authenticating to the Management Interface#
The Management Interface, as well as all related administration APIs, always require authentication based on JSON Web Tokens (JWT).
- To activate this setup, run::
a2ensite linotp2
There are three available sites: linotp2, linotp2-radius and linotp2-certs. The latter two additionally provide optional authentication measures which we describe below.
Note
Ensure that only one site is active at a time. You can deactivate a site by using a2dissite
.
Note
By default, only users configured in a special administrators realm can obtain a JWT by providing correct login credentials. The users on this administrative realm are at first only configurable via the LinOTP CLI but you can later on promote other resolvers to administrator level. They may then include users from external directories via e.g. LDAP.
Optional: additional authentication measures
You can use RADIUS authentication or client certificates as an extra security factor so that unauthorized users cannot access the Management Interface login endpoint. This is how you can configure the Apache webserver for the extra steps:
First deactivate other sites by using
a2dissite
. For example, if you have previously activated the “linotp2” site, runa2dissite linotp2
.Activate the respective sites:
RADIUS authentication: activate RADIUS authentication to authenticate with OTP tokens by running:
a2ensite linotp2-radiusClient certificates: the LinOTP server will use the Common Name of the Distinguished Name of the client certificate. The client certificate can also be located on a smartcard. Activate this method by running:
a2ensite linotp2-certs
To activate the changes, restart the Apache web server:
/etc/init.d/apache2 restart