RegistryAdmin est l'outil d'interface utilisateur du registre Docker qui permet aux utilisateurs de gérer l'accès et les entrées d'un registre Docker privé. Il fournit une interface utilisateur Web pour gérer les référentiels, les images et l'accès des utilisateurs, et permet aux utilisateurs de s'authentifier à l'aide de l'un ou l'autre password
. L'objectif principal du projet est de fournir une API de haut niveau pour gérer l'accès des utilisateurs à un registre privé et de restreindre les actions des utilisateurs (telles que le push et le pull) pour des référentiels spécifiques basés sur l'image officielle du registre privé Docker. Cela peut être utile pour les propriétaires de registre qui souhaitent avoir plus de contrôle sur leur registre et pouvoir en gérer l'accès plus facilement.
Interface utilisateur Web créée avec le framework React-Admin et les composants MUI.
pull
/ push
) pour le schéma d'authentification token
) RegistryAdmin est un outil qui fonctionne conjointement avec un registre Docker privé et utilise l'API V2 du registre pour communiquer avec lui. Il possède le point de terminaison HTTP utilisé pour authentifier les utilisateurs à l’aide d’un jeton et pour vérifier leurs droits d’accès. Pour utiliser RegistryAdmin avec un registre, celui-ci doit être configuré pour prendre en charge l'authentification basée sur un jeton. Cela permet aux utilisateurs d'obtenir ou de restreindre l'accès à certaines actions (telles que pull
ou push
) en fonction de leur jeton d'authentification.
# in registry config file
...
auth :
token :
realm : https://{registry-admin-host}/api/v1/registry/auth
service : container_registry_service_name
issuer : registry_token_issuer_name
rootcertbundle : /certs/cert.crt # path to certificate bundle
Vous pouvez utiliser le schéma d'authentification htpasswd
, mais avec cette méthode, vous pouvez uniquement gérer les utilisateurs et ne pas restreindre l'accès aux référentiels par un utilisateur spécifique. Cette fonctionnalité n'est disponible que lors de l'utilisation de l'authentification par jeton.
Pour améliorer l'expérience utilisateur avec des fonctionnalités telles que le tri, la recherche et la saisie semi-automatique, RegistryAdmin dispose d'un système de stockage intégré qui se synchronise avec les données du registre. Ceci est nécessaire pour éviter les limites de l'API de recherche (catalogue) exposées par l'API du registre, car la fonction de recherche autorise uniquement la pagination avec un curseur et ne prend pas en charge la recherche par entrée du référentiel. L'application comprend également un garbage collector interne pour vérifier la cohérence des données dans le stockage intégré.
Pour détecter les modifications dans le registre, vous devez configurer la notification du registre à envoyer à l'application RegistryAdmin.
# in registry config file
...
notifications :
events :
includereferences : true
endpoints :
- name : ra-listener
disabled : false
url : http://{registry-admin-host}/api/v1/registry/events
headers :
Authorization : [ Basic Y2xpZW50MDg6Y0t1cnNrQWdybzA4 ]
timeout : 1s
threshold : 5
backoff : 3s
ignoredmediatypes :
- application/octet-stream
ignore :
mediatypes :
- application/octet-stream
Accès à l'interface utilisateur de RegistryAdmin en fonction du rôle de l'utilisateur :
Admin
- droits complets de lecture et d'écriture pour les utilisateurs, accès et entrées des référentiels.Manager
- droits limités pour parcourir la liste d'accès et les entrées des référentiels.User
: peut parcourir uniquement les entrées des référentiels attribués.RegistryAdmin distribué sous forme de petit binaire autonome ainsi que d'image Docker. Binary prend en charge plusieurs architectures et plusieurs systèmes d'exploitation, notamment linux_x86_64, linux_arm64, linux_arm, macos_x86_64, macos_arm64 et windows_x86_64. L’image Docker prend en charge les architectures linux_x86_64, linux_arm64 et linux_arm.
La dernière version stable a la balise docker :vX.YZ (avec :latest alias) et le maître actuel a la balise :master.
Pour commencer, vous devrez configurer les paramètres requis dans un fichier docker-compose ou à l'aide d'indicateurs de ligne de commande. Vous pouvez trouver divers exemples de configuration dans le dossier _examples.
Lorsque vous démarrez RegistryAdmin en tant que conteneur Docker, vous devez définir l'autorisation pour l'utilisateur des dossiers d'application ( certs
, config
, data
) avec l'UID 1001
. Pour remplacer l'UID dans un conteneur, vous devez utiliser la variable d'environnement dans un conteneur en commençant par les paramètres APP_UID
.
chown -R 1001:1001 {root-registry-admin-folder}
hostname
- définissez le nom d'hôte ou l'adresse IP à inclure dans l'en-tête AllowedOrigins
qui est utilisé pour vérifier les requêtes CORS
port
- définissez le port que l'application utilisera pour écouter les requêtes HTTP (la valeur par défaut est 80). Remarque : Si vous démarrez l'application en tant que conteneur Docker, seuls les ports 80
et 443
sont exposés à l'intérieur du conteneur.
store.type
- définit le type de stockage pour les données principales du magasin (utilisateurs, accès, référentiels). Par défaut ( embed
)
Now implement embed storage type only
store.admin_password
- remplace le mot de passe administrateur par défaut lors de la première création du stockage (mot de passe par défaut : admin
)store.embed.path
- définit le chemin d'accès pour le fichier de stockage intégré (par défaut : ./data.db
) registry.host
- définit l'hôte principal ou l'adresse IP de l'instance de registre privé avec le préfixe du schéma de protocole.
example: host: https://{registry-host}
registry.port
- port d'une instance de registre Docker privée (par défaut : 5000
)registry.auth_type
- définit le type d'authentification token
ou basic
(par défaut : token
).issuer
- nom de l'émetteur qui vérifie dans le registre, le nom de l'émetteur doit être le même dans le registre Docker privé et dans RegistryAdmin.service
- nom du service défini dans les paramètres du registre, le nom du service doit être le même dans le registre Docker privé et dans RegistryAdmin. ❗ Gardez à l’esprit que les options certs
requis par le type d’authentification token
doivent être définies.
registry.certs.path
- répertoire racine où seront générés et stockés les certificats pour la signature des jetonsregistry.certs.key
- chemin d'accès à la clé privée pour la signature du jetonregistry.certs.public_key
- chemin d'accès à la clé publique pour vérifier la signature du jetonregistry.certs.ca
- chemin d'accès au groupe d'autorités de certificationregistry.certs.fqdns
- FQDN(s) requis pour ajouter le certificat de registre et les vérifications à la demande des clientsregistry.certs.ip
- une adresse IP sera ajoutée au champ d'extension de certificat (SAN). S'il est omis, une erreur de certificat peut se produire. Les certificats seront générés automatiquement si registry.certs.path
est valide et que le répertoire est vide. Si les options certs
ne sont pas définies, les certificats seront créés dans un répertoire personnel de l'utilisateur dans le sous-dossier .registry-certs
:
~/.registry-certs/
registry_auth.key
registry_auth.pub
registry_auth_ca.crt
Remarque : lorsque des certificats auto-signés sont utilisés, vous devez configurer Docker Engine sur un hôte client pour travailler avec ceux-ci.
# https://docs.docker.com/config/daemon/
# /etc/docker/daemon.json (Linux)
# C:ProgramDatadockerconfigdaemon.json (Windows)
{
...
"insecure-registries": ["{registry-host}:{port}"],
...
}
Les certificats générés pour le jeton de registre peuvent également être utilisés pour HTTP TLS/SSL. Ce certificat s'ajoute automatiquement à l'autorité de certification approuvée. Mais si vous utilisez un autre certificat pour l'accès HTTPS, vous devez l'ajouter au pool d'autorités de certification de confiance. Pour cela, utilisez l'option
--registry.https-certs
pour définir le chemin d'accès à un certificat utilisé utilisé pour l'accès TLS/SSL. Il est également requis pour les certificats émis par Let's Encrypt. En outre, vous pouvez définir l'option --registry.https-insecure
pour ignorer la vérification du certificat de confiance, mais de manière NON RECOMMANDÉE.
# in a registry-admin config
registry :
...
certs :
...
https_cert : /{path-to-ssl}/cert.pem
...
Gardez à l'esprit que si vous utilisez le mode SSL auto
, vous devez définir l'option --ssl.acme-location
pour stocker le cache ACME. Ensuite, la date du cache doit être définie dans la configuration registry
dans l'option Letsencrypt :
letsencrypt :
cachefile : /path/to/cache-file
email : [email protected]
hosts : [you-registry.domain.org]
Registre V2 pris en charge uniquement. Pour utiliser le registre Docker avec l'authentification par jeton, vous devez le configurer en tant que gestionnaire de contrôle d'accès autonome pour les ressources hébergées par d'autres services qui souhaitent authentifier et gérer les autorisations à l'aide d'un gestionnaire de contrôle d'accès distinct. Pour obtenir plus d'informations à ce sujet, suivez les documentations officielles.
Dans un premier temps, vous devez définir l'option auth
pour l'authentification token
et définir certificate
et key
spécifiques générés avec l'application RegistryAdmin. Les options de jeton doivent être les mêmes que les options définies par RegistryAdmin Registry
( issuer
, service
, cert_ca
). L'application RegistryAdmin dispose d'un point de terminaison public pour authentifier les demandes des utilisateurs au registre, qui doit être utilisé dans l'option de registre realm
.
https://{registry-admin-host}:{port}/api/v1/auth
❗ realm
est une option d' adresse IP ou d'instance de nom d'hôte RegistryAdmin qui doit être accessible aux clients Docker qui l'utilisent pour s'authentifier auprès du registre privé.
auth :
token :
realm : http://{registry-admin-hostname}/api/v1/registry/auth
service : container_registry
issuer : registry_token_issuer
rootcertbundle : /certs/cert.crt
Pour gérer les événements de registre et déclencher la tâche du référentiel (telle que l'ajout d'une nouvelle entrée, la mise à jour ou la suppression d'une entrée du référentiel), vous devez configurer les options de notification du registre :
url
- URL http(s) vers l'hôte RegistryAdmin avec le chemin du point de terminaison des événements.
Authorization
de tout utilisateur activé et enregistré et son mot de passe dans l'application RegistryAdmin, encodé en Base64.
notifications :
events :
includereferences : true
endpoints :
- name : ra-listener
disabled : false
url : http://registry-admin/api/v1/registry/events
headers :
Authorization : [Basic YWRtaW46c3VwZXItc2VjcmV0] # encoded in Base64 as 'admin:super-secret'
timeout : 1s
threshold : 5
backoff : 3s
ignoredmediatypes :
- application/octet-stream
ignore :
mediatypes :
- application/octet-stream
option basic
utilisant le fichier .htpasswd
et ne prend pas en charge la restriction de l'accès à des référentiels spécifiques. Pour utiliser l'authentification basic
, vous avez besoin des options suivantes :
login
- nom d'utilisateur pour accéder au registre Dockerpassword
- mot de passe pour accéder au registre Docker Le registre Docker lit le fichier .htpasswd
à chaque fois lors de l'authentification de l'appel et ne nécessite pas de redémarrer le service de registre après la mise à jour ou la suppression de l'utilisateur dans RegistryAdmin
Par défaut, aucun journal de requêtes n'est généré. Cela peut être activé en définissant --logger.enabled
. Le journal (à rotation automatique) a le format de journal combiné Apache
L'utilisateur peut également activer la connexion stdout avec --logger.stdout
. Cela n'affectera pas la journalisation des fichiers ci-dessus, mais affichera quelques informations minimales sur les requêtes traitées, quelque chose comme ceci :
127.0.0.1 - - [06/Dec/2022:18:36:34 +0300] "GET /auth/user HTTP/2.0" 200 159
127.0.0.1 - - [06/Dec/2022:18:36:34 +0300] "GET /api/v1/registry/auth HTTP/2.0" 200 198
Lorsque RegistryAdmin a accès depuis Internet, vous devez configurer au minimum des règles de sécurité pour empêcher la force brute du mot de passe. Le moyen le plus simple d'utiliser le service fail2ban
avec le fichier journal d'accès sur un hôte Docker.
access.log
pour le service RegistryAdmin # in registry-admin config file
logger :
enabled : true
filename : /var/log/registry-admin/access.log # mount the directory to a docker host folder for get access for fail2ban
max_size : 5M
max_backups : 3
filter
avec la règle pour le service registry-admin
qui gère les erreurs d'authentification 401
et 403
# /etc/fail2ban/filter.d/registry-admin.conf
[Definition]
failregex = ^<HOST> .+" 40[1,3] d+ .*$
ignoreregex =
fail2ban
au niveau de l'instruction de chaîne, car le trafic système normal apparaît traditionnellement sur la chaîne INPUT
, tandis que le trafic du conteneur Docker est envoyé via la chaîne FORWARD
. # in the /etc/fail2ban/action.d/ directory
sudo cp iptables-common.conf iptables-common-forward.conf
sudo sed -i ' s/INPUT/FORWARD/g ' iptables-common-forward.conf
sudo cp iptables-multiport.conf iptables-multiport-forward.conf
sudo sed -i ' s/iptables-common.conf/iptables-common-forward.conf/g ' iptables-multiport-forward.conf
jail
avec la règle registry-admin
# in /etc/fail2ban/jail.local
[registry-admin]
enabled = true
port = http,https # or set your custom port
filter = registry-admin
banaction = iptables-multiport-forward
logpath = /{path-to-logs-mounted-dir}/logs/access.log
maxretry = 5
findtime = 1h
bantime = 1d
Chaque option peut être fournie sous trois formes : ligne de commande, paire clé d'environnement : valeur ou fichier de configuration (formats json
ou yaml
). Les options de ligne de commande ont uniquement une forme longue, comme --hostname=localhost. La clé d'environnement (nom) répertoriée pour chaque option sous forme de suffixe, c'est-à-dire [$HOSTNAME].
Fichier de configuration autorisé au format json
et yml
--listen: listen on host:port (127.0.0.1:80/443 without) (default: *) [$RA_LISTEN]
--hostname: Main hostname of service (default: localhost) [$RA_HOST_NAME]
--port: Main web-service port. Default:80 (default: 80) [$RA_PORT]
--config-file: Path to config file [$RA_CONFIG_FILE]
--debug enable the debug mode [$RA_DEBUG]
registry:
--registry.host: Main host or address to docker registry service [$RA_REGISTRY_HOST]
--registry.port: Port which registry accept requests. Default:5000 (default: 5000) [$RA_REGISTRY_PORT]
--registry.auth-type:[basic|token] Type for auth to docker registry service. Available 'basic' and 'token'. Default 'token' (default: token) [$RA_REGISTRY_AUTH_TYPE]
--registry.login: Username is a credential for access to registry service using basic auth type [$RA_REGISTRY_LOGIN]
--registry.password: Password is a credential for access to registry service using basic auth type [$RA_REGISTRY_PASSWORD]
--registry.htpasswd: Path to htpasswd file when basic auth type selected [$RA_REGISTRY_HTPASSWD]
--registry.https-insecure Set https connection to registry insecure [$RA_REGISTRY_HTTPS_INSECURE]
--registry.service: A service name which defined in registry settings [$RA_REGISTRY_SERVICE]
--registry.issuer: A token issuer name which defined in registry settings [$RA_REGISTRY_ISSUER]
--registry.token-ttl: Define registry auth token TTL (in seconds). Default value 60 seconds. [$RA_REGISTRY_TOKEN_TTL]
--registry.gc-interval: Use for define custom time interval for garbage collector execute (minutes), default 1 hours [$RA_REGISTRY_GC_INTERVAL]
certs:
--registry.certs.path: A path to directory where will be stored new self-signed cert,keys and CA files, when 'token' auth type is used [$RA_REGISTRY_CERTS_CERT_PATH]
--registry.certs.key: A path where will be stored new self-signed private key file, when 'token' auth type is used [$RA_REGISTRY_CERTS_KEY_PATH]
--registry.certs.public-key: A path where will be stored new self-signed public key file, when 'token' auth type is used [$RA_REGISTRY_CERTS_PUBLIC_KEY_PATH]
--registry.certs.ca-root: A path where will be stored new CA bundles file, when 'token' auth type is used [$RA_REGISTRY_CERTS_CA_ROOT_PATH]
--registry.certs.fqdn: FQDN(s) for registry certificates [$RA_REGISTRY_CERTS_FQDN]
--registry.certs.ip: Address which appends to certificate SAN (Subject Alternative Name) [$RA_REGISTRY_CERTS_IP]
--registry.https-certs: A path to a HTTPS certificate used for TLS access to registry instance [$RA_REGISTRY_HTTPS_CERT]
auth:
--auth.token-secret: Main secret for auth token sign [$RA_AUTH_TOKEN_SECRET]
--auth.jwt-issuer: Token issuer signature (default: zebox) [$RA_AUTH_ISSUER_NAME]
--auth.jwt-ttl: Define JWT expired timeout (default: 1h) [$RA_AUTH_JWT_TTL]
--auth.cookie-ttl: Define cookies expired timeout (default: 24h) [$RA_AUTH_COOKIE_TTL]
logger:
--logger.stdout enable stdout logging [$RA_LOGGER_STDOUT]
--logger.enabled enable access and error rotated logs [$RA_LOGGER_ENABLED]
--logger.file: location of access log (default: access.log) [$RA_LOGGER_FILE]
--logger.max-size: maximum size before it gets rotated (default: 10M) [$RA_LOGGER_SIZE]
--logger.max-backups: maximum number of old log files to retain (default: 10) [$RA_LOGGER_BACKUPS]
ssl:
--ssl.type:[none|static|auto] ssl (auto) support. Default is 'none' (default: none) [$RA_SSL_TYPE]
--ssl.cert: path to cert.pem file [$RA_SSL_CERT]
--ssl.key: path to key.pem file [$RA_SSL_KEY]
--ssl.acme-location: dir where certificates will be stored by autocert manager (default: ./acme) [$RA_SSL_ACME_LOCATION]
--ssl.acme-email: admin email for certificate notifications [$RA_SSL_ACME_EMAIL]
--ssl.port: Main web-service secure SSL port. Default:443 (default: 443) [$RA_SSL_PORT]
--ssl.http-port: http port for redirect to https and acme challenge test (default: 80) [$RA_SSL_ACME_HTTP_PORT]
--ssl.fqdn: FQDN(s) for ACME certificates [$RA_SSL_ACME_FQDN]
store:
--store.type:[embed] type of storage (default: embed) [$RA_STORE_DB_TYPE]
--store.admin-password: Define password for default admin user when storage create first (default: admin) [$RA_STORE_ADMIN_PASSWORD]
embed:
--store.embed.path: Parent directory for the sqlite files (default: ./data.db) [$RA_STORE_EMBED_DB_PATH]
Help Options:
-? Show this help message
-h, --help Show this help message
frontend
local, vous devez exécuter RegistryAdmin avec la variable d'environnement définie RA_DEV_HOST=http://127.0.0.1:3000
pour éviter les erreurs CORS
dans un navigateur. De plus, .env.development
doit contenir un nom d'hôte de développement valide de RegistryAdmin.engine
et peut être utilisé pour étendre le type de stockage pris en chargeEmbed
utilise la base de données SQLite
et CGO
requis est activéLe projet est en cours de développement actif et peut subir des modifications importantes jusqu'à la sortie de la v1. Cependant, nous faisons de notre mieux pour ne pas casser les choses, sauf s'il y a une bonne raison.
Ce projet a été inspiré par les projets et les idées d'Umputun