taler-deployment

Deployment scripts and configuration files
Log | Files | Refs | README

README.md (8245B)


      1 GNU Taler regional currency deployment
      2 ======================================
      3 
      4 This directory contains a normal Ansible deployment for a single-host GNU
      5 Taler regional currency. An operator runs Ansible over SSH; no repository
      6 checkout or setup script is needed on the managed server.
      7 
      8 Requirements
      9 ------------
     10 
     11 The operator machine needs Python 3 and `ansible-core` 2.20 or newer. The
     12 managed host must:
     13 
     14 - run a supported Debian or Ubuntu release with PostgreSQL 15 or newer;
     15 - be reachable over SSH by a user that can become root;
     16 - have `bank.DOMAIN`, `exchange.DOMAIN`, and `backend.DOMAIN` resolve to it;
     17 - have `DOMAIN` resolve to it when the landing page is enabled (the default);
     18 - allow inbound HTTP and, when TLS is enabled, HTTPS traffic.
     19 
     20 Create an inventory
     21 -------------------
     22 
     23 Run the inventory wizard on the operator machine:
     24 
     25 ```console
     26 $ cd regional-currency-ng
     27 $ ./inventory-wizard.py
     28 ```
     29 
     30 Alternatively, copy `inventory.example.yml`, remove the host example that does
     31 not apply, and adjust every host, domain, contact, and password value:
     32 
     33 ```console
     34 $ cp inventory.example.yml inventory/HOST.yml
     35 $ chmod 0600 inventory/HOST.yml
     36 $ editor inventory/HOST.yml
     37 ```
     38 
     39 The example contains one normal deployment without conversion and one testing
     40 deployment with simulated CHF conversion. Do not leave both example hosts in a
     41 live inventory unless both are intentional targets.
     42 
     43 `./main.sh` is retained as a compatibility alias for the wizard. The wizard
     44 only asks questions and creates one ordinary Ansible inventory file for each
     45 target:
     46 
     47 ```text
     48 inventory/HOST.yml
     49 ```
     50 
     51 Each file contains that target's SSH connection and regional-currency
     52 variables, is created with mode `0600`, and generated inventories are ignored
     53 by Git. The file is plain YAML. There is no custom secret format or encryption
     54 layer.
     55 
     56 The wizard is incremental. Run it again with the same inventory directory to
     57 add another target file. Enter an existing inventory host name to update only
     58 that target's file; the current settings become the prompt defaults and custom
     59 variables are preserved. An encrypted target file must be decrypted with
     60 `ansible-vault decrypt` before the wizard can update it.
     61 
     62 If the inventory should be encrypted, use Ansible Vault directly:
     63 
     64 ```console
     65 $ ansible-vault encrypt inventory/HOST.yml
     66 ```
     67 
     68 Use `--ask-vault-pass` or the usual Ansible vault-password options on later
     69 commands.
     70 
     71 Deploy
     72 ------
     73 
     74 Check SSH and privilege escalation first, then run the playbook:
     75 
     76 ```console
     77 $ ansible -i inventory regional_currency -m ping
     78 $ ansible-playbook -i inventory site.yml
     79 ```
     80 
     81 Add `--ask-become-pass` when the SSH user's sudo configuration requires a
     82 password.
     83 
     84 For an encrypted target inventory file:
     85 
     86 ```console
     87 $ ansible-playbook --ask-vault-pass \
     88     -i inventory site.yml
     89 ```
     90 
     91 Running the playbook again reconciles the host with the inventory. Ansible
     92 installs the Taler packages, configures nginx and optional Let's Encrypt TLS,
     93 initializes LibEuFin, the exchange, and the merchant backend, and starts their
     94 systemd units. Every normal playbook run upgrades the packages managed by this
     95 role to the newest versions offered by the configured APT repositories. Take a
     96 database and configuration backup before running the playbook when an upstream
     97 upgrade may require operational rollback.
     98 
     99 The deployed currency and domain are recorded on the server after the first
    100 successful run. Once fiat conversion is active, its currency and account
    101 identity are recorded as well. The role refuses later inventory changes to
    102 these identity values because changing them in place requires a separately
    103 planned migration. Enabling conversion on a deployment that did not previously
    104 use it is supported.
    105 
    106 Runtime-generated values
    107 ------------------------
    108 
    109 The LibEuFin exchange-account payto URI and its wire-gateway token are created
    110 on the managed host. They are stored root-only below
    111 `/var/lib/taler-regional-currency` so subsequent Ansible runs reuse them. The
    112 exchange offline private key remains owned by the
    113 `taler-exchange-offline` account. These values are never copied into the
    114 operator inventory.
    115 
    116 This deployment intentionally performs exchange master-key signing online on
    117 the regional-currency host. A daily systemd timer signs newly generated keys
    118 and keeps fee schedules available for the current and following calendar year.
    119 This favors unattended operation for a small regional deployment, but an
    120 attacker who compromises the host may also gain the master signing key. It is
    121 not the split online/offline arrangement recommended for higher-value exchange
    122 deployments.
    123 
    124 On a fresh exchange, generated denominations use a one-month withdrawal
    125 period. The role deliberately never rewrites an installed denomination
    126 configuration; denomination attributes are immutable after their first use.
    127 
    128 After deployment
    129 ----------------
    130 
    131 The services are available at:
    132 
    133 - `https://DOMAIN/` (or HTTP when TLS is disabled), with links to the services;
    134 - `https://bank.DOMAIN/` (or HTTP when TLS is disabled);
    135 - `https://exchange.DOMAIN/`;
    136 - `https://backend.DOMAIN/`.
    137 
    138 The landing page is enabled by default. Set
    139 `regional_currency_enable_landing_page: false` in the target inventory to
    140 remove its static files and bare-domain nginx virtual host. The service
    141 subdomains remain available.
    142 
    143 When fiat conversion is enabled, complete the LibEuFin Nexus EBICS enrollment
    144 with the bank while `regional_currency_enable_nexus_services` remains `false`.
    145 Then set it to `true` in that host's inventory and run the playbook again. The
    146 role first checks one transient fetch and submit before enabling the continuous
    147 Nexus services. Setting the variable back to `false` stops and disables them.
    148 The inventory wizard asks about this switch only for conversion deployments.
    149 
    150 For a conversion deployment without a real fiat bank connection, set
    151 `regional_currency_conversion_test_mode: true`. This is restricted to testing
    152 deployments, keeps the Nexus workers disabled, and retains initiated cash-out
    153 payments for inspection. See [CONVERSION-TESTING.md](CONVERSION-TESTING.md) for
    154 the complete command-line wallet, simulated cash-in, and cash-out runbook.
    155 
    156 The nginx proxy limits token creation to 30 requests per minute per client IP
    157 and challenge requests to 10 requests per minute by default. Operators can
    158 tune `regional_currency_bank_token_rate`,
    159 `regional_currency_bank_token_burst`,
    160 `regional_currency_bank_challenge_rate`, and
    161 `regional_currency_bank_challenge_burst` in the host inventory.
    162 
    163 Merchant instances and their credentials must be created separately.
    164 
    165 Dangerously reset a test exchange
    166 ---------------------------------
    167 
    168 The destructive reset playbook deletes the exchange database, all offline and
    169 online exchange keys, and the generated denomination configuration. It then
    170 uses the normal regional-currency role to provision a new exchange and update
    171 the merchant with the new exchange master public key. Existing coins, reserves,
    172 and exchange-related payment state become permanently unusable.
    173 
    174 The playbook refuses inventories where
    175 `regional_currency_testing_deployment` is not `true`. Limit each invocation to
    176 the intended target:
    177 
    178 ```console
    179 $ ansible-playbook -i inventory dangerously-reset-exchange.yml --limit HOST
    180 ```
    181 
    182 For each host, enter the displayed domain-specific confirmation phrase. The
    183 playbook processes hosts one at a time so one confirmation cannot authorize a
    184 different target accidentally.
    185 
    186 The reset preserves the LibEuFin bank database, the exchange bank account and
    187 token, the merchant database, TLS state, and the recorded deployment identity.
    188 Because the fresh exchange database has no previous wirewatch position, it may
    189 observe historical incoming transfers from the preserved bank account again.
    190 This playbook is therefore suitable only for disposable testing deployments.
    191 
    192 If normal reprovisioning fails after deletion, correct the reported problem and
    193 run `site.yml` to finish reconciling the deployment. The deleted test data and
    194 keys cannot be recovered by the playbooks.
    195 
    196 The `diagnose.sh` and `list-incoming.sh` scripts are server-side diagnostic
    197 utilities, not deployment or upgrade entry points. All deployment and package
    198 upgrade work is performed by `ansible-playbook` from the operator machine.