taler-docs

Documentation for GNU Taler components, APIs and protocols
Log | Files | Refs | README | LICENSE

taler-challenger-manual.rst (18949B)


      1 ..
      2   This file is part of GNU TALER.
      3 
      4   Copyright (C) 2023, 2024 Taler Systems SA
      5 
      6   TALER is free software; you can redistribute it and/or modify it under the
      7   terms of the GNU Affero General Public License as published by the Free Software
      8   Foundation; either version 2.1, or (at your option) any later version.
      9 
     10   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
     11   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     12   A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more details.
     13 
     14   You should have received a copy of the GNU Affero General Public License along with
     15   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     16 
     17   @author Christian Grothoff
     18   @author Florian Dold
     19 
     20 Challenger Operator Manual
     21 ##########################
     22 
     23 .. contents:: Table of Contents
     24   :depth: 2
     25   :local:
     26 
     27 
     28 Introduction
     29 ============
     30 
     31 About Challenger
     32 ----------------
     33 
     34 Challenger is an OAuth 2.0-compatible address validation service.
     35 By redirecting a user-agent to a Challenger service a client can
     36 have Challenger validate that the user is able to receive messages
     37 at a particular address and obtain that address via the ``/info``
     38 endpoint.
     39 
     40 
     41 About this manual
     42 -----------------
     43 
     44 This manual targets system administrators who want to install,
     45 operate or integrate a challenger service.  To report issues
     46 or learn about known limitations, please check our
     47 `bug tracker <https://bugs.taler.net>`__.
     48 
     49 
     50 Architecture overview
     51 ---------------------
     52 
     53 The following picture gives an overview of the Challenger
     54 architecture and the main interactions:
     55 
     56 .. image:: images/challenger.png
     57 
     58 Here, the *resource owner* is a user that is in control
     59 of some *address* at a messaging service. This could be
     60 an e-mail account, a mobile phone number (for SMS), or
     61 a physical mail address (using the post office as the
     62 messaging service).
     63 
     64 The *resource owner* makes some request that requires
     65 some *client* to be in need of address validation. The
     66 *client* is registered with the Challenger OAuth 2.0
     67 service and first authorizes an address validation to
     68 be initiated. The client then redirects the resource
     69 owner to the Challenger service. In step (2), the resource
     70 owner submits the address that they claim to own.
     71 
     72 The Challenger service then creates a TAN code and
     73 submits it to the given address via a configurable
     74 *helper script* that is specific to the type of address
     75 being validated. When the resource owner submits the
     76 correct TAN code in step (6), they are given a token
     77 that they can provide to the client. Using this token
     78 the client can then finally obtain the now validated
     79 address in step (8).
     80 
     81 Address data, TAN codes and meta-data such as the number
     82 of failed attempts to submit a TAN code are recorded
     83 in a Postgres database by the Challenger service.
     84 
     85 .. _ChallengerInstallation:
     86 
     87 Installation
     88 ============
     89 
     90 In this guide's shell-session fragments, the command prompt shows two pieces
     91 of information:
     92 
     93 * Who is performing the command
     94   (``$user`` vs ``root``, and ending character ``$`` vs ``#``).
     95 
     96 
     97 Installing from source
     98 ----------------------
     99 
    100 The following instructions will show how to install libgnunetutil and
    101 the core GNU Taler libraries from source.
    102 
    103 The package sources can be find in our
    104 `download directory <http://ftpmirror.gnu.org/taler/>`__.
    105 
    106 GNU Taler components version numbers follow the ``MAJOR.MINOR.MICRO`` format.
    107 The general rule for compatibility is that ``MAJOR`` and ``MINOR`` must match.
    108 Exceptions to this general rule are documented in the release notes.
    109 For example, Challenger 1.3.0 should be compatible with Taler exchange 1.4.x
    110 as the MAJOR version matches.  A MAJOR version of 0 indicates experimental
    111 development, and you are expected to always run all of the *latest* releases
    112 together (no compatibility guarantees).
    113 
    114 First, the following packages need to be installed before we can compile the
    115 backend:
    116 
    117 .. include:: frags/list-of-dependencies.rst
    118 
    119 .. include:: frags/installing-gnunet.rst
    120 
    121 .. include:: frags/install-before-check.rst
    122 
    123 There is no need to actually run a GNUnet peer or a Taler exchange to use
    124 Challenger -- all Challenger needs from GNUnet and Taler are a number of
    125 headers and libraries!
    126 
    127 .. include:: frags/installing-taler-exchange.rst
    128 
    129 
    130 .. include:: frags/installing-challenger.rst
    131 
    132 .. include:: frags/install-before-check.rst
    133 
    134 
    135 
    136 Installing the Challenger binary packages on Debian
    137 ---------------------------------------------------
    138 
    139 .. include:: frags/installing-debian.rst
    140 
    141 To install the Challenger, you can now simply run:
    142 
    143 .. code-block:: shell-session
    144 
    145    # apt install challenger
    146 
    147 Note that the package does not perform any configuration work except for
    148 setting up the various users and the systemd service scripts. You still must
    149 configure at least the database, HTTP reverse proxy (typically with TLS
    150 certificates) and the terms of service.
    151 
    152 Installing the GNU Taler binary packages on Trisquel
    153 ----------------------------------------------------
    154 
    155 .. include:: frags/installing-trisquel.rst
    156 
    157 Installing the GNU Taler binary packages on Ubuntu
    158 --------------------------------------------------
    159 
    160 .. include:: frags/installing-ubuntu.rst
    161 
    162 To install the Taler exchange, you can now simply run:
    163 
    164 .. code-block:: shell-session
    165 
    166    # apt install challenger
    167 
    168 Note that the package does not perform any configuration work except for
    169 setting up the various users and the systemd service scripts. You still must
    170 configure at least the database, HTTP reverse proxy (typically with TLS
    171 certificates), and the terms of service.
    172 
    173 
    174 Services, users, groups and file system hierarchy
    175 -------------------------------------------------
    176 
    177 The *challenger* package will use several system users
    178 to compartmentalize different parts of the system:
    179 
    180 * ``challenger-httpd``: runs the HTTP daemon with the core business logic.
    181 * ``postgres``: runs the PostgreSQL database (from *postgresql* package).
    182 * ``www-data``: runs the frontend HTTPS service with the TLS keys (from *nginx* package).
    183 
    184 The package will deploy a systemd service files in
    185 ``/usr/lib/systemd/system/`` for Challenger:
    186 
    187 * ``challenger-httpd.service``: the Challenger logic with the public REST API.
    188 
    189 
    190 Configuration Fundamentals
    191 ==========================
    192 
    193 This chapter provides fundamental details about the exchange configuration.
    194 
    195 The configuration for all Taler components uses a single configuration file
    196 as entry point: ``/etc/challenger/challenger.conf``.
    197 
    198 System defaults are automatically loaded from files in
    199 ``/usr/share/challenger/config.d``.  These default files should never be modified.
    200 
    201 The default configuration ``challenger.conf`` configuration file also includes all
    202 configuration files in ``/etc/challenger/conf.d``.
    203 
    204 To view the entire configuration annotated with the source of each configuration option, you
    205 can use the ``challenger-config`` helper:
    206 
    207 
    208 .. code-block:: shell-session
    209 
    210   [root@exchange-online]# challenger-config --diagnostics
    211   < ... annotated, full configuration ... >
    212 
    213 .. warning::
    214 
    215   While ``challenger-config`` also supports rewriting configuration files, we strongly
    216   recommend to edit configuration files manually, as ``challenger-config`` does not
    217   preserve comments and, by default, rewrites ``/etc/challenger/challenger.conf``.
    218 
    219 .. include:: frags/configuration-format.rst
    220 
    221 
    222 Fundamental Setup: Address validation
    223 -------------------------------------
    224 
    225 Each challenger service is designed to validate one type of address. Possible
    226 address types include:
    227 
    228 * phone numbers (via SMS)
    229 * e-mail addresses (via SMTP)
    230 * mail addresses (via postal service)
    231 
    232 In principle, additional types of addresses can easily be added by extending
    233 the respective HTML and programs to send challenges to the new address type.
    234 
    235 To make different types of address validations possible, the Challenger
    236 configuration contains two configuration options.
    237 
    238 (1) The ``ADDRESS_TYPE`` configuration option informs Challenger about the
    239     type of address it is expected to validate. It is returned as part of
    240     the OAuth 2.0 ``/info`` endpoint to the client, and is typically also
    241     used when deciding how to render the HTML form for address entry that is
    242     shown to the user.
    243 
    244 (2) The ``AUTH_COMMAND`` configuration option specifies which command
    245     Challenger should run to send a challenge to an address. The actual
    246     address is given to this subcommand as the first argument (``$1``),
    247     while the text with the challenge is passed to standard input.
    248     The subcommand should terminate with a status code of 0 on success.
    249 
    250 .. code-block:: ini
    251   :caption: /etc/challenger/challenger.conf
    252 
    253    [challenger]
    254    ADDRESS_TYPE = email
    255    AUTH_COMMAND = challenger-send-email.sh
    256    # ... rest of file ...
    257 
    258 Challenger comes with ``AUTH_COMMAND`` shell scripts for sending e-mail, SMS
    259 and postal mail. Note that for SMS and postal mail the Challenger scripts uses
    260 third party services to actually send the SMS or print and mail the postal
    261 mail. These third parties naturally charge money for their services, and thus
    262 the Challenger administrator will need to add the respective credentials to
    263 the SMS and postal mail scripts before they can function.  In any case, these
    264 scripts should be primarily seen as *examples* on how to write authentication
    265 commands.
    266 
    267 .. note::
    268 
    269   We strongly welcome contributions for additional scripts with alternative
    270   providers or for new types of addresses.
    271 
    272 
    273 Legal conditions for using the service
    274 --------------------------------------
    275 
    276 .. include:: frags/legal.rst
    277 
    278 Database Configuration
    279 ----------------------
    280 
    281 The access credentials for the Challenger database are configured in
    282 ``/etc/challenger/challenger.conf``.  Currently, only PostgreSQL is
    283 supported as a database backend.
    284 
    285 .. note::
    286 
    287    The **challenger-dbconfig** tool can be used to automate the database
    288    setup. When using the Debian/Ubuntu packages, the user should already have
    289    been created, so you can just run the tool without any arguments and should
    290    have a working database configuration.  Subsequently, you should still run
    291    **taler-challenger-dbinit** as the ``challenger-httpd`` user to
    292    initialize the database schema.
    293 
    294 
    295 To create a database for Challenger on the local system, run:
    296 
    297 .. code-block:: shell-session
    298 
    299   [root@exchange-online]# su - postgres
    300   [postgres@exchange-online]# createuser challenger-httpd
    301   [postgres@exchange-online]# createdb -O challenger-httpd challenger
    302   [postgres@exchange-online]# exit
    303 
    304 This will create a ``challenger`` database owned by the ``taler-httpd`` user.
    305 We will use that user later to perform database maintenance operations.
    306 
    307 Assuming the above database setup, the database credentials to configure
    308 in the configuration file would simply be:
    309 
    310 .. code-block:: ini
    311   :caption: /etc/challenger/challenger.conf
    312 
    313   [challenger]
    314   DB = postgres
    315 
    316   [challenger-postgres]
    317   CONFIG = postgres:///challenger
    318 
    319 If the database is run on a different host, please follow the instructions
    320 from the PostgreSQL manual for configuring remote access.
    321 
    322 After configuring the database credentials, the Challenger database needs
    323 to be initialized with the following command:
    324 
    325 .. code-block:: shell-session
    326 
    327   [root@exchange-online]# sudo -u challenger-httpd challenger-dbinit
    328 
    329 .. note::
    330 
    331   To run this command, the user must have ``CREATE TABLE``, ``CREATE
    332   INDEX``, ``ALTER TABLE`` and (in the future possibly even) ``DROP TABLE``
    333   permissions.  Those permissions are only required for this step (which may
    334   have to be repeated when upgrading a deployment).  Afterwards, during
    335   normal operation, permissions to ``CREATE`` or ``ALTER`` tables are not
    336   required by Challenger and thus should not be granted.  For more
    337   information, see :doc:`manpages/challenger-dbinit.1`.
    338 
    339 
    340 Deployment
    341 ==========
    342 
    343 This chapter describes how to deploy Challenger once the basic installation
    344 and configuration are completed.
    345 
    346 .. _ChallengerServing:
    347 
    348 Serving
    349 -------
    350 
    351 The Challenger can serve HTTP over both TCP and UNIX domain socket.
    352 
    353 The following options are to be configured in the section ``[challenger]``:
    354 
    355 -  ``SERVE``: Must be set to ``tcp`` to serve HTTP over TCP, or ``unix`` to serve
    356    HTTP over a UNIX domain socket.
    357 
    358 -  ``PORT``: Set to the TCP port to listen on if ``SERVE`` is ``tcp``.
    359 
    360 -  ``UNIXPATH``: Set to the UNIX domain socket path to listen on if ``SERVE`` is
    361    ``unix``.
    362 
    363 - ``UNIXPATH_MODE``: Number giving the mode with the access permission mask
    364    for the ``UNIXPATH`` (i.e. 660 = ``rw-rw---``). Make sure to set it in such
    365    a way that your reverse proxy has permissions to access the UNIX domain
    366    socket.  The default (660) assumes that the reverse proxy is a member of
    367    the group under which the exchange HTTP server is running.
    368 
    369 .. _ChallengerReverseProxy:
    370 
    371 Reverse Proxy Setup
    372 -------------------
    373 
    374 By default, the ``challenger-httpd`` service listens for HTTP connections
    375 on a UNIX domain socket.  To make the service publicly available, a reverse
    376 proxy such as nginx should be used.  You must configure the reverse proxy
    377 to use TLS as this is required by OAuth 2.0.
    378 
    379 The ``challenger`` package ships with a sample configuration that can be
    380 enabled in nginx:
    381 
    382 .. code-block:: shell-session
    383 
    384   [root@exchange-online]# vim /etc/nginx/sites-available/challenger
    385   < ... customize configuration ... >
    386   [root@exchange-online]# ln -s /etc/nginx/sites-available/challenger \
    387                                 /etc/nginx/sites-enabled/challenger
    388   [root@exchange-online]# systemctl reload nginx
    389 
    390 
    391 Launching Challenger
    392 --------------------
    393 
    394 A running exchange requires starting the following processes:
    395 
    396 -   ``challenger-httpd`` (needs database access)
    397 
    398 The processes should be started via a hypervisor like
    399 ``systemd`` or ``gnunet-arm`` that automatically re-starts them should they
    400 have terminated unexpectedly.  Furthermore, the hypervisor
    401 *should* periodically re-start the service (say once per hour)
    402 to limit Postgres database memory utilization.
    403 
    404 .. note::
    405 
    406   The ``challenger-httpd`` does not ship with HTTPS enabled by default.
    407   It must thus be run behind an HTTPS reverse proxy that performs
    408   TLS termination on the same system.  Thus, it would typically be configured
    409   to listen on a UNIX domain socket.
    410 
    411 Given proper packaging, all of the above are realized via a simple systemd
    412 target. This enables Challenger to be properly started using a simple command:
    413 
    414 .. code-block:: shell-session
    415 
    416   # systemctl start challenger-httpd.service
    417 
    418 
    419 Authorizing clients
    420 -------------------
    421 
    422 Before clients can use Challenger, they must be explicitly configured. Each
    423 client is identified via its OAuth 2.0 REDIRECT URI.  Thus, a client must have
    424 exactly one REDIRECT URI. Challenger also does not allow multiple clients sharing the same REDIRECT URI.
    425 
    426 .. note::
    427 
    428   The OAuth 2.0 specification allows for a client to register
    429   zero or multiple REDIRECT URIs. However, zero is insecure
    430   as it creates an open redirector, and multiple REDIRECT URIs
    431   can trivially be implemented with Challenger by adding more
    432   clients.
    433 
    434 You can add or remove clients at any time; the Challenger service does not
    435 need to be running, but if it is you can still add or remove clients without
    436 restarting the service.  To add (or remove) a client, you must use the
    437 ``challenger-admin`` command:
    438 
    439 .. code-block:: shell-session
    440 
    441   # sudo -u challenger-httpd challenger-admin --add=$CLIENT_SECRET $CLIENT_REDIRECT_URI
    442 
    443 Here, ``$CLIENT_SECRET`` is the client secret of OAuth 2.0 which will be used in
    444 various parts of the protocol to authenticate the client. It must begin with the "secret-token:" prefix of RFC 8959.  The
    445 ``$CLIENT_REDIRECT_URI`` is the REDIRECT URI where the user-agent will be redirected to upon
    446 completion of the process.  The ``challenger-admin`` command will
    447 then output the *CLIENT_ID*, which will be a unique positive number.
    448 The first time you run the command, you will thus likely see:
    449 ``Client added. Client ID is: 1``.  This CLIENT_ID, the ``$CLIENT_SECRET``
    450 and the ``$CLIENT_REDIRECT_URI`` will form the foundation for the OAuth 2.0
    451 configuration.
    452 
    453 
    454 OAuth 2.0 integration
    455 ---------------------
    456 
    457 When integrating Challenger into an OAuth 2.0 process, you need to provide the
    458 three options from the previous section, but also the authorization, token and
    459 info endpoints.  For Challenger, these are ``/authorize``, ``/token`` and
    460 ``/info``.  However, the ``/authorize`` endpoint is special, as it is actually
    461 ``/authorize/$NONCE`` where ``$NONCE`` is a nonce that must be first requested
    462 by the client using the ``/setup/$CLIENT_ID`` endpoint!
    463 
    464 .. note::
    465 
    466   This extra step prevents user-agents from (ab)using the Challenger service
    467   to send challenges to addresses even when there is no authorized client
    468   that desires address validation. This is an important feature as address
    469   validation could be expensive.
    470 
    471 Thus, to generate the authorization URL, a client must first POST to
    472 ``/setup/$CLIENT_ID`` using their client secret in an ``Authorization: Bearer
    473 $CLIENT_SECRET`` HTTP header to obtain a fresh ``$NONCE``.  It is (optionally)
    474 possible to pass an address in the body of the ``/setup`` POST request. In
    475 this case, Challenger will pre-populate the address of the KYC form with the
    476 given body. Here, the format of the body is *address type*-specific.
    477 
    478 .. note::
    479 
    480   By passing a flag ``read_only: true`` editing of the address in the SPA can
    481   be disabled. However, the backend currently does not enforce this
    482   (see #9349).
    483 
    484 In the GNU Taler exchange configuration, this is indicated by appending
    485 ``#setup`` to the ``KYC_OAUTH2_AUTHORIZE_URL`` endpoint.  Be careful to quote
    486 the URL, as ``#`` is otherwise interpreted as the beginning of a comment by
    487 the configuration file syntax:
    488 
    489 .. code-block:: ini
    490   :caption: /etc/taler-exchange/conf.d/exchange-oauth2.conf
    491 
    492   [kyc-provider-example-oauth2]
    493   LOGIC = oauth2
    494   # (generic options omitted)
    495   KYC_OAUTH2_AUTHORIZE_URL = "https://challenger.example.com/authorize#setup"
    496   KYC_OAUTH2_TOKEN_URL = "https://challenger.example.com/token"
    497   KYC_OAUTH2_INFO_URL = "https://challenger.example.com/info"
    498   KYC_OAUTH2_CLIENT_ID = 1
    499   # Make sure to include the RFC 8959 prefix in "$SECRET"
    500   KYC_OAUTH2_CLIENT_SECRET = "$SECRET"
    501 
    502 
    503 
    504 Database management
    505 -------------------
    506 
    507 .. note::
    508 
    509   We advise to make good backups before experimenting with
    510   the database.
    511 
    512 To update the Challenger database after upgrading to a newer
    513 version of Challenger, you should simply re-run ``challenger-dbinit``.
    514 Without further options, this command is expected to preserve
    515 all data and only migrate the existing database to the latest
    516 schema:
    517 
    518 .. code-block:: console
    519 
    520    $ challenger-dbinit
    521 
    522 To delete stale data from the Challenger database, you can use
    523 garbage collection:
    524 
    525 .. code-block:: console
    526 
    527    $ challenger-dbinit --garbagecollect
    528 
    529 
    530 The Challenger database can be re-initialized using:
    531 
    532 .. code-block:: console
    533 
    534    $ challenger-dbinit --reset
    535 
    536 However, running this command will result in all data in the database
    537 being lost.