# PatchCenter — Guide de deploiement SANEF ## Identifiants ### PostgreSQL - **Host:** localhost:5432 - **Database:** patchcenter_db - **User:** patchcenter - **Password:** PatchCenter2026! - **Superuser:** postgres (sans mot de passe, auth peer) ### Application Web | User | Password | Role | |------|----------|------| | admin | Admin@2026 | admin | | khalid | (defini a la creation) | admin | ### JWT - Secret: `slpm-patchcenter-secret-key-2026-change-in-production` - Algorithme: HS256 - Expiration: 8h (cookie session, expire a la fermeture navigateur) --- ## Deploiement sur un serveur SANEF ### Prerequis serveur - Debian 12/13 ou RHEL 8/9 - Python 3.11+ - PostgreSQL 15+ - Acces reseau aux serveurs (pour prereqs SSH) - 2 Go RAM minimum, 10 Go disque ### Etape 1 — Cloner le code ```bash cd /opt git clone https://github.com/kalidmoutaouakil-dot/SLPM.git patchcenter cd patchcenter ``` ### Etape 2 — Environnement Python ```bash python3 -m venv venv source venv/bin/activate pip install fastapi uvicorn jinja2 sqlalchemy psycopg2-binary python-jose[cryptography] passlib[bcrypt] bcrypt==4.0.1 python-multipart requests paramiko openpyxl ``` ### Etape 3 — PostgreSQL ```bash # Installer PostgreSQL apt install -y postgresql # Creer la base et l'utilisateur sudo -u postgres psql << SQL CREATE USER patchcenter WITH PASSWORD 'PatchCenter2026!'; CREATE DATABASE patchcenter_db OWNER patchcenter; \c patchcenter_db CREATE EXTENSION IF NOT EXISTS citext; CREATE EXTENSION IF NOT EXISTS pg_trgm; SQL ``` ### Etape 4 — Restaurer la base Copier le dump sur le serveur puis : ```bash # Depuis le backup gunzip -c db_YYYYMMDD_HHMM.sql.gz | sudo -u postgres psql -d patchcenter_db # Ou depuis un dump frais de la VM dev pg_dump -h localhost -p 5432 -U patchcenter patchcenter_db | psql -d patchcenter_db ``` Verifier les permissions : ```bash sudo -u postgres psql -d patchcenter_db << SQL GRANT ALL ON ALL TABLES IN SCHEMA public TO patchcenter; GRANT ALL ON ALL SEQUENCES IN SCHEMA public TO patchcenter; GRANT USAGE ON SCHEMA public TO patchcenter; SQL ``` ### Etape 5 — Configuration Editer `/opt/patchcenter/app/config.py` ou utiliser des variables d'environnement : ```bash export DATABASE_URL="postgresql://patchcenter:PatchCenter2026!@localhost:5432/patchcenter_db" export SECRET_KEY="changer-cette-cle-en-production" ``` ### Etape 6 — Cle SSH (pour prereqs) ```bash mkdir -p /opt/patchcenter/keys cp /chemin/vers/id_rsa_cybglobal.pem /opt/patchcenter/keys/ chmod 600 /opt/patchcenter/keys/id_rsa_cybglobal.pem ``` ### Etape 7 — Service systemd ```bash cat > /etc/systemd/system/patchcenter.service << EOF [Unit] Description=PatchCenter Web App After=network.target postgresql.service Wants=postgresql.service [Service] Type=simple User=root WorkingDirectory=/opt/patchcenter ExecStart=/opt/patchcenter/venv/bin/uvicorn app.main:app --host 0.0.0.0 --port 8080 Restart=always RestartSec=3 [Install] WantedBy=multi-user.target EOF systemctl daemon-reload systemctl enable patchcenter systemctl start patchcenter ``` ### Etape 8 — Verifier ```bash curl http://localhost:8080/health # {"status":"ok","app":"PatchCenter","version":"2.0"} ``` Acceder a http://SERVEUR:8080 → login admin / Admin@2026 ### Etape 9 — Backup cron ```bash mkdir -p /home/backup cat > /home/backup/backup.sh << 'BKEOF' #!/bin/bash DATE=$(date +%Y%m%d_%H%M) BKDIR=/home/backup PGPASSWORD='PatchCenter2026!' pg_dump -U patchcenter -h localhost patchcenter_db | gzip > $BKDIR/db_$DATE.sql.gz tar czf $BKDIR/code_$DATE.tar.gz -C /opt patchcenter/app 2>/dev/null find $BKDIR -name 'db_*.sql.gz' -mtime +30 -delete find $BKDIR -name 'code_*.tar.gz' -mtime +30 -delete echo "Backup OK: $DATE" BKEOF chmod +x /home/backup/backup.sh (crontab -l 2>/dev/null; echo '0 2 * * * /home/backup/backup.sh >> /home/backup/backup.log 2>&1') | crontab - ``` --- ## Architecture ``` /opt/patchcenter/ ├── app/ │ ├── main.py # FastAPI entry point │ ├── config.py # Configuration │ ├── auth.py # JWT + bcrypt │ ├── database.py # SQLAlchemy engine │ ├── dependencies.py # get_db, get_current_user │ ├── routers/ │ │ ├── auth.py # Login/logout │ │ ├── dashboard.py # Dashboard stats │ │ ├── servers.py # CRUD serveurs │ │ ├── campaigns.py # Campagnes patching │ │ ├── planning.py # Planning annuel │ │ ├── specifics.py # Serveurs specifiques │ │ ├── settings.py # Configuration modules │ │ └── users.py # Gestion utilisateurs │ ├── services/ │ │ ├── server_service.py # Logique serveurs │ │ ├── campaign_service.py # Logique campagnes │ │ ├── prereq_service.py # Verification prereqs │ │ ├── qualys_service.py # Sync Qualys API │ │ └── secrets_service.py # Chiffrement Fernet │ └── templates/ │ ├── base.html # Layout + sidebar │ ├── login.html │ ├── dashboard.html │ ├── servers.html │ ├── campaigns.html │ ├── campaign_detail.html │ ├── planning.html │ ├── specifics.html │ ├── settings.html │ ├── users.html │ └── partials/ │ ├── server_detail.html │ ├── server_edit.html │ ├── specific_edit.html │ └── campaign_preview.html ├── keys/ # Cles SSH (non versionne) ├── venv/ # Env Python (non versionne) └── .gitignore ``` ## Base de donnees — Tables principales | Table | Lignes | Description | |-------|--------|-------------| | servers | 1045 | Inventaire serveurs | | server_ips | 869 | IPs reelle/connexion | | server_specifics | 82 | Specificites patching | | qualys_assets | 1114 | Assets Qualys | | qualys_tags | ~300 | Tags Qualys | | qualys_asset_tags | ~3000 | Liaison assets-tags | | domains | 8 | Domaines (INF, TRA, PEA...) | | environments | 6 | Environnements | | vcenters | 3 | vCenters vSphere | | campaigns | - | Campagnes patching | | patch_sessions | - | Sessions par serveur | | patch_planning | 87 | Planning annuel 2026 | | users | 3 | Utilisateurs | | user_permissions | 6 | Permissions par module | | app_secrets | ~5 | Credentials chiffres | | audit_log | - | Journal d'audit | ## Proxy SANEF Si le serveur est derriere le proxy : ```bash export HTTP_PROXY=http://proxy.sanef.fr:8080 export HTTPS_PROXY=http://proxy.sanef.fr:8080 export NO_PROXY=localhost,127.0.0.1,.sanef.groupe,.sanef.fr ``` Pour pip : ```bash pip install --proxy http://proxy.sanef.fr:8080 ```