Changeset - 39f81c536ad4
[Not reviewed]
default
0 2 0
Mads Kiilerich - 7 years ago 2018-12-23 21:16:07
mads@kiilerich.com
docs: Fix a couple of build warnings

Now down to the usual:
build/docs/api/models.rst: WARNING: document isn't included in any toctree
2 files changed with 6 insertions and 3 deletions:
0 comments (0 inline, 0 general)
docs/administrator_guide/auth.rst
Show inline comments
 
.. _authentication:
 

	
 
====================
 
Authentication setup
 
====================
 

	
 
Users can be authenticated in different ways. By default, Kallithea
 
uses its internal user database. Alternative authentication
 
methods include LDAP, PAM, Crowd, and container-based authentication.
 

	
 
.. _ldap-setup:
 

	
 

	
 
LDAP Authentication
 
-------------------
 

	
 
Kallithea supports LDAP authentication. In order
 
to use LDAP, you have to install the python-ldap_ package. This package is
 
available via PyPI, so you can install it by running::
 

	
 
    pip install python-ldap
 

	
 
.. note:: ``python-ldap`` requires some libraries to be installed on
 
          your system, so before installing it check that you have at
 
          least the ``openldap`` and ``sasl`` libraries.
 

	
 
Choose *Admin > Authentication*, click the ``kallithea.lib.auth_modules.auth_ldap`` button
 
and then *Save*, to enable the LDAP plugin and configure its settings.
 

	
 
Here's a typical LDAP setup::
 

	
 
 Connection settings
 
 Enable LDAP          = checked
 
 Host                 = host.example.com
 
 Account              = <account>
 
 Password             = <password>
 
 Connection Security  = LDAPS
 
 Certificate Checks   = DEMAND
 

	
 
 Search settings
 
 Base DN              = CN=users,DC=host,DC=example,DC=org
 
 LDAP Filter          = (&(objectClass=user)(!(objectClass=computer)))
 
 LDAP Search Scope    = SUBTREE
 

	
 
 Attribute mappings
 
 Login Attribute      = uid
 
 First Name Attribute = firstName
 
 Last Name Attribute  = lastName
 
 Email Attribute      = mail
 

	
 
If your user groups are placed in an Organisation Unit (OU) structure, the Search Settings configuration differs::
 

	
 
 Search settings
 
 Base DN              = DC=host,DC=example,DC=org
 
 LDAP Filter          = (&(memberOf=CN=your user group,OU=subunit,OU=unit,DC=host,DC=example,DC=org)(objectClass=user))
 
 LDAP Search Scope    = SUBTREE
 

	
 
.. _enable_ldap:
 

	
 
Enable LDAP : required
 
    Whether to use LDAP for authenticating users.
 

	
 
.. _ldap_host:
 

	
 
Host : required
 
    LDAP server hostname or IP address. Can be also a comma separated
 
    list of servers to support LDAP fail-over.
 

	
 
.. _Port:
 

	
 
Port : optional
 
    Defaults to 389 for PLAIN un-encrypted LDAP and START_TLS.
 
    Defaults to 636 for LDAPS.
 

	
 
.. _ldap_account:
 

	
 
Account : optional
 
    Only required if the LDAP server does not allow anonymous browsing of
 
    records.  This should be a special account for record browsing.  This
 
    will require `LDAP Password`_ below.
 

	
 
.. _LDAP Password:
 

	
 
Password : optional
 
    Only required if the LDAP server does not allow anonymous browsing of
 
    records.
 

	
 
.. _Enable LDAPS:
 

	
 
Connection Security : required
 
    Defines the connection to LDAP server
 

	
 
    PLAIN
 
        Plain unencrypted LDAP connection.
 
        This will by default use `Port`_ 389.
 

	
 
    LDAPS
 
        Use secure LDAPS connections according to `Certificate
 
        Checks`_ configuration.
 
        This will by default use `Port`_ 636.
 

	
 
    START_TLS
 
        Use START TLS according to `Certificate Checks`_ configuration on an
 
        apparently "plain" LDAP connection.
 
        This will by default use `Port`_ 389.
 

	
 
.. _Certificate Checks:
 

	
 
Certificate Checks : optional
 
    How SSL certificates verification is handled -- this is only useful when
 
    `Enable LDAPS`_ is enabled.  Only DEMAND or HARD offer full SSL security
 
    with mandatory certificate validation, while the other options are
 
    susceptible to man-in-the-middle attacks.
 

	
 
    NEVER
 
        A serve certificate will never be requested or checked.
 

	
 
    ALLOW
 
        A server certificate is requested.  Failure to provide a
 
        certificate or providing a bad certificate will not terminate the
 
        session.
 

	
 
    TRY
 
        A server certificate is requested.  Failure to provide a
 
        certificate does not halt the session; providing a bad certificate
 
        halts the session.
 

	
 
    DEMAND
 
        A server certificate is requested and must be provided and
 
        authenticated for the session to proceed.
 

	
 
    HARD
 
        The same as DEMAND.
 

	
 
.. _Custom CA Certificates:
 

	
 
Custom CA Certificates : optional
 
    Directory used by OpenSSL to find CAs for validating the LDAP server certificate.
 
    Python 2.7.10 and later default to using the system certificate store, and
 
    this should thus not be necessary when using certificates signed by a CA
 
    trusted by the system.
 
    It can be set to something like `/etc/openldap/cacerts` on older systems or
 
    if using self-signed certificates.
 

	
 
.. _Base DN:
 

	
 
Base DN : required
 
    The Distinguished Name (DN) where searches for users will be performed.
 
    Searches can be controlled by `LDAP Filter`_ and `LDAP Search Scope`_.
 

	
 
.. _LDAP Filter:
 

	
 
LDAP Filter : optional
 
    A LDAP filter defined by RFC 2254.  This is more useful when `LDAP
 
    Search Scope`_ is set to SUBTREE.  The filter is useful for limiting
 
    which LDAP objects are identified as representing Users for
 
    authentication.  The filter is augmented by `Login Attribute`_ below.
 
    This can commonly be left blank.
 

	
 
.. _LDAP Search Scope:
 

	
 
LDAP Search Scope : required
 
    This limits how far LDAP will search for a matching object.
 

	
 
    BASE
 
        Only allows searching of `Base DN`_ and is usually not what you
 
        want.
 

	
 
    ONELEVEL
 
        Searches all entries under `Base DN`_, but not Base DN itself.
 

	
 
    SUBTREE
 
        Searches all entries below `Base DN`_, but not Base DN itself.
 
        When using SUBTREE `LDAP Filter`_ is useful to limit object
 
        location.
 

	
 
.. _Login Attribute:
 

	
 
Login Attribute : required
 
    The LDAP record attribute that will be matched as the USERNAME or
 
    ACCOUNT used to connect to Kallithea.  This will be added to `LDAP
 
    Filter`_ for locating the User object.  If `LDAP Filter`_ is specified as
 
    "LDAPFILTER", `Login Attribute`_ is specified as "uid" and the user has
 
    connected as "jsmith" then the `LDAP Filter`_ will be augmented as below
 
    ::
 

	
 
        (&(LDAPFILTER)(uid=jsmith))
 

	
 
.. _ldap_attr_firstname:
 

	
 
First Name Attribute : required
 
    The LDAP record attribute which represents the user's first name.
 

	
 
.. _ldap_attr_lastname:
 

	
 
Last Name Attribute : required
 
    The LDAP record attribute which represents the user's last name.
 

	
 
.. _ldap_attr_email:
 

	
 
Email Attribute : required
 
    The LDAP record attribute which represents the user's email address.
 

	
 
If all data are entered correctly, and python-ldap_ is properly installed
 
users should be granted access to Kallithea with LDAP accounts.  At this
 
time user information is copied from LDAP into the Kallithea user database.
 
This means that updates of an LDAP user object may not be reflected as a
 
user update in Kallithea.
 

	
 
If You have problems with LDAP access and believe You entered correct
 
information check out the Kallithea logs, any error messages sent from LDAP
 
will be saved there.
 

	
 
Active Directory
 
^^^^^^^^^^^^^^^^
 

	
 
Kallithea can use Microsoft Active Directory for user authentication.  This
 
is done through an LDAP or LDAPS connection to Active Directory.  The
 
following LDAP configuration settings are typical for using Active
 
Directory ::
 

	
 
 Base DN              = OU=SBSUsers,OU=Users,OU=MyBusiness,DC=v3sys,DC=local
 
 Login Attribute      = sAMAccountName
 
 First Name Attribute = givenName
 
 Last Name Attribute  = sn
 
 Email Attribute     = mail
 

	
 
All other LDAP settings will likely be site-specific and should be
 
appropriately configured.
 

	
 

	
 
Authentication by container or reverse-proxy
 
--------------------------------------------
 

	
 
Kallithea supports delegating the authentication
 
of users to its WSGI container, or to a reverse-proxy server through which all
 
clients access the application.
 

	
 
When these authentication methods are enabled in Kallithea, it uses the
 
username that the container/proxy (Apache or Nginx, etc.) provides and doesn't
 
perform the authentication itself. The authorization, however, is still done by
 
Kallithea according to its settings.
 

	
 
When a user logs in for the first time using these authentication methods,
 
a matching user account is created in Kallithea with default permissions. An
 
administrator can then modify it using Kallithea's admin interface.
 

	
 
It's also possible for an administrator to create accounts and configure their
 
permissions before the user logs in for the first time, using the :ref:`create-user` API.
 

	
 
Container-based authentication
 
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 

	
 
In a container-based authentication setup, Kallithea reads the user name from
 
the ``REMOTE_USER`` server variable provided by the WSGI container.
 

	
 
After setting up your container (see :ref:`apache_mod_wsgi`), you'll need
 
to configure it to require authentication on the location configured for
 
Kallithea.
 

	
 
Proxy pass-through authentication
 
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 

	
 
In a proxy pass-through authentication setup, Kallithea reads the user name
 
from the ``X-Forwarded-User`` request header, which should be configured to be
 
sent by the reverse-proxy server.
 

	
 
After setting up your proxy solution (see :ref:`apache_virtual_host_reverse_proxy`,
 
:ref:`apache_subdirectory` or :ref:`nginx_virtual_host`), you'll need to
 
configure the authentication and add the username in a request header named
 
``X-Forwarded-User``.
 

	
 
For example, the following config section for Apache sets a subdirectory in a
 
reverse-proxy setup with basic auth:
 

	
 
.. code-block:: apache
 

	
 
    <Location /someprefix>
 
      ProxyPass http://127.0.0.1:5000/someprefix
 
      ProxyPassReverse http://127.0.0.1:5000/someprefix
 
      SetEnvIf X-Url-Scheme https HTTPS=1
 

	
 
      AuthType Basic
 
      AuthName "Kallithea authentication"
 
      AuthUserFile /srv/kallithea/.htpasswd
 
      Require valid-user
 

	
 
      RequestHeader unset X-Forwarded-User
 

	
 
      RewriteEngine On
 
      RewriteCond %{LA-U:REMOTE_USER} (.+)
 
      RewriteRule .* - [E=RU:%1]
 
      RequestHeader set X-Forwarded-User %{RU}e
 
    </Location>
 

	
 
Setting metadata in container/reverse-proxy
 
"""""""""""""""""""""""""""""""""""""""""""
 
When a new user account is created on the first login, Kallithea has no information about
 
the user's email and full name. So you can set some additional request headers like in the
 
example below. In this example the user is authenticated via Kerberos and an Apache
 
mod_python fixup handler is used to get the user information from a LDAP server. But you
 
could set the request headers however you want.
 

	
 
.. code-block:: apache
 

	
 
    <Location /someprefix>
 
      ProxyPass http://127.0.0.1:5000/someprefix
 
      ProxyPassReverse http://127.0.0.1:5000/someprefix
 
      SetEnvIf X-Url-Scheme https HTTPS=1
 

	
 
      AuthName "Kerberos Login"
 
      AuthType Kerberos
 
      Krb5Keytab /etc/apache2/http.keytab
 
      KrbMethodK5Passwd off
 
      KrbVerifyKDC on
 
      Require valid-user
 

	
 
      PythonFixupHandler ldapmetadata
 

	
 
      RequestHeader set X_REMOTE_USER %{X_REMOTE_USER}e
 
      RequestHeader set X_REMOTE_EMAIL %{X_REMOTE_EMAIL}e
 
      RequestHeader set X_REMOTE_FIRSTNAME %{X_REMOTE_FIRSTNAME}e
 
      RequestHeader set X_REMOTE_LASTNAME %{X_REMOTE_LASTNAME}e
 
    </Location>
 

	
 
.. code-block:: python
 

	
 
    from mod_python import apache
 
    import ldap
 

	
 
    LDAP_SERVER = "ldaps://server.mydomain.com:636"
 
    LDAP_USER = ""
 
    LDAP_PASS = ""
 
    LDAP_ROOT = "dc=mydomain,dc=com"
 
    LDAP_FILTER = "sAMAccountName=%s"
 
    LDAP_ATTR_LIST = ['sAMAccountName','givenname','sn','mail']
 

	
 
    def fixuphandler(req):
 
        if req.user is None:
 
            # no user to search for
 
            return apache.OK
 
        else:
 
            try:
 
                if('\\' in req.user):
 
                    username = req.user.split('\\')[1]
 
                elif('@' in req.user):
 
                    username = req.user.split('@')[0]
 
                else:
 
                    username = req.user
 
                l = ldap.initialize(LDAP_SERVER)
 
                l.simple_bind_s(LDAP_USER, LDAP_PASS)
 
                r = l.search_s(LDAP_ROOT, ldap.SCOPE_SUBTREE, LDAP_FILTER % username, attrlist=LDAP_ATTR_LIST)
 

	
 
                req.subprocess_env['X_REMOTE_USER'] = username
 
                req.subprocess_env['X_REMOTE_EMAIL'] = r[0][1]['mail'][0].lower()
 
                req.subprocess_env['X_REMOTE_FIRSTNAME'] = "%s" % r[0][1]['givenname'][0]
 
                req.subprocess_env['X_REMOTE_LASTNAME'] = "%s" % r[0][1]['sn'][0]
 
            except Exception, e:
 
                apache.log_error("error getting data from ldap %s" % str(e), apache.APLOG_ERR)
 

	
 
            return apache.OK
 

	
 
.. note::
 
   If you enable proxy pass-through authentication, make sure your server is
 
   only accessible through the proxy. Otherwise, any client would be able to
 
   forge the authentication header and could effectively become authenticated
 
   using any account of their liking.
 

	
 

	
 
.. _python-ldap: http://www.python-ldap.org/
docs/overview.rst
Show inline comments
 
.. _overview:
 

	
 
=====================
 
Installation overview
 
=====================
 

	
 
Some overview and some details that can help understanding the options when
 
installing Kallithea.
 

	
 

	
 
Python environment
 
------------------
 

	
 
**Kallithea** is written entirely in Python_ and requires Python version
 
2.6 or higher. Python 3.x is currently not supported.
 

	
 
Given a Python installation, there are different ways of providing the
 
environment for running Python applications. Each of them pretty much
 
corresponds to a ``site-packages`` directory somewhere where packages can be
 
installed.
 

	
 
Kallithea itself can be run from source or be installed, but even when running
 
from source, there are some dependencies that must be installed in the Python
 
environment used for running Kallithea.
 

	
 
- Packages *could* be installed in Python's ``site-packages`` directory ... but
 
  that would require running pip_ as root and it would be hard to uninstall or
 
  upgrade and is probably not a good idea unless using a package manager.
 

	
 
- Packages could also be installed in ``~/.local`` ... but that is probably
 
  only a good idea if using a dedicated user per application or instance.
 

	
 
- Finally, it can be installed in a virtualenv_. That is a very lightweight
 
  "container" where each Kallithea instance can get its own dedicated and
 
  self-contained virtual environment.
 

	
 
We recommend using virtualenv for installing Kallithea.
 

	
 

	
 
Installation methods
 
--------------------
 

	
 
Kallithea must be installed on a server. Kallithea is installed in a Python
 
environment so it can use packages that are installed there and make itself
 
available for other packages.
 

	
 
Two different cases will pretty much cover the options for how it can be
 
installed.
 

	
 
- The Kallithea source repository can be cloned and used -- it is kept stable and
 
  can be used in production. The Kallithea maintainers use the development
 
  branch in production. The advantage of installation from source and regularly
 
  updating it is that you take advantage of the most recent improvements. Using
 
  it directly from a DVCS also means that it is easy to track local customizations.
 

	
 
  Running ``pip install -e .`` in the source will use pip to install the
 
  necessary dependencies in the Python environment and create a
 
  ``.../site-packages/Kallithea.egg-link`` file there that points at the Kallithea
 
  source.
 

	
 
- Kallithea can also be installed from ready-made packages using a package manager.
 
  The official released versions are available on PyPI_ and can be downloaded and
 
  installed with all dependencies using ``pip install kallithea``.
 

	
 
  With this method, Kallithea is installed in the Python environment as any
 
  other package, usually as a ``.../site-packages/Kallithea-X-py2.7.egg/``
 
  directory with Python files and everything else that is needed.
 

	
 
  (``pip install kallithea`` from a source tree will do pretty much the same
 
  but build the Kallithea package itself locally instead of downloading it.)
 

	
 
.. note:: Kallithea includes front-end code that needs to be processed first.
 
The tool npm_ is used to download external dependencies and orchestrate the
 
processing. The ``npm`` binary must thus be available.
 
.. note::
 
   Kallithea includes front-end code that needs to be processed first.
 
   The tool npm_ is used to download external dependencies and orchestrate the
 
   processing. The ``npm`` binary must thus be available.
 

	
 

	
 
Web server
 
----------
 

	
 
Kallithea is (primarily) a WSGI_ application that must be run from a web
 
server that serves WSGI applications over HTTP.
 

	
 
Kallithea itself is not serving HTTP (or HTTPS); that is the web server's
 
responsibility. Kallithea does however need to know its own user facing URL
 
(protocol, address, port and path) for each HTTP request. Kallithea will
 
usually use its own HTML/cookie based authentication but can also be configured
 
to use web server authentication.
 

	
 
There are several web server options:
 

	
 
- Kallithea uses the Gearbox_ tool as command line interface. Gearbox provides
 
  ``gearbox serve`` as a convenient way to launch a Python WSGI / web server
 
  from the command line. That is perfect for development and evaluation.
 
  Actual use in production might have different requirements and need extra
 
  work to make it manageable as a scalable system service.
 

	
 
  Gearbox comes with its own built-in web server but Kallithea defaults to use
 
  Waitress_. Gunicorn_ is also an option. These web servers have different
 
  limited feature sets.
 

	
 
  The web server used by ``gearbox`` is configured in the ``.ini`` file passed
 
  to it. The entry point for the WSGI application is configured
 
  in ``setup.py`` as ``kallithea.config.middleware:make_app``.
 

	
 
- `Apache httpd`_ can serve WSGI applications directly using mod_wsgi_ and a
 
  simple Python file with the necessary configuration. This is a good option if
 
  Apache is an option.
 

	
 
- uWSGI_ is also a full web server with built-in WSGI module.
 

	
 
- IIS_ can also server WSGI applications directly using isapi-wsgi_.
 

	
 
- A `reverse HTTP proxy <https://en.wikipedia.org/wiki/Reverse_proxy>`_
 
  can be put in front of another web server which has WSGI support.
 
  Such a layered setup can be complex but might in some cases be the right
 
  option, for example to standardize on one internet-facing web server, to add
 
  encryption or special authentication or for other security reasons, to
 
  provide caching of static files, or to provide load balancing or fail-over.
 
  Nginx_, Varnish_ and HAProxy_ are often used for this purpose, often in front
 
  of a ``gearbox serve`` that somehow is wrapped as a service.
 

	
 
The best option depends on what you are familiar with and the requirements for
 
performance and stability. Also, keep in mind that Kallithea mainly is serving
 
dynamically generated pages from a relatively slow Python process. Kallithea is
 
also often used inside organizations with a limited amount of users and thus no
 
continuous hammering from the internet.
 

	
 

	
 
.. _Python: http://www.python.org/
 
.. _Gunicorn: http://gunicorn.org/
 
.. _Waitress: http://waitress.readthedocs.org/en/latest/
 
.. _virtualenv: http://pypi.python.org/pypi/virtualenv
 
.. _Gearbox: http://turbogears.readthedocs.io/en/latest/turbogears/gearbox.html
 
.. _PyPI: https://pypi.python.org/pypi
 
.. _Apache httpd: http://httpd.apache.org/
 
.. _mod_wsgi: https://code.google.com/p/modwsgi/
 
.. _isapi-wsgi: https://github.com/hexdump42/isapi-wsgi
 
.. _uWSGI: https://uwsgi-docs.readthedocs.org/en/latest/
 
.. _nginx: http://nginx.org/en/
 
.. _iis: http://en.wikipedia.org/wiki/Internet_Information_Services
 
.. _pip: http://en.wikipedia.org/wiki/Pip_%28package_manager%29
 
.. _WSGI: http://en.wikipedia.org/wiki/Web_Server_Gateway_Interface
 
.. _HAProxy: http://www.haproxy.org/
 
.. _Varnish: https://www.varnish-cache.org/
 
.. _npm: https://www.npmjs.com/
0 comments (0 inline, 0 general)