# πŸ“ Architecture Secure Proxy ## Vue d'Ensemble ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Internet / External Users β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ https://secure.k2r.ovh β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Nginx/SSL β”‚ β”‚ (Reverse Proxy)β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ http://localhost:3000 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Secure Proxy (Node.js) β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Express Server β”‚ β”‚ β”‚ β”‚ - OIDC Authentication (Keycloak) β”‚ β”‚ β”‚ β”‚ - Session Management β”‚ β”‚ β”‚ β”‚ - Rate Limiting & Security β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Routes β”‚ β”‚ β”‚ β”‚ - /auth/* (Authentification) β”‚ β”‚ β”‚ β”‚ - /api/* (Admin API) β”‚ β”‚ β”‚ β”‚ - /admin (Panel Admin) β”‚ β”‚ β”‚ β”‚ - /* (Reverse Proxy) β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Middleware β”‚ β”‚ β”‚ β”‚ - OIDC Middleware β”‚ β”‚ β”‚ β”‚ - Proxy Middleware β”‚ β”‚ β”‚ β”‚ - Security Middleware β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Database (SQLite) β”‚ β”‚ β”‚ β”‚ - Services Management β”‚ β”‚ β”‚ β”‚ - Audit Logs β”‚ β”‚ β”‚ β”‚ - Access Logs β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Keycloak OIDC β”‚ β”‚ Internal Services β”‚ β”‚ (Authentication)β”‚ β”‚ - API Server β”‚ β”‚ β”‚ β”‚ - Grafana β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ - React App β”‚ β”‚ - Custom Services β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ## Structure des Fichiers ``` openidv2/ β”‚ β”œβ”€β”€ πŸ“ src/ # Code source principal β”‚ β”œβ”€β”€ server.js # Serveur Express principal β”‚ β”œβ”€β”€ config.js # Configuration centralisΓ©e β”‚ β”œβ”€β”€ db.js # Gestion SQLite β”‚ β”‚ β”‚ β”œβ”€β”€ πŸ“ middleware/ β”‚ β”‚ β”œβ”€β”€ oidcMiddleware.js # Authentification OIDC/Keycloak β”‚ β”‚ β”œβ”€β”€ security.js # Rate limit, CSRF, headers, logs β”‚ β”‚ └── proxyMiddleware.js # Logique du reverse proxy β”‚ β”‚ β”‚ β”œβ”€β”€ πŸ“ routes/ β”‚ β”‚ β”œβ”€β”€ authRoutes.js # Routes d'authentification β”‚ β”‚ β”œβ”€β”€ adminRoutes.js # API admin (CRUD services) β”‚ β”‚ └── dashboardRoutes.js # Routes dashboard β”‚ β”‚ β”‚ β”œβ”€β”€ πŸ“ controllers/ β”‚ β”‚ β”œβ”€β”€ authController.js # Logique auth (login, callback) β”‚ β”‚ β”œβ”€β”€ serviceController.js # CRUD des services β”‚ β”‚ └── adminController.js # Stats et logs β”‚ β”‚ β”‚ β”œβ”€β”€ πŸ“ services/ β”‚ β”‚ └── serviceManager.js # Business logic (DB interactions) β”‚ β”‚ β”‚ └── πŸ“ utils/ β”‚ └── logger.js # Logging centralisΓ© β”‚ β”œβ”€β”€ πŸ“ public/ β”‚ └── admin.html # Interface admin (UI complΓ¨te) β”‚ β”œβ”€β”€ πŸ“ db/ β”‚ └── services.db # Base de donnΓ©es SQLite β”‚ β”œβ”€β”€ πŸ“ scripts/ β”‚ β”œβ”€β”€ initDb.js # Initialiser la DB β”‚ └── seedDb.js # Charger donnΓ©es d'exemple β”‚ β”œβ”€β”€ πŸ“ sessions/ # Sessions utilisateur (créé Γ  runtime) β”‚ β”œβ”€β”€ Configuration β”‚ β”œβ”€β”€ .env # Variables d'environnement β”‚ β”œβ”€β”€ .env.example # ModΓ¨le de configuration β”‚ β”œβ”€β”€ package.json # DΓ©pendances Node.js β”‚ β”œβ”€β”€ docker-compose.yml # Stack Docker (dev) β”‚ β”œβ”€β”€ Dockerfile # Image Docker β”‚ └── nginx.example.conf # Config Nginx β”‚ └── Documentation β”œβ”€β”€ README.md # Documentation complΓ¨te β”œβ”€β”€ INSTALLATION.md # Guide installation dΓ©taillΓ© β”œβ”€β”€ QUICKSTART.md # DΓ©marrage rapide β”œβ”€β”€ ARCHITECTURE.md # Ce fichier └── test-api.sh # Tests API ``` ## Flux de RequΓͺte ### 1️⃣ Authentification OIDC ``` Utilisateur β†’ http://localhost:3000/ ↓ Pas d'authentification ? ↓ Redirect β†’ /auth/login ↓ Utilisateur clique "Login" ↓ GET /auth/login ↓ Redirect vers Keycloak Authorization Endpoint ↓ Utilisateur s'authentifie sur Keycloak ↓ Keycloak redirige vers /callback avec code ↓ POST /auth/callback ↓ Exchange code β†’ Token ↓ RΓ©cupΓ©rer userInfo ↓ CrΓ©er session utilisateur ↓ Redirect vers page demandΓ©e originalement ``` ### 2️⃣ AccΓ¨s Γ  un Service ProtΓ©gΓ© ``` Utilisateur (authentifiΓ©) β†’ GET /myapp ↓ Trouve service dans DB ↓ Service nΓ©cessite auth ? ↓ Utilisateur a session ? ↓ OUI β†’ Proxifier vers target ↓ Utilisateur (anonyme) β†’ GET /public ↓ Service trouvΓ© ↓ Service nΓ©cessite auth ? ↓ NON β†’ Proxifier directement ``` ### 3️⃣ Management Admin ``` Admin β†’ GET /admin ↓ VΓ©rifier : req.session.user.isAdmin ? ↓ NON β†’ 403 Forbidden ↓ OUI β†’ Servir interface admin.html ↓ Admin clique "+ New Service" ↓ POST /api/services (avec CSRF token) ↓ Valider les donnΓ©es ↓ InsΓ©rer dans DB ↓ Log action d'audit ↓ Retourner service créé ↓ RΓ©ponse affichΓ©e dans l'UI ``` ## Flux de DonnΓ©es ### Services Table (SQLite) ```sql services { id VARCHAR PRIMARY KEY -- UUID unique name VARCHAR UNIQUE -- Nom du service path VARCHAR UNIQUE -- Chemin public (/myapp) target_url VARCHAR -- URL cible (http://localhost:8080) require_auth BOOLEAN -- Authentification requise ? description TEXT -- Description enabled BOOLEAN -- Service actif ? created_at DATETIME -- Date crΓ©ation updated_at DATETIME -- Date modification } ``` ### Audit Logs Table ```sql audit_logs { id INTEGER PRIMARY KEY AUTO_INCREMENT action VARCHAR -- SERVICE_CREATED, UPDATED, DELETED user_id VARCHAR -- ID Keycloak de l'admin service_id VARCHAR FK -- Service affectΓ© ip_address VARCHAR -- IP de l'admin details JSON -- DΓ©tails (donnΓ©es modifiΓ©es) timestamp DATETIME -- Quand } ``` ### Access Logs Table ```sql access_logs { id INTEGER PRIMARY KEY AUTO_INCREMENT service_id VARCHAR FK -- Service accΓ©dΓ© user_id VARCHAR -- Utilisateur (si auth) path VARCHAR -- Chemin complet method VARCHAR -- GET, POST, etc. status_code INTEGER -- Code rΓ©ponse (200, 404, etc.) response_time_ms INTEGER -- Temps rΓ©ponse en ms ip_address VARCHAR -- IP du client timestamp DATETIME -- Quand } ``` ## Flux de SΓ©curitΓ© ### OIDC Flow (Authorization Code) ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Browser β”‚ β”‚ Secure Proxy β”‚ β”‚ Keycloak β”‚ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ │──GET /auth/login───────►│ β”‚ β”‚ │──GET /auth/authorizeβ”‚ β”‚ β”‚ (with state, nonce)─►│ β”‚ β”‚ β”‚ │◄────────────────────────────────────────Redirect with code β”‚ (to /callback) β”‚ β”‚ β”‚ β”‚ β”‚ │──GET /callback?code────►│ β”‚ β”‚ │──POST token───────►│ β”‚ │◄──ID+Access Token──│ β”‚ β”‚ β”‚ │◄────User data in session| β”‚ β”‚ β”‚ β”‚ ``` ### Rate Limiting & Security ``` Request β†’ Check IP in rate limit store ↓ Count exceeded ? ↓ OUI β†’ 429 Too Many Requests ↓ NON β†’ Continue ↓ CSRF check (POST/PUT/DELETE) ↓ Security headers added ↓ Request logged ↓ Response sent ``` ## Performance & ScalabilitΓ© ### Optimisations Actuelles - **Reverse Proxy** : http-proxy avec streaming - **Rate Limiting** : En-mΓ©moire (scalable avec Redis) - **Logs** : SQLite (adaptΓ© pour small-medium) - **Sessions** : File-based (pour dev) ### Pour la Production ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Nginx β”‚ ← Load balancer + SSL termination β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”œβ”€β–Ί [Proxy 1] ←► Redis (sessions) β”œβ”€β–Ί [Proxy 2] ←► + └─► [Proxy 3] ←► PostgreSQL (logs & services) ``` ## SΓ©curitΓ© en Couches ### Couche 1 : Transport - SSL/TLS avec Nginx - HSTS headers ### Couche 2 : Authentification - OIDC avec Keycloak - Sessions sΓ©curisΓ©es (httpOnly, sameSite) ### Couche 3 : Autorisation - VΓ©rification admin pour /admin et /api - Service auth check avant proxy ### Couche 4 : Validation - CSRF tokens - Input validation sur tous les endpoints - SQL injections protection (parameterized queries) ### Couche 5 : Monitoring - Audit logs de toutes les actions - Access logs de tous les services - Rate limiting anti-DDoS ## ExtensibilitΓ© ### Ajouter un Nouveau Middleware ```javascript // 1. CrΓ©er src/middleware/myMiddleware.js export function myMiddleware(req, res, next) { // Your logic next(); } // 2. Dans server.js import { myMiddleware } from './middleware/myMiddleware.js'; app.use(myMiddleware); ``` ### Ajouter une Nouvelle Route ```javascript // 1. CrΓ©er route handler export function myHandler(req, res) { res.json({ message: 'Hello' }); } // 2. CrΓ©er route file src/routes/myRoutes.js const router = express.Router(); router.get('/myendpoint', myHandler); // 3. Dans server.js import myRoutes from './routes/myRoutes.js'; app.use('/api/my', myRoutes); ``` ### Modifier l'UI Admin - Γ‰diter `public/admin.html` - Ajouter sections, boutons, formulaires - Le JavaScript charge automatiquement l'API --- **Architecture modulaire, sΓ©curisΓ©e et extensible** ✨