.. _server_configuration: Configuration background information ------------------------------------- .. 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 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. _config_token_database: Token database .............. 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 make 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.ini`` file, which is usually located at ``/etc/linotp2/linotp.ini``. For Oracle change it to:: sqlalchemy.url = oracle://:@/ Be assured that you set up the encKey before creating the database tables. The database tables are then created by calling:: paster setup-app /etc/linotp2/linotp.ini A more detailed setup description for running LinOTP with Oracle or DB2 can be found at section :ref:`database_connection`. .. _python_search_path: Python search path .................. The path where your LinOTP components are installed must be contained in your python search path. This will be given, when you installed LinOTP by either of the described ways. Anyway if the command ``paster setup-app linotp.ini`` returns the error message:: pkg_resources.DistributionNotFound: LinOTP then your python search path needs to be fixed. Then start a python shell:: # python Python 2.6.4 (r264:75706, Dec 7 2009, 18:45:15) [GCC 4.4.1] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import sys >>> sys.path ['', '/usr/local/lib/python2.6/dist-packages/docutils-0.5-py2.6.egg', '/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.5.5-py2.6.egg', '/usr/local/lib/python2.6/dist-packages/Pylons-0.9.7-py2.6.egg', '/usr/local/lib/python2.6/dist-packages/Tempita-0.4-py2.6.egg', '/usr/local/lib/python2.6/dist-packages/WebTest-1.2-py2.6.egg', '/usr/local/lib/python2.6/dist-packages/WebError-0.10.1-py2.6.egg', '/usr/local/lib/python2.6/dist-packages/WebOb-0.9.6.1-py2.6.egg', '/usr/local/lib/python2.6/dist-packages/Mako-0.2.4-py2.6.egg', '/usr/local/lib/python2.6/dist-packages/nose-0.11.1-py2.6.egg', '/usr/local/lib/python2.6/dist-packages/decorator-3.0.0-py2.6.egg', '/usr/local/lib/python2.6/dist-packages/simplejson-2.0.9-py2.6.egg', '/usr/local/lib/python2.6/dist-packages/FormEncode-1.2.2-py2.6.egg', '/usr/local/lib/python2.6/dist-packages/PasteScript-1.7.3-py2.6.egg', '/usr/local/lib/python2.6/dist-packages/PasteDeploy-1.3.3-py2.6.egg', '/usr/local/lib/python2.6/dist-packages/Paste-1.7.2-py2.6.egg', '/usr/local/lib/python2.6/dist-packages/Beaker-1.4-py2.6.egg', '/usr/local/lib/python2.6/dist-packages/WebHelpers-0.6.4-py2.6.egg', '/usr/local/lib/python2.6/dist-packages/Routes-1.10.3-py2.6.egg', '/usr/local/lib/python2.6/dist-packages/Pygments-1.0-py2.6.egg', '/usr/local/lib/python2.6/dist-packages/LinOtpUserIdResolverEE-2.0.1rc3-py2.6.egg', '/usr/local/lib/python2.6/dist-packages/LinOTP-2.0.1rc3-py2.6.egg', '/usr/lib/python2.6', '/usr/lib/python2.6/plat-linux2', '/usr/lib/python2.6/lib-tk', '/usr/lib/python2.6/lib-old', '/usr/lib/python2.6/lib-dynload', '/usr/lib/python2.6/dist-packages', '/usr/lib/python2.6/dist-packages/PIL', '/home/koelbel', '/usr/lib/python2.6/dist-packages/gst-0.10', '/usr/lib/pymodules/python2.6', '/usr/lib/python2.6/dist-packages/gtk-2.0', '/usr/lib/pymodules/python2.6/gtk-2.0', '/usr/lib/python2.6/dist-packages/wx383 2.6-gtk2-unicode', '/usr/lib/python2.6/dist-packages/wx-2.8-gtk2-unicode', '/usr/local/lib/python2.6/dist-packages'] Check the output for your path. If it is not contained, you need to append your directory to the search path. Press *Ctrl-D* to exit the python shell. To append a new path to the Python search path, you need to place a file ``linotp.pth`` into an existing directory of the python search path. So create a file e.g. ``/usr/lib/python2.6/site-packages/linotp.pth`` with the following content:: /usr/local/lib/python2.6/dist-packages/ 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 ``/etc/linotp2/linotp.ini`` you can define two parameters for this:: radius.dictfile= /etc/linotp2/dictionary radius.nas_identifier = LinOTP The *radius.dictfile* is the file that contains the RADIUS attributes definitions. LinOTP comes with a default one. But you can extend it according to special vendor attributes if necessary. The *radius.nas_identifier* is the NAS_Identifier that is also send within the RADIUS Auth Request. All other parameters are configured in the RADIUS token itself. Please see the section :ref:`enroll_radius` for further information on this. Paster ...... To get a quick result easily you may use the python-paste and just start the paster with the following command:: paster serve /etc/linotp2/linotp.ini You should at least enable ``ssl_pem`` in your ``linotp.ini`` to have an encrypted communication between the authentication module or the management clients and LinOTP. Nevertheless, this will provide you with no authentication for the management, i.e. everyone having IP access to your LinOTP Server will be able to manage the tokens. .. note:: *Paster* is also used to create the database tables (see :ref:`config_token_database`) Start script '''''''''''' A Red Hat style start script is contained in the packages:: /ect/init.d/linotp2-paster This will start the paster as user ``linotp``. .. note:: In the default configuration the paster would listen on all IP addresses, which means that the LinOTP server would be visible without encryption and authentication! .. note:: When running with Apache, you do not need this start script! You can start the paster during boot time automatically by issuing the following commands:: chkconfig --add linotp2-paster chkconfig linotp2-paster on .. _apache_configuration: Apache web server ................. To enable encryption and authentication for the LinOTP Server LinOTP can run in a web server. LinOTP will run as WSGI [#wsgi]_ 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. .. [#wsgi] http://code.google.com/p/modwsgi 1. Install apache2, 2. install libapache2-mod-wsgi [#wsgi_debian]_, 3. enable mod-wsgi and mod-ssl with your Apache:: a2enmod wsgi a2enmod ssl 4. If you want to authenticate with username/password do a:: a2enmod auth_digest 5. 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``. 6. Activate this configuration by:: a2ensite linotp2 7. You may disable any other default site:: a2dissite .. [#wsgi_debian] 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: Apache configuration file '''''''''''''''''''''''''' This example configuration applies to Apache version 2.4. The configuration file starts with the VirtualHost definition:: 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:: AllowOverride None Require all denied LinOTP documentation:: Require all granted Alias /doc/html /usr/share/doc/linotpdoc/html LinOTP WSGI application link:: Require all granted 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=* 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``. We now set up authentication for the different LinOTP interfaces, based on their URL paths: **/manage** This interface provides the user interface for administrative tasks. All tasks that can be done with the graphical management client – except enrolling eToken NG-OTP – can also be done with this web interface. The authentication to this web interface needs to be setup in the Apache configuration. You may also setup OTP authentication for the management interface. For how to do this see :ref:`otp_apache`. The manage application uses the following data interfaces: /system, /license, /audit, and /admin. It is, by default, configured in a single LocationMatch directive so that all the interfaces belonging together are secured with the same access rights. **/system** This interface is used to configure the LinOTP Server. You should protect this interface either by password authentication provided by Apache or by client certificate authentication. The Management Clients (server configuration dialog) communicate via this interface. You can restrict access to this interface for a special user group, so that several users may manage the tokens but only a few users may configure server settings. **/license** This interface is used to upload license files to the LinOTP server, and to retrieve licensing information. It should be protected with authentication similar to that of ``/admin`` or ``/system.`` **/audit** This interface is used to search the audit trail to monitor operations. It should be protected in the same authentication manner like /admin or /system. **/admin** This is used for all token management tasks like enrolling, assigning, deleting tokens. You should protect this interface either by password authentication provided by Apache or by client certificate authentication. The Management Clients communicate via this interface. **/api/helpdesk** This interface is used by the linotp-helpdesk web application. It is secured with a different digest auth file than the administrative interfaces. If you change the auth type for this interface, be sure to keep the linotp-helpdesk auth configuration in sync to ensure seamless interaction between the backend and frontend of the helpdesk. **/gettoken** This interface is used to retrieve OTP values. It is secured with a different digest auth file than the administrative interfaces. This means that, by default, no one is allowed to use the interface if no access is explicitly permitted. **/selfservice** This interface is used by end users to manage their own OTP tokens. This interface uses the /userservice interface that provides its own authentication, so there is no special need to protect it within the Apache configuration. As the user authenticates with a username to this interface, /selfservice should only be accessible from your local network. **/userservice** This interface is used by the selfservice application. The user is authenticated against the user database that is defined in the corresponding user ID resolver. As the user authenticates with a username to this interface, /userservice should only be accessible from your local network but must match the same settings as /selfservice. **/validate** This interface is used to authenticate the users. The authentication modules ``pam_linotp`` and ``rlm_linotp2`` communicate via this interface. You should encrypt the communication with this interface (running with SSL) and you may also setup authentication to this interface, but it is not that crucial as it is with /admin and /system. You might want to restrict the IP addresses that are allowed to contact this interface. This can be achieved by a configuration like:: Order deny,allow Deny from all Allow from 192.168.1.17 The complete default access configuration looks as follows:: AuthType Digest AuthName "LinOTP2 admin area" AuthDigestProvider file AuthUserFile /etc/linotp2/admins Require valid-user #---------------------------------------- # Here we do client certificate auth #---------------------------------------- # SSLVerifyClient require # SSLVerifyDepth 2 # # Who signed the client certificates # SSLCACertificateFile /etc/ssl/certs/ca.crt # # what client certs are allowed to log in? # SSLRequire ( %{SSL_CLIENT_S_DN_OU} eq "az" and %{SSL_CLIENT_S_DN_CN} in {"linotpadm", "Manfred Mann"} ) AuthType Digest AuthName "LinOTP2 helpdesk area" AuthDigestProvider file AuthUserFile /etc/linotp2/auth_helpdesk Require valid-user #---------------------------------------- # Here we do client certificate auth #---------------------------------------- # SSLVerifyClient require # SSLVerifyDepth 2 # # Who signed the client certificates # SSLCACertificateFile /etc/ssl/certs/ca.crt # # what client certs are allowed to log in? # SSLRequire ( %{SSL_CLIENT_S_DN_OU} eq "az" and %{SSL_CLIENT_S_DN_CN} in {"linotpadm", "Manfred Mann"} ) AuthType Digest AuthName "LinOTP2 gettoken" AuthDigestProvider file AuthUserFile /etc/linotp2/gettoken-api Require valid-user # The authentication of the selfservice is done from within the application # No Authentication The above Location directives demonstrate how to do authentication either with digest authentication or with client certificate authentication. To create a AuthUserFile for digest authentication you should use the command htdigest. 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 :ref:`issuing_ca`:: 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 "

Internal Server Error

…"
.. 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 self signed test certificate as described in :ref:`creating_ssl_certs`. Different authentication schemes for Management Interface ''''''''''''''''''''''''''''''''''''''''''''''''''''''''' There are several different methods to authenticate to the management interface. All three methods are supported by the WebUI and the command line client. **Username/Password** This can be either basic authentication or digest authentication. .. note:: If you want to authenticate against LDAP (see section :ref:`apache_ldap`), you need to do basic authentication. You can activate this by:: a2ensite linotp2 You need to deactivate other schemes by using ``a2dissite``. **RADIUS Authentication** You can use the RADIUS authentication to authenticate with OTP tokens to the LinOTP Management. Activate this by:: a2ensite linotp2-radius You need to deactivate other schemes by using ``a2dissite``. **Client Certificates** You can also authenticate to the LinOTP management by using client certificates. Please note, that the LinOTP server then will use the Common Name of the Distinguished Name of the client certificate. Using the WebUI the client certificate can also be located on a smartcard. Activate this by:: a2ensite linotp2-certs You need to deactivate other schemes by using ``a2dissite``. .. _apache_ldap: Authenticating users against LDAP or Active Directory ''''''''''''''''''''''''''''''''''''''''''''''''''''' You may also want to authenticate to your LinOTP server with already existing accounts in your LDAP or Active Directory. To accomplish that, you need to configure the corresponding Location directive and do the following steps: Activate ``authnz_ldap`` for Apache:: a2enmod authnz_ldap Configure the Location directive. This could be the /admin, /system and /license controller. To do this edit the file ``/etc/apache2/sites-enabled/linotp2``:: AuthBasicProvider ldap AuthType Basic AuthName "LinOTP 2 admin area" AuthLDAPURL "ldap://172.16.200.61:389/ou=linotp,dc=linotp-test,dc=local?sAMAccountName?sub?(objectClass=user)" NONE AuthLDAPBindDN "LDAPserviceUser@linotp-test" AuthLDAPBindPassword "test123!" Require ldap-group cn=linotp_admin_users, ou=linotp, dc=linotp-test, dc=local In this case all members of the group *linotp_admin_users* are allowed to manage LinOTP and its tokens. For other possible filters and restrictions see the *authnz_ldap* documentation at http://httpd.apache.org/docs/2.1/mod/mod_authnz_ldap.html . To activate the changes, restart the Apache web server:: /etc/init.d/apache2 restart .. _issuing_ca: Issuing Certificate Authority ''''''''''''''''''''''''''''' If you want to setup the Apache web server to run with TLS, you need to have a CA (certificate authority) certificate, a server certificate, and the private key to the web server certificate. If you do not have a CA and a web server certificate available, there is also a sample CA contained in the LinOTPdoc package. You can find the CA depending on your installation at /usr/share/doc/linotp/examples/CA or /usr/local/share/doc/linotp/examples/CA. The sample just consists of two files: * Makefile * openssl.cnf Either change to this directory or copy the files to a location you like. Prior to using the CA, you need to have your distribution packages make and openssl installed. Typing:: make gives you an overview, what you can do with this sample CA. To get started with LinOTP and Apache + SSL you need to do the following steps: 1. Create your new CA:: make initca This will create a subdirectory keys and it will create the CA certificate. The file ``keys/ca.crt`` is the CA certificate for the Apache directive SSLCACertificateFile. 2. Create a request for your web server:: make req ext=server name= 3. Sign the request for the web server / issue the certificate for the web server:: make sign ext=server name= This will create the file ``keys/.pem`` for the Apache directive ``SSLCertificateFile`` and the file ``keys/.key`` for the Apache directive ``SSLCertificateKeyFile``. 4. Create a request for a admin user if you want to use client certificate authentication:: make req ext=user name= 5. Sign the request for the admin user / issue the certificate for the admin user:: make sign ext=user name= 6. The files ``keys/.pem`` and ``keys/.key`` need to be transferred to the client and configured in the LinOTP Management Client GUI. .. note:: The private key files created in this process are passphrase protected. If you need to remove the passphrase use:: openssl rsa -in adminname.key -out adminname-wop.key which will create a key file adminname-wop.key without a passphrase. .. note:: linotpadm.py supports key files with passphrases at the command line. glinotpadm.py does not handle passphrases nicely at the moment. The request for the passphrase will be echoed to the terminal, where you started glinotpadm.py. The passphrase will be requested for every connect to the LinOTP Server, which naturally are a lot. Digest authentication and client certificate authentication can not be used at the same time.