diff options
Diffstat (limited to 'taler-exchange-manual.rst')
-rw-r--r-- | taler-exchange-manual.rst | 935 |
1 files changed, 921 insertions, 14 deletions
diff --git a/taler-exchange-manual.rst b/taler-exchange-manual.rst index 1604d49f..3b06fe7e 100644 --- a/taler-exchange-manual.rst +++ b/taler-exchange-manual.rst @@ -1,7 +1,7 @@ .. This file is part of GNU TALER. - Copyright (C) 2014-2020 Taler Systems SA + Copyright (C) 2014-2023 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software @@ -15,6 +15,7 @@ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> @author Christian Grothoff + @author Florian Dold GNU Taler Exchange Operator Manual ################################## @@ -46,7 +47,7 @@ offering regular currencies today. About this manual ----------------- -This tutorial targets system administrators who want to install and +This manual targets system administrators who want to install and operate a GNU Taler exchange. Organizational prerequisites @@ -289,6 +290,35 @@ Before installing a Taler exchange, please make sure that your system does not have swap space enabled. Swap space is a security risk that Taler does not try to mitigate against. +We recommend the setup of offline signing keys to be done on a second machine that +does not have Internet access. + +In this guide's shell-session fragments, the command prompt shows two pieces +of information: + +* Who is performing the command + (``$user`` vs ``root``, and ending character ``$`` vs ``#``). +* Host where the command is supposed to be executed + (``exchange-offline`` vs ``exchange-online``). + It is possible to do the entire setup on one machine, + but we do not recommend this for security reasons. + +Before you start +---------------- + +To deploy this with a real bank, you need: + + * IBAN of the bank account to use + * BIC of the bank + * EBICS host, user and partner IDs + +Information to write down during the installation: + + * LibEuFin Nexus superuser password + * Taler facade base URL + * exchange Nexus username and password + + Installing from source ---------------------- @@ -333,9 +363,9 @@ Installing the GNU Taler binary packages on Debian To install the Taler exchange, you can now simply run: -.. code-block:: console +.. code-block:: shell-session - # apt install taler-exchange + [root@exchange-online]# apt install taler-exchange Note that the package does not perform any configuration work except for setting up the various users and the systemd service scripts. You still must @@ -343,8 +373,12 @@ configure at least the database, HTTP reverse proxy (typically with TLS certificates), denomination and fee structure, bank account, auditor(s), offline signing and the terms of service. -Sample configuration files for the HTTP reverse proxy can be found in -``/etc/taler-exchange/``. +On the offline system, you should run at least: + +.. code-block:: shell-session + + [root@exchange-offline]# apt install taler-exchange-offline + Installing the GNU Taler binary packages on Trisquel ---------------------------------------------------- @@ -358,9 +392,9 @@ Installing the GNU Taler binary packages on Ubuntu To install the Taler exchange, you can now simply run: -.. code-block:: console +.. code-block:: shell-session - # apt install taler-exchange + [root@exchange-online]# apt install taler-exchange Note that the package does not perform any configuration work except for setting up the various users and the systemd service scripts. You still must @@ -368,16 +402,873 @@ configure at least the database, HTTP reverse proxy (typically with TLS certificates), denomination and fee structure, bank account, auditor(s), offline signing and the terms of service. -Sample configuration files for the HTTP reverse proxy can be found in -``/etc/taler-exchange/``. +On the offline system, you should run at least: +.. code-block:: shell-session -Configuration + [root@exchange-offline]# apt install taler-exchange-offline + + +Services, users, groups and file system hierarchy +------------------------------------------------- + +The *taler-exchange* package will create several system users +to compartmentalize different parts of the system: + +* ``taler-exchange-httpd``: runs the HTTP daemon with the core business logic. +* ``taler-exchange-secmod-rsa``: manages the RSA private online signing keys. +* ``taler-exchange-secmod-eddsa``: manages the EdDSA private online signing keys. +* ``taler-exchange-closer``: closes idle reserves by triggering wire transfers that refund the originator. +* ``taler-exchange-aggregator``: aggregates deposits into larger wire transfer requests. +* ``taler-exchange-wire``: performs wire transfers with the bank (via LibEuFin/Nexus). +* ``postgres``: runs the PostgreSQL database (from *postgresql* package). +* ``www-data``: runs the frontend HTTPS service with the TLS keys (from *nginx* package). + +.. note:: + + The *taler-merchant* package additionally creates a ``taler-merchant-httpd`` user + to run the HTTP daemon with the merchant business logic. + + +The exchange setup uses the following system groups: + +* ``taler-exchange-db``: group for all Taler users with direct database access, specifically taler-exchange-httpd, taler-exchange-wire, taler-exchange-closer and taler-exchange-aggregator. +* ``taler-exchange-secmod``: group for processes with access to online signing keys; this group must have three users: taler-exchange-secmod-rsa, taler-exchange-secmod-eddsa and taler-exchange-httpd. +* ``taler-exchange-offline``: group for the access to the offline private key (only used on the offline host and not used on the online system). + + + +The package will deploy systemd service files in +``/usr/lib/systemd/system/`` for the various components: + +* ``taler-exchange-aggregator.service``: service that schedules wire transfers + which combine multiple deposits to the same merchant. +* ``taler-exchange-closer.service``: service that watches for reserves that have been abandoned and schedules wire transfers to send the money back to the originator. +* ``taler-exchange-httpd.service``: main Taler exchange logic with the public REST API. +* ``taler-exchange-httpd.socket``: systemd socket activation for the Taler exchange HTTP daemon. +* ``taler-exchange-secmod-eddsa.service``: software security module for making EdDSA signatures. +* ``taler-exchange-secmod-rsa.service``: software security module for making RSA signatures. +* ``taler-exchange-secmod-cs.service``: software security module for making CS signatures. +* ``taler-exchange-transfer.service``: service that triggers outgoing wire transfers (pays merchants). +* ``taler-exchange-wirewatch.service``: service that watches for incoming wire transfers (first step of withdraw). +* ``taler-exchange.target``: Main target for the Taler exchange to be operational. + + +The deployment creates the following key locations in the system: + +* ``/etc/taler/``: configuration files. +* ``/run/taler/``: contains the UNIX domain sockets for inter-process communication (IPC). +* ``/var/lib/taler/``: serves as the $HOME for all Taler users and contains sub-directories + with the private keys; which keys are stored here depends on the host: + + * online system: exchange-secmod-eddsa and exchange-secmod-rsa keys. + * offline system: exchange-offline keys. + + +Exchange Database Setup +======================= + +The access credentials for the exchange's database are configured in +``/etc/taler/secrets/exchange-db.secret.conf``. Currently, only PostgreSQL is +supported as a database backend. + +The following users must have access to the exchange database: + +* taler-exchange-httpd +* taler-exchange-wire +* taler-exchange-aggregator +* taler-exchange-closer + +These users are all in the taler-exchange-db group, and the +``exchange-db.secret.conf`` should already be only readable by users in +this group. + +To create a database for the Taler exchange on the local system, run: + +.. code-block:: shell-session + + [root@exchange-online]# su - postgres + [postgres@exchange-online]# createuser taler-exchange-httpd + [postgres@exchange-online]# createuser taler-exchange-wire + [postgres@exchange-online]# createuser taler-exchange-aggregator + [postgres@exchange-online]# createuser taler-exchange-closer + [postgres@exchange-online]# createdb -O taler-exchange-httpd taler-exchange + [postgres@exchange-online]# exit + +This will create a ``taler-exchange`` database owned by the +``taler-exchange-httpd`` user. We will use that user later to perform +database maintenance operations. + + +Assuming the above database setup, the database credentials to configure +in the configuration file would simply be: + +.. code-block:: ini + :caption: /etc/taler/secrets/exchange-db.secret.conf + + [exchangedb-postgres] + CONFIG=postgres:///taler-exchange + + +If the database is run on a different host, please follow the instructions +from the PostgreSQL manual for configuring remote access. + +After configuring the database credentials, the exchange database needs +to be initialized with the following command: + +.. code-block:: shell-session + + [root@exchange-online]# sudo -u taler-exchange-httpd taler-exchange-dbinit + +Finally we need to grant the other accounts limited access: + +.. code-block:: shell-session + + [root@exchange-online]# sudo -u taler-exchange-httpd bash + [taler-exchange-httpd@exchange-online]# echo 'GRANT SELECT,INSERT,UPDATE ON ALL TABLES IN SCHEMA public TO "taler-exchange-aggregator";' \ + | psql taler-exchange + [taler-exchange-httpd@exchange-online]# echo 'GRANT SELECT,INSERT,UPDATE ON ALL TABLES IN SCHEMA public TO "taler-exchange-closer";' \ + | psql taler-exchange + [taler-exchange-httpd@exchange-online]# echo 'GRANT SELECT,INSERT,UPDATE ON ALL TABLES IN SCHEMA public TO "taler-exchange-wire";' \ + | psql taler-exchange + [taler-exchange-httpd@exchange-online]# echo 'GRANT USAGE ON ALL SEQUENCES IN SCHEMA public TO "taler-exchange-aggregator";' \ + | psql taler-exchange + [taler-exchange-httpd@exchange-online]# echo 'GRANT USAGE ON ALL SEQUENCES IN SCHEMA public TO "taler-exchange-closer";' \ + | psql taler-exchange + [taler-exchange-httpd@exchange-online]# echo 'GRANT USAGE ON ALL SEQUENCES IN SCHEMA public TO "taler-exchange-wire";' \ + | psql taler-exchange + [taler-exchange-httpd@exchange-online]# exit + +.. note:: + + The above instructions for changing database permissions only work *after* + having initialized the database with ``taler-exchange-dbinit``, as + the tables to exist before permissions can be granted on them. The + ``taler-exchange-dbinit`` tool cannot setup these permissions, as it + does not know which users will be used for which processes. + + +Basic Setup: Currency and Denominations +======================================= + +A Taler exchange only supports a single currency. The currency +and the smallest currency unit supported by the bank system +must be specified in ``/etc/taler/taler.conf``. + +.. code-block:: ini + :caption: /etc/taler/taler.conf + + [taler] + CURRENCY = EUR + CURRENCY_ROUND_UNIT = EUR:0.01 + + # ... rest of file ... + +.. warning:: + + When editing ``/etc/taler/taler.conf``, take care to not accidentally remove + the ``@inline-matching@`` directive to include the configuration files in ``conf.d``. + +Next, the electronic cash denominations that the exchange offers must be +specified. The ``taler-wallet-cli`` has a helper command that generates a +reasonable denomination structure. + +.. code-block:: shell-session + + [root@exchange-online]# taler-wallet-cli deployment gen-coin-config \ + --min-amount EUR:0.01 \ + --max-amount EUR:100 \ + > /etc/taler/conf.d/exchange-coins.conf + +You can manually review and edit the generated configuration file. The main +change that is possibly required is updating the various fees. + + +Wire Gateway Setup +================== + +The Taler Wire Gateway is an API that connects the Taler exchange to +the underlying core banking system. + +LibEuFin is an implementation of the Wire Gateway API for the EBICS protocol. +This section will walk through (1) installing and configuring LibEuFin and +(2) connecting the Taler Exchange to LibEuFin. + +.. note:: + + If you do not have a bank account with EBICS but want to test these instructions, + you can use the EBICS sandbox as described in the + :doc:`LibEuFin Tutorial <libeufin/nexus-tutorial>`. + + +Installation and Basic Configuration +------------------------------------ + +First, install the ``libeufin`` package. This can be done on the ``exchange-online`` +machine or a different one. + +.. code-block:: shell-session + + [root@exchange-online]# apt-get install -y libeufin + +The main component of LibEuFin is called the Nexus. It implements a Web +service that provides a JSON abstraction layer to access bank accounts. + +The HTTP port and database connection string can be edited in the configuration: + +.. code-block:: ini + :caption: /etc/libeufin/nexus.env + + LIBEUFIN_NEXUS_PORT=5017 + LIBEUFIN_NEXUS_DB_CONNECTION=jdbc:sqlite:/var/lib/libeufin/nexus/nexus-db.sqlite3 + +After configuring the database, you can start the service. +The database is initialized automatically. + + +.. code-block:: shell-session + + [root@exchange-online]# systemctl enable libeufin-nexus + [root@exchange-online]# systemctl start libeufin-nexus + +You can now create a superuser account. The command to +create the superuser needs direct database access, thus +the configuration file is sourced first, and the relevant +environment variable is exported. + +.. code-block:: console + + [root@exchange-online]# source /etc/libeufin/nexus.env + [root@exchange-online]# export LIBEUFIN_NEXUS_DB_CONNECTION + [root@exchange-online]# NEXUS_ADMIN_PW=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 13) + [root@exchange-online]# libeufin-nexus superuser admin --password $NEXUS_ADMIN_PW + +If you omit ``--password $NEXUS_ADMIN_PW``, you will interactively be asked for a password. +For simplicity, a superuser can as well act as a normal user, but an API +to create less privileged users is offered. + +.. note:: + + User and permissions management in LibEuFin is still under development. + In particular, permissions for non-superusers are very limited at the moment. + + +Connecting Nexus with an EBICS account +-------------------------------------- + +The command line interface of the LibEuFin Nexus needs the following three +values to be defined in the environment: ``LIBEUFIN_NEXUS_URL``, +``LIBEUFIN_NEXUS_USERNAME``, and ``LIBEUFIN_NEXUS_PASSWORD``. In this example, +``LIBEUFIN_NEXUS_USERNAME`` should be set to ``admin``, and +``LIBEUFIN_NEXUS_PASSWORD`` to the value hold in ``NEXUS_ADMIN_PW`` from the +previous step (the ``libeufin-nexus superuser`` command). The +``LIBEUFIN_NEXUS_URL`` could be given as ``http://localhost:5017/``. + +Next, we create a EBICS *bank connection* that Nexus can use to communicate with the bank. + +.. code-block:: console + + [root@exchange-online]# libeufin-cli \ + connections \ + new-ebics-connection \ + --ebics-url $EBICS_BASE_URL \ + --host-id $EBICS_HOST_ID \ + --partner-id $EBICS_PARTNER_ID \ + --ebics-user-id $EBICS_USER_ID \ + $CONNECTION_NAME + +If this step executes correctly, Nexus will have created all the cryptographic +material that is needed on the client side; in this EBICS example, it created +the signature and identification keys. It is therefore advisable to *make +a backup copy* of such keys. + +.. code-block:: console + + [root@exchange-online]# libeufin-cli \ + connections \ + export-backup \ + --passphrase $SECRET \ + --output-file $BACKUP_FILE \ + $CONNECTION_NAME + +At this point, Nexus needs to both communicate its keys to the bank, and +download the bank's keys. This synchronization happens through the INI, HIA, and +finally, HPB message types. + +After the electronic synchronization, the subscriber must confirm their keys +by sending a physical mail to the bank. The following command helps generating +such letter: + +.. code-block:: console + + [root@exchange-online]# libeufin-cli connections get-key-letter $CONNECTION_NAME out.pdf + +.. code-block:: console + + [root@exchange-online]# libeufin-cli \ + connections \ + connect \ + $CONNECTION_NAME + +.. + FIXME: Maybe is not 100% clear that 'connecting' means exchanging keys + with the bank? + +Once the connection is synchronized, Nexus needs to import locally the data +corresponding to the bank accounts offered by the bank connection just made. +The command below downloads the list of the bank accounts offered by ``$CONNECTION_NAME``. + +.. code-block:: console + + [root@exchange-online]# libeufin-cli \ + connections \ + download-bank-accounts \ + $CONNECTION_NAME + +It is now possible to list the accounts offered by the connection. + +.. code-block:: console + + [root@exchange-online]# libeufin-cli \ + connections \ + list-offered-bank-accounts \ + $CONNECTION_NAME + +.. note:: + + The ``nexusBankAccountId`` field should at this step be ``null``, + as we have not yet imported the bank account and thus the account + does not yet have a local name. + +Nexus now needs an explicit import of the accounts it should manage. This +step is needed to let the user pick a custom name for such accounts. + +.. code-block:: console + + [root@exchange-online]# libeufin-cli \ + connections \ + import-bank-account \ + --offered-account-id testacct01 \ + --nexus-bank-account-id $LOCAL_ACCOUNT_NAME \ + $CONNECTION_NAME + +Once a Nexus user imported a bank account (``$LOCAL_ACCOUNT_NAME``) +under a certain connection (``$CONNECTION_NAME``), it is possible +to accomplish the usual operations for any bank account: asking for the +list of transactions, and making a payment. + +Testing: Requesting the transaction history +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The LibEuFin Nexus keeps a local copy of the bank account's transaction +history. Before querying transactions locally, it is necessary +to request transactions for the bank account via the bank connection. + +This command asks Nexus to download the latest transaction reports/statements +through the bank connection: + +.. code-block:: console + + [root@exchange-online]# libeufin-cli accounts fetch-transactions $LOCAL_ACCOUNT_NAME + +.. note:: + + By default, the latest available transactions are fetched. It is also + possible to specify a custom date range (or even all available transactions) + and the type of transactions to fetch (inter-day statements or intra-day + reports). + +.. + FIXME: Possibly the date range filter is still missing, see #6243. + +Once Nexus has stored all the information in the database, the +client can ask to actually see the transactions: + +.. code-block:: console + + [root@exchange-online]# libeufin-cli accounts transactions $LOCAL_ACCOUNT_NAME + +Testing: Making payments +~~~~~~~~~~~~~~~~~~~~~~~~ + +Payments pass through two phases: preparation and submission. The preparation +phase assigns the payment initiation a unique ID, which prevents accidental +double submissions of payments in case of network failures or other +disruptions. + + +The following command prepares a payment: + +.. code-block:: console + + [root@exchange-online]# libeufin-cli accounts prepare-payment \ + --creditor-iban=$IBAN_TO_SEND_MONEY_TO \ + --creditor-bic=$BIC_TO_SEND_MONEY_TO \ + --creditor-name=$CREDITOR_NAME \ + --payment-amount=$AMOUNT \ + --payment-subject=$SUBJECT \ + $LOCAL_ACCOUNT_NAME + +Note: the ``$AMOUNT`` value needs the format ``X.Y:CURRENCY``; for example +``EUR:10``, or ``EUR:1.01``. + +The previous command should return a value (``$UUID``) that uniquely +identifies the prepared payment in the Nexus system. That is needed +in the next step, to **send the payment instructions to the bank**: + +.. code-block:: console + + [root@exchange-online]# libeufin-cli accounts submit-payments \ + --payment-uuid $UUID \ + $LOCAL_ACCOUNT_NAME + +Automatic scheduling +~~~~~~~~~~~~~~~~~~~~ + +With an EBICS bank connection, the LibEuFin Nexus needs to regularly query for +new transactions and (re-)submit prepared payments. + +It is possible to schedule these tasks via an external task scheduler such as +cron(8). However, the nexus also has an internal task scheduling mechanism for +accounts. + + +The following three commands create a schedule for submitting payments hourly, +fetching transactions (intra-day reports) every 5 minutes, and (inter-day statements) +once at 11pm every day: + +.. code-block:: console + + [root@exchange-online]# libeufin-cli accounts task-schedule $LOCAL_ACCOUNT_NAME \ + --task-type="submit" \ + --task-name='submit-payments-hourly' \ + --task-cronspec='0 0 *' + + [root@exchange-online]# libeufin-cli accounts task-schedule $LOCAL_ACCOUNT_NAME \ + --task-type="fetch" \ + --task-name='fetch-5min' \ + --task-cronspec='0 */5 *' \ + --task-param-level=report \ + --task-param-range-type=latest + + [root@exchange-online]# libeufin-cli accounts task-schedule $LOCAL_ACCOUNT_NAME \ + --task-type="fetch" \ + --task-name='fetch-daily' \ + --task-cronspec='0 0 23' \ + --task-param-level=statement \ + --task-param-range-type=latest + +The cronspec has the following format, which is slightly non-standard due to +the ``SECONDS`` field + +.. code-block:: none + + SECONDS MINUTES HOURS DAY-OF-MONTH[optional] MONTH[optional] DAY-OF-WEEK[optional] + + +Creating a Taler facade +~~~~~~~~~~~~~~~~~~~~~~~ + +Facades are additional abstraction layers that can serve +specific purposes. For example, one application might need +a filtered version of the transaction history, or it might +want to refuse payments that do not conform to certain rules. + +At this moment, only the *Taler facade type* is implemented +in the Nexus, and the command below instantiates one under a +existing bank account / connection pair. You can freely +assign an identifier for the ``$FACADE_NAME`` below: + +.. code-block:: console + + [root@exchange-online]# libeufin-cli facades new-taler-wire-gateway-facade \ + --currency EUR \ + --facade-name $FACADE_NAME \ + $CONNECTION_NAME \ + $LOCAL_ACCOUNT_NAME + +At this point, the additional :doc:`taler-wire-gateway API <core/api-wire>` +becomes offered by the Nexus. The purpose is to let a Taler exchange rely on +Nexus to manage its bank account. + +The base URL of the facade that can be used by the Taler exchange +as the Taler Wire Gateway base URL can be seen by listing the facades: + +.. code-block:: console + + [root@exchange-online]# libeufin-cli facades list + +Managing Permissions and Users +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This guide has so far assumed that a superuser is accessing the LibEuFin Nexus. +However, it is advisable that the Nexus is accessed with users that only have a +minimal set of permissions. + +The Nexus currently only has support for giving non-superusers access to Taler +wire gateway facades. + +To create a new user, use the ``users`` subcommand of the CLI: + +.. code-block:: console + + [root@exchange-online]# libeufin-cli users list + # [ ... shows available users ... ] + + [root@exchange-online]# libeufin-cli users create $USERNAME + # [ ... will prompt for password ... ] + +Permissions are managed with the ``permissions`` subcommand. +The following commands grant permissions to view the transaction history +and create payment initiations with a Taler wire gateway facade: + + +.. code-block:: console + + [root@exchange-online]# libeufin-cli permissions grant \ + user $USERNAME \ + facade $FACADENAME \ + facade.talerwiregateway.history + + [root@exchange-online]# libeufin-cli permissions grant \ + user $USERNAME \ + facade $FACADENAME \ + facade.talerwiregateway.transfer + +.. + FIXME: The two commands above output an empty JSON object + when successful. Possibly, we should suppress that (just like + the other commands do). + +The list of all granted permissions can be reviewed: + +.. code-block:: console + + [root@exchange-online]# libeufin-cli permissions list + + +Exchange Wire Configuration +--------------------------- + +The exchange must be configured with the right settings to +access the Taler Wire Gateway. An exchange can be configured +to use multiple bank accounts by using multiple Wire Gateways. +Typically only one Wire Gateway is used. + +A Taler Wire Gateway is configured in a configuration section that follows the +pattern ``exchange-account-$id``, where ``$id`` is an internal identifier for +the bank account accessed by the exchange. The basic information for an account should +be put in ``/etc/taler/conf.d/exchange-business.conf``. +The secret credentials to access the Taler Wire Gateway API should +be put into a corresponding ``exchange-accountcredentials-$id`` section +in ``/etc/taler/secrets/exchange-accountcredentials.conf``. +The latter file +should already be only readable for the ``taler-exchange-wire`` user. Other +exchange processes should not have access to this information. + +.. code-block:: ini + :caption: /etc/taler/conf.d/exchange-business.conf + + [exchange-account-1] + enable_credit = yes + enable_debit = yes + + # Account identifier in the form of an RFC-8905 payto:// URI. + # For SEPA, looks like payto://iban/$IBAN?receiver-name=$NAME + # Make sure to URL-encode spaces in $NAME! + payto_uri = + + @inline-secret@ exchange-accountcredentials-1 ../secrets/exchange-accountcredentials.secret.conf + + +.. code-block:: ini + :caption: /etc/taler/secrets/exchange-accountcredentials.secret.conf + + [exchange-accountcredentials-1] + + # LibEuFin expects basic auth. + wire_gateway_auth_method = basic + + # Username and password set in LibEuFin. + username = ... + password = ... + + # Base URL of the wire gateway set up with LibEuFin. + wire_gateway_url = ... + + +The Wire Gateway configuration can be tested with the following command: + +.. code-block:: shell-session + + [root@exchange-online]# taler-exchange-wire-gateway-client \ + --section exchange-accountcredentials-1 --debit-history + [root@exchange-online]# taler-exchange-wire-gateway-client \ + --section exchange-accountcredentials-1 --credit-history + + +Exchange Web service / API Setup +================================ + +By default, the ``taler-exchange-httpd`` service listens for HTTP connections +on a UNIX domain socket. To make the service publicly available, a reverse +proxy such as nginx should be used. We strongly recommend to configure nginx +to use TLS. + +The public URL that the exchange will be served under should +be put in ``/etc/taler/conf.d/exchange-business.conf`` configuration file. + +.. code-block:: ini + :caption: /etc/taler/conf.d/exchange-business.conf + + [exchange] + BASE_URL = https://example.com/ + + # ... rest of file ... + +The ``taler-exchange`` package ships with a sample configuration that can be +enabled in nginx: + +.. code-block:: shell-session + + [root@exchange-online]# vim /etc/nginx/sites-available/taler-exchange + < ... customize configuration ... > + [root@exchange-online]# ln -s /etc/nginx/sites-available/taler-exchange \ + /etc/nginx/sites-enabled/taler-exchange + [root@exchange-online]# systemctl reload nginx + + +The exchange HTTP service can now be started: + +.. code-block:: shell-session + + [root@exchange-online]# systemctl start taler-exchange.target + + +.. note:: + + At this point, the exchange service is not yet fully operational. + + +To check whether the exchange is running correctly under the advertized +base URL, run: + +.. code-block:: shell-session + + [root@exchange-online]# export BASE_URL=$(taler-config -s exchange -o base_url) + [root@exchange-online]# wget ${BASE_URL}management/keys + +The request might take some time to complete on slow machines, because +a lot of key material will be generated. + + +Offline Signing Setup +===================== + +The offline signing keys of the exchange should be stored on a different machine. +The responsibilities of this offline signing machine are: + +* Generation of the exchange's offline master signing key. +* Secure storage of the exchange's offline master signing key. +* Generation of certificates (signed with the offline master signing key) that will be imported by the exchange. + + +.. code-block:: shell-session + + [root@exchange-offline]# sudo -u taler-exchange-offline taler-exchange-offline setup + < ... prints the exchange master public key > + +The public key printed as the output of this command must be put into the configuration +of the online machine: + +.. code-block:: ini + :caption: /etc/taler/conf.d/exchange-business.conf + + [exchange] + MASTER_PUBLIC_KEY = YE6Q6TR1ED... + + # ... rest of file ... + +The exchange HTTP service must be running before you can complete the offline +signing procedure. Note that the exchange may be running without offline keys, +but will not yet be operational. To make the exchange HTTP service +operational, the following steps involving the offline signing machine must be +completed: + +1. The public keys of various online keys used by the exchange service are exported + via a management HTTP API. +2. The offline signing system validates this request and signs it. + Additionally, the offline signing system signs policy messages + to configure the exchange's bank accounts and associated fees. +3. The messages generated by the offline signing system are uploaded + via the management API of the exchange HTTP service. + + +.. code-block:: shell-session + + [root@exchange-online]# taler-exchange-offline \ + download > sig-request.json + + [root@exchange-offline]# taler-exchange-offline \ + sign < sig-request.json > sig-response.json + [root@exchange-offline]# taler-exchange-offline \ + enable-account payto://iban/$IBAN?receiver-name=$NAME > acct-response.json + [root@exchange-offline]# taler-exchange-offline \ + wire-fee now iban EUR:0 EUR:0 EUR:0 > fee-response.json + [root@exchange-offline]# taler-exchange-offline \ + global-fee now EUR:0 EUR:0 EUR:0 EUR:0 4w 4w 6y 4 > global-response.json + [root@exchange-online]# taler-exchange-offline upload < sig-response.json + [root@exchange-online]# taler-exchange-offline upload < acct-response.json + [root@exchange-online]# taler-exchange-offline upload < fee-response.json + [root@exchange-online]# taler-exchange-offline upload < global-response.json + + + + +Setup Linting ============= -This chapter provides an overview of the exchange configuration. Or at -least eventually will do so, for now it is a somewhat wild description -of some of the options. +The ``taler-wallet-cli`` package comes with an experimental tool that runs various +checks on the current GNU Taler exchange deployment: + +.. code-block:: shell-session + + [root@exchange-online]# apt install taler-wallet-cli + [root@exchange-online]# taler-wallet-cli deployment lint-exchange + +You can optionally pass the ``--debug`` option to get more verbose output, and +``--continue`` to continue with further checks even though a previous one has +failed. + + +Testing and Troubleshooting +=========================== + +The following shell session illustrates how the wallet can be used to withdraw +electronic cash from the exchange and subsequently spend it. For these steps, +a merchant backend is not required, as the wallet acts as a merchant. + + +.. code-block:: shell-session + + # This will now output a payto URI that money needs to be sent to in order to allow withdrawal + # of taler coins. + $ taler-wallet-cli advanced withdraw-manually --exchange $EXCHANGE_URL --amount EUR:10.50 + + +Show the status of the manual withdrawal operation. + +.. code-block:: shell-session + + $ taler-wallet-cli transactions + +At this point, a bank transfer to the exchange's bank account +needs to be made with the correct subject / remittance information +as instructed by the wallet after the first step. With the +above configuration, it should take about 5 minutes after the +wire transfer for the incoming transfer to be observed by the +Nexus. + +Run the following command to check whether the exchange received +an incoming bank transfer: + +.. code-block:: shell-session + + [root@exchange-online]# taler-exchange-wire-gateway-client \ + --section exchange-accountcredentials-1 --credit-history + +Once the transfer has been made, try completing the withdrawal +using: + +.. code-block:: shell-session + + $ taler-wallet-cli run-pending + +Afterwards, check the status of transactions and show the +current wallet balance: + +.. code-block:: shell-session + + $ taler-wallet-cli transactions + $ taler-wallet-cli balance + + +Now, we can directly deposit coins via the exchange into a target +account. (Usually, a payment is made via a merchant. The wallet +provides this functionality for testing.) + +.. code-block:: shell-session + + $ taler-wallet-cli deposit create EUR:5 \ + payto://iban/$IBAN?receiver-name=Name + $ taler-wallet-cli run-pending + + +Check if this transaction was successful (from the perspective +of the wallet): + +.. code-block:: shell-session + + $ taler-wallet-cli transactions + +If the transaction failed, fix any open issue(s) with the exchange and +run the "run-pending" command. + +The wallet can also track if the exchange wired the money to the merchant +account. The "deposit group id" can be found in the output of the +transactions list. + +.. code-block:: shell-session + + $ taler-wallet-cli deposit track $DEPOSIT_GROUP_ID + +You can also check using the exchange-tools whether the exchange sent +the an outgoing transfer: + +.. code-block:: shell-session + + [root@exchange-online]# taler-exchange-wire-gateway-client \ + --section exchange-accountcredentials-1 --debit-history + +After enough time has passed, the money should arrive at the specified IBAN. + + + +Configuration Details +===================== + +This chapter provides details about the exchange configuration. + +The configuration for all Taler components uses a single configuration file +as entry point: ``/etc/taler/taler.conf``. + +System defaults are automatically loaded from files in +``/usr/share/taler/config.d``. These default files should never be modified. + +The default configuration ``taler.conf`` configuration file also includes all +configuration files in ``/etc/taler/conf.d``. The settings from files in +``conf.d`` are only relevant to particular components of Taler, while +``taler.conf`` contains settings that affect all components. + + +The directory ``/etc/taler/secrets`` contains configuration file snippets with +values that should only be readable to certain users. They are included with the ``@inline-secret@`` +directive and should end with ``.secret.conf``. + +To view the entire configuration annotated with the source of each configuration option, you +can use the ``taler-config`` helper: + + +.. code-block:: shell-session + + [root@exchange-online]# taler-config --diagnostics + < ... annotated, full configuration ... > + +.. warning:: + + While ``taler-config`` also supports rewriting configuration files, we strongly + recommend to edit configuration files manually, as ``taler-config`` does not + preserve comments and, by default, rewrites ``/etc/taler/taler.conf``. .. include:: frags/configuration-format.rst @@ -1081,3 +1972,19 @@ time (operating system and user space) and other details. Naturally, additional instrumentation (including using features of the PostgreSQL database itself) may help discover performance issues. + + +FIXMEs +====== + +* We should have some summary with the inventory of services that should be + running. Systemd by default doesn't show this nicely. Maybe suggest running + "systemd list-dependencies taler-exchange.target"? +* When multiple TWGs are configured, which one will be used by the taler-exchange-transfer? CG: ALL! + + * FD: Sure, for incoming transactions. But how does taler-exchange-transfer decide which TWG to use for an outgoing transaction? + +* What happens when the TWG doesn't like one particular outgoing transaction? + How to recover from that as a sysadmin when it happens in practice? +* This document duplicates some details, should be de-duplicated! + |