diff --git a/.gitignore b/.gitignore index 9333d3e..6391ab8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +# SSL certificates (auto-generated or user-provided) +/certs/ + # ElectrumX server data /electrumx-data/ diff --git a/Dockerfile.electrumx b/Dockerfile.electrumx index 4282930..c2cd688 100644 --- a/Dockerfile.electrumx +++ b/Dockerfile.electrumx @@ -1,7 +1,7 @@ FROM lukechilds/electrumx # Install curl (needed by entrypoint for RPC calls and IP detection) -RUN apk add --no-cache curl || apt-get update && apt-get install -y --no-install-recommends curl && rm -rf /var/lib/apt/lists/* +RUN apk add --no-cache curl openssl || apt-get update && apt-get install -y --no-install-recommends curl openssl && rm -rf /var/lib/apt/lists/* # Copy Palladium coin definition and patch ElectrumX COPY electrumx-patch/coins_plm.py /tmp/coins_plm.py @@ -28,34 +28,6 @@ for target in [ print('>> Patched ElectrumX with Palladium coin classes') PATCH -RUN mkdir -p /certs && \ - cat >/certs/openssl.cnf <<'EOF' && \ - openssl req -x509 -nodes -newkey rsa:4096 -days 3650 \ - -keyout /certs/server.key -out /certs/server.crt \ - -config /certs/openssl.cnf && \ - chmod 600 /certs/server.key && chmod 644 /certs/server.crt -[req] -distinguished_name = dn -x509_extensions = v3_req -prompt = no - -[dn] -C = IT -ST = - -L = - -O = ElectrumX -CN = plm.local - -[v3_req] -keyUsage = keyEncipherment, dataEncipherment, digitalSignature -extendedKeyUsage = serverAuth -subjectAltName = @alt_names - -[alt_names] -DNS.1 = plm.local -IP.1 = 127.0.0.1 -EOF - ENV SSL_CERTFILE=/certs/server.crt ENV SSL_KEYFILE=/certs/server.key diff --git a/README.md b/README.md index 8fe5b3a..5d1cae6 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,9 @@ palladium-stack/ │ ├── blocks/ # Blockchain blocks (auto-generated) │ ├── chainstate/ # Blockchain state (auto-generated) │ └── ... # Other runtime data (auto-generated) +├── certs/ # SSL certificates (auto-generated on first run) +│ ├── server.crt # Self-signed certificate +│ └── server.key # Private key ├── electrumx-data/ # ElectrumX database (auto-generated) ├── web-dashboard/ # Web monitoring dashboard │ ├── app.py # Flask backend API @@ -271,7 +274,7 @@ docker compose up -d **What happens:** 1. Builds three Docker images: `palladium-node`, `electrumx-server`, and `palladium-dashboard` 2. Starts Palladium node first -3. Starts ElectrumX (waits for node to be ready) +3. Starts ElectrumX (waits for node to be ready, auto-generates SSL certificates in `./certs/` if not present) 4. Starts Web Dashboard (connects to both services) **First build takes 5-10 minutes.** @@ -455,8 +458,6 @@ Key settings in `.palladium/palladium.conf`: | `port=2333` | Default | P2P network port (mainnet) | | `rpcport=2332` | Default | RPC port (mainnet) | -**Important:** current `docker-compose.yml` starts `palladiumd` with command-line `-rpcallowip=0.0.0.0/0`, which overrides `rpcallowip` values in `palladium.conf`. Keep this in mind for security hardening. - **ZeroMQ Ports (optional):** - `28332` - Block hash notifications - `28333` - Transaction hash notifications @@ -680,8 +681,9 @@ docker compose build --no-cache ``` 3. **SSL Certificates:** - - Default uses self-signed certificates - - For production, use valid SSL certificates (Let's Encrypt) + - Self-signed certificates are auto-generated on first startup in `./certs/` + - The certificate includes localhost and the auto-detected public IP in its SAN + - To use your own certificates (e.g. Let's Encrypt), place `server.crt` and `server.key` in `./certs/` before starting 4. **Dashboard Access:** - Consider adding authentication @@ -744,7 +746,7 @@ environment: ## Notes -* **Data Persistence:** All data stored in `./.palladium/` and `./electrumx-data/` +* **Data Persistence:** All data stored in `./.palladium/`, `./electrumx-data/`, and `./certs/` * **Backup:** Regularly backup `.palladium/wallet.dat` if you store funds * **Network Switch:** Always clear ElectrumX database when switching networks * **Updates:** Check for Palladium Core updates regularly diff --git a/docker-compose.yml b/docker-compose.yml index ea9c269..1901a89 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -72,6 +72,7 @@ services: volumes: - ./electrumx-data:/data - ./.palladium/palladium.conf:/palladium-config/palladium.conf:ro + - ./certs:/certs dashboard: build: diff --git a/entrypoint.sh b/entrypoint.sh index d4b4cd8..dd120aa 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -70,6 +70,61 @@ echo "DAEMON_URL: http://${RPC_USER}:***@palladiumd:${RPC_PORT}/" echo "REPORT_SERVICES: ${REPORT_SERVICES:-not set}" echo "==========================================" +# ── SSL certificate generation (skip if certs already exist) ── +if [ ! -f /certs/server.crt ] || [ ! -f /certs/server.key ]; then + echo "SSL certificates not found, generating self-signed certificate..." + + # Collect SAN entries + SAN="DNS.1 = localhost" + SAN_IDX=1 + IP_IDX=1 + SAN="${SAN}\nIP.${IP_IDX} = 127.0.0.1" + + # Try to detect public IP for SAN + for url in https://icanhazip.com https://ifconfig.me https://api.ipify.org; do + DETECTED_IP=$(curl -sf --max-time 5 "$url" 2>/dev/null | tr -d '[:space:]') + if [ -n "$DETECTED_IP" ]; then + IP_IDX=$((IP_IDX + 1)) + SAN="${SAN}\nIP.${IP_IDX} = ${DETECTED_IP}" + echo ">> Including public IP in certificate SAN: ${DETECTED_IP}" + break + fi + done + + cat >/tmp/openssl.cnf </dev/null + + chmod 600 /certs/server.key + chmod 644 /certs/server.crt + rm -f /tmp/openssl.cnf + echo ">> SSL certificate generated successfully" +else + echo ">> Using existing SSL certificates from /certs/" +fi + # Update TX_COUNT / TX_COUNT_HEIGHT in coins.py from the live node echo "Fetching chain tx stats from palladiumd..." TX_STATS=$(curl -sf --user "${RPC_USER}:${RPC_PASSWORD}" \