taler-docs

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

commit c13fedafc26535cbd70915e04f515ae7d7291278
parent a8085e4ae47ce94ae5a3802cb3c3e31a345bef99
Author: Christian Grothoff <christian@grothoff.org>
Date:   Wed, 10 May 2023 11:57:07 +0200

update exchange documentation

Diffstat:
Mtaler-exchange-manual.rst | 1205+++++++++++++++++++++++++++++++++++++++----------------------------------------
1 file changed, 591 insertions(+), 614 deletions(-)

diff --git a/taler-exchange-manual.rst b/taler-exchange-manual.rst @@ -197,6 +197,31 @@ components: copy of the database. +.. _Keys: + +Keys +---- + +The exchange works with four types of keys: + +- master key (kept offline) + +- sign keys (signs normal messages from the exchange) + +- denomination keys (signs electronic coins, see section Coins) + +- security module keys (signs sign keys and denomination keys) + +Additionally, the exchange is sometimes concerned with the auditor's public +key (to verify messages signed by auditors approved by the exchange operator) +and the merchant's public key (to verify refunds are authorized by the +merchant). + +Most of the keys are managed fully automatically or configured as part of the +denomination configuration. However, the exchange master keys (the offline +keys) have some configuration settings. + + Offline keys ------------ @@ -318,7 +343,7 @@ Information to write down during the installation: * Taler facade base URL * exchange Nexus username and password - + Installing from source ---------------------- @@ -326,7 +351,7 @@ Installing from source The following instructions will show how to install libgnunetutil and the GNU Taler exchange from source. -The package sources can be find in our +The package sources can be find in our `download directory <http://ftpmirror.gnu.org/taler/>`__. GNU Taler components version numbers follow the ``MAJOR.MINOR.MICRO`` format. @@ -465,6 +490,51 @@ The deployment creates the following key locations in the system: * offline system: exchange-offline keys. +Configuration Fundamentals +========================== + +This chapter provides fundamental 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 + + +.. _Using-taler_002dconfig-exchange: + +.. include:: frags/using-taler-config.rst + + Exchange Database Setup ======================= @@ -506,6 +576,9 @@ in the configuration file would simply be: .. code-block:: ini :caption: /etc/taler/secrets/exchange-db.secret.conf + [exchange] + DB = postgres + [exchangedb-postgres] CONFIG=postgres:///taler-exchange @@ -520,6 +593,17 @@ to be initialized with the following command: [root@exchange-online]# sudo -u taler-exchange-httpd taler-exchange-dbinit + ..note:: + + To run this command, the user must have ``CREATE TABLE``, ``CREATE + INDEX``, ``ALTER TABLE`` and (in the future possibly even) ``DROP TABLE`` + permissions. Those permissions are only required for this step (which may + have to be repeated when upgrading a deployment). Afterwards, during + normal operation, permissions to ``CREATE`` or ``ALTER`` tables are not + required by any of the Taler exchange processes and thus should not be + granted. For more information, see + :doc:`manpages/taler-exchange-dbinit.1`. + Finally we need to grant the other accounts limited access: .. code-block:: shell-session @@ -546,7 +630,7 @@ Finally we need to grant the other accounts limited access: 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 ======================================= @@ -758,7 +842,7 @@ 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 @@ -789,7 +873,7 @@ client can ask to actually see the transactions: [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 @@ -823,7 +907,7 @@ in the next step, to **send the payment instructions to the bank**: $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. @@ -867,7 +951,7 @@ the ``SECONDS`` field Creating a Taler facade -~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^ Facades are additional abstraction layers that can serve specific purposes. For example, one application might need @@ -899,7 +983,7 @@ as the Taler Wire Gateway base URL can be seen by listing the facades: [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 @@ -947,8 +1031,60 @@ The list of all granted permissions can be reviewed: [root@exchange-online]# libeufin-cli permissions list -Exchange Wire Configuration ---------------------------- +.. _Bank-account: + +Exchange Bank Account Configuration +----------------------------------- + +To configure a bank account in Taler, we need to furnish two pieces of +information: + +- The ``payto://`` URI of the bank account, which uniquely idenfies the + account. Examples for such URIs include + ``payto://iban/CH9300762011623852957`` for a bank account with + an IBAN or + ``payto://x-taler-bank/localhost:8080/2`` for the 2nd bank account a + the Taler bank demonstrator running at ``localhost`` on port 8080. + The first part of the URI following ``payto://`` (“iban” or + “x-taler-bank”) is called the wire method. + +- The ``taler-exchange-wirewatch`` and ``taler-exchange-transfer`` + tools needs to be provided resources for authentication + to the respective banking service. The format in which the + authentication information is currently a username and password + for HTTP basic authentication. + +You can configure multiple accounts for an exchange by creating sections +starting with “exchange-account-” for the section name. You can ENABLE for +each account whether it should be used, and for what (incoming or outgoing +wire transfers): + +.. code-block:: ini + + [exchange-account-1] + # With x-taler-bank (say for PyBank) + PAYTO_URI = "payto://x-taler-bank/bank.demo.taler.net/Exchange" + + # Example using IBAN (for use with LibEuFin) + # PAYTO_URI = "payto://iban/CH9300762011623852957" + + # URL for talking to the bank wire the wire API. + WIRE_GATEWAY_URL = https://bank.demo.taler.net/taler-wire-gateway/Exchange + + # Use for exchange-aggregator (outgoing transfers) + ENABLE_DEBIT = YES + # Use for exchange-wirewatch (and listed in /wire) + ENABLE_CREDIT = YES + + # Authentication options for exchange bank account go here. + # (Next sections have examples of authentication mechanisms) + WIRE_GATEWAY_AUTH_METHOD = basic + USERNAME = exchange + PASSWORD = super-secure + + ..note:: + + FIXME: the text below explains basically the same thing again. We should de-duplicate it. The exchange must be configured with the right settings to access the Taler Wire Gateway. An exchange can be configured @@ -957,12 +1093,11 @@ 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 +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. @@ -1007,8 +1142,41 @@ The Wire Gateway configuration can be tested with the following command: --section exchange-accountcredentials-1 --credit-history -Exchange Web service / API Setup -================================ +.. _Deployment: + +Deployment +========== + +This chapter describes how to deploy the exchange once the basic installation +and configuration are completed. + +.. _Serving: + +Serving +------- + +The exchange can serve HTTP over both TCP and UNIX domain socket. + +The following options are to be configured in the section ``[exchange]``: + +- ``SERVE``: Must be set to ``tcp`` to serve HTTP over TCP, or ``unix`` to serve + HTTP over a UNIX domain socket. + +- ``PORT``: Set to the TCP port to listen on if ``SERVE`` is ``tcp``. + +- ``UNIXPATH``: Set to the UNIX domain socket path to listen on if ``SERVE`` is + ``unix``. + +- ``UNIXPATH_MODE``: Number giving the mode with the access permission mask + for the ``UNIXPATH`` (i.e. 660 = ``rw-rw---``). Make sure to set it in such + a way that your reverse proxy has permissions to access the UNIX domain + socket. The default (660) assumes that the reverse proxy is a member of + the group under which the exchange HTTP server is running. + +.. _ReverseProxy: + +Reverse Proxy 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 @@ -1038,456 +1206,113 @@ enabled in nginx: [root@exchange-online]# systemctl reload nginx -The exchange HTTP service can now be started: - -.. code-block:: shell-session + .. _Coins-denomination-keys: - [root@exchange-online]# systemctl start taler-exchange.target +Coins (denomination keys) +------------------------- +Sections specifying denomination (coin) information start with ``coin_``. By +convention, the name continues with ``$CURRENCY_[$SUBUNIT]_$VALUE_$REVISION``, +i.e. ``[coin_eur_ct_10_0]`` for a 10 cent piece. However, only the ``coin_`` +prefix is mandatory. Once configured, these configuration values must not +change. The ``$REVISION`` part of the section name should be incremented if +any of the coin attributes in the section changes. Each ``coin_``-section +must then have the following options: -.. note:: +- ``VALUE``: How much is the coin worth, the format is + CURRENCY:VALUE.FRACTION. For example, a 10 cent piece is "EUR:0.10". - At this point, the exchange service is not yet fully operational. +- ``DURATION_WITHDRAW``: How long can a coin of this type be withdrawn? + This limits the losses incurred by the exchange when a denomination + key is compromised. +- ``DURATION_SPEND``: How long is a coin of the given type valid? Smaller + values result in lower storage costs for the exchange. -To check whether the exchange is running correctly under the advertized -base URL, run: +- ``DURATION_LEGAL``: How long is the coin of the given type legal? -.. code-block:: shell-session +- ``FEE_WITHDRAW``: What does it cost to withdraw this coin? Specified + using the same format as value. - [root@exchange-online]# export BASE_URL=$(taler-config -s exchange -o base_url) - [root@exchange-online]# wget ${BASE_URL}management/keys +- ``FEE_DEPOSIT``: What does it cost to deposit this coin? Specified using + the same format as value. -The request might take some time to complete on slow machines, because -a lot of key material will be generated. +- ``FEE_REFRESH``: What does it cost to refresh this coin? Specified using + the same format as value. +- ``FEE_REFUND``: What does it cost to refund this coin? + Specified using the same format as value. -Offline Signing Setup -===================== +- ``CIPHER``: Which cipher to use for this coin? Must be either ``RSA`` or + ``CS``. -The offline signing keys of the exchange should be stored on a different machine. -The responsibilities of this offline signing machine are: +- ``RSA_KEYSIZE``: How many bits should the RSA modulus (product of the two + primes) have for this type of coin. -* 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. +- ``AGE_RESTRICTED``: Set to ``YES`` to make this a denomination with support + for age restrictions. See age restriction extension below for details. + This option is optional and defaults to ``NO``. +See :doc:`manpages/taler.conf.5` for information on *duration* values +(i.e. ``DURATION_WITHDRAW`` and ``DURATION_SPEND`` above, +and ``OVERLAP_DURATION`` and ``DURATION`` below). +Additionally, there are two global configuration options of note: -.. code-block:: shell-session +- ``[taler-exchange-secmod-rsa/OVERLAP_DURATION]``: What is the overlap of the + withdrawal timespan for denomination keys? The value given here must + be smaller than any of the ``DURATION_WITHDRAW`` values for any of the coins. - [root@exchange-offline]# sudo -u taler-exchange-offline taler-exchange-offline setup - < ... prints the exchange master public key > +- ``[taler-exchange-secmod-rsa/LOOKAHEAD_SIGN]``: For how far into the future + should denomination keys be pre-generated? This allows the exchange and + auditor operators to download, offline-sign, and upload denomination key + signatures for denomination keys that will be used in the future by the + exchange. -The public key printed as the output of this command must be put into the configuration -of the online machine: +.. index:: maintenance +.. note:: + We recommend setting the ``LOOKAHEAD_SIGN`` value to at least one year and + then to perform the offline-signing procedure at least once every 6 months + to ensure that there is sufficient time for wallets to learn the new keys + and to avoid unavailability in case this critical maintenance procedure is + delayed. -.. code-block:: ini - :caption: /etc/taler/conf.d/exchange-business.conf +.. note:: + It is crucial that the configuration provided in these sections is identical (!) + for the exchange and the crypto helpers. We recommend pointing both users + to the same configuration file! - [exchange] - MASTER_PUBLIC_KEY = YE6Q6TR1ED... - # ... rest of file ... +.. _Sign-keys: -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: +Sign keys +--------- -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. +There are three global configuration options of note for sign keys: +- ``[taler-exchange-secmod-eddsa/DURATION]``: How long are sign keys + used to sign messages? After this time interval expires, a fresh + sign key will be used (key rotation). We recommend using + a ``DURATION`` of a few weeks to a few months for sign keys. -.. code-block:: shell-session +- ``[taler-exchange-secmod-eddsa/OVERLAP_DURATION]``: What is the overlap of the + timespan for sign keys? We recommend a few minutes or hours. Must + be smaller than ``DURATION``. - [root@exchange-online]# taler-exchange-offline \ - download > sig-request.json +- ``[taler-exchange-secmod-eddsa/LOOKAHEAD_SIGN]``: For how far into the future + should sign keys be pre-generated? This allows the exchange and + auditor operators to download, offline-sign, and upload sign key + signatures for sign keys that will be used in the future by the exchange. - [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 +.. note:: + We recommend setting the ``LOOKAHEAD_SIGN`` value to at least one year and + then to perform the offline-signing procedure at least once every 6 months + to ensure that there is sufficient time for wallets to learn the new keys + and to avoid unavailability in case this critical maintenance procedure is + delayed. - - -Setup Linting -============= - -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 - - -.. _Using-taler_002dconfig-exchange: - -.. include:: frags/using-taler-config.rst - - -.. _Keying: - -Keying ------- - -The exchange works with four types of keys: - -- master key (kept offline) - - To create a master key, use: - - .. code-block:: console - - $ taler-exchange-offline setup - -- sign keys (signs normal messages from the exchange) - -- denomination keys (signs electronic coins, see section Coins) - -- security module keys (signs sign keys and denomination keys) - -Additionally, the exchange is sometimes concerned with the auditor's public -key (to verify messages signed by auditors approved by the exchange operator) -and the merchant's public key (to verify refunds are authorized by the -merchant). - - -Key options include: - -- ``[exchange-offline/MASTER_PRIV_FILE]``: Path to the exchange’s master private file. Only needs to be provided on the offline system where the ``taler-exchange-offline`` command is used. - -- ``[exchange/MASTER_PUBLIC_KEY]``: Must specify the exchange’s master public key. Needed for the exchange to verify information signed by the offline system. - - -.. _Serving: - -Serving -------- - -The exchange can serve HTTP over both TCP and UNIX domain socket. - -The following options are to be configured in the section ``[exchange]``: - -- ``SERVE``: Must be set to ``tcp`` to serve HTTP over TCP, or ``unix`` to serve - HTTP over a UNIX domain socket. - -- ``PORT``: Set to the TCP port to listen on if ``SERVE`` is ``tcp``. - -- ``UNIXPATH``: Set to the UNIX domain socket path to listen on if ``SERVE`` is - ``unix``. - -- ``UNIXPATH_MODE``: Number giving the mode with the access permission mask - for the ``UNIXPATH`` (i.e. 660 = ``rw-rw---``). - -.. _Currency: - -Currency --------- - -The exchange supports only one currency. This data is set under the -respective option ``CURRENCY`` in section ``[taler]``. - -.. _Database: - -Database --------- - -The option ``DB`` in section ``[exchange]`` gets the database backend’s name the -exchange is going to use. So far, only ``db = postgres`` is supported. After -choosing the backend, it is mandatory to supply the connection string -(namely, the database name). This is possible in two ways: - -- via an environment variable: ``TALER_EXCHANGEDB_POSTGRES_CONFIG``. - -- via configuration option ``CONFIG``, under section ``[exchangedb-$BACKEND]``. - For example, the demo exchange is configured as follows: - -.. code-block:: ini - - [exchange] - ... - DB = postgres - ... - - [exchangedb-postgres] - CONFIG = postgres:///talerdemo - - -Given this database configuration, the database can be initialized using: - -.. code-block:: console - - $ taler-exchange-dbinit - -Note that to run this command, the user must have ``CREATE TABLE``, ``CREATE -INDEX``, ``ALTER TABLE`` and (in the future possibly even) ``DROP TABLE`` -permissions. Those permissions are only required for this step (which may -have to be repeated when upgrading a deployment). Afterwards, during normal -operation, permissions to ``CREATE`` or ``ALTER`` tables are not required by -any of the Taler exchange processes and thus should not be granted. -For more information, see :doc:`manpages/taler-exchange-dbinit.1`. - -Commands, like ``taler-exchange-dbinit``, that support the ``-l LOGFILE`` -command-line option, send logging output to standard error by default. - -.. _Coins-denomination-keys: - -Coins (denomination keys) -------------------------- - -Sections specifying denomination (coin) information start with ``coin_``. By -convention, the name continues with ``$CURRENCY_[$SUBUNIT]_$VALUE_$REVISION``, -i.e. ``[coin_eur_ct_10_0]`` for a 10 cent piece. However, only the ``coin_`` -prefix is mandatory. Once configured, these configuration values must not -change. The ``$REVISION`` part of the section name should be incremented if -any of the coin attributes in the section changes. Each ``coin_``-section -must then have the following options: - -- ``VALUE``: How much is the coin worth, the format is - CURRENCY:VALUE.FRACTION. For example, a 10 cent piece is "EUR:0.10". - -- ``DURATION_WITHDRAW``: How long can a coin of this type be withdrawn? - This limits the losses incurred by the exchange when a denomination - key is compromised. - -- ``DURATION_SPEND``: How long is a coin of the given type valid? Smaller - values result in lower storage costs for the exchange. - -- ``DURATION_LEGAL``: How long is the coin of the given type legal? - -- ``FEE_WITHDRAW``: What does it cost to withdraw this coin? Specified - using the same format as value. - -- ``FEE_DEPOSIT``: What does it cost to deposit this coin? Specified using - the same format as value. - -- ``FEE_REFRESH``: What does it cost to refresh this coin? Specified using - the same format as value. - -- ``FEE_REFUND``: What does it cost to refund this coin? - Specified using the same format as value. - -- ``CIPHER``: Which cipher to use for this coin? Must be either ``RSA`` or - ``CS``. - -- ``RSA_KEYSIZE``: How many bits should the RSA modulus (product of the two - primes) have for this type of coin. - -See :doc:`manpages/taler.conf.5` for information on *duration* values -(i.e. ``DURATION_WITHDRAW`` and ``DURATION_SPEND`` above, -and ``OVERLAP_DURATION`` and ``DURATION`` below). -Additionally, there are two global configuration options of note: - -- ``[taler-exchange-secmod-rsa/OVERLAP_DURATION]``: What is the overlap of the - withdrawal timespan for denomination keys? The value given here must - be smaller than any of the ``DURATION_WITHDRAW`` values for any of the coins. - -- ``[taler-exchange-secmod-rsa/LOOKAHEAD_SIGN]``: For how far into the future - should denomination keys be pre-generated? This allows the exchange and - auditor operators to download, offline-sign, and upload denomination key - signatures for denomination keys that will be used in the future by the - exchange. - -.. index:: maintenance -.. note:: - We recommend setting the ``LOOKAHEAD_SIGN`` value to at least one year and - then to perform the offline-signing procedure at least once every 6 months - to ensure that there is sufficient time for wallets to learn the new keys - and to avoid unavailability in case this critical maintenance procedure is - delayed. - -.. note:: - It is crucial that the configuration provided in these sections is identical (!) - for the exchange and the crypto helpers. We recommend pointing both users - to the same configuration file! - - - -.. _Sign-keys: - -Sign keys ---------- - -There are three global configuration options of note for sign keys: - -- ``[taler-exchange-secmod-eddsa/DURATION]``: How long are sign keys - used to sign messages? After this time interval expires, a fresh - sign key will be used (key rotation). We recommend using - a ``DURATION`` of a few weeks to a few months for sign keys. - -- ``[taler-exchange-secmod-eddsa/OVERLAP_DURATION]``: What is the overlap of the - timespan for sign keys? We recommend a few minutes or hours. Must - be smaller than ``DURATION``. - -- ``[taler-exchange-secmod-eddsa/LOOKAHEAD_SIGN]``: For how far into the future - should sign keys be pre-generated? This allows the exchange and - auditor operators to download, offline-sign, and upload sign key - signatures for sign keys that will be used in the future by the exchange. - -.. note:: - We recommend setting the ``LOOKAHEAD_SIGN`` value to at least one year and - then to perform the offline-signing procedure at least once every 6 months - to ensure that there is sufficient time for wallets to learn the new keys - and to avoid unavailability in case this critical maintenance procedure is - delayed. - - -Terms of Service ----------------- +Terms of Service +---------------- The exchange has an endpoint "/terms" to return the terms of service (in legal language) of the exchange operator. The wallet will show @@ -1540,136 +1365,53 @@ the exchange would return ``TERMS_DIR/en/v1.html`` lacking an HTML version in French. -.. _Bank-account: - -Bank account ------------- - -To configure a bank account in Taler, we need to furnish two pieces of -information: - -- The ``payto://`` URI of the bank account, which uniquely idenfies the - account. Examples for such URIs include - ``payto://iban/CH9300762011623852957`` for a bank account with - an IBAN or - ``payto://x-taler-bank/localhost:8080/2`` for the 2nd bank account a - the Taler bank demonstrator running at ``localhost`` on port 8080. - The first part of the URI following ``payto://`` (“iban” or - “x-taler-bank”) is called the wire method. - -- The ``taler-exchange-wirewatch`` and ``taler-exchange-transfer`` - tools needs to be provided resources for authentication - to the respective banking service. The format in which the - authentication information is currently a username and password - for HTTP basic authentication. - -You can configure multiple accounts for an exchange by creating sections -starting with “exchange-account-” for the section name. You can ENABLE for -each account whether it should be used, and for what (incoming or outgoing -wire transfers): - -.. code-block:: ini - - [exchange-account-1] - # With x-taler-bank (say for PyBank) - PAYTO_URI = "payto://x-taler-bank/bank.demo.taler.net/Exchange" - - # Example using IBAN (for use with LibEuFin) - # PAYTO_URI = "payto://iban/CH9300762011623852957" - - # URL for talking to the bank wire the wire API. - WIRE_GATEWAY_URL = https://bank.demo.taler.net/taler-wire-gateway/Exchange - - # Use for exchange-aggregator (outgoing transfers) - ENABLE_DEBIT = YES - # Use for exchange-wirewatch (and listed in /wire) - ENABLE_CREDIT = YES - - # Authentication options for exchange bank account go here. - # (Next sections have examples of authentication mechanisms) - WIRE_GATEWAY_AUTH_METHOD = basic - USERNAME = exchange - PASSWORD = super-secure - - -The command line tool ``taler-exchange-offline`` must be used to -sign the ``payto://`` URI in a way suitable to convince wallets that -this is the correct address to wire funds to. -For example, the utility may be invoked as -follows to enable a wire account: - -.. code-block:: console - - $ taler-exchange-offline enable-account payto://iban/CH9300762011623852957 - -The resulting JSON output must be uploaded to the exchange using -``taler-exchange-offline upload``. -For details, see :doc:`manpages/taler-exchange-offline.1`. - - -.. _Wire-fee-structure: - -Wire fee structure -^^^^^^^^^^^^^^^^^^ - -.. index:: wire fee -.. index:: fee - -For each wire method (“iban” or “x-taler-bank”) the -exchange must know about applicable wire fees. This is also done -using the ``taler-exchange-offline`` tool: +.. _OfflineConfiguration: -.. code-block:: console +Setting up the offline signing key +---------------------------------- - $ taler-exchange-offline wire-fee 2040 iban EUR:0.05 EUR:0.10 EUR:0.15 +Before launching an exchange, the offline signing (master) key must be +generated and set in the configuration. The offline signing keys of the +exchange should be stored on a different machine. The responsibilities of +this offline signing machine are: -The above sets the wire fees for wire transfers involving ``iban`` accounts -(in Euros) in the year 2040 to 5 cents (wire fee) and 10 cents (closing fee). -The tool only supports setting fees that applies for the entire calendar year. - -We recommend provisioning an exchange with wire fees at least for the next two -years. Note that once the fees have been set for a year, they cannot be -changed (basically, by signing the fees the exchange makes a legally binding -offer to the customers). - -.. index:: maintenance -.. note:: - Provisioning future wire fees, like provisioning future denomination - and signing keys, are key regular maintenance procedures for every - exchange operator. We recommend setting automated reminders for - this maintenance activity! +* 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. +* Revocation of keys when the online system was compromised or is being terminated -.. _Auditor-configuration: +Configuration file options related to the master key are: -Auditor configuration ---------------------- +- ``[exchange-offline/MASTER_PRIV_FILE]``: Path to the exchange’s master + private file. Only needs to be provided on the offline system where the + ``taler-exchange-offline`` command is used. The default value is usually + fine and does not require adjustment. -The exchange must be informed about any auditor that is expected to provision -it with auditor signatures. This is also done using the -``taler-exchange-offline`` tool on the offline system. First, the auditor -must be configured and provide the exchange operator with its public key and -the URL of it's REST API. The exchange operator also needs a human-readable -name that may be shown to users to identify the auditor. Given this -information, the exchange operator can enable the auditor: +- ``[exchange/MASTER_PUBLIC_KEY]``: Must specify the exchange’s master public + key. Needed for the exchange to verify information signed by the offline + system. This value must almost always be set explicitly by hand. -.. code-block:: console - $ taler-exchange-offline enable-auditor $PUB_KEY $REST_URL "$AUDITOR_NAME" > auditor.json -As before, the *auditor.json* file must then be copied from the offline system -to a system connected to the exchange and there ``uploaded`` to the exchange. +.. code-block:: shell-session + [root@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: -.. _Deployment: +.. code-block:: ini + :caption: /etc/taler/conf.d/exchange-business.conf -Deployment -========== + [exchange] + MASTER_PUBLIC_KEY = YE6Q6TR1ED... -This chapter describes how to deploy the exchange once it has been -configured. + # ... rest of file ... +With this last step, we are finally ready to launch the +main exchange process. .. _Launch: @@ -1679,6 +1421,7 @@ Launching an exchange A running exchange requires starting the following processes: - ``taler-exchange-secmod-rsa`` (as special user, sharing group with the HTTPD) +- ``taler-exchange-secmod-cs`` (as special user, sharing group with the HTTPD) - ``taler-exchange-secmod-eddsa`` (as special user, sharing group with the HTTPD) - ``taler-exchange-httpd`` (needs database access) - ``taler-exchange-aggregator`` (only needs database access) @@ -1686,7 +1429,7 @@ A running exchange requires starting the following processes: - ``taler-exchange-wirewatch`` (needs bank account read credentials and database access) - ``taler-exchange-transfer`` (needs credentials to initiate outgoing wire transfers and database access) -The crypto helpers must be started before the ``taler-exchange-httpd`` and +The crypto helpers (``secmod``) must be started before the ``taler-exchange-httpd`` and they should use the same configuration file. For the most secure deployment, we recommend using separate users for each of @@ -1724,18 +1467,77 @@ missed. attack surface.) -.. _Keys-generation: +Given proper packaging, all of the above are realized via a simple systemd +target. This enables the various processes of an exchange service to be +started using a simple command: -Keys generation ---------------- +.. 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, Key Maintenance and Tear-Down +==================================================== + +The exchange HTTP service must be running before you can complete the +following offline signing procedure. Note that when an exchange is running +without offline keys its not fully operational. To make the exchange HTTP +service fully 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. + +A typical minimal setup would look something like this: + +.. code-block:: shell-session + + [anybody@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 > fee-response.json + [root@exchange-offline]# taler-exchange-offline \ + global-fee now EUR:0 EUR:0 EUR:0 4w 6y 4 > global-response.json + + [anybody@exchange-online]# taler-exchange-offline upload < sig-response.json + [anybody@exchange-online]# taler-exchange-offline upload < acct-response.json + [anybody@exchange-online]# taler-exchange-offline upload < fee-response.json + [anybody@exchange-online]# taler-exchange-offline upload < global-response.json + +The following sections will discuss these steps in more depth. + +.. _Keys-generation: -Once the configuration is properly set up, all the keys can be signed using -the offline key on the offline system by the tool ``taler-exchange-offline``. -To do this, one must first start the crypto helpers and the ``taler-exchange-httpd`` -process (the tools for wire transfers may also be started, but do not have to -run yet). +Signing the online signing keys +------------------------------- -Next, the *future* key material should be downloaded using: +To sign the online signing keys, first the *future* key material should be downloaded using: .. code-block:: console @@ -1766,57 +1568,103 @@ that is able to again communicate with the exchange. On that system, run: $ taler-exchange-offline upload < offline-sigs.json -to provision the signatures to the exchange. At this point, the -exchange will be able to use those keys, but wallets and merchants -may not yet trust them! Thus, the next step is for the auditor -to affirm that they are auditing this exchange. Details about -this are described in :doc:`taler-auditor-manual`. +to provision the signatures to the exchange. -The simplistic (without using offline keys for the auditor) way -to do this would be: +The ``download sign upload`` sequence in the commands above has to be done +periodically, as it signs the various online signing keys of the exchange +which periodically expire. + + +Account signing +--------------- + +The ``enable-account`` step is important to must be used to sign the +``payto://`` URI in a way suitable to convince wallets that this is the +correct address to wire funds to. Note that for each bank account, additional +options **must** be set in the configuration file to tell the exchange how to +access the bank account. The offline tool *only* configures the externally +visible portions of the setup. The chapter on `Bank account <_Bank-account>`_ configuration has further details. + +taler-exchange-offline accepts additional options to configure the use of the +account. For example, additional options can be used to add currency +conversion or to restrict interactions to bank accounts from certain +countries: .. code-block:: console - $ taler-auditor-offline download sign upload + $ taler-exchange-offline \ + enable-account payto://iban/CH9300762011623852957 + conversion-url https://conversion.example.com/ -For more information, see :doc:`manpages/taler-auditor-offline.1`. +For details on optional ``enable-account`` arguments, +see :doc:`manpages/taler-exchange-offline.1`. +.. _Wire-fee-structure: -Private key storage -------------------- +Wire fee structure +------------------ -Keeping the private keys the helpers create secret is paramount. If the -private keys are lost, it is easy to provision fresh keys (with the help of -the auditor). Thus, we recommend that the private keys of the crypto helpers -are *not* backed up: in the rare event of a disk failure, they can be -regenerated. However, we do recommend using RAID (1+1 or 1+1+1) for all -disks of the system. +.. index:: wire fee +.. index:: fee +For each wire method (“iban” or “x-taler-bank”) the +exchange must know about applicable wire fees. This is also done +using the ``taler-exchange-offline`` tool: -.. _Database-upgrades: +.. code-block:: console -Database upgrades ------------------ + $ taler-exchange-offline wire-fee 2040 iban EUR:0.05 EUR:0.10 -Currently, there is no way to upgrade the database between Taler -versions. +The above sets the wire fees for wire transfers involving ``iban`` accounts +(in Euros) in the year 2040 to 5 cents (wire fee) and 10 cents (closing fee). +The tool only supports setting fees that applies for the entire calendar year. -The exchange database can be re-initialized using: +We recommend provisioning an exchange with wire fees at least for the next two +years. Note that once the fees have been set for a year, they cannot be +changed (basically, by signing the fees the exchange makes a legally binding +offer to the customers). + +.. index:: maintenance +.. note:: + Provisioning future wire fees, like provisioning future denomination + and signing keys, are key regular maintenance procedures for every + exchange operator. We recommend setting automated reminders for + this maintenance activity! + + +.. _Auditor-configuration: + +Auditor configuration +--------------------- + +At this point, the exchange will be able to use those keys, but wallets and +merchants may not yet trust them! Thus, the next step is for an auditor to +affirm that they are auditing this exchange. Before an auditor can do this, +the exchange service must be informed about any auditor that is expected to +provision it with auditor signatures. + +This is also done using the ``taler-exchange-offline`` tool on the offline +system. First, the auditor must be configured and provide the exchange +operator with its public key (using ``taler-auditor-offline setup``) and the +URL of it's REST API. The exchange operator also needs a human-readable name +that may be shown to users to identify the auditor. For more information on +how to setup and operate an auditor, see +:doc:`manpages/taler-auditor-offline.1` and :doc:`taler-auditor-manual`. + +Given this information, the exchange operator can enable the auditor: .. code-block:: console - $ taler-exchange-dbinit -r + $ taler-exchange-offline enable-auditor $PUB_KEY $REST_URL "$AUDITOR_NAME" > auditor.json -However, running this command will result in all data in the database -being lost, which may result in significant financial liabilities as the -exchange can then not detect double-spending. Hence this operation must -not be performed in a production system. +As before, the *auditor.json* file must then be copied from the offline system +to a system connected to the exchange and there ``uploaded`` to the exchange using ``taler-exchange-offline upload``. .. _Revocations: Revocations -^^^^^^^^^^^ +----------- When an exchange goes out of business or detects that the private key of a denomination key pair has been compromised, it may revoke some or all @@ -1843,24 +1691,133 @@ of ``taler-exchange-offline``. under highly unusual (“emergency”) conditions and not in normal operation. -Testing a deployment -==================== + + +Setup Linting +============= + +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 +=========================== We recommend testing whether an exchange deployment is functional by using the Taler wallet command line interface. The tool can be used to withdraw and deposit electronic cash via the exchange without having to deploy and operate a -separate merchant backend and storefront. For more information, see -:doc:`taler-wallet-cli-manual`. +separate merchant backend and storefront. + +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 -.. _Diagnostics: +After enough time has passed, the money should arrive at the specified IBAN. + +For more information on the taler-wallet-cli tool, see +:doc:`taler-wallet`. + + +Private key storage +------------------- -Diagnostics -=========== +Keeping the private keys the helpers create secret is paramount. If the +private keys are lost, it is easy to provision fresh keys (with the help of +the auditor). Thus, we recommend that the private keys of the crypto helpers +are *not* backed up: in the rare event of a disk failure, they can be +regenerated. However, we do recommend using RAID (1+1 or 1+1+1) for all +disks of the system. -This chapter includes various sections on specific topics that might be -helpful to understand how the exchange operates. The information may also be -helpful for diagnostics. .. _Internal-audit: @@ -1908,6 +1865,27 @@ The database scheme used by the exchange looks as follows: .. image:: exchange-db.png +.. _Database-upgrades: + +Database upgrades +----------------- + +Currently, there is no way to upgrade the database between Taler +versions. + +The exchange database can be re-initialized using: + +.. code-block:: console + + $ taler-exchange-dbinit --reset + +However, running this command will result in all data in the database +being lost, which may result in significant financial liabilities as the +exchange can then not detect double-spending. Hence this operation must +not be performed in a production system. + + + .. _ExchangeBenchmarking: Benchmarking @@ -1922,13 +1900,13 @@ exchange and auditor. For the bank, both a "fakebank" (``-f``) and a clients, or only launch the parallel clients (``-m``), for example for distributed testing over a network. -For each *parallel* (``-p``) client, a number of *reserves* (``-r``) is first established by -**transferring** money from a "user" account (42) to the Exchange's account -with the respective reserve public key as wire subject. Next, the -client will **withdraw** a *number of coins* (``-n``) from the reserve and -**deposit** them. Additionally, a *fraction* (``-R``) of the dirty coins will then be -subject to **refreshing**. For some deposits, the auditor will receive -**deposit confirmations**. +For each *parallel* (``-p``) client, a number of *reserves* (``-r``) is first +established by **transferring** money from a "user" account (42) to the +Exchange's account with the respective reserve public key as wire subject. +Next, the client will **withdraw** a *number of coins* (``-n``) from the +reserve and **deposit** them. Additionally, a *fraction* (``-R``) of the dirty +coins will then be subject to **refreshing**. For some deposits, the auditor +will receive **deposit confirmations**. Operations that are not covered today include closing reserves, refunds and recoups. @@ -1953,8 +1931,8 @@ You can run a first simple benchmark using: $ taler-exchange-offline -c benchmark.conf \ download sign \ enable-account payto://iban/CH9300762011623852957 \ - wire-fee iban EUR:0 EUR:0 EUR:0 \ - global-fee EUR:0 EUR:0 EUR:0 EUR:0 4w 4w 6y 4 \ + wire-fee iban EUR:0 EUR:0 \ + global-fee EUR:0 EUR:0 EUR:0 4w 6y 4 \ upload $ kill -TERM $HTTPD_PID $ taler-exchange-benchmark -c benchmark.conf -p 4 -r 1 -n 10 @@ -1986,5 +1964,4 @@ FIXMEs * 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! - +* This document (still) duplicates some details, should be de-duplicated!