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
|
# 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.
|
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
|
### 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`.
|
- `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.
|
- `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
|
### Fixed
|
||||||
- `/signer/health` retournait 502 via le reverse proxy ; désormais HTTP 200 avec corps `ok`.
|
- `/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
|
## [1.0.0] - 2024-12-19
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
@ -235,6 +235,7 @@ services:
|
|||||||
- ./proxy/nginx.conf:/etc/nginx/conf.d/default.conf:ro
|
- ./proxy/nginx.conf:/etc/nginx/conf.d/default.conf:ro
|
||||||
- ./certs:/etc/nginx/certs:ro
|
- ./certs:/etc/nginx/certs:ro
|
||||||
- ./ihm_client/dist:/usr/share/nginx/html:ro
|
- ./ihm_client/dist:/usr/share/nginx/html:ro
|
||||||
|
- ./acme:/var/www/certbot:ro
|
||||||
ports:
|
ports:
|
||||||
- "80:80"
|
- "80:80"
|
||||||
- "443:443"
|
- "443:443"
|
||||||
|
@ -597,6 +597,24 @@ sudo certbot --nginx -d your-domain.com
|
|||||||
sudo certbot renew --dry-run
|
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
|
## 🔧 Configuration de Monitoring
|
||||||
|
|
||||||
### 1. Prometheus
|
### 1. Prometheus
|
||||||
|
@ -172,6 +172,27 @@ chmod +x scripts/generate_certs.sh
|
|||||||
./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
|
### 4. Configuration Bitcoin Core
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@ -268,6 +289,18 @@ relay_id=relay-1 # Changer pour chaque relay
|
|||||||
|
|
||||||
## 🚀 Démarrage
|
## 🚀 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
|
### 1. Démarrage Complet
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
@ -1,7 +1,19 @@
|
|||||||
server {
|
server {
|
||||||
listen 80;
|
listen 80;
|
||||||
|
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;
|
return 301 https://$host$request_uri;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
server {
|
server {
|
||||||
listen 443 ssl http2;
|
listen 443 ssl http2;
|
||||||
@ -19,6 +31,7 @@ server {
|
|||||||
add_header X-Content-Type-Options nosniff always;
|
add_header X-Content-Type-Options nosniff always;
|
||||||
add_header X-XSS-Protection "1; mode=block" always;
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
add_header Referrer-Policy "strict-origin-when-cross-origin" 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)
|
# 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;
|
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