Nexus Repository Manager¶
Concepts : gestionnaire de depots¶
Un gestionnaire de depots (repository manager) centralise le stockage et la distribution de tous les artefacts logiciels d'une organisation : packages RPM, images Docker, modules npm, packages Python, etc.
Pourquoi miroir les packages en local ?¶
| Avantage | Explication |
|---|---|
| Air-gap | L'infrastructure fonctionne meme sans Internet |
| Performance | Les packages sont telecharges une seule fois, puis servis localement a debit LAN |
| Fiabilite | Pas de dependance aux CDN externes (pannes, rate-limiting) |
| Securite | Point de controle unique pour auditer les packages entrants |
| Reproductibilite | Les versions des packages sont figees dans le cache local |
Types de repositories dans Nexus¶
Nexus propose trois types de repositories :
graph LR
subgraph NEXUS["Nexus Repository Manager"]
PROXY["Proxy<br/>(miroir upstream)"]
HOSTED["Hosted<br/>(artefacts internes)"]
GROUP["Group<br/>(agregation)"]
PROXY --> GROUP
HOSTED --> GROUP
end
UPSTREAM["Upstream<br/>(dl.rockylinux.org,<br/>pypi.org, etc.)"] -->|"Cache on first request"| PROXY
CLIENT["Client<br/>(yum, docker, pip)"] -->|"Single URL"| GROUP
style GROUP fill:#27ae60,color:#fff
style PROXY fill:#3498db,color:#fff
style HOSTED fill:#e67e22,color:#fff
| Type | Role | Exemple |
|---|---|---|
| Proxy | Miroir d'un depot distant. Telecharge depuis l'upstream au premier acces, puis sert depuis le cache | rocky-baseos → dl.rockylinux.org |
| Hosted | Stocke des artefacts crees en interne (pas d'upstream) | Packages RPM internes, images Docker custom |
| Group | Combine plusieurs proxy et/ou hosted sous une seule URL | rpm-all regroupe tous les proxies YUM |
Fonctionnement du cache proxy
Quand un client demande un package pour la premiere fois, Nexus le telecharge depuis l'upstream (via le proxy Squid + Fortigate), le stocke dans son cache local, puis le sert au client. Les requetes suivantes pour le meme package sont servies directement depuis le cache, sans aucun acces Internet.
Architecture Nexus¶
| Parametre | Valeur |
|---|---|
| Nom VM | INF-PDEV40B |
| Adresse IP | 10.15.100.65 (VLAN 106 -- Services) |
| Ressources | 2 vCPU, 8 Go RAM |
| URL | https://repo.infra.indio (port 443) |
| Version | Nexus OSS (Sonatype Nexus Repository Manager) |
| TLS | Certificat emis par Vault PKI Intermediate CA |
| Proxy sortant | http://10.15.50.3:3128 (Squid VIP) |
| Systeme | Rocky Linux 9.6 |
graph TB
subgraph INFRA["Infrastructure interne"]
VM1["VMs Rocky<br/>(yum)"]
VM2["VMs Docker<br/>(docker pull)"]
VM3["VMs Dev<br/>(npm, pip)"]
end
subgraph NEXUS["Nexus — repo.infra.indio:443"]
RPM["rpm-all<br/>(group)"]
DOCKER["docker-all<br/>(group)"]
NPM["npm-all<br/>(group)"]
PYPI["pypi-all<br/>(group)"]
end
subgraph EXTERNAL["Internet (via Squid + FGT)"]
UPS1["dl.rockylinux.org"]
UPS2["registry-1.docker.io"]
UPS3["registry.npmjs.org"]
UPS4["pypi.org"]
end
VM1 -->|"HTTPS"| RPM
VM2 -->|"HTTPS"| DOCKER
VM3 -->|"HTTPS"| NPM
VM3 -->|"HTTPS"| PYPI
RPM -.->|"Cache miss"| UPS1
DOCKER -.->|"Cache miss"| UPS2
NPM -.->|"Cache miss"| UPS3
PYPI -.->|"Cache miss"| UPS4
style NEXUS fill:#27ae60,color:#fff
Repositories group (points d'acces clients)¶
Les clients n'utilisent que les URLs des groups. Chaque group agregue un ou plusieurs repositories proxy (et eventuellement hosted) :
| Type | Group | URL complete | Contenu |
|---|---|---|---|
| RPM/YUM | rpm-all |
https://repo.infra.indio/repository/rpm-all/ |
Tous les proxies YUM ci-dessous |
| Docker | docker-all |
https://repo.infra.indio/repository/docker-all/ |
Docker Hub, GHCR, Quay (proxies) |
| npm | npm-all |
https://repo.infra.indio/repository/npm-all/ |
npmjs.org (proxy) |
| PyPI | pypi-all |
https://repo.infra.indio/repository/pypi-all/ |
pypi.org (proxy) |
Proxies YUM configures¶
Chaque repository proxy est configure avec l'URL upstream correspondante. Nexus telecharge et met en cache les packages automatiquement au premier acces.
| Repository proxy | URL upstream | Contenu |
|---|---|---|
rocky-baseos |
https://dl.rockylinux.org/pub/rocky/9/BaseOS/x86_64/os/ |
Packages de base Rocky Linux 9 |
rocky-appstream |
https://dl.rockylinux.org/pub/rocky/9/AppStream/x86_64/os/ |
Packages applicatifs Rocky 9 |
epel-9 |
https://download.fedoraproject.org/pub/epel/9/Everything/x86_64/ |
Extra Packages for Enterprise Linux 9 |
elastic-8 |
https://artifacts.elastic.co/packages/8.x/yum/ |
Elasticsearch, Kibana, Logstash 8.x |
wazuh-4 |
https://packages.wazuh.com/4.x/yum/ |
Wazuh Manager, agents, Wazuh Indexer |
docker-ce |
https://download.docker.com/linux/centos/9/x86_64/stable/ |
Docker Community Edition |
gitlab-ce |
https://packages.gitlab.com/gitlab/gitlab-ce/el/9/x86_64/ |
GitLab Community Edition |
zabbix-7 |
https://repo.zabbix.com/zabbix/7.0/rhel/9/x86_64/ |
Zabbix Server, agents, frontend |
hashicorp |
https://rpm.releases.hashicorp.com/RHEL/9/x86_64/stable/ |
Vault, Terraform, Packer |
Pas de GPG check sur les proxies
Nexus ne verifie pas les signatures GPG en interne. C'est le client yum/dnf qui
effectue la verification GPG cote VM avec gpgcheck=1. La chaine de confiance
est maintenue de bout en bout.
Configuration des clients via Ansible¶
Le role Ansible common deploie automatiquement les fichiers de configuration YUM
sur toutes les VMs pour pointer vers Nexus :
# /etc/yum.repos.d/nexus-rocky-baseos.repo
[nexus-rocky-baseos]
name=Rocky Linux 9 - BaseOS (Nexus)
baseurl=https://repo.infra.indio/repository/rocky-baseos/
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-9
sslverify=1
sslcacert=/etc/pki/tls/certs/ca-bundle.crt
| Directive | Role |
|---|---|
baseurl |
Pointe vers le repository Nexus (pas l'upstream) |
gpgcheck=1 |
Verification de la signature GPG des packages |
sslverify=1 |
Verification du certificat TLS de Nexus |
sslcacert |
Chemin vers le bundle CA (inclut la CA Vault) |
Le role common desactive egalement les fichiers repo d'origine (/etc/yum.repos.d/rocky*.repo)
pour eviter tout telechargement direct depuis Internet.
Docker registry via Nexus¶
Nexus expose un proxy Docker qui permet de telecharger des images de conteneurs sans acces direct a Docker Hub.
Fonctionnement¶
sequenceDiagram
participant D as Docker Client
participant N as Nexus (docker-all)
participant R as Docker Hub
D->>N: docker pull repo.infra.indio/repository/docker-all/nginx:latest
alt Image en cache
N-->>D: Image servie depuis le cache
else Premier telechargement
N->>R: Pull depuis registry-1.docker.io (via Squid)
R-->>N: Layers de l'image
N->>N: Stockage en cache
N-->>D: Image servie
end
Commande de pull¶
# Pull d'une image via Nexus (prefixer par le hostname Nexus)
docker pull repo.infra.indio/repository/docker-all/nginx:latest
# Equivalent a : docker pull docker.io/library/nginx:latest
# mais via le cache Nexus
Configuration Docker daemon
Le Docker daemon des VMs est configure pour utiliser Nexus comme registry mirror.
Le certificat CA de la PKI Vault est installe dans le trust store Docker
(/etc/docker/certs.d/repo.infra.indio/ca.crt).
TLS et chaine de confiance¶
Le certificat HTTPS de Nexus est emis par la PKI Vault (Intermediate CA) :
| Parametre | Valeur |
|---|---|
| Emetteur (Issuer) | CN=Infra Indio Intermediate CA |
| Subject | CN=repo.infra.indio |
| SAN | DNS:repo.infra.indio, IP:10.15.100.65 |
| Validite | 1 an |
| CRL | https://10.15.100.74:8200/v1/pki_int/crl |
| OCSP | https://10.15.100.74:8200/v1/pki_int/ocsp |
La CA chain (Root CA + Intermediate CA) est distribuee sur toutes les VMs par le role
Ansible common dans /etc/pki/ca-trust/source/anchors/. Ainsi, sslverify=1 fonctionne
pour yum, docker, pip et npm sans erreur de certificat.
Capacite air-gap¶
Grace a Nexus, l'infrastructure peut fonctionner sans acces Internet :
graph TB
subgraph ONLINE["Mode connecte (normal)"]
N1["Nexus"] -->|"Proxy cache"| UP["Upstreams Internet"]
N1 -->|"Sert depuis cache"| VM1["VMs"]
end
subgraph OFFLINE["Mode air-gap (coupure)"]
N2["Nexus<br/>(cache local)"] -->|"Sert depuis cache"| VM2["VMs"]
N2 -.-x|"Pas d'acces"| UP2["Internet"]
end
style OFFLINE fill:#f9f9f9
style UP2 fill:#e74c3c,color:#fff
Prerequis pour le mode air-gap
Pour qu'un package soit disponible en air-gap, il faut qu'il ait ete telecharge
au moins une fois pendant que l'acces Internet etait disponible. Il est recommande
de faire un yum makecache et un docker pull de toutes les images necessaires
avant une coupure planifiee.