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.