- Ajout du script add_external_node.sh pour gérer les nœuds externes - Configuration external_nodes.conf avec dev3-relay - Scripts de test pour dev3.4nkweb.com (connectivité WSS) - Documentation complète (CONFIGURATION_DEV3.md, RESUME_AJOUT_DEV3.md) - Scripts de test de synchronisation et monitoring - Configuration multi-relais avec 3 instances - Mise à jour de la documentation technique et fonctionnelle - Scripts de démarrage et monitoring pour les 3 relais
378 lines
9.3 KiB
Markdown
378 lines
9.3 KiB
Markdown
# Découverte des Nœuds et Ajout de Nœuds Externes
|
|
|
|
## Comment les relais découvrent-ils initialement les autres nœuds ?
|
|
|
|
### 1. Découverte automatique (actuelle)
|
|
|
|
Actuellement, les relais utilisent une **découverte statique** basée sur les noms de conteneurs Docker :
|
|
|
|
```rust
|
|
// Dans sync.rs - discover_relays()
|
|
let relay_hosts = vec![
|
|
"sdk_relay_1",
|
|
"sdk_relay_2",
|
|
"sdk_relay_3",
|
|
];
|
|
```
|
|
|
|
**Mécanisme :**
|
|
1. Chaque relais a une liste prédéfinie des autres relais
|
|
2. Au démarrage, il tente de se connecter à chaque relais de la liste
|
|
3. Il ignore son propre nom (`relay_id`)
|
|
4. Il ajoute les relais découverts à sa liste `known_relays`
|
|
|
|
### 2. Configuration par relay_id
|
|
|
|
Chaque relais a un `relay_id` unique dans sa configuration :
|
|
|
|
```toml
|
|
# .conf.docker.relay1
|
|
relay_id=relay-1
|
|
|
|
# .conf.docker.relay2
|
|
relay_id=relay-2
|
|
|
|
# .conf.docker.relay3
|
|
relay_id=relay-3
|
|
```
|
|
|
|
### 3. Partage de la liste des relais
|
|
|
|
Une fois connectés, les relais partagent leur liste de relais connus via des messages `RelaySync` :
|
|
|
|
```rust
|
|
// Création d'un message RelaySync
|
|
pub fn create_relay_sync(&self) -> Result<SyncMessage> {
|
|
let known_relays = self.known_relays.lock().unwrap();
|
|
let relays: Vec<RelayInfo> = known_relays.values().cloned().collect();
|
|
|
|
let payload = SyncPayload::RelayData {
|
|
relays,
|
|
network_topology,
|
|
};
|
|
|
|
Ok(SyncMessage::new(SyncType::RelaySync, self.relay_id.clone(), payload))
|
|
}
|
|
```
|
|
|
|
## Comment ajouter un nœud externe ?
|
|
|
|
### Option 1: Modification de la liste statique
|
|
|
|
**Pour ajouter un nœud externe, il faut modifier le code source :**
|
|
|
|
```rust
|
|
// Dans sync.rs - discover_relays()
|
|
let relay_hosts = vec![
|
|
"sdk_relay_1",
|
|
"sdk_relay_2",
|
|
"sdk_relay_3",
|
|
"external-relay-1", // ← Nouveau nœud externe
|
|
"external-relay-2", // ← Autre nœud externe
|
|
];
|
|
```
|
|
|
|
**Avantages :**
|
|
- Simple à implémenter
|
|
- Contrôle total sur les nœuds autorisés
|
|
|
|
**Inconvénients :**
|
|
- Nécessite une recompilation
|
|
- Pas flexible pour l'ajout dynamique
|
|
- Centralisé
|
|
|
|
### Option 2: Configuration externe (recommandée)
|
|
|
|
**Créer un fichier de configuration pour les nœuds externes :**
|
|
|
|
```toml
|
|
# external_nodes.conf
|
|
[relays]
|
|
external-relay-1 = "external-relay-1.example.com:8090"
|
|
external-relay-2 = "external-relay-2.example.com:8090"
|
|
external-relay-3 = "192.168.1.100:8090"
|
|
|
|
[discovery]
|
|
auto_discover = true
|
|
bootstrap_nodes = [
|
|
"bootstrap-1.4nk.net:8090",
|
|
"bootstrap-2.4nk.net:8090"
|
|
]
|
|
```
|
|
|
|
**Modification du code pour supporter la configuration :**
|
|
|
|
```rust
|
|
pub struct DiscoveryConfig {
|
|
pub external_relays: HashMap<String, String>,
|
|
pub auto_discover: bool,
|
|
pub bootstrap_nodes: Vec<String>,
|
|
}
|
|
|
|
impl SyncManager {
|
|
pub fn load_discovery_config(&self) -> Result<DiscoveryConfig> {
|
|
// Charger depuis external_nodes.conf
|
|
}
|
|
|
|
pub async fn discover_relays(&self) -> Result<()> {
|
|
let config = self.load_discovery_config()?;
|
|
|
|
// Découverte locale (Docker)
|
|
for host in &["sdk_relay_1", "sdk_relay_2", "sdk_relay_3"] {
|
|
// ... logique existante
|
|
}
|
|
|
|
// Découverte externe
|
|
for (relay_id, address) in &config.external_relays {
|
|
let relay_info = RelayInfo {
|
|
relay_id: relay_id.clone(),
|
|
address: address.clone(),
|
|
// ... autres champs
|
|
};
|
|
self.add_relay(relay_info)?;
|
|
}
|
|
|
|
// Découverte via bootstrap nodes
|
|
if config.auto_discover {
|
|
for bootstrap in &config.bootstrap_nodes {
|
|
self.discover_via_bootstrap(bootstrap).await?;
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
}
|
|
```
|
|
|
|
### Option 3: Découverte via DNS
|
|
|
|
**Utiliser des enregistrements DNS pour la découverte :**
|
|
|
|
```rust
|
|
pub async fn discover_via_dns(&self, domain: &str) -> Result<()> {
|
|
// Résoudre les enregistrements SRV ou A
|
|
let addresses = dns_lookup::get_host_addresses(domain)?;
|
|
|
|
for addr in addresses {
|
|
let relay_info = RelayInfo {
|
|
relay_id: format!("relay-{}", addr),
|
|
address: format!("{}:8090", addr),
|
|
// ... autres champs
|
|
};
|
|
self.add_relay(relay_info)?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
```
|
|
|
|
### Option 4: Découverte via API REST
|
|
|
|
**Créer une API pour l'enregistrement des nœuds :**
|
|
|
|
```rust
|
|
// Endpoint pour enregistrer un nouveau nœud
|
|
POST /api/relays/register
|
|
{
|
|
"relay_id": "external-relay-1",
|
|
"address": "external-relay-1.example.com:8090",
|
|
"capabilities": ["sync", "mesh"],
|
|
"version": "1.0.0"
|
|
}
|
|
|
|
// Endpoint pour récupérer la liste des nœuds
|
|
GET /api/relays/list
|
|
```
|
|
|
|
## Implémentation recommandée
|
|
|
|
### 1. Créer un fichier de configuration externe
|
|
|
|
```bash
|
|
# Créer le fichier de configuration
|
|
cat > 4NK/4NK_node/sdk_relay/external_nodes.conf << EOF
|
|
[relays]
|
|
# Nœuds externes connus
|
|
external-relay-1 = "external-relay-1.example.com:8090"
|
|
external-relay-2 = "192.168.1.100:8090"
|
|
|
|
[discovery]
|
|
auto_discover = true
|
|
bootstrap_nodes = [
|
|
"bootstrap-1.4nk.net:8090"
|
|
]
|
|
|
|
[security]
|
|
allowed_domains = [
|
|
"*.4nk.net",
|
|
"*.example.com"
|
|
]
|
|
EOF
|
|
```
|
|
|
|
### 2. Modifier le code pour supporter la configuration
|
|
|
|
```rust
|
|
// Dans sync.rs
|
|
use std::fs;
|
|
use toml;
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
struct ExternalConfig {
|
|
relays: HashMap<String, String>,
|
|
discovery: DiscoverySettings,
|
|
security: SecuritySettings,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
struct DiscoverySettings {
|
|
auto_discover: bool,
|
|
bootstrap_nodes: Vec<String>,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
struct SecuritySettings {
|
|
allowed_domains: Vec<String>,
|
|
}
|
|
|
|
impl SyncManager {
|
|
pub fn load_external_config(&self) -> Result<ExternalConfig> {
|
|
let config_content = fs::read_to_string("external_nodes.conf")?;
|
|
let config: ExternalConfig = toml::from_str(&config_content)?;
|
|
Ok(config)
|
|
}
|
|
|
|
pub async fn discover_relays(&self) -> Result<()> {
|
|
// Découverte locale (existante)
|
|
let local_hosts = vec!["sdk_relay_1", "sdk_relay_2", "sdk_relay_3"];
|
|
for host in local_hosts {
|
|
// ... logique existante
|
|
}
|
|
|
|
// Découverte externe (nouvelle)
|
|
if let Ok(config) = self.load_external_config() {
|
|
for (relay_id, address) in &config.relays {
|
|
let relay_info = RelayInfo {
|
|
relay_id: relay_id.clone(),
|
|
address: address.clone(),
|
|
sp_address: "".to_string(),
|
|
version: "1.0.0".to_string(),
|
|
uptime: 0,
|
|
last_seen: SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs(),
|
|
capabilities: vec!["sync".to_string(), "mesh".to_string()],
|
|
health_status: HealthStatus::Healthy,
|
|
};
|
|
self.add_relay(relay_info)?;
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
}
|
|
```
|
|
|
|
### 3. Script pour ajouter un nœud externe
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
# add_external_node.sh
|
|
|
|
RELAY_ID=$1
|
|
ADDRESS=$2
|
|
CONFIG_FILE="4NK/4NK_node/sdk_relay/external_nodes.conf"
|
|
|
|
if [ -z "$RELAY_ID" ] || [ -z "$ADDRESS" ]; then
|
|
echo "Usage: $0 <relay_id> <address:port>"
|
|
echo "Example: $0 external-relay-1 external-relay-1.example.com:8090"
|
|
exit 1
|
|
fi
|
|
|
|
# Ajouter le nœud à la configuration
|
|
echo "Adding external node: $RELAY_ID -> $ADDRESS"
|
|
|
|
# Vérifier si le fichier existe
|
|
if [ ! -f "$CONFIG_FILE" ]; then
|
|
cat > "$CONFIG_FILE" << EOF
|
|
[relays]
|
|
|
|
[discovery]
|
|
auto_discover = true
|
|
bootstrap_nodes = []
|
|
|
|
[security]
|
|
allowed_domains = ["*.4nk.net"]
|
|
EOF
|
|
fi
|
|
|
|
# Ajouter le nœud
|
|
sed -i "/^\[relays\]$/a $RELAY_ID = \"$ADDRESS\"" "$CONFIG_FILE"
|
|
|
|
echo "✅ External node added successfully!"
|
|
echo "🔄 Restart relays to apply changes:"
|
|
echo " docker-compose restart sdk_relay_1 sdk_relay_2 sdk_relay_3"
|
|
```
|
|
|
|
## Sécurité et validation
|
|
|
|
### Validation des nœuds externes
|
|
|
|
```rust
|
|
impl SyncManager {
|
|
pub fn validate_external_relay(&self, relay_info: &RelayInfo) -> Result<bool> {
|
|
// Vérifier le format de l'adresse
|
|
if !self.is_valid_address(&relay_info.address) {
|
|
return Ok(false);
|
|
}
|
|
|
|
// Vérifier le domaine autorisé
|
|
if !self.is_allowed_domain(&relay_info.address) {
|
|
return Ok(false);
|
|
}
|
|
|
|
// Vérifier la connectivité
|
|
if !self.can_connect_to_relay(&relay_info.address).await? {
|
|
return Ok(false);
|
|
}
|
|
|
|
Ok(true)
|
|
}
|
|
|
|
pub async fn can_connect_to_relay(&self, address: &str) -> Result<bool> {
|
|
// Test de connectivité WebSocket
|
|
// ... logique de test
|
|
}
|
|
}
|
|
```
|
|
|
|
### Gestion des nœuds malveillants
|
|
|
|
```rust
|
|
impl SyncManager {
|
|
pub fn blacklist_relay(&self, relay_id: &str, reason: &str) {
|
|
// Ajouter à la liste noire
|
|
// Arrêter les connexions
|
|
// Notifier les autres relais
|
|
}
|
|
|
|
pub fn rate_limit_relay(&self, relay_id: &str) {
|
|
// Limiter le nombre de messages
|
|
// Surveiller les comportements suspects
|
|
}
|
|
}
|
|
```
|
|
|
|
## Conclusion
|
|
|
|
**Recommandation :** Utiliser l'**Option 2 (Configuration externe)** car elle offre :
|
|
|
|
1. **Flexibilité** : Ajout de nœuds sans recompilation
|
|
2. **Sécurité** : Contrôle des domaines autorisés
|
|
3. **Évolutivité** : Support pour la découverte automatique
|
|
4. **Simplicité** : Configuration par fichier
|
|
|
|
**Prochaines étapes :**
|
|
1. Implémenter le support de `external_nodes.conf`
|
|
2. Créer le script `add_external_node.sh`
|
|
3. Ajouter la validation et la sécurité
|
|
4. Tester avec des nœuds externes
|