
- Mise à jour de l'API pour charger les fichiers .env dans l'ordre: .env.secrets -> .env -> .env.auto -> .env.post - Ajout du script generate_variables.sh pour générer automatiquement les variables Docker - Création des fichiers .env.auto et .env.post pour le templating complet - Mise à jour de la documentation pour refléter le nouvel ordre de chargement - Génération automatique du docker-compose.yml avec templates des services - Support complet des variables emboîtées entre les fichiers d'environnement
306 lines
9.0 KiB
Markdown
306 lines
9.0 KiB
Markdown
# Traitement des Variables d'Environnement
|
|
|
|
## 🔧 Vue d'ensemble
|
|
|
|
L'API Vault 4NK intègre un système avancé de traitement des variables d'environnement qui résout automatiquement les références de variables dans les fichiers de configuration avant leur chiffrement et transmission.
|
|
|
|
## 🚀 Fonctionnalités
|
|
|
|
### Résolution automatique des variables
|
|
- **Syntaxes supportées** : `$VAR` et `${VAR}`
|
|
- **Résolution récursive** : Les variables peuvent référencer d'autres variables
|
|
- **Protection contre les boucles infinies** : Détection automatique des dépendances circulaires
|
|
- **Traitement en mémoire** : Les fichiers originaux ne sont jamais modifiés
|
|
|
|
### Sources de variables (ordre de chargement)
|
|
1. **Fichier `.env.secrets`** : `storage/<env>/.env.secrets` (secrets de base)
|
|
2. **Fichier `.env`** : `storage/<env>/.env` (variables de configuration, peut utiliser les secrets)
|
|
3. **Fichier `.env.auto`** : `storage/<env>/.env.auto` (variables générées automatiquement, peut utiliser les précédentes)
|
|
4. **Fichier `.env.post`** : `storage/<env>/.env.post` (variables finales, peut utiliser toutes les précédentes)
|
|
- **Variables système** : Non utilisées (isolation complète)
|
|
- **Fichiers de sous-répertoires** : Non chargés (configurations spécifiques aux services)
|
|
|
|
## 📋 Syntaxes supportées
|
|
|
|
### Syntaxe simple : `$VAR`
|
|
```bash
|
|
# Variables de base
|
|
DOMAIN=4nkweb.com
|
|
HOST=dev4.$DOMAIN
|
|
ROOT_HOST=$HOST
|
|
ROOT_URL=https://$ROOT_HOST
|
|
|
|
# Résolution automatique
|
|
DOMAIN → 4nkweb.com
|
|
HOST → dev4.4nkweb.com
|
|
ROOT_HOST → dev4.4nkweb.com
|
|
ROOT_URL → https://dev4.4nkweb.com
|
|
```
|
|
|
|
### Syntaxe avec accolades : `${VAR}`
|
|
```bash
|
|
# Variables complexes
|
|
LOG_DIR=/home/debian/4NK_env/logs
|
|
BITCOIN_LOG_DIR=${LOG_DIR}/bitcoin
|
|
TOR_LOG_DIR=${LOG_DIR}/tor
|
|
|
|
# Résolution automatique
|
|
LOG_DIR → /home/debian/4NK_env/logs
|
|
BITCOIN_LOG_DIR → /home/debian/4NK_env/logs/bitcoin
|
|
TOR_LOG_DIR → /home/debian/4NK_env/logs/tor
|
|
```
|
|
|
|
## 🔄 Processus de résolution
|
|
|
|
### 1. Chargement des variables (ordre séquentiel)
|
|
```python
|
|
# Chargement des fichiers d'environnement dans l'ordre correct
|
|
env_files = ['.env.secrets', '.env', '.env.auto', '.env.post']
|
|
variables = {}
|
|
|
|
for env_filename in env_files:
|
|
env_file_path = STORAGE_ROOT / env / env_filename
|
|
if env_file_path.exists():
|
|
variables.update(load_env_file(env_file_path))
|
|
```
|
|
|
|
### 2. Résolution récursive
|
|
```python
|
|
def resolve_variable(var_name, visited=None):
|
|
if var_name in visited: # Protection contre les boucles
|
|
return f"${var_name}"
|
|
|
|
visited.add(var_name)
|
|
value = variables[var_name]
|
|
|
|
# Résolution des sous-variables
|
|
for match in find_variables(value):
|
|
resolved = resolve_variable(match, visited.copy())
|
|
value = value.replace(f"${{{match}}}", resolved)
|
|
value = value.replace(f"${match}", resolved)
|
|
|
|
return value
|
|
```
|
|
|
|
### 3. Traitement du contenu
|
|
```python
|
|
def process_content(content):
|
|
# Pattern pour ${VARIABLE}
|
|
pattern1 = r'\$\{([^}]+)\}'
|
|
for var_name in re.findall(pattern1, content):
|
|
resolved_value = resolve_variable(var_name)
|
|
content = content.replace(f"${{{var_name}}}", resolved_value)
|
|
|
|
# Pattern pour $VARIABLE
|
|
pattern2 = r'\$([A-Za-z_][A-Za-z0-9_]*)'
|
|
for var_name in re.findall(pattern2, content):
|
|
if f"${{{var_name}}}" not in content: # Éviter les doublons
|
|
resolved_value = resolve_variable(var_name)
|
|
content = content.replace(f"${var_name}", resolved_value)
|
|
|
|
return content
|
|
```
|
|
|
|
## 🛡️ Sécurité et protection
|
|
|
|
### Protection contre les attaques
|
|
- **Dépendances circulaires** : Détection et prévention automatiques
|
|
- **Variables non définies** : Conservation de la syntaxe originale
|
|
- **Isolation** : Seul le fichier `.env` principal est utilisé
|
|
|
|
### Exemples de protection
|
|
```bash
|
|
# Dépendance circulaire détectée
|
|
HOST=dev4.$DOMAIN
|
|
DOMAIN=$HOST
|
|
|
|
# Résultat : Conservation de la syntaxe
|
|
HOST → dev4.$DOMAIN # Variable non résolue
|
|
DOMAIN → $HOST # Variable non résolue
|
|
```
|
|
|
|
## 📁 Structure des fichiers
|
|
|
|
### Fichier `.env` principal
|
|
```bash
|
|
# storage/dev/.env
|
|
DOMAIN=4nkweb.com
|
|
HOST=dev4.$DOMAIN
|
|
ROOT_HOST=$HOST
|
|
ROOT_URL=https://$ROOT_HOST
|
|
ROOT_DIR_LOGS=/home/debian/4NK_env/logs
|
|
TOR_LOGS_DIR=$ROOT_DIR_LOGS/tor
|
|
SDK_TOR_DATA_DIR=$ROOT_DIR_LOGS/sdk_tor
|
|
```
|
|
|
|
### Fichier `.env.secrets`
|
|
```bash
|
|
# storage/dev/.env.secrets
|
|
BDD_USER=bdd_user
|
|
BDD_PASSWORD=bdd_password
|
|
POSTGRESQL_USER=$BDD_USER
|
|
POSTGRESQL_PASSWORD=$BDD_PASSWORD
|
|
SIGNER_API_KEY=your-api-key-change-this
|
|
VITE_JWT_SECRET_KEY=52b3d77617bb00982dfee15b08effd52cfe5b2e69b2f61cc4848cfe1e98c0bc9
|
|
GRAFANA_ADMIN_PASSWORD=admin123
|
|
BITCOIN_RPC_AUTH=bitcoin:c8ea921c7357bd6a5a8a7c43a12350a7$955e25b17672987b17c5a12f12cd8b9c1d38f0f86201c8cd47fc431f2e1c7956
|
|
```
|
|
|
|
> **⚠️ Important** : Le fichier `.env.secrets` contient des informations sensibles et ne doit jamais être committé dans le contrôle de version.
|
|
|
|
### Fichiers de configuration
|
|
```bash
|
|
# storage/dev/bitcoin/bitcoin.conf
|
|
datadir=$ROOT_DIR_LOGS/bitcoin
|
|
logdir=$ROOT_DIR_LOGS/bitcoin
|
|
rpcbind=$HOST
|
|
rpcport=8332
|
|
```
|
|
|
|
### Résolution automatique
|
|
```bash
|
|
# Contenu après résolution (en mémoire)
|
|
datadir=/home/debian/4NK_env/logs/bitcoin
|
|
logdir=/home/debian/4NK_env/logs/bitcoin
|
|
rpcbind=dev4.4nkweb.com
|
|
rpcport=8332
|
|
```
|
|
|
|
## 🔧 Configuration de l'API
|
|
|
|
### Initialisation
|
|
```python
|
|
class SecureVaultAPI:
|
|
def __init__(self):
|
|
# Processeurs d'environnement par environnement
|
|
self.env_processors = {}
|
|
|
|
def _get_env_processor(self, env: str) -> EnvProcessor:
|
|
if env not in self.env_processors:
|
|
env_file = STORAGE_ROOT / env / '.env'
|
|
self.env_processors[env] = EnvProcessor(env_file)
|
|
return self.env_processors[env]
|
|
```
|
|
|
|
### Utilisation dans les endpoints
|
|
```python
|
|
@self.app.route('/<env>/<path:file_path>', methods=['GET'])
|
|
def serve_file(env: str, file_path: str):
|
|
# Lecture du fichier
|
|
file_content = self._read_file(env, file_path)
|
|
|
|
# Traitement des variables d'environnement
|
|
env_processor = self._get_env_processor(env)
|
|
processed_content = env_processor.process_content(file_content)
|
|
|
|
# Chiffrement du contenu traité
|
|
encrypted_content, next_key = self._encrypt_with_user_key_and_next(
|
|
processed_content, user_id, env
|
|
)
|
|
|
|
return encrypted_content
|
|
```
|
|
|
|
## 🧪 Tests et validation
|
|
|
|
### Test de résolution
|
|
```python
|
|
# Test des variables d'environnement
|
|
env_processor = EnvProcessor(Path("storage/dev/.env"))
|
|
|
|
# Test de résolution simple
|
|
result = env_processor.process_content("Host: $HOST")
|
|
assert result == "Host: dev4.4nkweb.com"
|
|
|
|
# Test de résolution complexe
|
|
result = env_processor.process_content("URL: $ROOT_URL/api")
|
|
assert result == "URL: https://dev4.4nkweb.com/api"
|
|
```
|
|
|
|
### Validation des dépendances
|
|
```python
|
|
# Test de protection contre les boucles
|
|
env_processor.process_content("$CIRCULAR_VAR")
|
|
# Résultat : $CIRCULAR_VAR (conservé tel quel)
|
|
```
|
|
|
|
## 📊 Exemples concrets
|
|
|
|
### Configuration Bitcoin
|
|
```bash
|
|
# Avant résolution
|
|
datadir=$ROOT_DIR_LOGS/bitcoin
|
|
logdir=$ROOT_DIR_LOGS/bitcoin
|
|
rpcbind=$HOST
|
|
rpcport=8332
|
|
|
|
# Après résolution (automatique)
|
|
datadir=/home/debian/4NK_env/logs/bitcoin
|
|
logdir=/home/debian/4NK_env/logs/bitcoin
|
|
rpcbind=dev4.4nkweb.com
|
|
rpcport=8332
|
|
```
|
|
|
|
### Configuration Tor
|
|
```bash
|
|
# Avant résolution
|
|
DataDirectory $SDK_TOR_DATA_DIR
|
|
Log notice file $TOR_LOGS_DIR/tor.log
|
|
SocksPort $HOST:9050
|
|
|
|
# Après résolution (automatique)
|
|
DataDirectory /home/debian/4NK_env/logs/sdk_tor
|
|
Log notice file /home/debian/4NK_env/logs/tor/tor.log
|
|
SocksPort dev4.4nkweb.com:9050
|
|
```
|
|
|
|
## 🔍 Debugging et logs
|
|
|
|
### Activation des logs
|
|
```python
|
|
import logging
|
|
logging.basicConfig(level=logging.INFO)
|
|
|
|
# Logs automatiques
|
|
logger.info(f"Variables chargées depuis {env_file}: {len(variables)} variables")
|
|
logger.info(f"Variable résolue: {var_name} = {resolved_value}")
|
|
logger.warning(f"Dépendance circulaire détectée pour {var_name}")
|
|
```
|
|
|
|
### Messages de debug
|
|
```
|
|
INFO: Variables chargées depuis storage/dev/.env: 15 variables
|
|
INFO: Variable résolue: HOST = xxx.com
|
|
INFO: Variable résolue: ROOT_URL = https://xxx.com
|
|
WARNING: Variable non trouvée: UNDEFINED_VAR
|
|
```
|
|
|
|
## 🌐 Intégration SDK
|
|
|
|
### Récupération des fichiers traités
|
|
```typescript
|
|
// Le SDK reçoit automatiquement les fichiers avec variables résolues
|
|
const file = await client.getFile('dev', 'bitcoin/bitcoin.conf');
|
|
console.log(file.content); // Variables déjà résolues
|
|
|
|
// Vérification des variables résolues
|
|
const hasVariables = file.content.includes('$');
|
|
console.log(`Variables résolues: ${!hasVariables}`);
|
|
```
|
|
|
|
### Synchronisation locale
|
|
```typescript
|
|
// Synchronisation avec variables résolues
|
|
const syncResult = await client.syncLocalFiles({
|
|
environment: 'dev',
|
|
localDir: '../confs'
|
|
});
|
|
|
|
// Les fichiers dans confs/ contiennent les variables résolues
|
|
console.log(`Fichiers synchronisés: ${syncResult.synced}`);
|
|
```
|
|
|
|
---
|
|
|
|
**Note** : Le traitement des variables d'environnement est entièrement transparent pour l'utilisateur final. Les fichiers originaux dans `storage/` ne sont jamais modifiés, et toutes les résolutions se font en mémoire lors de la récupération des fichiers.
|