RegistryAdmin은 사용자가 개인 Docker 레지스트리의 액세스 및 항목을 관리할 수 있는 Docker 레지스트리 UI 도구입니다. 이는 리포지토리, 이미지 및 사용자 액세스를 관리하기 위한 웹 기반 사용자 인터페이스를 제공하며 사용자는 두 가지 password
중 하나를 사용하여 인증할 수 있습니다. 프로젝트의 주요 목표는 개인 레지스트리에 대한 사용자 액세스를 관리하기 위한 고급 API를 제공하고 공식 개인 Docker 레지스트리 이미지를 기반으로 특정 저장소에 대한 사용자 작업(예: 푸시 및 풀)을 제한하는 것입니다. 이는 자신의 레지스트리에 대해 더 많은 제어권을 갖고 싶고 레지스트리에 대한 액세스를 더 쉽게 관리할 수 있기를 원하는 레지스트리 소유자에게 유용할 수 있습니다.
React-Admin 프레임워크 및 MUI 구성 요소를 사용하여 만든 웹 사용자 인터페이스입니다.
token
인증 방식에 대한 사용자 작업( pull
/ push
)을 기반으로 리포지토리에 대한 액세스 제한) RegistryAdmin은 개인 Docker 레지스트리와 함께 작동하고 레지스트리의 V2 API를 사용하여 통신하는 도구입니다. 토큰을 사용하여 사용자를 인증하고 액세스 권한을 확인하는 데 사용되는 HTTP 끝점이 있습니다. 레지스트리와 함께 RegistryAdmin을 사용하려면 토큰 기반 인증을 지원하도록 레지스트리를 구성해야 합니다. 이를 통해 사용자는 인증 토큰을 기반으로 특정 작업(예: pull
또는 push
)에 대한 액세스 권한을 부여하거나 제한할 수 있습니다.
# 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
htpasswd
인증 체계를 사용할 수 있지만 이 방법을 사용하면 사용자를 관리할 수만 있고 특정 사용자의 저장소 액세스를 제한할 수는 없습니다. 이 기능은 토큰 기반 인증을 사용하는 경우에만 사용할 수 있습니다.
정렬, 검색 및 자동 완성과 같은 기능으로 사용자 경험을 향상시키기 위해 RegistryAdmin에는 레지스트리의 데이터와 동기화되는 내장형 저장 시스템이 있습니다. 이는 레지스트리 API에 의해 노출된 검색 API(카탈로그)의 한계를 피하기 위해 필요합니다. 검색 기능은 커서를 사용한 페이지 매기기만 허용하고 저장소 항목별 검색은 지원하지 않기 때문입니다. 앱에는 내장된 저장소의 데이터 일관성을 확인하기 위한 내부 가비지 수집기도 포함되어 있습니다.
레지스트리에서 변경 사항을 포착하려면 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
사용자 역할에 따라 RegistryAdmin UI에 액세스:
Admin
- 사용자의 읽기 및 쓰기, 저장소 액세스 및 항목에 대한 모든 권한입니다.Manager
- 찾아보기 액세스 목록 및 저장소 항목에 대한 제한된 권한입니다.User
- 할당된 저장소 항목만 찾아볼 수 있습니다.RegistryAdmin은 작은 독립형 바이너리와 도커 이미지로 배포됩니다. 바이너리는 linux_x86_64, linux_arm64, linux_arm, macos_x86_64, macos_arm64 및 windows_x86_64를 포함한 여러 아키텍처와 여러 운영 체제를 지원합니다. Docker 이미지는 linux_x86_64, linux_arm64 및 linux_arm 아키텍처를 지원합니다.
최신 안정 버전에는 :vX.YZ 도커 태그(:latest 별칭 포함)가 있고 현재 마스터에는 :master 태그가 있습니다.
시작하려면 docker-compose 파일에서 또는 명령줄 플래그를 사용하여 필수 매개변수를 설정해야 합니다. _examples 폴더에서 다양한 구성 예시를 확인할 수 있습니다.
RegistryAdmin을 Docker 컨테이너로 시작할 때 UID 1001
을 사용하여 응용 프로그램 폴더( certs
, config
, data
) 사용자에 대한 권한을 설정해야 합니다. 컨테이너 내부의 UID 재정의를 위해서는 APP_UID
매개변수를 시작하는 컨테이너의 환경 변수를 사용해야 합니다.
chown -R 1001:1001 {root-registry-admin-folder}
hostname
- CORS
요청을 확인하는 데 사용되는 AllowedOrigins
헤더에 포함할 호스트 이름 또는 IP 주소를 정의합니다.
port
- 애플리케이션이 HTTP 요청을 수신하는 데 사용할 포트를 정의합니다(기본값은 80). 참고: 앱을 Docker 컨테이너로 시작하면 포트 80
및 443
만 컨테이너 내부에 노출됩니다.
store.type
- 저장소 기본 데이터(사용자, 액세스, 저장소)에 대한 저장소 유형을 정의합니다. 기본값( embed
)
Now implement embed storage type only
store.admin_password
- 스토리지를 처음 생성할 때 기본 관리자 비밀번호를 재정의합니다(기본 비밀번호: admin
).store.embed.path
- 포함된 저장소 파일의 경로 이름을 정의합니다(기본값: ./data.db
). registry.host
- 프로토콜 체계 접두사를 사용하여 개인 레지스트리 인스턴스의 기본 호스트 또는 IP 주소를 정의합니다.
example: host: https://{registry-host}
registry.port
- 프라이빗 도커 레지스트리 인스턴스의 포트(기본값: 5000
)registry.auth_type
- 인증 유형 token
또는 basic
정의합니다(기본값: token
).issuer
- 레지스트리 내부를 확인하는 발급자 이름, 프라이빗 도커 레지스트리와 RegistryAdmin의 발급자 이름이 동일해야 합니다.service
- 레지스트리 설정에 정의된 서비스 이름으로, 프라이빗 도커 레지스트리와 RegistryAdmin의 서비스 이름이 동일해야 합니다. ❗ token
인증 유형 필수 certs
옵션을 정의해야 한다는 점에 유의하세요.
registry.certs.path
- 토큰 서명을 위해 인증서가 생성되고 저장되는 루트 디렉터리registry.certs.key
- 토큰 서명을 위한 개인 키 경로registry.certs.public_key
- 토큰 서명 확인을 위한 공개 키 경로registry.certs.ca
- 인증 기관 번들의 경로registry.certs.fqdns
- 클라이언트 요청 시 레지스트리 인증서 및 확인을 위해 추가하는 데 필요한 FQDNregistry.certs.ip
- IP 주소가 SAN(인증서 확장 필드)에 추가됩니다. 생략할 경우 인증서 오류가 발생할 수 있습니다. registry.certs.path
가 유효하고 디렉터리가 비어 있으면 인증서가 자동으로 생성됩니다. certs
옵션이 정의되지 않은 경우 인증서는 하위 폴더 .registry-certs
의 사용자 홈 디렉터리에 생성됩니다.
~/.registry-certs/
registry_auth.key
registry_auth.pub
registry_auth_ca.crt
참고: 자체 서명된 인증서를 사용하는 경우 해당 인증서와 함께 작동하도록 클라이언트 호스트에서 Docker 엔진을 구성해야 합니다.
# https://docs.docker.com/config/daemon/
# /etc/docker/daemon.json (Linux)
# C:ProgramDatadockerconfigdaemon.json (Windows)
{
...
"insecure-registries": ["{registry-host}:{port}"],
...
}
레지스트리 토큰용으로 생성된 인증서는 HTTP TLS/SSL에도 사용할 수 있습니다. 해당 인증서는 신뢰할 수 있는 CA에 자동으로 추가됩니다. 그러나 HTTPS 액세스를 위해 다른 인증서를 사용하는 경우 이를 신뢰할 수 있는 CA 풀에 추가해야 합니다. 이를 위해 옵션을 사용하십시오.
--registry.https-certs
TLS/SSL 액세스에 사용되는 인증서에 대한 경로를 정의합니다. Let's Encrypt에서 발급한 인증서에도 필요합니다. 또한 신뢰할 수 있는 인증서에 대한 건너뛰기 확인을 위해 --registry.https-insecure
옵션을 정의할 수 있지만 권장되지는 않습니다.
# in a registry-admin config
registry :
...
certs :
...
https_cert : /{path-to-ssl}/cert.pem
...
auto
SSL 모드를 사용하는 경우 ACME 캐시 저장을 위해 --ssl.acme-location
옵션을 정의해야 합니다. 그런 다음 캐시 날짜는 letsencrypt 옵션의 registry
구성에서 정의되어야 합니다.
letsencrypt :
cachefile : /path/to/cache-file
email : [email protected]
hosts : [you-registry.domain.org]
레지스트리 V2만 지원됩니다. 토큰 인증과 함께 Docker 레지스트리를 사용하려면 별도의 액세스 제어 관리자를 사용하여 권한을 인증하고 관리하려는 다른 서비스에서 호스팅하는 리소스에 대한 독립형 액세스 제어 관리자로 구성해야 합니다. 이에 대한 자세한 내용을 보려면 공식 문서를 참조하세요.
먼저 token
인증에 대한 auth
옵션을 정의하고 RegistryAdmin 앱으로 생성된 특정 certificate
와 key
설정해야 합니다. 토큰 옵션은 RegistryAdmin Registry
정의 옵션( issuer
, service
, cert_ca
)과 동일해야 합니다. RegistryAdmin 앱에는 레지스트리에 대한 사용자 요청을 인증하기 위한 공개 엔드포인트가 있으며, 이는 realm
레지스트리 옵션에서 사용해야 합니다.
https://{registry-admin-host}:{port}/api/v1/auth
❗ realm
개인 레지스트리에 인증하기 위해 이를 사용하는 Docker 클라이언트가 액세스해야 하는 IP 주소 또는 호스트 이름 RegistryAdmin 인스턴스의 옵션입니다.
auth :
token :
realm : http://{registry-admin-hostname}/api/v1/registry/auth
service : container_registry
issuer : registry_token_issuer
rootcertbundle : /certs/cert.crt
레지스트리 이벤트를 처리하고 저장소 작업을 트리거하려면(예: 저장소 항목 새로 추가, 업데이트 또는 삭제) 레지스트리 알림 옵션을 설정해야 합니다.
url
- 이벤트 엔드포인트 경로가 있는 RegistryAdmin 호스트에 대한 http(s) URL입니다.
Base64로 인코딩된 RegistryAdmin 앱에서 활성화되고 등록된 모든 사용자와 해당 비밀번호에 대한 Authorization
.
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
.htpasswd
파일을 사용하는 basic
옵션이며 특정 저장소에 대한 액세스 제한을 지원하지 않습니다. basic
인증을 사용하려면 다음 옵션이 필요합니다.
login
- 도커 레지스트리에 액세스하기 위한 사용자 이름password
- 도커 레지스트리에 접근하기 위한 비밀번호 Docker 레지스트리는 호출을 인증할 때마다 .htpasswd
파일을 읽고 RegistryAdmin에서 사용자 업데이트 또는 삭제 후 레지스트리 서비스를 다시 시작할 필요가 없습니다.
기본적으로 요청 로그가 생성되지 않습니다. --logger.enabled
설정하여 이를 활성화할 수 있습니다. 로그(자동 회전)에는 Apache 결합 로그 형식이 있습니다.
사용자는 --logger.stdout
사용하여 stdout 로그온을 설정할 수도 있습니다. 위의 파일 로깅에는 영향을 미치지 않지만 다음과 같이 처리된 요청에 대한 최소한의 정보를 출력합니다.
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
RegistryAdmin이 인터넷에서 액세스할 수 있는 경우 비밀번호 무차별 대입을 방지하기 위해 보안 규칙을 최소한으로 설정해야 합니다. Docker 호스트의 액세스 로그 파일과 함께 fail2ban
서비스를 사용하는 가장 간단한 방법입니다.
access.log
구성 # 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
401
및 403
auth/z 오류를 처리하는 registry-admin
서비스에 대한 규칙을 사용하여 filter
만듭니다. # /etc/fail2ban/filter.d/registry-admin.conf
[Definition]
failregex = ^<HOST> .+" 40[1,3] d+ .*$
ignoreregex =
fail2ban
조치를 준비해야 합니다. 왜냐하면 일반적인 시스템 트래픽은 전통적으로 INPUT
체인에서 발생하는 반면 Docker 컨테이너 트래픽은 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
registry-admin
규칙을 사용하여 jail
만들기 # 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
각 옵션은 명령줄, 환경 키:값 쌍 또는 구성 파일( json
또는 yaml
형식)의 세 가지 형식으로 제공될 수 있습니다. 명령줄 옵션에는 --hostname=localhost와 같이 긴 형식만 있습니다. 각 옵션에 대해 접미사로 나열된 환경 키(이름)입니다(예: [$HOSTNAME]).
json
및 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
개발의 경우 브라우저에서 CORS
오류를 방지하려면 정의된 환경 변수 RA_DEV_HOST=http://127.0.0.1:3000
사용하여 RegistryAdmin을 실행해야 합니다. 또한 .env.development
RegistryAdmin의 유효한 개발 호스트 이름이 포함되어야 합니다.engine
인터페이스를 사용하여 스토리지를 구현하고 지원되는 스토리지 유형을 확장하는 데 사용할 수 있습니다.Embed
SQLite
데이터베이스를 사용하고 필수 CGO
활성화이 프로젝트는 활발히 개발 중이며 v1이 출시될 때까지 주요 변경 사항이 있을 수 있습니다. 다만, 정당한 사유가 없는 이상 깨지지 않도록 최선을 다하고 있습니다.
이 프로젝트는 Umputun의 프로젝트와 아이디어에서 영감을 받았습니다.