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.