Fondamentaux des miroirs de paquets¶
Les ecosystemes de paquets¶
Chaque langage, chaque OS, chaque plateforme possède son propre système de distribution de paquets. Un miroir interne doit supporter les ecosystemes utilises dans l'entreprise.
Paquets système¶
| Ecosysteme | Format | Registre public | Outils clients |
|---|---|---|---|
| Debian | .deb | archive.ubuntu.com | apt, dpkg |
| RHEL | .rpm | mirrorlist.centos.org | yum, dnf, rpm |
| Alpine | .apk | dl-cdn.alpinelinux.org | apk |
Les dépôts système sont composes de fichiers binaires et de metadonnees (Packages.gz pour apt, repodata/repomd.xml pour yum). Un miroir doit repliquer ces metadonnees pour que les clients retrouvent la même arborescence qu'en amont.
Paquets applicatifs¶
| Ecosysteme | Format | Registre public | Outils clients |
|---|---|---|---|
| npm | tarball .tgz | registry.npmjs.org | npm, yarn, pnpm |
| PyPI | wheel, sdist | pypi.org | pip, poetry, uv |
| Maven | .jar, .pom | repo.maven.apache.org | mvn, gradle |
| Go | module zip + info | proxy.golang.org | go mod |
| NuGet | .nupkg | api.nuget.org | dotnet, nuget |
| RubyGems | .gem | rubygems.org | gem, bundle |
Artefacts d'infrastructure¶
| Ecosysteme | Format | Registre public | Outils clients |
|---|---|---|---|
| Docker/OCI | Layers OCI, manifests | registry-1.docker.io | docker, podman |
| Helm | .tgz (chart archive) | artifacthub.io | helm |
| Terraform | Provider binaires | registry.terraform.io | terraform, tofu |
Modèles de dépôts¶
Un gestionnaire de dépôts organise les artefacts en trois types fondamentaux : proxy, hosted et group.
Dépôt proxy (cache-through)¶
Le dépôt proxy fait office de cache transparent devant un registre distant. Lorsqu'un client demande un paquet :
graph LR
Client -->|requete| Proxy["Depot Proxy"]
Proxy -->|cache miss| Public["Registre public"]
Proxy --> Check{"cache hit ?"}
Check -->|oui| Local["reponse locale"]
Check -->|non| Download["telechargement,<br/>stockage, reponse"] Comportement :
- Le client interroge le proxy comme s'il etait le registre officiel
- Si le paquet est en cache local, réponse immédiate
- Sinon, le proxy telecharge depuis l'upstream, le stocke, puis répond au client
- Les requêtes suivantes sont servies depuis le cache
Avantages : aucune configuration prealable des paquets a cacher, disponibilité en cas de panne upstream (pour les paquets déjà caches), deduplication des telechargements.
Dépôt hosted (paquets internes)¶
Le dépôt hosted stocke les artefacts produits en interne : bibliotheques privées, images Docker applicatives, packages npm internes. Aucun upstream n'est configuré.
graph LR
CICD["CI/CD Pipeline"] -->|push| Hosted["Depot Hosted"]
Autre["Autre projet"] -->|pull| Hosted Cas d'usage :
- Bibliotheques internes partagees entre équipes
- Artefacts de build (
.jar,.whl, images Docker) - Packages forks de projets open source avec correctifs internes
Dépôt group (agregation)¶
Le dépôt group expose un point d'entree unique qui agrege plusieurs dépôts (proxy et hosted) :
graph TD
Client -->|requete| Group["Depot Group"]
Group --> Hosted["Depot Hosted<br/>(interne)"]
Group --> Proxy1["Depot Proxy 1<br/>(registre A)"]
Group --> Proxy2["Depot Proxy 2<br/>(registre B)"] Le group résout les paquets dans l'ordre de priorité defini :
- Chercher dans le dépôt hosted (paquets internes d'abord)
- Chercher dans le premier proxy
- Chercher dans le deuxieme proxy
Priorité au hosted pour prevenir la dependency confusion
Toujours placer le dépôt hosted en premier dans l'ordre de résolution du group. Cela empeche un paquet malveillant public de même nom qu'un paquet interne de prendre le dessus.
Stratégies de caching¶
Cache complet vs cache a la demande¶
| Stratégie | Description | Stockage requis | Cas d'usage |
|---|---|---|---|
| Cache a la demande | Seuls les paquets demandes sont telecharges | Faible | Approche par defaut (proxy) |
| Miroir complet | Réplication integrale du registre upstream | Tres eleve | Environnement air-gapped |
| Prefetch selectif | Telechargement anticipe des paquets critiques | Moyen | Garantir la disponibilité offline |
Politique d'expiration¶
Les caches doivent gérer la fraicheur des metadonnees et des artefacts :
# Exemple de politique de cache Nexus
proxy:
remote_url: https://registry.npmjs.org
content_max_age: 1440 # Artefacts : verifier toutes les 24h
metadata_max_age: 1440 # Metadonnees : verifier toutes les 24h
negative_cache:
enabled: true
ttl: 15 # Paquets introuvables : re-essayer apres 15 min
Negative cache
Le negative cache evite de bombarder l'upstream pour des paquets inexistants, mais il peut retarder la disponibilité d'un paquet nouvellement publie. Un TTL de 15 minutes est un bon compromis.
SBOM et provenance¶
Software Bill of Materials¶
Un SBOM est un inventaire complet des composants logiciels d'un projet. Les miroirs internes facilitent la génération de SBOM car ils centralisent l'ensemble des paquets consommes.
| Format SBOM | Standard | Outils de génération |
|---|---|---|
| SPDX | ISO 5962 | syft, trivy, scancode |
| CycloneDX | OWASP | cdxgen, trivy, syft |
Provenance et attestation¶
Les ecosystemes modernes ajoutent des mécanismes de provenance :
| Ecosysteme | Mécanisme de provenance | Vérification |
|---|---|---|
| npm | Provenance statements (Sigstore) | npm audit signatures |
| PyPI | Attestations PEP 740 | Vérification via Sigstore |
| Docker | Cosign signatures, SLSA provenance | cosign verify, slsa-verifier |
| Go | go.sum (hash de chaque module) | Vérification automatique par go mod |
| Maven | Signatures PGP des artefacts | Vérification par Gradle/Maven |
Menaces sur la chaîne d'approvisionnement¶
Typosquatting¶
Un attaquant publie un paquet au nom proche d'un paquet populaire. L'utilisateur qui fait une faute de frappe installe le paquet malveillant.
| Paquet legitime | Paquet malveillant (exemple) |
|---|---|
requests | requets, request |
lodash | 1odash, lodash-utils |
colors | co1ors, colour |
Mitigation : le miroir interne peut maintenir une liste blanche de paquets autorises, ou scanner automatiquement les nouvelles entrees.
Dependency confusion¶
Un attaquant publie sur le registre public un paquet portant le même nom qu'un paquet interne, avec un numero de version supérieur. Le gestionnaire de paquets résout vers la version publique.
Registre public : @company/utils v99.0.0 ← malveillant
Registre interne : @company/utils v1.2.3 ← legitime
pip install @company/utils
→ Resout vers v99.0.0 (publique) si le registre public est interroge en premier
Mitigation :
- Dépôt group avec hosted en priorité
- Utiliser des namespaces/scopes (
@company/pour npm) - Bloquer la résolution de noms internes sur les dépôts proxy
Mainteneur compromis¶
Un compte de mainteneur est compromis (credentials voles, social engineering) et une version malveillante est publiee sous le nom legitime du paquet.
| Incident | Paquet | Impact |
|---|---|---|
| event-stream 2018 | event-stream | Vol de cryptomonnaies |
| ua-parser-js 2021 | ua-parser-js | Cryptomining + vol |
| colors.js 2022 | colors | Sabotage volontaire |
| xz-utils 2024 | xz | Backdoor SSH (liblzma) |
Mitigation : delai de propagation configurable dans le proxy (ne pas servir immédiatement les nouvelles versions), scanning automatique, pinning des versions.
Vérification des signatures et content trust¶
Docker Content Trust (DCT)¶
# Activer la verification des signatures Docker
export DOCKER_CONTENT_TRUST=1
# Signer une image lors du push
docker push registry.internal:5000/app:v1.0.0
# Notary verifie la signature au pull
docker pull registry.internal:5000/app:v1.0.0
Cosign (Sigstore)¶
# Signer une image OCI
cosign sign --key cosign.key registry.internal:5000/app:v1.0.0
# Verifier la signature
cosign verify --key cosign.pub registry.internal:5000/app:v1.0.0
Vérification GPG pour les dépôts apt/rpm¶
# Importer la cle GPG du depot
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys ABCDEF1234567890
# Verifier la signature du fichier Release
gpg --verify Release.gpg Release
Le miroir doit preserver les signatures
Un miroir interne doit relayer les signatures et les metadonnees de provenance sans les altérer. Si le miroir re-signe les paquets, cela casse la chaîne de confiance et empeche les clients de vérifier l'authenticite aupres de la source originale.