diff --git a/.github/workflows/external_trigger.yml b/.github/workflows/external_trigger.yml index 14a0405..a09c3e8 100644 --- a/.github/workflows/external_trigger.yml +++ b/.github/workflows/external_trigger.yml @@ -27,7 +27,7 @@ jobs: echo "> External trigger running off of main branch. To disable this trigger, add \`socket-proxy_main\` into the Github organizational variable \`SKIP_EXTERNAL_TRIGGER\`." >> $GITHUB_STEP_SUMMARY printf "\n## Retrieving external version\n\n" >> $GITHUB_STEP_SUMMARY EXT_RELEASE=$(curl -sL "http://dl-cdn.alpinelinux.org/alpine/v3.21/main/x86_64/APKINDEX.tar.gz" | tar -xz -C /tmp \ - && awk '/^P:'"nginx"'$/,/V:/' /tmp/APKINDEX | sed -n 2p | sed 's/^V://') + && awk '/^P:'"haproxy"'$/,/V:/' /tmp/APKINDEX | sed -n 2p | sed 's/^V://') echo "Type is \`alpine_repo\`" >> $GITHUB_STEP_SUMMARY if grep -q "^socket-proxy_main_${EXT_RELEASE}" <<< "${SKIP_EXTERNAL_TRIGGER}"; then echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY @@ -104,7 +104,7 @@ jobs: if [ "${EXT_RELEASE}" == "${IMAGE_VERSION}" ]; then echo "Version \`${EXT_RELEASE}\` already pushed, exiting" >> $GITHUB_STEP_SUMMARY exit 0 - elif [[ $(curl -sL "http://dl-cdn.alpinelinux.org/alpine/v3.21/main/aarch64/APKINDEX.tar.gz" | tar -xz -C /tmp && awk '/^P:'"nginx"'$/,/V:/' /tmp/APKINDEX | sed -n 2p | sed 's/^V://') != "${EXT_RELEASE}" ]]; then + elif [[ $(curl -sL "http://dl-cdn.alpinelinux.org/alpine/v3.21/main/aarch64/APKINDEX.tar.gz" | tar -xz -C /tmp && awk '/^P:'"haproxy"'$/,/V:/' /tmp/APKINDEX | sed -n 2p | sed 's/^V://') != "${EXT_RELEASE}" ]]; then echo "New version \`${EXT_RELEASE}\` found; but not all arch repos updated yet; exiting" >> $GITHUB_STEP_SUMMARY FAILURE_REASON="New version ${EXT_RELEASE} for socket-proxy tag latest is detected, however not all arch repos are updated yet. Will try again later." curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://cdn.discordapp.com/avatars/354986384542662657/df91181b3f1cf0ef1592fbe18e0962d7.png","embeds": [{"color": 9802903, diff --git a/Dockerfile b/Dockerfile index 8e8a19c..e3dd769 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,7 @@ FROM docker.io/alpine:3.21 # set version label ARG BUILD_DATE ARG VERSION -ARG NGINX_VERSION +ARG HAPROXY_VERSION LABEL build_version="Linuxserver.io version:- ${VERSION} Build-date:- ${BUILD_DATE}" LABEL maintainer="thespad" @@ -14,18 +14,19 @@ RUN \ echo "**** install build packages ****" && \ apk add --no-cache \ alpine-release \ - bash \ - curl \ - envsubst && \ - if [ -z ${NGINX_VERSION+x} ]; then \ - NGINX_VERSION=$(curl -sL "http://dl-cdn.alpinelinux.org/alpine/v3.21/main/x86_64/APKINDEX.tar.gz" | tar -xz -C /tmp \ - && awk '/^P:nginx$/,/V:/' /tmp/APKINDEX | sed -n 2p | sed 's/^V://'); \ + curl && \ + if [ -z ${HAPROXY_VERSION+x} ]; then \ + HAPROXY_VERSION=$(curl -sL "http://dl-cdn.alpinelinux.org/alpine/v3.21/main/x86_64/APKINDEX.tar.gz" | tar -xz -C /tmp \ + && awk '/^P:haproxy$/,/V:/' /tmp/APKINDEX | sed -n 2p | sed 's/^V://'); \ fi && \ apk add --no-cache \ - nginx==${NGINX_VERSION} && \ + haproxy==${HAPROXY_VERSION} && \ printf "Linuxserver.io version: ${VERSION}\nBuild-date: ${BUILD_DATE}" > /build_version && \ - rm -f /etc/nginx/conf.d/stream.conf && \ - rm -f /etc/nginx/http.d/default.conf + apk del --no-cache \ + curl && \ + rm -rf \ + /etc/haproxy \ + /tmp/* ENV ALLOW_RESTARTS=0 \ ALLOW_STOP=0 \ @@ -58,6 +59,4 @@ ENV ALLOW_RESTARTS=0 \ # add local files COPY root/ / -EXPOSE 2375 - ENTRYPOINT ["/docker-entrypoint.sh"] diff --git a/Dockerfile.aarch64 b/Dockerfile.aarch64 index 8e8a19c..e3dd769 100644 --- a/Dockerfile.aarch64 +++ b/Dockerfile.aarch64 @@ -5,7 +5,7 @@ FROM docker.io/alpine:3.21 # set version label ARG BUILD_DATE ARG VERSION -ARG NGINX_VERSION +ARG HAPROXY_VERSION LABEL build_version="Linuxserver.io version:- ${VERSION} Build-date:- ${BUILD_DATE}" LABEL maintainer="thespad" @@ -14,18 +14,19 @@ RUN \ echo "**** install build packages ****" && \ apk add --no-cache \ alpine-release \ - bash \ - curl \ - envsubst && \ - if [ -z ${NGINX_VERSION+x} ]; then \ - NGINX_VERSION=$(curl -sL "http://dl-cdn.alpinelinux.org/alpine/v3.21/main/x86_64/APKINDEX.tar.gz" | tar -xz -C /tmp \ - && awk '/^P:nginx$/,/V:/' /tmp/APKINDEX | sed -n 2p | sed 's/^V://'); \ + curl && \ + if [ -z ${HAPROXY_VERSION+x} ]; then \ + HAPROXY_VERSION=$(curl -sL "http://dl-cdn.alpinelinux.org/alpine/v3.21/main/x86_64/APKINDEX.tar.gz" | tar -xz -C /tmp \ + && awk '/^P:haproxy$/,/V:/' /tmp/APKINDEX | sed -n 2p | sed 's/^V://'); \ fi && \ apk add --no-cache \ - nginx==${NGINX_VERSION} && \ + haproxy==${HAPROXY_VERSION} && \ printf "Linuxserver.io version: ${VERSION}\nBuild-date: ${BUILD_DATE}" > /build_version && \ - rm -f /etc/nginx/conf.d/stream.conf && \ - rm -f /etc/nginx/http.d/default.conf + apk del --no-cache \ + curl && \ + rm -rf \ + /etc/haproxy \ + /tmp/* ENV ALLOW_RESTARTS=0 \ ALLOW_STOP=0 \ @@ -58,6 +59,4 @@ ENV ALLOW_RESTARTS=0 \ # add local files COPY root/ / -EXPOSE 2375 - ENTRYPOINT ["/docker-entrypoint.sh"] diff --git a/Jenkinsfile b/Jenkinsfile index a980cc9..664aa07 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -19,7 +19,7 @@ pipeline { DOCKERHUB_TOKEN=credentials('docker-hub-ci-pat') QUAYIO_API_TOKEN=credentials('quayio-repo-api-token') GIT_SIGNING_KEY=credentials('484fbca6-9a4f-455e-b9e3-97ac98785f5f') - BUILD_VERSION_ARG = 'NGINX_VERSION' + BUILD_VERSION_ARG = 'HAPROXY_VERSION' LS_USER = 'linuxserver' LS_REPO = 'docker-socket-proxy' CONTAINER_NAME = 'socket-proxy' @@ -28,7 +28,7 @@ pipeline { PR_DOCKERHUB_IMAGE = 'lspipepr/socket-proxy' DIST_IMAGE = 'alpine' DIST_REPO = 'http://dl-cdn.alpinelinux.org/alpine/v3.21/main/' - DIST_REPO_PACKAGES = 'nginx' + DIST_REPO_PACKAGES = 'haproxy' MULTIARCH='true' CI='true' CI_WEB='false' diff --git a/README.md b/README.md index b4419fe..53e5b5c 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ The architectures supported by this image are: ## Application Setup -This container is based on [https://github.com/Tecnativa/docker-socket-proxy](https://github.com/Tecnativa/docker-socket-proxy) and as such does not follow our usual container conventions. It *does not* support mods or custom scripts/services, or running as a user other than root (or the docker user in a rootless environment). It is designed to act as a drop-in replacement for the Tecnativa container. +This container is conceptually based on [https://github.com/Tecnativa/docker-socket-proxy](https://github.com/Tecnativa/docker-socket-proxy) and as such does not follow our usual container conventions. It *does not* support mods or custom scripts/services, or running as a user other than root (or the docker user in a rootless environment). It is designed to act as a drop-in replacement for the Tecnativa container. The container should be run on the same docker network as the service(s) using it. Most containers that would normally connect to a mounted docker.sock can have their endpoint overridden using the `DOCKER_HOST` environment variable if they do not offer the option in their configuration; it should typically be pointed to `tcp://socket-proxy:2375`. @@ -100,7 +100,6 @@ services: - PING=1 #optional - PLUGINS=0 #optional - POST=0 #optional - - PROXY_READ_TIMEOUT=240 #optional - SECRETS=0 #optional - SERVICES=0 #optional - SESSION=0 #optional @@ -141,7 +140,6 @@ docker run -d \ -e PING=1 `#optional` \ -e PLUGINS=0 `#optional` \ -e POST=0 `#optional` \ - -e PROXY_READ_TIMEOUT=240 `#optional` \ -e SECRETS=0 `#optional` \ -e SERVICES=0 `#optional` \ -e SESSION=0 `#optional` \ @@ -172,7 +170,7 @@ Containers are configured using parameters passed at runtime (such as those abov | `-e CONFIGS=0` | `/configs` | | `-e CONTAINERS=0` | `/containers` | | `-e DISTRIBUTION=0` | `/distribution` | -| `-e DISABLE_IPV6=0` | Set to `1` to prevent nginx binding to the IPv6 interface for legacy system that cannot support IPv6. | +| `-e DISABLE_IPV6=0` | Set to `1` to prevent binding to the IPv6 interface for legacy system that cannot support IPv6. | | `-e EVENTS=1` | `/events` | | `-e EXEC=0` | `/exec` & `/containers/{id}/exec` | | `-e IMAGES=0` | `/images` | @@ -182,7 +180,6 @@ Containers are configured using parameters passed at runtime (such as those abov | `-e PING=1` | `/_ping` | | `-e PLUGINS=0` | `/plugins` | | `-e POST=0` | When set to `0`, only `GET` and `HEAD` operations are allowed, making API access read-only. | -| `-e PROXY_READ_TIMEOUT=240` | Connection timeout when no data is being sent. Useful for tailing quiet containers. Accepts values in s/m/h/d/w, no suffix assumes s. | | `-e SECRETS=0` | `/secrets` | | `-e SERVICES=0` | `/services` | | `-e SESSION=0` | `/session` | @@ -315,6 +312,7 @@ Once registered you can define the dockerfile to use with `-f Dockerfile.aarch64 ## Versions +* **06.04.25:** - Switch back to haproxy for better handling of `docker exec` connection hijacking. * **02.01.25:** - Support custom read timeout values. * **05.12.24:** - Rebase to Alpine 3.21. * **26.08.24:** - Change `ALLOW_START`, `ALLOW_STOP`, and `ALLOW_RESTARTS` to work even with `POST=0`. diff --git a/jenkins-vars.yml b/jenkins-vars.yml index 994a3cd..08b82ad 100644 --- a/jenkins-vars.yml +++ b/jenkins-vars.yml @@ -9,7 +9,7 @@ ls_branch: main image_sbom: true image_provenance: true repo_vars: - - BUILD_VERSION_ARG = 'NGINX_VERSION' + - BUILD_VERSION_ARG = 'HAPROXY_VERSION' - LS_USER = 'linuxserver' - LS_REPO = 'docker-socket-proxy' - CONTAINER_NAME = 'socket-proxy' @@ -18,7 +18,7 @@ repo_vars: - PR_DOCKERHUB_IMAGE = 'lspipepr/socket-proxy' - DIST_IMAGE = 'alpine' - DIST_REPO = 'http://dl-cdn.alpinelinux.org/alpine/v3.21/main/' - - DIST_REPO_PACKAGES = 'nginx' + - DIST_REPO_PACKAGES = 'haproxy' - MULTIARCH='true' - CI='true' - CI_WEB='false' diff --git a/readme-vars.yml b/readme-vars.yml index d01f5ca..834fc2d 100644 --- a/readme-vars.yml +++ b/readme-vars.yml @@ -59,7 +59,7 @@ full_custom_readme: | ## Application Setup - This container is based on [https://github.com/Tecnativa/docker-socket-proxy](https://github.com/Tecnativa/docker-socket-proxy) and as such does not follow our usual container conventions. It *does not* support mods or custom scripts/services, or running as a user other than root (or the docker user in a rootless environment). It is designed to act as a drop-in replacement for the Tecnativa container. + This container is conceptually based on [https://github.com/Tecnativa/docker-socket-proxy](https://github.com/Tecnativa/docker-socket-proxy) and as such does not follow our usual container conventions. It *does not* support mods or custom scripts/services, or running as a user other than root (or the docker user in a rootless environment). It is designed to act as a drop-in replacement for the Tecnativa container. The container should be run on the same docker network as the service(s) using it. Most containers that would normally connect to a mounted docker.sock can have their endpoint overridden using the `DOCKER_HOST` environment variable if they do not offer the option in their configuration; it should typically be pointed to `tcp://socket-proxy:2375`. @@ -107,7 +107,6 @@ full_custom_readme: | - PING=1 #optional - PLUGINS=0 #optional - POST=0 #optional - - PROXY_READ_TIMEOUT=240 #optional - SECRETS=0 #optional - SERVICES=0 #optional - SESSION=0 #optional @@ -148,7 +147,6 @@ full_custom_readme: | -e PING=1 `#optional` \ -e PLUGINS=0 `#optional` \ -e POST=0 `#optional` \ - -e PROXY_READ_TIMEOUT=240 `#optional` \ -e SECRETS=0 `#optional` \ -e SERVICES=0 `#optional` \ -e SESSION=0 `#optional` \ @@ -179,7 +177,7 @@ full_custom_readme: | | `-e CONFIGS=0` | `/configs` | | `-e CONTAINERS=0` | `/containers` | | `-e DISTRIBUTION=0` | `/distribution` | - | `-e DISABLE_IPV6=0` | Set to `1` to prevent nginx binding to the IPv6 interface for legacy system that cannot support IPv6. | + | `-e DISABLE_IPV6=0` | Set to `1` to prevent binding to the IPv6 interface for legacy system that cannot support IPv6. | | `-e EVENTS=1` | `/events` | | `-e EXEC=0` | `/exec` & `/containers/{id}/exec` | | `-e IMAGES=0` | `/images` | @@ -189,7 +187,6 @@ full_custom_readme: | | `-e PING=1` | `/_ping` | | `-e PLUGINS=0` | `/plugins` | | `-e POST=0` | When set to `0`, only `GET` and `HEAD` operations are allowed, making API access read-only. | - | `-e PROXY_READ_TIMEOUT=240` | Connection timeout when no data is being sent. Useful for tailing quiet containers. Accepts values in s/m/h/d/w, no suffix assumes s. | | `-e SECRETS=0` | `/secrets` | | `-e SERVICES=0` | `/services` | | `-e SESSION=0` | `/session` | @@ -322,6 +319,7 @@ full_custom_readme: | ## Versions + * **06.04.25:** - Switch back to haproxy for better handling of `docker exec` connection hijacking. * **02.01.25:** - Support custom read timeout values. * **05.12.24:** - Rebase to Alpine 3.21. * **26.08.24:** - Change `ALLOW_START`, `ALLOW_STOP`, and `ALLOW_RESTARTS` to work even with `POST=0`. diff --git a/root/docker-entrypoint.sh b/root/docker-entrypoint.sh index d59f9ac..dceaa14 100755 --- a/root/docker-entrypoint.sh +++ b/root/docker-entrypoint.sh @@ -1,18 +1,14 @@ -#!/bin/bash +#!/bin/sh -export PROXY_READ_TIMEOUT=${PROXY_READ_TIMEOUT:-240} +mkdir -p /run/haproxy -if [[ $POST == 1 ]] && [[ $DISABLE_IPV6 == 1 ]]; then - envsubst "$(printf '${%s} ' $(bash -c "compgen -A variable"))" < /templates/default_post_ipv4.template > /run/default.conf -elif [[ $POST == 0 ]] && [[ $DISABLE_IPV6 == 1 ]]; then - envsubst "$(printf '${%s} ' $(bash -c "compgen -A variable"))" < /templates/default_nopost_ipv4.template > /run/default.conf -elif [[ $POST == 1 ]]; then - envsubst "$(printf '${%s} ' $(bash -c "compgen -A variable"))" < /templates/default_post.template > /run/default.conf +if [ "${DISABLE_IPV6}" = 1 ]; then + BIND_PROTO=":2375" else - envsubst "$(printf '${%s} ' $(bash -c "compgen -A variable"))" < /templates/default_nopost.template > /run/default.conf + BIND_PROTO="[::]:2375 v4v6" fi -mkdir /run/nginx-tmp +sed "s/@@BIND_PROTO@@/${BIND_PROTO}/g" /templates/haproxy.cfg > /run/haproxy/haproxy.cfg echo ' ─────────────────────────────────────── @@ -32,7 +28,7 @@ To support LSIO projects visit: https://www.linuxserver.io/donate/ ───────────────────────────────────────' -if [[ -f /build_version ]]; then +if [ -f /build_version ]; then cat /build_version echo ' ─────────────────────────────────────── @@ -41,4 +37,4 @@ fi echo "[ls.io-init] done." -exec /usr/sbin/nginx -e stderr +exec /usr/sbin/haproxy -f /run/haproxy/haproxy.cfg -W -db diff --git a/root/etc/nginx/nginx.conf b/root/etc/nginx/nginx.conf deleted file mode 100644 index 70fa50a..0000000 --- a/root/etc/nginx/nginx.conf +++ /dev/null @@ -1,76 +0,0 @@ -### Based on alpine defaults -# https://git.alpinelinux.org/aports/tree/main/nginx/nginx.conf?h=3.19-stable - -user root; - -# Enables the use of JIT for regular expressions to speed-up their processing. -pcre_jit on; - -# Configures default error logger. -error_log stderr; - -# Includes files with directives to load dynamic modules. -include /etc/nginx/modules/*.conf; - -# Include files with config snippets into the root context. -include /etc/nginx/conf.d/*.conf; - -events { - # The maximum number of simultaneous connections that can be opened by - # a worker process. - worker_connections 1024; -} - -http { - # Includes mapping of file name extensions to MIME types of responses - # and defines the default type. - include /etc/nginx/mime.types; - default_type application/octet-stream; - - # Don't tell nginx version to the clients. Default is 'on'. - server_tokens off; - - # Specifies the maximum accepted body size of a client request, as - # indicated by the request header Content-Length. If the stated content - # length is greater than this size, then the client receives the HTTP - # error code 413. Set to 0 to disable. Default is '1m'. - client_max_body_size 0; - - client_body_temp_path /run/nginx-tmp/nginx 1 2; - proxy_temp_path /run/nginx-tmp/nginx-proxy; - fastcgi_temp_path /run/nginx-tmp/nginx-fastcgi; - uwsgi_temp_path /run/nginx-tmp/nginx-uwsgi; - scgi_temp_path /run/nginx-tmp/nginx-scgi; - - # Sendfile copies data between one FD and other from within the kernel, - # which is more efficient than read() + write(). Default is off. - sendfile on; - - # Causes nginx to attempt to send its HTTP response head in one packet, - # instead of using partial frames. Default is 'off'. - tcp_nopush on; - - # all ssl related config moved to ssl.conf - # included in server blocks where listen 443 is defined - - # Enable gzipping of responses. - #gzip on; - - # Set the Vary HTTP header as defined in the RFC 2616. Default is 'off'. - gzip_vary on; - - # Helper variable for proxying websockets. - map $http_upgrade $connection_upgrade { - default upgrade; - '' close; - } - - # Sets the path, format, and configuration for a buffered log write. - access_log /dev/stdout; - - # Includes virtual hosts configs. - include /run/default.conf; -} - -daemon off; -pid /run/nginx.pid; diff --git a/root/etc/nginx/proxy.conf b/root/etc/nginx/proxy.conf deleted file mode 100644 index 149c445..0000000 --- a/root/etc/nginx/proxy.conf +++ /dev/null @@ -1,34 +0,0 @@ -# Timeout if the real server is dead -proxy_next_upstream error timeout invalid_header http_500 http_502 http_503; - -# Proxy Connection Settings -proxy_buffers 32 4k; -proxy_connect_timeout 240; -proxy_headers_hash_bucket_size 128; -proxy_headers_hash_max_size 1024; -proxy_http_version 1.1; -proxy_redirect http:// $scheme://; -proxy_send_timeout 240; - -# Proxy Cache and Cookie Settings -proxy_cache_bypass $cookie_session; -#proxy_cookie_path / "/; Secure"; # enable at your own risk, may break certain apps -proxy_no_cache $cookie_session; - -# Proxy Header Settings -proxy_set_header Connection $connection_upgrade; -proxy_set_header Early-Data $ssl_early_data; -proxy_set_header Host $host; -proxy_set_header Proxy ""; -proxy_set_header Upgrade $http_upgrade; -proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; -proxy_set_header X-Forwarded-Host $host; -proxy_set_header X-Forwarded-Method $request_method; -proxy_set_header X-Forwarded-Port $server_port; -proxy_set_header X-Forwarded-Proto $scheme; -proxy_set_header X-Forwarded-Server $host; -proxy_set_header X-Forwarded-Ssl on; -proxy_set_header X-Forwarded-Uri $request_uri; -proxy_set_header X-Original-Method $request_method; -proxy_set_header X-Original-URL $scheme://$http_host$request_uri; -proxy_set_header X-Real-IP $remote_addr; diff --git a/root/templates/default_nopost.template b/root/templates/default_nopost.template deleted file mode 100644 index 79778f9..0000000 --- a/root/templates/default_nopost.template +++ /dev/null @@ -1,65 +0,0 @@ -server { - listen 2375 default_server; - listen [::]:2375 default_server; - - server_name _; - - set $dockersocket $SOCKET_PATH; - set $path_restarts $ALLOW_RESTARTS; - set $path_stop $ALLOW_STOP; - set $path_start $ALLOW_START; - set $path_auth $AUTH; - set $path_build $BUILD; - set $path_commit $COMMIT; - set $path_configs $CONFIGS; - set $path_containers $CONTAINERS; - set $path_distribution $DISTRIBUTION; - set $path_events $EVENTS; - set $path_exec $EXEC; - set $path_images $IMAGES; - set $path_info $INFO; - set $path_networks $NETWORKS; - set $path_nodes $NODES; - set $path_ping $PING; - set $path_plugins $PLUGINS; - set $path_secrets $SECRETS; - set $path_services $SERVICES; - set $path_session $SESSION; - set $path_swarm $SWARM; - set $path_system $SYSTEM; - set $path_tasks $TASKS; - set $path_version $VERSION; - set $path_volumes $VOLUMES; - - include /etc/nginx/proxy.conf; - - proxy_read_timeout $PROXY_READ_TIMEOUT; - - location ~* ^(/v[\d\.]+)?/containers/[a-zA-Z0-9_.-]+/start {if ($path_start = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/containers/[a-zA-Z0-9_.-]+/stop {if ($path_stop = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/containers/[a-zA-Z0-9_.-]+/(stop|restart|kill) {if ($path_restarts = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/auth {limit_except GET HEAD {deny all;}if ($path_auth = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/build {limit_except GET HEAD {deny all;}if ($path_build = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/commit {limit_except GET HEAD {deny all;}if ($path_commit = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/configs {limit_except GET HEAD {deny all;}if ($path_configs = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/containers {limit_except GET HEAD {deny all;}if ($path_containers = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/distribution {limit_except GET HEAD {deny all;}if ($path_distribution = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/events {limit_except GET HEAD {deny all;}if ($path_events = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/exec {limit_except GET HEAD {deny all;}if ($path_exec = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/images {limit_except GET HEAD {deny all;}if ($path_images = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/info {limit_except GET HEAD {deny all;}if ($path_info = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/networks {limit_except GET HEAD {deny all;}if ($path_networks = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/nodes {limit_except GET HEAD {deny all;}if ($path_nodes = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/_ping {limit_except GET HEAD {deny all;}if ($path_ping = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/plugins {limit_except GET HEAD {deny all;}if ($path_plugins = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/secrets {limit_except GET HEAD {deny all;}if ($path_secrets = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/services {limit_except GET HEAD {deny all;}if ($path_services = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/session {limit_except GET HEAD {deny all;}if ($path_session = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/swarm {limit_except GET HEAD {deny all;}if ($path_swarm = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/system {limit_except GET HEAD {deny all;}if ($path_system = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/tasks {limit_except GET HEAD {deny all;}if ($path_tasks = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/version {limit_except GET HEAD {deny all;}if ($path_version = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/volumes {limit_except GET HEAD {deny all;}if ($path_volumes = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location / {return 403;} - -} diff --git a/root/templates/default_nopost_ipv4.template b/root/templates/default_nopost_ipv4.template deleted file mode 100644 index b5ad1c0..0000000 --- a/root/templates/default_nopost_ipv4.template +++ /dev/null @@ -1,64 +0,0 @@ -server { - listen 2375 default_server; - - server_name _; - - set $dockersocket $SOCKET_PATH; - set $path_restarts $ALLOW_RESTARTS; - set $path_stop $ALLOW_STOP; - set $path_start $ALLOW_START; - set $path_auth $AUTH; - set $path_build $BUILD; - set $path_commit $COMMIT; - set $path_configs $CONFIGS; - set $path_containers $CONTAINERS; - set $path_distribution $DISTRIBUTION; - set $path_events $EVENTS; - set $path_exec $EXEC; - set $path_images $IMAGES; - set $path_info $INFO; - set $path_networks $NETWORKS; - set $path_nodes $NODES; - set $path_ping $PING; - set $path_plugins $PLUGINS; - set $path_secrets $SECRETS; - set $path_services $SERVICES; - set $path_session $SESSION; - set $path_swarm $SWARM; - set $path_system $SYSTEM; - set $path_tasks $TASKS; - set $path_version $VERSION; - set $path_volumes $VOLUMES; - - include /etc/nginx/proxy.conf; - - proxy_read_timeout $PROXY_READ_TIMEOUT; - - location ~* ^(/v[\d\.]+)?/containers/[a-zA-Z0-9_.-]+/start {if ($path_start = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/containers/[a-zA-Z0-9_.-]+/stop {if ($path_stop = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/containers/[a-zA-Z0-9_.-]+/(stop|restart|kill) {if ($path_restarts = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/auth {limit_except GET HEAD {deny all;}if ($path_auth = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/build {limit_except GET HEAD {deny all;}if ($path_build = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/commit {limit_except GET HEAD {deny all;}if ($path_commit = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/configs {limit_except GET HEAD {deny all;}if ($path_configs = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/containers {limit_except GET HEAD {deny all;}if ($path_containers = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/distribution {limit_except GET HEAD {deny all;}if ($path_distribution = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/events {limit_except GET HEAD {deny all;}if ($path_events = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/exec {limit_except GET HEAD {deny all;}if ($path_exec = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/images {limit_except GET HEAD {deny all;}if ($path_images = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/info {limit_except GET HEAD {deny all;}if ($path_info = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/networks {limit_except GET HEAD {deny all;}if ($path_networks = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/nodes {limit_except GET HEAD {deny all;}if ($path_nodes = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/_ping {limit_except GET HEAD {deny all;}if ($path_ping = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/plugins {limit_except GET HEAD {deny all;}if ($path_plugins = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/secrets {limit_except GET HEAD {deny all;}if ($path_secrets = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/services {limit_except GET HEAD {deny all;}if ($path_services = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/session {limit_except GET HEAD {deny all;}if ($path_session = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/swarm {limit_except GET HEAD {deny all;}if ($path_swarm = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/system {limit_except GET HEAD {deny all;}if ($path_system = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/tasks {limit_except GET HEAD {deny all;}if ($path_tasks = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/version {limit_except GET HEAD {deny all;}if ($path_version = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/volumes {limit_except GET HEAD {deny all;}if ($path_volumes = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location / {return 403;} - -} diff --git a/root/templates/default_post.template b/root/templates/default_post.template deleted file mode 100644 index c042183..0000000 --- a/root/templates/default_post.template +++ /dev/null @@ -1,65 +0,0 @@ -server { - listen 2375 default_server; - listen [::]:2375 default_server; - - server_name _; - - set $dockersocket $SOCKET_PATH; - set $path_restarts $ALLOW_RESTARTS; - set $path_stop $ALLOW_STOP; - set $path_start $ALLOW_START; - set $path_auth $AUTH; - set $path_build $BUILD; - set $path_commit $COMMIT; - set $path_configs $CONFIGS; - set $path_containers $CONTAINERS; - set $path_distribution $DISTRIBUTION; - set $path_events $EVENTS; - set $path_exec $EXEC; - set $path_images $IMAGES; - set $path_info $INFO; - set $path_networks $NETWORKS; - set $path_nodes $NODES; - set $path_ping $PING; - set $path_plugins $PLUGINS; - set $path_secrets $SECRETS; - set $path_services $SERVICES; - set $path_session $SESSION; - set $path_swarm $SWARM; - set $path_system $SYSTEM; - set $path_tasks $TASKS; - set $path_version $VERSION; - set $path_volumes $VOLUMES; - - include /etc/nginx/proxy.conf; - - proxy_read_timeout $PROXY_READ_TIMEOUT; - - location ~* ^(/v[\d\.]+)?/containers/[a-zA-Z0-9_.-]+/start {if ($path_start = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/containers/[a-zA-Z0-9_.-]+/stop {if ($path_stop = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/containers/[a-zA-Z0-9_.-]+/(stop|restart|kill) {if ($path_restarts = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/auth {if ($path_auth = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/build {if ($path_build = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/commit {if ($path_commit = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/configs {if ($path_configs = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/containers {if ($path_containers = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/distribution {if ($path_distribution = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/events {if ($path_events = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/exec {if ($path_exec = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/images {if ($path_images = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/info {if ($path_info = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/networks {if ($path_networks = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/nodes {if ($path_nodes = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/_ping {if ($path_ping = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/plugins {if ($path_plugins = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/secrets {if ($path_secrets = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/services {if ($path_services = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/session {if ($path_session = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/swarm {if ($path_swarm = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/system {if ($path_system = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/tasks {if ($path_tasks = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/version {if ($path_version = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/volumes {if ($path_volumes = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location / {return 403;} - -} diff --git a/root/templates/default_post_ipv4.template b/root/templates/default_post_ipv4.template deleted file mode 100644 index 21c41c4..0000000 --- a/root/templates/default_post_ipv4.template +++ /dev/null @@ -1,64 +0,0 @@ -server { - listen 2375 default_server; - - server_name _; - - set $dockersocket $SOCKET_PATH; - set $path_restarts $ALLOW_RESTARTS; - set $path_stop $ALLOW_STOP; - set $path_start $ALLOW_START; - set $path_auth $AUTH; - set $path_build $BUILD; - set $path_commit $COMMIT; - set $path_configs $CONFIGS; - set $path_containers $CONTAINERS; - set $path_distribution $DISTRIBUTION; - set $path_events $EVENTS; - set $path_exec $EXEC; - set $path_images $IMAGES; - set $path_info $INFO; - set $path_networks $NETWORKS; - set $path_nodes $NODES; - set $path_ping $PING; - set $path_plugins $PLUGINS; - set $path_secrets $SECRETS; - set $path_services $SERVICES; - set $path_session $SESSION; - set $path_swarm $SWARM; - set $path_system $SYSTEM; - set $path_tasks $TASKS; - set $path_version $VERSION; - set $path_volumes $VOLUMES; - - include /etc/nginx/proxy.conf; - - proxy_read_timeout $PROXY_READ_TIMEOUT; - - location ~* ^(/v[\d\.]+)?/containers/[a-zA-Z0-9_.-]+/start {if ($path_start = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/containers/[a-zA-Z0-9_.-]+/stop {if ($path_stop = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/containers/[a-zA-Z0-9_.-]+/(stop|restart|kill) {if ($path_restarts = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/auth {if ($path_auth = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/build {if ($path_build = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/commit {if ($path_commit = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/configs {if ($path_configs = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/containers {if ($path_containers = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/distribution {if ($path_distribution = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/events {if ($path_events = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/exec {if ($path_exec = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/images {if ($path_images = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/info {if ($path_info = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/networks {if ($path_networks = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/nodes {if ($path_nodes = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/_ping {if ($path_ping = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/plugins {if ($path_plugins = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/secrets {if ($path_secrets = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/services {if ($path_services = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/session {if ($path_session = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/swarm {if ($path_swarm = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/system {if ($path_system = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/tasks {if ($path_tasks = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/version {if ($path_version = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location ~* ^(/v[\d\.]+)?/volumes {if ($path_volumes = 0){return 403;}proxy_pass http://unix:$dockersocket;} - location / {return 403;} - -} diff --git a/root/templates/haproxy.cfg b/root/templates/haproxy.cfg new file mode 100644 index 0000000..965de9a --- /dev/null +++ b/root/templates/haproxy.cfg @@ -0,0 +1,56 @@ +global + log stdout format raw daemon info + pidfile /run/haproxy.pid + maxconn 2000 + +defaults + mode http + log global + option httplog + option dontlognull + option http-server-close + option redispatch + retries 3 + timeout http-request 10s + timeout queue 1m + timeout connect 10s + timeout client 10m + timeout server 10m + timeout http-keep-alive 10s + timeout check 10s + maxconn 2000 + +backend docker + server socket $SOCKET_PATH + +frontend proxy + bind @@BIND_PROTO@@ + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/containers/[a-zA-Z0-9_.-]+/((stop)|(restart)|(kill)) } { env(ALLOW_RESTARTS) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/containers/[a-zA-Z0-9_.-]+/start } { env(ALLOW_START) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/containers/[a-zA-Z0-9_.-]+/stop } { env(ALLOW_STOP) -m bool } + http-request deny unless METH_GET || { env(POST) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/auth } { env(AUTH) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/build } { env(BUILD) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/commit } { env(COMMIT) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/configs } { env(CONFIGS) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/containers } { env(CONTAINERS) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/distribution } { env(DISTRIBUTION) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/events } { env(EVENTS) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/exec } { env(EXEC) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/grpc } { env(GRPC) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/images } { env(IMAGES) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/info } { env(INFO) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/networks } { env(NETWORKS) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/nodes } { env(NODES) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/_ping } { env(PING) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/plugins } { env(PLUGINS) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/secrets } { env(SECRETS) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/services } { env(SERVICES) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/session } { env(SESSION) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/swarm } { env(SWARM) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/system } { env(SYSTEM) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/tasks } { env(TASKS) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/version } { env(VERSION) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/volumes } { env(VOLUMES) -m bool } + http-request deny + default_backend docker