security: fix audit points 5-9 + optimize echo_push/info endpoints
- Point 5 (SSRF): Add URL validation for WELIST_SERVER_URL (src/validation.rs) - Point 6 (DB Access): Add DB path validation, symlink check, WAL mode (open_db) - Point 8 (HTTPS): Extract nginx config, add deployment checklist, bind warnings - Point 9 (Input Validation): Add NETWORKS check (404 for unknown), txid 64-hex validation - Optimize echo_push: parse transactions outside DB lock, batch duplicate check, N+1 xpub lookup eliminated via HashSet cache - Optimize echo_info: derive BIP32 address outside DB lock, minimize lock duration - Fix echo_stats SQL injection via parameter binding + add idx_stats_chain index - New regression tests: ssrf_tests, db_path_validation, input_validation_tests
This commit is contained in:
@@ -176,6 +176,46 @@ server {
|
||||
|
||||
---
|
||||
|
||||
## Production Deployment Checklist
|
||||
|
||||
Before exposing `bal` to the internet, verify the following steps. The `bal-server` is a plain HTTP application and must **never** be bound directly to a public IP or `0.0.0.0`.
|
||||
|
||||
### 1. `bal-server` Bind Address
|
||||
- [ ] `bal-server.env` (or `.env`) sets `BAL_SERVER_BIND_ADDRESS=127.0.0.1` (not `0.0.0.0`).
|
||||
- [ ] `BAL_SERVER_BIND_PORT` is the port used by Nginx `proxy_pass` (default `9137`).
|
||||
- [ ] Firewall blocks inbound connections to `BAL_SERVER_BIND_PORT` from external interfaces (e.g., `iptables -A INPUT -p tcp --dport 9137 -s 127.0.0.1 -j ACCEPT` and `DROP` for others).
|
||||
|
||||
### 2. Reverse Proxy (Nginx + TLS)
|
||||
- [ ] Nginx is installed (`contrib/download_and_install_bal.sh` handles this).
|
||||
- [ ] The template `contrib/nginx/bal-server.conf` is copied to `/etc/nginx/sites-available/` and symlinked to `sites-enabled`.
|
||||
- [ ] The file has a real domain name replacing `BAL_DOMAIN`.
|
||||
- [ ] `listen 443 ssl http2;` is active.
|
||||
- [ ] `certbot` or an equivalent CA has provided a valid certificate.
|
||||
- [ ] `proxy_pass` points to `http://127.0.0.1:9137` (or whatever `BAL_SERVER_BIND_PORT` is).
|
||||
- [ ] `client_max_body_size` in Nginx matches `BAL_SERVER_ACTIX_MAX_BODY_SIZE` (default `1m`).
|
||||
- [ ] HTTP port 80 redirects to HTTPS (`return 301 https://...`).
|
||||
- [ ] Nginx `limit_req` zone is configured if desired (backup to `actix-governor`).
|
||||
|
||||
### 3. Database and Secrets
|
||||
- [ ] Database file is owned by the `bal` user (`chown bal:bal /var/bal/bal.db`).
|
||||
- [ ] Database file permissions are `600` (`chmod 600 /var/bal/bal.db`).
|
||||
- [ ] `.env` file is in `.gitignore` and not committed.
|
||||
- [ ] `private_key.pem` and `privkey.pem` are not in the repository (use `git ls-files` to verify).
|
||||
- [ ] `public_key.pem` is readable by Nginx if served directly (otherwise let the actix endpoint handle it).
|
||||
|
||||
### 4. Pusher and ZMQ
|
||||
- [ ] ZMQ endpoints are configured for `127.0.0.1` only (e.g., `tcp://127.0.0.1:28332`).
|
||||
- [ ] `BAL_PUSHER_SEND_STATS` is set to `false` unless the `welist` endpoint is actually needed.
|
||||
- [ ] If stats are enabled, `WELIST_SERVER_URL` is a valid external HTTPS domain (not IP, not local).
|
||||
- [ ] Firewall blocks inbound TCP port `28332` (or your custom `bitcoin`, `regtest`, etc. ZMQ ports) from external interfaces.
|
||||
|
||||
### 5. Logging and Monitoring
|
||||
- [ ] `RUST_LOG` is set to `info` or `warn` in production (not `debug` or `trace`).
|
||||
- [ ] Log files are rotated (e.g., via `logrotate`) and stored only under `/var/log/bal/` or systemd journal.
|
||||
- [ ] Log files are not in the same directory as the database or the private key.
|
||||
|
||||
---
|
||||
|
||||
## Tor and Privacy
|
||||
|
||||
The `contrib/install_tor.sh` script installs Tor for use as an onion-routed proxy. It can be used to:
|
||||
|
||||
Reference in New Issue
Block a user