From 7716f8b44a0128f93fc10a8cc98b8c9034516b93 Mon Sep 17 00:00:00 2001 From: Joxit Date: Mon, 24 Jun 2019 23:54:21 +0200 Subject: [PATCH 1/2] feat: Supports custom headers when the ui is used as proxy --- bin/entrypoint | 18 ++++++++++--- examples/proxy-headers/README.md | 22 +++++++++++++++ examples/proxy-headers/docker-compose.yml | 27 +++++++++++++++++++ .../registry-config/credentials.yml | 25 +++++++++++++++++ .../proxy-headers/registry-config/htpasswd | 1 + nginx/default.conf | 1 + package.json | 2 +- 7 files changed, 92 insertions(+), 4 deletions(-) create mode 100644 examples/proxy-headers/README.md create mode 100644 examples/proxy-headers/docker-compose.yml create mode 100644 examples/proxy-headers/registry-config/credentials.yml create mode 100644 examples/proxy-headers/registry-config/htpasswd diff --git a/bin/entrypoint b/bin/entrypoint index 12417e13..ea8a7b54 100755 --- a/bin/entrypoint +++ b/bin/entrypoint @@ -1,5 +1,5 @@ #!/bin/sh -$@ + sed -i "s,\${URL},${URL}," scripts/docker-registry-ui.js sed -i "s,\${REGISTRY_TITLE},${REGISTRY_TITLE}," scripts/docker-registry-ui.js sed -i "s,\${PULL_URL},${PULL_URL}," scripts/docker-registry-ui.js @@ -8,13 +8,25 @@ if [ -z "${DELETE_IMAGES}" ] || [ "${DELETE_IMAGES}" = false ] ; then sed -i -r "s/(isImageRemoveActivated[:=])[^,;]*/\1false/" scripts/docker-registry-ui.js fi +get_nginx_proxy_headers() { + env | while read e; do + if [ -n "$(echo $e | grep -o '^NGINX_PROXY_HEADER_')" ]; then + key=$(echo ${e%%=*} | sed 's/^NGINX_PROXY_HEADER_//' | sed 's/_/-/g') + value=${e#*=} + echo "Add proxy header $key: $value" >&2 + echo -n "proxy_set_header ${key} \"${value}\"; " + fi + done +} + if [ -n "${REGISTRY_URL}" ] ; then sed -i "s,\${REGISTRY_URL},${REGISTRY_URL}," /etc/nginx/conf.d/default.conf + sed -i "s^\${NGINX_PROXY_HEADERS}^$(get_nginx_proxy_headers)^" /etc/nginx/conf.d/default.conf sed -i "s,#!,," /etc/nginx/conf.d/default.conf fi if [ -z "$@" ]; then - nginx -g "daemon off;" + exec nginx -g "daemon off;" else - $@ + exec $@ fi diff --git a/examples/proxy-headers/README.md b/examples/proxy-headers/README.md new file mode 100644 index 00000000..0d54874d --- /dev/null +++ b/examples/proxy-headers/README.md @@ -0,0 +1,22 @@ +# Set custom headers to the registry example + +The interface and the docker registry will be accessible with . + +This example highlight the usage of custom headers when the UI is used as a proxy. When you wants to use a header name with hyphens, replace them by underscores in the variable. + +Headers can be useful in some cases such as avoid sending credentials when you are on the UI. Or give to the registry server other properties such as X-Forward-For header. + +I will set these two headers in this example. + +In order to set your credentials in the header, you need to know how [Authorization](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization) header works. Here we use the `Basic` authentication scheme, the credentials are constructed like this: +- The username and the password are combined with a colon (`registry:ui`). +- The resulting string is base64 encoded (`cmVnaXN0cnk6dWk=`). You can simply run `echo -n "registry:ui" | base64`. +- In your header, put this value `Basic cmVnaXN0cnk6dWk=` +- In your docker-compose, the environment will look like `NGINX_PROXY_HEADER_Authorization=Basic cmVnaXN0cnk6dWk=` + +Tip: Use [docker-compose .env file](https://docs.docker.com/compose/environment-variables/#the-env-file) for this . + + +For X-Forward-For, replace all hyphens by underscores, and the value will be a nginx variable which is `$proxy_add_x_forwarded_for`. In your docker compose you will need to duplicate the `$` character. In your docker-compose, your environment will look like `NGINX_PROXY_HEADER_X_Forwarded_For=$$proxy_add_x_forwarded_for` + +As usual, run the project with `docker-compose up -d` (for background mode) \ No newline at end of file diff --git a/examples/proxy-headers/docker-compose.yml b/examples/proxy-headers/docker-compose.yml new file mode 100644 index 00000000..853ca377 --- /dev/null +++ b/examples/proxy-headers/docker-compose.yml @@ -0,0 +1,27 @@ +version: '2.0' +services: + registry: + image: registry:2.7 + volumes: + - ./registry-data:/var/lib/registry + - ./registry-config/credentials.yml:/etc/docker/registry/config.yml + - ./registry-config/htpasswd:/etc/docker/registry/htpasswd + networks: + - registry-ui-net + + ui: + image: joxit/docker-registry-ui:static + ports: + - 80:80 + environment: + - REGISTRY_TITLE=My Private Docker Registry + - REGISTRY_URL=http://registry:5000 + - NGINX_PROXY_HEADER_Authorization=Basic cmVnaXN0cnk6dWk= + - NGINX_PROXY_HEADER_X_Forwarded_For=$$proxy_add_x_forwarded_for + depends_on: + - registry + networks: + - registry-ui-net + +networks: + registry-ui-net: diff --git a/examples/proxy-headers/registry-config/credentials.yml b/examples/proxy-headers/registry-config/credentials.yml new file mode 100644 index 00000000..31dd619a --- /dev/null +++ b/examples/proxy-headers/registry-config/credentials.yml @@ -0,0 +1,25 @@ +version: 0.1 +log: + fields: + service: registry +storage: + delete: + enabled: true + cache: + blobdescriptor: inmemory + filesystem: + rootdirectory: /var/lib/registry +http: + addr: :5000 + headers: + X-Content-Type-Options: [nosniff] + Access-Control-Allow-Origin: ['http://localhost'] + Access-Control-Allow-Methods: ['HEAD', 'GET', 'OPTIONS', 'DELETE'] + Access-Control-Allow-Headers: ['Authorization'] + Access-Control-Max-Age: [1728000] + Access-Control-Allow-Credentials: [true] + Access-Control-Expose-Headers: ['Docker-Content-Digest'] +auth: + htpasswd: + realm: basic-realm + path: /etc/docker/registry/htpasswd \ No newline at end of file diff --git a/examples/proxy-headers/registry-config/htpasswd b/examples/proxy-headers/registry-config/htpasswd new file mode 100644 index 00000000..b5767d72 --- /dev/null +++ b/examples/proxy-headers/registry-config/htpasswd @@ -0,0 +1 @@ +registry:$2y$11$1bmuJLK8HrQl5ACS/WeqRuJLUArUZfUcP2R23asmozEpfN76.pCHy \ No newline at end of file diff --git a/nginx/default.conf b/nginx/default.conf index 05108687..5d8ec01d 100644 --- a/nginx/default.conf +++ b/nginx/default.conf @@ -25,6 +25,7 @@ server { #! return 404; #! } #! proxy_set_header Host $http_host; +#! ${NGINX_PROXY_HEADERS} #! proxy_pass ${REGISTRY_URL}; #! } diff --git a/package.json b/package.json index 6ddec5dd..39ef3fc2 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "dependencies": {}, "devDependencies": { "del": "^3.0.0", - "gulp": "^4.0.1", + "gulp": "^4.0.2", "gulp-clean-css": "^4.2.0", "gulp-concat": "^2.6.0", "gulp-filter": "^5.1.0", From 4fee7b44d3ae26b1292a86135937b9c1d82cd069 Mon Sep 17 00:00:00 2001 From: Joxit Date: Tue, 2 Jul 2019 23:04:32 +0200 Subject: [PATCH 2/2] feat: Supports custom headers via file `/etc/nginx/.env` Remove the print of headers for security --- bin/entrypoint | 10 ++++++++-- examples/proxy-headers/README.md | 9 +++------ examples/proxy-headers/docker-compose.yml | 3 ++- examples/proxy-headers/nginx.env | 1 + 4 files changed, 14 insertions(+), 9 deletions(-) create mode 100644 examples/proxy-headers/nginx.env diff --git a/bin/entrypoint b/bin/entrypoint index ea8a7b54..279f90b9 100755 --- a/bin/entrypoint +++ b/bin/entrypoint @@ -9,11 +9,17 @@ if [ -z "${DELETE_IMAGES}" ] || [ "${DELETE_IMAGES}" = false ] ; then fi get_nginx_proxy_headers() { - env | while read e; do + ( + env && + if [ -f "/etc/nginx/.env" ]; then + cat /etc/nginx/.env + # Force new line + echo "" + fi + ) | while read e; do if [ -n "$(echo $e | grep -o '^NGINX_PROXY_HEADER_')" ]; then key=$(echo ${e%%=*} | sed 's/^NGINX_PROXY_HEADER_//' | sed 's/_/-/g') value=${e#*=} - echo "Add proxy header $key: $value" >&2 echo -n "proxy_set_header ${key} \"${value}\"; " fi done diff --git a/examples/proxy-headers/README.md b/examples/proxy-headers/README.md index 0d54874d..93d509f3 100644 --- a/examples/proxy-headers/README.md +++ b/examples/proxy-headers/README.md @@ -2,20 +2,17 @@ The interface and the docker registry will be accessible with . -This example highlight the usage of custom headers when the UI is used as a proxy. When you wants to use a header name with hyphens, replace them by underscores in the variable. +This example highlight the usage of custom headers when the UI is used as a proxy. When you wants to use a header name with hyphens, replace them by underscores in the variable. You can put headers in environment variable or in config file `/etc/nginx/.env`. They have the same writing style. Headers can be useful in some cases such as avoid sending credentials when you are on the UI. Or give to the registry server other properties such as X-Forward-For header. -I will set these two headers in this example. +I will set these two headers in this example. X-Forward-For by environment variable and Authorization by file. In order to set your credentials in the header, you need to know how [Authorization](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization) header works. Here we use the `Basic` authentication scheme, the credentials are constructed like this: - The username and the password are combined with a colon (`registry:ui`). - The resulting string is base64 encoded (`cmVnaXN0cnk6dWk=`). You can simply run `echo -n "registry:ui" | base64`. - In your header, put this value `Basic cmVnaXN0cnk6dWk=` -- In your docker-compose, the environment will look like `NGINX_PROXY_HEADER_Authorization=Basic cmVnaXN0cnk6dWk=` - -Tip: Use [docker-compose .env file](https://docs.docker.com/compose/environment-variables/#the-env-file) for this . - +- In your `/etc/nginx/.env`, the file will contains `NGINX_PROXY_HEADER_Authorization=Basic cmVnaXN0cnk6dWk=` For X-Forward-For, replace all hyphens by underscores, and the value will be a nginx variable which is `$proxy_add_x_forwarded_for`. In your docker compose you will need to duplicate the `$` character. In your docker-compose, your environment will look like `NGINX_PROXY_HEADER_X_Forwarded_For=$$proxy_add_x_forwarded_for` diff --git a/examples/proxy-headers/docker-compose.yml b/examples/proxy-headers/docker-compose.yml index 853ca377..190edeea 100644 --- a/examples/proxy-headers/docker-compose.yml +++ b/examples/proxy-headers/docker-compose.yml @@ -16,8 +16,9 @@ services: environment: - REGISTRY_TITLE=My Private Docker Registry - REGISTRY_URL=http://registry:5000 - - NGINX_PROXY_HEADER_Authorization=Basic cmVnaXN0cnk6dWk= - NGINX_PROXY_HEADER_X_Forwarded_For=$$proxy_add_x_forwarded_for + volumes: + - ./nginx.env:/etc/nginx/.env depends_on: - registry networks: diff --git a/examples/proxy-headers/nginx.env b/examples/proxy-headers/nginx.env new file mode 100644 index 00000000..f308be48 --- /dev/null +++ b/examples/proxy-headers/nginx.env @@ -0,0 +1 @@ +NGINX_PROXY_HEADER_Authorization=Basic cmVnaXN0cnk6dWk= \ No newline at end of file