release: 1.1.2 (latest)
- HSTS activé sur Nginx - Scripts de déploiement initial (avec/sans certificats) - Docs installation/configuration enrichies (webroot, renouvellement, déploiement)
This commit is contained in:
parent
538aab294b
commit
3488b497de
17
CHANGELOG.md
17
CHANGELOG.md
@ -1,4 +1,15 @@
|
||||
# Changelog - 4NK Node
|
||||
## [1.1.2] - 2025-08-27
|
||||
|
||||
### Added
|
||||
- Scripts de déploiement initial:
|
||||
- `scripts/deploy_first_install_with_certs.sh` (Let’s Encrypt webroot + cron de renouvellement)
|
||||
- `scripts/deploy_first_install_no_certs.sh` (auto‑signé)
|
||||
|
||||
### Changed
|
||||
- Nginx: activation de HSTS (Strict‑Transport‑Security) sur l’hôte public
|
||||
- Documentation: INSTALLATION.md et CONFIGURATION.md enrichies (webroot ACME, renouvellement, déploiement automatisé)
|
||||
|
||||
|
||||
Tous les changements notables de ce projet seront documentés dans ce fichier.
|
||||
|
||||
@ -63,10 +74,16 @@ et ce projet adhère au [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
||||
### Changed
|
||||
- `docker-compose.yml` : ajout d’un mini serveur HTTP (busybox httpd) sur `sdk_signer` pour l’endpoint de santé interne 9092, exposé via Nginx en `/signer/health`.
|
||||
- `sdk_relay/healthcheck.sh` : assouplissement du healthcheck (attente d’un indicateur de démarrage) pour éviter les faux négatifs durant la phase de rescan/initialisation.
|
||||
- CI : publication automatique des releases sur push de tag `v*` via secret `RELEASE_TOKEN`.
|
||||
|
||||
### Fixed
|
||||
- `/signer/health` retournait 502 via le reverse proxy ; désormais HTTP 200 avec corps `ok`.
|
||||
|
||||
### Added
|
||||
- Scripts de déploiement initial:
|
||||
- `scripts/deploy_first_install_with_certs.sh` (Let’s Encrypt webroot, cron de renouvellement)
|
||||
- `scripts/deploy_first_install_no_certs.sh` (auto‑signé)
|
||||
|
||||
## [1.0.0] - 2024-12-19
|
||||
|
||||
### Added
|
||||
|
@ -235,6 +235,7 @@ services:
|
||||
- ./proxy/nginx.conf:/etc/nginx/conf.d/default.conf:ro
|
||||
- ./certs:/etc/nginx/certs:ro
|
||||
- ./ihm_client/dist:/usr/share/nginx/html:ro
|
||||
- ./acme:/var/www/certbot:ro
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
|
@ -597,6 +597,24 @@ sudo certbot --nginx -d your-domain.com
|
||||
sudo certbot renew --dry-run
|
||||
```
|
||||
|
||||
### 3. Production (webroot, HSTS et renouvellement)
|
||||
|
||||
- Le reverse proxy sert les challenges ACME en HTTP: `/.well-known/acme-challenge/` via le montage `./acme -> /var/www/certbot`.
|
||||
- Le certificat de production est installé dans `./certs/server.crt` et `./certs/server.key`.
|
||||
- HSTS est activé par défaut (entête `Strict-Transport-Security: max-age=31536000; includeSubDomains`).
|
||||
- Renouvellement: script idempotent `scripts/renew_certs.sh` (webroot certbot + reload Nginx).
|
||||
- Déploiement initial automatisé: `scripts/deploy_first_install_with_certs.sh` (avec certificats) ou `scripts/deploy_first_install_no_certs.sh` (auto‑signé).
|
||||
|
||||
Exécution manuelle:
|
||||
```bash
|
||||
./scripts/renew_certs.sh
|
||||
```
|
||||
|
||||
Cron (quotidien à 03:00):
|
||||
```bash
|
||||
0 3 * * * /home/debian/4NK_node/scripts/renew_certs.sh >> /home/debian/4NK_node/logs/cert_renew.log 2>&1
|
||||
```
|
||||
|
||||
## 🔧 Configuration de Monitoring
|
||||
|
||||
### 1. Prometheus
|
||||
|
@ -172,6 +172,27 @@ chmod +x scripts/generate_certs.sh
|
||||
./scripts/generate_certs.sh
|
||||
```
|
||||
|
||||
#### (Option production) Certificats Let’s Encrypt + HSTS
|
||||
|
||||
Pré-requis : le DNS du domaine (ex. `dev4.4nkweb.com`) pointe vers le serveur et le port 80 est accessible.
|
||||
|
||||
1) Le reverse proxy expose le webroot ACME en HTTP sur `/.well-known/acme-challenge/` (répertoire local `./acme`).
|
||||
|
||||
2) Émettre/renouveler et installer le certificat :
|
||||
```bash
|
||||
chmod +x scripts/renew_certs.sh
|
||||
./scripts/renew_certs.sh
|
||||
```
|
||||
|
||||
3) Activer un cron quotidien (03:00) :
|
||||
```bash
|
||||
0 3 * * * /home/debian/4NK_node/scripts/renew_certs.sh >> /home/debian/4NK_node/logs/cert_renew.log 2>&1
|
||||
```
|
||||
|
||||
Notes :
|
||||
- Les fichiers sont installés dans `./certs/server.crt` et `./certs/server.key` (droits: 0644/0600).
|
||||
- HSTS est activé par défaut sur le reverse proxy.
|
||||
|
||||
### 4. Configuration Bitcoin Core
|
||||
|
||||
```bash
|
||||
@ -268,6 +289,18 @@ relay_id=relay-1 # Changer pour chaque relay
|
||||
|
||||
## 🚀 Démarrage
|
||||
|
||||
### Déploiement automatisé (première installation)
|
||||
|
||||
Deux scripts facilitent l’installation complète A→Z :
|
||||
|
||||
- Avec certificats Let’s Encrypt (domaine requis):
|
||||
- `scripts/deploy_first_install_with_certs.sh --domain dev4.4nkweb.com --email admin@exemple.com [--skip-ui]`
|
||||
- Actions: préparation des dossiers, lancement du proxy pour ACME, émission LE en webroot, installation dans `./certs/`, démarrage complet, cron de renouvellement, vérifications.
|
||||
|
||||
- Sans certificats (auto‑signé):
|
||||
- `scripts/deploy_first_install_no_certs.sh [--skip-ui]`
|
||||
- Actions: génération auto‑signée via `scripts/generate_certs.sh`, démarrage complet, vérifications locales.
|
||||
|
||||
### 1. Démarrage Complet
|
||||
|
||||
```bash
|
||||
|
@ -1,6 +1,18 @@
|
||||
server {
|
||||
listen 80;
|
||||
return 301 https://$host$request_uri;
|
||||
server_name dev4.4nkweb.com;
|
||||
|
||||
# ACME HTTP-01 challenge (Let’s Encrypt)
|
||||
location ^~ /.well-known/acme-challenge/ {
|
||||
alias /var/www/certbot/.well-known/acme-challenge/;
|
||||
default_type text/plain;
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
# Redirection par défaut vers HTTPS
|
||||
location / {
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
@ -19,6 +31,7 @@ server {
|
||||
add_header X-Content-Type-Options nosniff always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
||||
# CSP minimale (adapter selon besoins)
|
||||
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; connect-src 'self' ws: wss: http: https:; img-src 'self' data:;" always;
|
||||
|
||||
|
40
scripts/deploy_first_install_no_certs.sh
Normal file
40
scripts/deploy_first_install_no_certs.sh
Normal file
@ -0,0 +1,40 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Déploiement initial A→Z sans certificats (auto-signé local)
|
||||
# Usage: ./scripts/deploy_first_install_no_certs.sh [--skip-ui]
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
BUILD_UI=1
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--skip-ui) BUILD_UI=0; shift;;
|
||||
*) echo "Option inconnue: $1" >&2; exit 2;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo "[1/5] Préparation des dossiers (certs)"
|
||||
mkdir -p "$ROOT_DIR/certs"
|
||||
|
||||
echo "[2/5] Génération de certificats auto-signés (script projet)"
|
||||
if [[ -x "$ROOT_DIR/scripts/generate_certs.sh" ]]; then
|
||||
( cd "$ROOT_DIR" && ./scripts/generate_certs.sh )
|
||||
else
|
||||
echo "scripts/generate_certs.sh introuvable ou non exécutable. Abandon." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[3/5] Optionnel: build UI locale (ihm_client/dist)"
|
||||
if [[ $BUILD_UI -eq 1 && -x "$ROOT_DIR/scripts/build_ui_local.sh" ]]; then
|
||||
( cd "$ROOT_DIR" && ./scripts/build_ui_local.sh ) || true
|
||||
fi
|
||||
|
||||
echo "[4/5] Démarrage complet de l’infrastructure (build si nécessaire)"
|
||||
docker compose -f "$ROOT_DIR/docker-compose.yml" up -d --build
|
||||
|
||||
echo "[5/5] Vérifications rapides"
|
||||
curl -skI https://127.0.0.1/signer/health | head -n 1 || true
|
||||
curl -skI https://127.0.0.1/ | head -n 1 || true
|
||||
|
||||
echo "Déploiement initial (auto-signé) terminé. Accès local: https://127.0.0.1/"
|
63
scripts/deploy_first_install_with_certs.sh
Normal file
63
scripts/deploy_first_install_with_certs.sh
Normal file
@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Déploiement initial A→Z avec certificats Let’s Encrypt (webroot)
|
||||
# Usage: ./scripts/deploy_first_install_with_certs.sh --domain dev4.4nkweb.com --email admin@example.com [--skip-ui]
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
DOMAIN=""
|
||||
EMAIL=""
|
||||
BUILD_UI=1
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--domain) DOMAIN="$2"; shift 2;;
|
||||
--email) EMAIL="$2"; shift 2;;
|
||||
--skip-ui) BUILD_UI=0; shift;;
|
||||
*) echo "Option inconnue: $1" >&2; exit 2;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ -z "$DOMAIN" || -z "$EMAIL" ]]; then
|
||||
echo "Erreur: --domain et --email sont requis" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
echo "[1/8] Préparation des dossiers (acme/letsencrypt/certs)"
|
||||
mkdir -p "$ROOT_DIR/acme/.well-known/acme-challenge" \
|
||||
"$ROOT_DIR/letsencrypt" \
|
||||
"$ROOT_DIR/letsencrypt_lib" \
|
||||
"$ROOT_DIR/certs"
|
||||
chmod -R 755 "$ROOT_DIR/acme"
|
||||
|
||||
echo "[2/8] Optionnel: build UI locale (ihm_client/dist)"
|
||||
if [[ $BUILD_UI -eq 1 && -x "$ROOT_DIR/scripts/build_ui_local.sh" ]]; then
|
||||
( cd "$ROOT_DIR" && ./scripts/build_ui_local.sh ) || true
|
||||
fi
|
||||
|
||||
echo "[3/8] Démarrage du reverse proxy pour le challenge ACME"
|
||||
docker compose -f "$ROOT_DIR/docker-compose.yml" up -d --no-deps reverse_proxy
|
||||
|
||||
echo "[4/8] Émission du certificat (Let’s Encrypt, webroot) pour $DOMAIN"
|
||||
docker run --rm \
|
||||
-v "$ROOT_DIR/acme:/var/www/certbot" \
|
||||
-v "$ROOT_DIR/letsencrypt:/etc/letsencrypt" \
|
||||
-v "$ROOT_DIR/letsencrypt_lib:/var/lib/letsencrypt" \
|
||||
certbot/certbot certonly --webroot -w /var/www/certbot -d "$DOMAIN" --email "$EMAIL" --agree-tos --non-interactive
|
||||
|
||||
echo "[5/8] Installation des fichiers de cert dans ./certs"
|
||||
install -m 0644 "$ROOT_DIR/letsencrypt/live/$DOMAIN/fullchain.pem" "$ROOT_DIR/certs/server.crt"
|
||||
install -m 0600 "$ROOT_DIR/letsencrypt/live/$DOMAIN/privkey.pem" "$ROOT_DIR/certs/server.key"
|
||||
|
||||
echo "[6/8] Démarrage complet de l’infrastructure (build si nécessaire)"
|
||||
docker compose -f "$ROOT_DIR/docker-compose.yml" up -d --build
|
||||
|
||||
echo "[7/8] Mise en place du renouvellement automatique (cron 03:00)"
|
||||
chmod +x "$ROOT_DIR/scripts/renew_certs.sh" || true
|
||||
(sudo crontab -l 2>/dev/null; echo "0 3 * * * $ROOT_DIR/scripts/renew_certs.sh >> $ROOT_DIR/logs/cert_renew.log 2>&1") | sudo crontab -
|
||||
|
||||
echo "[8/8] Vérifications rapides"
|
||||
curl -skI "https://$DOMAIN" | head -n 1 || true
|
||||
curl -skI "https://$DOMAIN/signer/health" | head -n 1 || true
|
||||
|
||||
echo "Déploiement initial terminé. Domaine: https://$DOMAIN"
|
32
scripts/renew_certs.sh
Executable file
32
scripts/renew_certs.sh
Executable file
@ -0,0 +1,32 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
DOMAIN="dev4.4nkweb.com"
|
||||
EMAIL="admin@4nkweb.com"
|
||||
ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
|
||||
mkdir -p "$ROOT_DIR/acme/.well-known/acme-challenge" "$ROOT_DIR/letsencrypt" "$ROOT_DIR/letsencrypt_lib" "$ROOT_DIR/certs"
|
||||
|
||||
# Renew certificates using the same webroot method (volumes must be consistent)
|
||||
docker run --rm \
|
||||
-v "$ROOT_DIR/acme:/var/www/certbot" \
|
||||
-v "$ROOT_DIR/letsencrypt:/etc/letsencrypt" \
|
||||
-v "$ROOT_DIR/letsencrypt_lib:/var/lib/letsencrypt" \
|
||||
certbot/certbot renew --non-interactive || true
|
||||
|
||||
# Fallback: issue if missing (first time)
|
||||
if [ ! -f "$ROOT_DIR/letsencrypt/live/$DOMAIN/fullchain.pem" ]; then
|
||||
docker run --rm \
|
||||
-v "$ROOT_DIR/acme:/var/www/certbot" \
|
||||
-v "$ROOT_DIR/letsencrypt:/etc/letsencrypt" \
|
||||
-v "$ROOT_DIR/letsencrypt_lib:/var/lib/letsencrypt" \
|
||||
certbot/certbot certonly --webroot -w /var/www/certbot -d "$DOMAIN" --email "$EMAIL" --agree-tos --non-interactive
|
||||
fi
|
||||
|
||||
install -m 0644 "$ROOT_DIR/letsencrypt/live/$DOMAIN/fullchain.pem" "$ROOT_DIR/certs/server.crt"
|
||||
install -m 0600 "$ROOT_DIR/letsencrypt/live/$DOMAIN/privkey.pem" "$ROOT_DIR/certs/server.key"
|
||||
|
||||
# Reload reverse proxy with updated files
|
||||
docker compose -f "$ROOT_DIR/docker-compose.yml" up -d --no-deps --force-recreate reverse_proxy
|
||||
|
||||
echo "Certificates installed for $DOMAIN and reverse proxy reloaded."
|
Loading…
x
Reference in New Issue
Block a user