From 5a4898367b5b9582907ac3e446452f45d9cca98b Mon Sep 17 00:00:00 2001 From: ab77 Date: Tue, 29 Mar 2022 09:08:29 -0700 Subject: [PATCH] (WIP) socialization with vanilla dockerd Change-type: minor --- .gitignore | 1 + docker-compose.yml | 95 ++++--- src/alpine/Dockerfile | 3 + src/balena-tests | 2 +- src/cert-manager/Dockerfile | 2 +- .../{Dockerfile.template => Dockerfile} | 0 src/haproxy-sidecar/balena.sh | 34 ++- src/haproxy/haproxy.cfg | 262 +++++++++--------- .../{Dockerfile.template => Dockerfile} | 0 src/tag-sidecar/balena.sh | 36 +-- 10 files changed, 240 insertions(+), 195 deletions(-) create mode 100644 src/alpine/Dockerfile rename src/haproxy-sidecar/{Dockerfile.template => Dockerfile} (100%) rename src/tag-sidecar/{Dockerfile.template => Dockerfile} (100%) diff --git a/.gitignore b/.gitignore index 7436ed1..4b35d2b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .DS_Store .balena +.env diff --git a/docker-compose.yml b/docker-compose.yml index 7081a78..6bb093b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -20,16 +20,17 @@ x-default-healthcheck: &default-healthcheck # (TBC) source from somewhere x-default-environment: &default-environment - COMMON_REGION: us-east-1 - COUNTRY: US - DNS_TLD: balena.local - LOCALITY_NAME: Seattle - MDNS_TLD: balena.local - ORG_UNIT: openBalena - ORG: balena - PRODUCTION_MODE: 'false' - STATE: Washington - SUPERUSER_EMAIL: admin@balena.local + COMMON_REGION: ${COMMON_REGION:-us-east-1} + COUNTRY: ${COUNTRY:-US} + DNS_TLD: ${DNS_TLD:-openbalena.local} + LOCALITY_NAME: ${LOCALITY_NAME:-Seattle} + MDNS_TLD: ${MDNS_TLD:-$DNS_TLD} + ORG_UNIT: ${ORG_UNIT:-openBalena} + ORG: ${ORG:-balena} + PRODUCTION_MODE: ${PRODUCTION_MODE:-false} + STATE: ${STATE:-Washington} + SUPERUSER_EMAIL: ${SUPERUSER_EMAIL:-admin@$DNS_TLD} + VERBOSE: ${VERBOSE:-true} x-default-healthcheck-trait: &with-default-healthcheck healthcheck: @@ -63,8 +64,16 @@ x-network-privileges-trait: &with-network-privileges x-base-service-definition: &base-service restart: unless-stopped + extends: + service: base services: + # https://docs.docker.com/compose/extends/#extending-services + base: + build: src/alpine + env_file: + - .env + # https://github.com/balena-io/open-balena-api api: <<: [ @@ -73,7 +82,7 @@ services: *with-default-privileges, *base-service, ] - image: balena/open-balena-api:build-ab77-open-balena + image: balena/open-balena-api:v0.204.1 depends_on: - db - redis @@ -100,6 +109,7 @@ services: OAUTH_CALLBACK_PROTOCOL: https PORT: 80 REDIS_HOST: redis:6379 + REDIS_IS_CLUSTER: 'false' SENTRY_CONFIG: ',' TOKEN_AUTH_JWT_ALGO: ES256 TOKENS_CONFIG: API_SERVICE_API_KEY:hex,AUTH_RESINOS_REGISTRY_CODE:hex,COOKIE_SESSION_SECRET:hex,JSON_WEB_TOKEN_SECRET:hex,MIXPANEL_TOKEN:hex,SUPERUSER_PASSWORD:hex,TOKEN_AUTH_BUILDER_TOKEN:hex,VPN_GUEST_API_KEY:hex,VPN_SERVICE_API_KEY:hex,API_VPN_SERVICE_API_KEY:API_SERVICE_API_KEY,REGISTRY2_TOKEN:TOKEN_AUTH_BUILDER_TOKEN @@ -112,10 +122,13 @@ services: *with-default-privileges, *base-service, ] - image: balena/open-balena-registry:build-ab77-open-balena + image: balena/open-balena-registry:v2.24.4 volumes: - certs-data:/certs - resin-data:/balena + depends_on: + - redis + - s3 environment: <<: *default-environment HOSTS_CONFIG: REGISTRY2_HOST:registry,REGISTRY2_TOKEN_AUTH_ISSUER:api,REGISTRY2_TOKEN_AUTH_REALM:api @@ -136,12 +149,12 @@ services: *with-default-privileges, *base-service, ] - image: balena/open-balena-vpn:v11.2.0 + image: balena/open-balena-vpn:v11.2.5 depends_on: - api environment: <<: *default-environment - HOSTS_CONFIG: VPN_HOST:vpn + HOSTS_CONFIG: VPN_HOST:cloudlink SENTRY_CONFIG: ',' TOKENS_CONFIG: ',' VPN_HAPROXY_USEPROXYPROTOCOL: 'true' @@ -168,7 +181,7 @@ services: *with-default-privileges, *base-service, ] - image: balena/open-balena-s3:build-ab77-open-balena + image: balena/open-balena-s3:v2.13.5 volumes: - s3-data:/export - certs-data:/certs @@ -206,18 +219,17 @@ services: net.ipv4.ip_unprivileged_port_start: 0 healthcheck: <<: *default-healthcheck - # (TBC) always succeeds - test: true | openssl s_client -connect localhost:443 -servername ${DNS_TLD} + test: true | openssl s_client -connect localhost:443 ports: # haproxy/http - - 80 + - "80:80/tcp" # haproxy/tcp-router - - 443 + - "443:443/tcp" # haproxy/stats - - 1936 + - "1936:1936/tcp" # postgresql/redis - - 5432 - - 6379 + - "5432:5432/tcp" + - "6379:6379/tcp" environment: <<: *default-environment LOGLEVEL: info @@ -227,8 +239,13 @@ services: haproxy-sidecar: <<: *base-service build: src/haproxy-sidecar + volumes: + # FIXME: different on balenaOS + - /var/run/docker.sock:/var/run/docker.sock environment: <<: *default-environment + # FIXME: different on balenaOS + DOCKER_HOST: unix:///var/run/docker.sock # resolved internally as {{service}}.{{dns-tld-without-balena-device-uuid}} to haproxy service ALIASES: api,db,delta,redis,registry,s3,stats,tunnel,vpn labels: @@ -238,22 +255,26 @@ services: # https://github.com/balena-io/balena-mdns-publisher mdns: <<: [ - *with-default-volumes, *with-default-healthcheck, *with-default-privileges, *base-service, ] - image: balena/balena-mdns-publisher:build-ab77-open-balena + image: balena/balena-mdns-publisher:v1.15.0 network_mode: host - labels: - io.balena.features.dbus: 1 + volumes: + - certs-data:/certs + - resin-data:/balena + - /var/run/dbus/system_bus_socket:/host/run/dbus/system_bus_socket environment: <<: *default-environment + DBUS_SESSION_BUS_ADDRESS: unix:path=/host/run/dbus/system_bus_socket HOSTS_CONFIG: ',' # externally advertised mDNS names as {{service}}.{{mdns-tld}} MDNS_SUBDOMAINS: api,ca,db,delta,minio,ocsp,redis,registry,s3,stats,tunnel,vpn SENTRY_CONFIG: ',' TOKENS_CONFIG: ',' + labels: + io.balena.features.dbus: 1 # https://github.com/balena-io/cert-manager # https://certbot.eff.org/docs/using.html @@ -280,7 +301,7 @@ services: # https://github.com/cloudflare/cfssl/blob/master/doc/api/intro.txt balena-ca: <<: *base-service - image: balena/ca-private:v0.0.5 + image: balena/ca-private:v0.0.6 volumes: - pki-data:/pki - certs-data:/certs @@ -300,21 +321,22 @@ services: # only relevant when running in AWS/EC2 tag-sidecar: build: src/tag-sidecar - restart: no + restart: 'no' environment: <<: *default-environment ENABLED: 'true' labels: io.balena.features.balena-api: 1 - # (WIP) https://github.com/balena-io-playground/balena-nested + # (WIP) https://github.com/balena-io-playground/balena-nested => balenaVirt balena-tests: <<: [ - *with-default-volumes, *with-default-privileges, *base-service, ] - build: src/balena-tests + build: + context: src/balena-tests + dockerfile: Dockerfile.amd64 command: /usr/sbin/balena.sh depends_on: - api @@ -328,28 +350,30 @@ services: - certs-data:/certs - resin-data:/balena - builder-certs-client:/docker-pki/client + - /lib/modules:/lib/modules healthcheck: test: /usr/sbin/docker-hc interval: 60s timeout: 60s retries: 5 devices: - # (TBC) not supported on AWS/EC2 unless using .metal instance classes|types - # only supported on AMIs built on AWS Nitro System + # Nested virtualisation support required on the host + # - not supported on AWS/EC2 unless using .metal instance classes|types + # - only supported on AMIs built on AWS Nitro System + # - otherwise run 'mknod /dev/kvm b 1 1' to create a dummy kvm device and endure - /dev/kvm:/dev/kvm - /dev/net/tun:/dev/net/tun labels: io.balena.features.balena-api: 1 io.balena.features.kernel-modules: 1 io.balena.features.supervisor-api: 1 - io.balena.features.sysfs: 1 # https://hub.docker.com/_/docker + # pseudo(builder) service docker: <<: [ *with-extended-privileges, *with-network-privileges, - *with-default-volumes, *with-default-privileges, *base-service, ] @@ -358,6 +382,7 @@ services: - builder-data:/var/lib/docker - builder-certs-ca:/docker-pki/ca - builder-certs-client:/docker-pki/client + - /sys:/sys environment: DOCKER_TLS_CERTDIR: /docker-pki healthcheck: diff --git a/src/alpine/Dockerfile b/src/alpine/Dockerfile new file mode 100644 index 0000000..e6a7521 --- /dev/null +++ b/src/alpine/Dockerfile @@ -0,0 +1,3 @@ +FROM alpine + +CMD sleep infinity diff --git a/src/balena-tests b/src/balena-tests index ca356fd..cf30f40 160000 --- a/src/balena-tests +++ b/src/balena-tests @@ -1 +1 @@ -Subproject commit ca356fd97235243e0a4323c83663c0e651ba1c60 +Subproject commit cf30f4061d7cd2a041c83b85db03a998c847f7a1 diff --git a/src/cert-manager/Dockerfile b/src/cert-manager/Dockerfile index 02dc5c4..92ce18a 100644 --- a/src/cert-manager/Dockerfile +++ b/src/cert-manager/Dockerfile @@ -1,3 +1,3 @@ -FROM balena/cert-manager:v0.0.14 +FROM balena/cert-manager:v0.0.15 COPY *.json /opt/ diff --git a/src/haproxy-sidecar/Dockerfile.template b/src/haproxy-sidecar/Dockerfile similarity index 100% rename from src/haproxy-sidecar/Dockerfile.template rename to src/haproxy-sidecar/Dockerfile diff --git a/src/haproxy-sidecar/balena.sh b/src/haproxy-sidecar/balena.sh index dae012c..ef41b5a 100755 --- a/src/haproxy-sidecar/balena.sh +++ b/src/haproxy-sidecar/balena.sh @@ -7,7 +7,13 @@ set -ea which curl || apk add curl --no-cache which jq || apk add jq --no-cache -network="${BALENA_APP_ID}_default" +if docker inspect "${BALENA_APP_UUID}_default" --format "{{.ID}}"; then + network="${BALENA_APP_UUID}_default" +elif docker inspect "${BALENA_APP_ID}_default" --format "{{.ID}}"; then + network="${BALENA_APP_ID}_default" +else + network=open-balena_default +fi # shellcheck disable=SC2153 for alias in ${ALIASES//,/ }; do @@ -16,28 +22,32 @@ for alias in ${ALIASES//,/ }; do done while true; do - while [ "$(curl --silent --retry 3 --fail \ - "${BALENA_SUPERVISOR_ADDRESS}/v1/device?apikey=${BALENA_SUPERVISOR_API_KEY}" \ - -H "Content-Type:application/json" | jq -r '.update_pending')" = 'true' ]; do - sleep "$(( (RANDOM % 3) + 3 ))s" - done - sleep "$(( (RANDOM % 5) + 5 ))s" + if [[ -n $BALENA_SUPERVISOR_ADDRESS ]] && [[ -n $BALENA_SUPERVISOR_API_KEY ]]; then + while [[ "$(curl --silent --retry 3 --fail \ + "${BALENA_SUPERVISOR_ADDRESS}/v1/device?apikey=${BALENA_SUPERVISOR_API_KEY}" \ + -H "Content-Type:application/json" | jq -r '.update_pending')" =~ true ]]; do + sleep "$(( (RANDOM % 3) + 3 ))s" + done + sleep "$(( (RANDOM % 5) + 5 ))s" + fi - while [ "$(docker ps \ - --filter "name=haproxy_" \ + while [[ "$(docker ps \ + --filter "name=haproxy" \ + --filter "expose=1936/tcp" \ --filter "status=running" \ --filter "network=${network}" \ - --format "{{.ID}}")" = '' ]; do + --format "{{.ID}}")" == '' ]]; do sleep "$(( (RANDOM % 3) + 3 ))s" done haproxy="$(docker ps \ - --filter "name=haproxy_" \ + --filter "name=haproxy" \ + --filter "expose=1936/tcp" \ --filter "status=running" \ --filter "network=${network}" \ --format "{{.ID}}")" - if ! [ "${restarted}" = "${haproxy}" ]; then + if ! [[ $restarted == "${haproxy}" ]]; then docker network disconnect "${network}" "${haproxy}" # shellcheck disable=SC2086 diff --git a/src/haproxy/haproxy.cfg b/src/haproxy/haproxy.cfg index a715958..b7b33a6 100644 --- a/src/haproxy/haproxy.cfg +++ b/src/haproxy/haproxy.cfg @@ -1,190 +1,194 @@ global - tune.ssl.default-dh-param 1024 - # https://github.com/haproxytech/haproxy-lua-cors - lua-load /usr/local/etc/haproxy/cors.lua - # https://www.haproxy.com/blog/introduction-to-haproxy-logging/ - log stdout format raw daemon "${LOGLEVEL}" - log stderr format raw daemon "${LOGLEVEL}" + tune.ssl.default-dh-param 1024 + # https://github.com/haproxytech/haproxy-lua-cors + lua-load /usr/local/etc/haproxy/cors.lua + # https://www.haproxy.com/blog/introduction-to-haproxy-logging/ + log stdout format raw daemon "${LOGLEVEL}" + log stderr format raw daemon "${LOGLEVEL}" + ssl-default-bind-options ssl-min-ver TLSv1.3 defaults - default-server init-addr last,libc,none - default-server inter 3s rise 2 fall 3 - log global - mode http - option contstats - option dontlognull - option forwardfor - option httplog - timeout client 63s - timeout connect 5s - timeout http-keep-alive 1s - timeout http-request 63s - timeout server 63s - timeout tunnel 3600s + default-server init-addr last,libc,none + default-server inter 3s rise 2 fall 3 + log global + mode http + option contstats + option dontlognull + option forwardfor + option httplog + timeout client 63s + timeout connect 5s + timeout http-keep-alive 1s + timeout http-request 63s + timeout server 63s + timeout tunnel 3600s resolvers docker-bridge-resolver - nameserver docker-resolver 127.0.0.11:53 - hold valid 0ms + nameserver docker-resolver 127.0.0.11:53 + hold valid 0ms http-errors balena-http-errors - errorfile 400 /etc/haproxy/errors/400.http - errorfile 401 /etc/haproxy/errors/401.http - errorfile 403 /etc/haproxy/errors/403.http - errorfile 404 /etc/haproxy/errors/404.http - errorfile 500 /etc/haproxy/errors/500.http - errorfile 502 /etc/haproxy/errors/502.http - errorfile 503 /etc/haproxy/errors/503.http + errorfile 400 /etc/haproxy/errors/400.http + errorfile 401 /etc/haproxy/errors/401.http + errorfile 403 /etc/haproxy/errors/403.http + errorfile 404 /etc/haproxy/errors/404.http + errorfile 500 /etc/haproxy/errors/500.http + errorfile 502 /etc/haproxy/errors/502.http + errorfile 503 /etc/haproxy/errors/503.http userlist balena - user balena insecure-password "${BALENA_DEVICE_UUID}" + user balena insecure-password "${BALENA_DEVICE_UUID}" listen haproxy-stats - bind *:1936 ssl crt "${CERT_CHAIN_PATH}" - stats auth "balena:${BALENA_DEVICE_UUID}" - stats enable - stats uri /metrics + bind *:1936 ssl crt "${CERT_CHAIN_PATH}" + stats auth "balena:${BALENA_DEVICE_UUID}" + stats enable + stats uri /metrics frontend http - bind *:80 - default_backend api-backend - errorfiles balena-http-errors - http-request capture req.hdr(Host) len 15 - http-response lua.cors - # https://www.haproxy.com/blog/haproxy-log-customization/ - log-format "%ci:%cp [%tr] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Ta %ST %B %CC %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs %{+Q}r" + bind *:80 + default_backend api-backend + errorfiles balena-http-errors + http-request capture req.hdr(Host) len 15 + http-response lua.cors + # https://www.haproxy.com/blog/haproxy-log-customization/ + log-format "%ci:%cp [%tr] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Ta %ST %B %CC %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs %{+Q}r" - acl host-api-backend hdr_beg(host) -i "api." - # default public device URL(s) always go to the API - acl host-pdu-default hdr_beg(host) -i "${BALENA_DEVICE_UUID}" - http-request add-header X-Forwarded-Proto http if host-api-backend - http-request add-header X-Forwarded-Proto https if host-pdu-default - use_backend api-backend if host-api-backend || host-pdu-default + acl api_dead nbsrv(api-backend) lt 1 + acl registry_dead nbsrv(registry-backend) lt 1 + monitor-uri /ping + monitor fail if api_dead registry_dead - acl host-registry-backend hdr_beg(host) -i "registry." - http-request add-header X-Forwarded-Proto http if host-registry-backend - use_backend registry-backend if host-registry-backend + acl host-api-backend hdr_beg(host) -i "api." + # default public device URL(s) always go to the API + acl host-pdu-default hdr(host) -m reg -i "\.?([0-9a-f]{32}|${BALENA_DEVICE_UUID})\.(devices|balena-?(.*)-devices)\." + use_backend api-backend if host-api-backend || host-pdu-default - acl host-s3-backend hdr_beg(host) -i "s3." - http-request add-header X-Forwarded-Proto http if host-s3-backend - use_backend s3-backend if host-s3-backend + acl host-registry-backend hdr_beg(host) -i "registry." + http-request add-header X-Forwarded-Proto http if host-registry-backend + use_backend registry-backend if host-registry-backend - acl host-minio-backend hdr_beg(host) -i "minio." - http-request add-header X-Forwarded-Proto http if host-minio-backend - use_backend minio-backend if host-minio-backend + acl host-s3-backend hdr_beg(host) -i "s3." + http-request add-header X-Forwarded-Proto http if host-s3-backend + use_backend s3-backend if host-s3-backend + + acl host-minio-backend hdr_beg(host) -i "minio." + http-request add-header X-Forwarded-Proto http if host-minio-backend + use_backend minio-backend if host-minio-backend # routes between OpenVPN, SSL and HTTPS traffic frontend tcp-router - mode tcp - option tcplog - log-format "%ci:%cp [%t] %ft %b/%s %Tw/%Tc/%Tt %B %ts %ac/%fc/%bc/%sc/%rc %sq/%bq" - bind *:443 - tcp-request inspect-delay 2s - tcp-request content accept if { req.ssl_hello_type 1 } - acl is_ssl req.ssl_ver 2:3.4 + mode tcp + option tcplog + log-format "%ci:%cp [%t] %ft %b/%s %Tw/%Tc/%Tt %B %ts %ac/%fc/%bc/%sc/%rc %sq/%bq" + bind *:443 + tcp-request inspect-delay 2s + tcp-request content accept if { req.ssl_hello_type 1 } + acl is_ssl req.ssl_ver 2:3.4 - acl sni-host-tunnel req_ssl_sni -m beg "tunnel." - use_backend redirect-to-tunnel if sni-host-tunnel + acl sni-host-tunnel req_ssl_sni -m beg "tunnel." + use_backend redirect-to-tunnel if sni-host-tunnel - # everything else => HTTPS - use_backend redirect-to-https if is_ssl + # everything else => HTTPS + use_backend redirect-to-https if is_ssl - # or VPN - use_backend vpn-backend if !is_ssl + # or VPN + use_backend vpn-backend if !is_ssl backend redirect-to-tunnel - mode tcp - balance roundrobin - server localhost 127.0.0.1:3129 + mode tcp + balance roundrobin + server localhost 127.0.0.1:3129 # https://stackoverflow.com/a/39213442/1559300 listen tunnel-backend - mode tcp - option tcplog - log-format "%ci:%cp [%t] %ft %b/%s %Tw/%Tc/%Tt %B %ts %ac/%fc/%bc/%sc/%rc %sq/%bq" - bind 127.0.0.1:3129 ssl crt "${CERT_CHAIN_PATH}" - server tunnel vpn:3128 resolvers docker-bridge-resolver resolve-prefer ipv4 check port 3128 + mode tcp + option tcplog + log-format "%ci:%cp [%t] %ft %b/%s %Tw/%Tc/%Tt %B %ts %ac/%fc/%bc/%sc/%rc %sq/%bq" + bind 127.0.0.1:3129 ssl crt "${CERT_CHAIN_PATH}" + server tunnel vpn:3128 resolvers docker-bridge-resolver resolve-prefer ipv4 check port 3128 backend vpn-backend - mode tcp - server openvpn vpn:443 resolvers docker-bridge-resolver resolve-prefer ipv4 send-proxy-v2 check-send-proxy check port 443 + mode tcp + server openvpn vpn:443 resolvers docker-bridge-resolver resolve-prefer ipv4 send-proxy-v2 check-send-proxy check port 443 backend redirect-to-https - mode tcp - balance roundrobin - server localhost 127.0.0.1:444 send-proxy-v2 + mode tcp + balance roundrobin + server localhost 127.0.0.1:444 send-proxy-v2 frontend https - bind 127.0.0.1:444 ssl crt "${CERT_CHAIN_PATH}" accept-proxy - default_backend api-backend - errorfiles balena-http-errors - http-request add-header X-Forwarded-Proto https - http-request capture req.hdr(Host) len 15 - http-response lua.cors - log-format "%ci:%cp [%tr] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Ta %ST %B %CC %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs %{+Q}r" + bind 127.0.0.1:444 ssl crt "${CERT_CHAIN_PATH}" accept-proxy + default_backend api-backend + errorfiles balena-http-errors + http-request add-header X-Forwarded-Proto https + http-request capture req.hdr(Host) len 15 + http-response lua.cors + log-format "%ci:%cp [%tr] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Ta %ST %B %CC %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs %{+Q}r" - acl host-api-backend hdr_beg(host) -i "api." - use_backend api-backend if host-api-backend + acl host-api-backend hdr_beg(host) -i "api." + use_backend api-backend if host-api-backend - acl host-registry-backend hdr_beg(host) -i "registry." - use_backend registry-backend if host-registry-backend + acl host-registry-backend hdr_beg(host) -i "registry." + use_backend registry-backend if host-registry-backend - acl host-s3-backend hdr_beg(host) -i "s3." - use_backend s3-backend if host-s3-backend + acl host-s3-backend hdr_beg(host) -i "s3." + use_backend s3-backend if host-s3-backend - acl host-minio-backend hdr_beg(host) -i "minio." - use_backend minio-backend if host-minio-backend + acl host-minio-backend hdr_beg(host) -i "minio." + use_backend minio-backend if host-minio-backend - acl host-ca-backend hdr_beg(host) -i "ca." - # only allow CRL requests unauthenticated, protect everything else - acl balena-ca-crl path -i -m beg /api/v1/cfssl/crl - acl balena-ca-auth http_auth(balena) - http-request auth realm balena-ca if host-ca-backend !balena-ca-auth !balena-ca-crl - use_backend ca-backend if host-ca-backend + acl host-ca-backend hdr_beg(host) -i "ca." + # only allow CRL requests unauthenticated, protect everything else + acl balena-ca-crl path -i -m beg /api/v1/cfssl/crl + acl balena-ca-auth http_auth(balena) + http-request auth realm balena-ca if host-ca-backend !balena-ca-auth !balena-ca-crl + use_backend ca-backend if host-ca-backend - acl host-ocsp-backend hdr_beg(host) -i "ocsp." - use_backend ocsp-backend if host-ocsp-backend + acl host-ocsp-backend hdr_beg(host) -i "ocsp." + use_backend ocsp-backend if host-ocsp-backend frontend postgres-frontend - mode tcp - bind *:5432 - use_backend db-backend - timeout client 1h + mode tcp + bind *:5432 + use_backend db-backend + timeout client 1h frontend redis-frontend - mode tcp - bind *:6379 - use_backend redis-backend - timeout client 1h + mode tcp + bind *:6379 + use_backend redis-backend + timeout client 1h backend api-backend - balance roundrobin - server api api:80 resolvers docker-bridge-resolver resolve-prefer ipv4 check port 80 + balance roundrobin + server api api:80 resolvers docker-bridge-resolver resolve-prefer ipv4 check port 80 backend registry-backend - balance roundrobin - server registry registry:80 resolvers docker-bridge-resolver resolve-prefer ipv4 check port 80 + balance roundrobin + server registry registry:80 resolvers docker-bridge-resolver resolve-prefer ipv4 check port 80 backend s3-backend - balance roundrobin - server s3 s3:80 resolvers docker-bridge-resolver resolve-prefer ipv4 check port 80 + balance roundrobin + server s3 s3:80 resolvers docker-bridge-resolver resolve-prefer ipv4 check port 80 # https://github.com/minio/console backend minio-backend - balance roundrobin - server s3-console s3:43697 resolvers docker-bridge-resolver resolve-prefer ipv4 check port 43697 + balance roundrobin + server s3-console s3:43697 resolvers docker-bridge-resolver resolve-prefer ipv4 check port 43697 backend db-backend - mode tcp - server db db:5432 resolvers docker-bridge-resolver resolve-prefer ipv4 check port 5432 + mode tcp + server db db:5432 resolvers docker-bridge-resolver resolve-prefer ipv4 check port 5432 backend redis-backend - mode tcp - server redis redis:6379 resolvers docker-bridge-resolver resolve-prefer ipv4 check port 6379 + mode tcp + server redis redis:6379 resolvers docker-bridge-resolver resolve-prefer ipv4 check port 6379 backend ca-backend - balance roundrobin - server cfssl-ca balena-ca:8888 resolvers docker-bridge-resolver resolve-prefer ipv4 check port 8888 + balance roundrobin + server cfssl-ca balena-ca:8888 resolvers docker-bridge-resolver resolve-prefer ipv4 check port 8888 backend ocsp-backend - balance roundrobin - server cfssl-ocsp balena-ca:8889 resolvers docker-bridge-resolver resolve-prefer ipv4 check port 8889 + balance roundrobin + server cfssl-ocsp balena-ca:8889 resolvers docker-bridge-resolver resolve-prefer ipv4 check port 8889 diff --git a/src/tag-sidecar/Dockerfile.template b/src/tag-sidecar/Dockerfile similarity index 100% rename from src/tag-sidecar/Dockerfile.template rename to src/tag-sidecar/Dockerfile diff --git a/src/tag-sidecar/balena.sh b/src/tag-sidecar/balena.sh index 49a1de0..f7df3f2 100755 --- a/src/tag-sidecar/balena.sh +++ b/src/tag-sidecar/balena.sh @@ -20,23 +20,25 @@ get_aws_meta() { fi } -which curl || apk add curl --no-cache -which jq || apk add jq --no-cache +if [[ -n $BALENA_API_URL ]] && [ -n $BALENA_DEVICE_UUID ]] && [[ -n $BALENA_API_KEY ]]; then + which curl || apk add curl --no-cache + which jq || apk add jq --no-cache -device_id="$(curl_with_opts \ - "${BALENA_API_URL}/v6/device?\$filter=uuid%20eq%20'${BALENA_DEVICE_UUID}'" \ - -H "Content-Type: application/json" \ - -H "Authorization: Bearer ${BALENA_API_KEY}" | jq -r .d[].id)" + device_id="$(curl_with_opts \ + "${BALENA_API_URL}/v6/device?\$filter=uuid%20eq%20'${BALENA_DEVICE_UUID}'" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer ${BALENA_API_KEY}" | jq -r .d[].id)" -for key in $(curl_with_opts http://169.254.169.254/latest/meta-data \ - | grep -Ev 'iam|metrics|identity-credentials|network|events'); do - for kv in $(get_aws_meta "http://169.254.169.254/latest/meta-data/${key}"); do - tag_key="$(echo "${kv}" | awk -F';' '{print $1}')" - value="$(echo "${kv}" | awk -F';' '{print $2}')" + for key in $(curl_with_opts http://169.254.169.254/latest/meta-data \ + | grep -Ev 'iam|metrics|identity-credentials|network|events'); do + for kv in $(get_aws_meta "http://169.254.169.254/latest/meta-data/${key}"); do + tag_key="$(echo "${kv}" | awk -F';' '{print $1}')" + value="$(echo "${kv}" | awk -F';' '{print $2}')" - curl_with_opts "${BALENA_API_URL}/v6/device_tag" \ - -H "Content-Type: application/json" \ - -H "Authorization: Bearer ${BALENA_API_KEY}" \ - --data "{\"device\":\"${device_id}\",\"tag_key\":\"${tag_key}\",\"value\":\"${value}\"}" - done -done + curl_with_opts "${BALENA_API_URL}/v6/device_tag" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer ${BALENA_API_KEY}" \ + --data "{\"device\":\"${device_id}\",\"tag_key\":\"${tag_key}\",\"value\":\"${value}\"}" + done + done +fi