diff --git a/README.md b/README.md index ed426c5..ac80174 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). +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. 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`. @@ -63,9 +63,9 @@ The container should be run on the same docker network as the service(s) using i ## Usage -To help you get started creating a container from this image you can either use docker-compose or the docker cli. +To help you get started creating a container from this image you can either use docker compose or the docker cli. -### docker-compose (recommended, [click here for more info](https://docs.linuxserver.io/general/docker-compose)) +### docker compose (recommended, [click here for more info](https://docs.linuxserver.io/general/docker compose)) ```yaml --- @@ -82,6 +82,7 @@ services: - COMMIT=0 #optional - CONFIGS=0 #optional - CONTAINERS=0 #optional + - DISABLE_IPV6=0 #optional - DISTRIBUTION=0 #optional - EVENTS=1 #optional - EXEC=0 #optional @@ -122,6 +123,7 @@ docker run -d \ -e CONFIGS=0 `#optional` \ -e CONTAINERS=0 `#optional` \ -e DISTRIBUTION=0 `#optional` \ + -e DISABLE_IPV6=0 `#optional` \ -e EVENTS=1 `#optional` \ -e EXEC=0 `#optional` \ -e IMAGES=0 `#optional` \ @@ -152,15 +154,16 @@ Containers are configured using parameters passed at runtime (such as those abov | Parameter | Function | | :----: | --- | -| `-e ALLOW_START=0` | `/containers/id/start` | -| `-e ALLOW_STOP=0` | `/containers/id/stop` | -| `-e ALLOW_RESTARTS=0` | `/containers/id/stop`, `/containers/id/restart`, and `/containers/id/kill` | +| `-e ALLOW_START=0` | `/containers/{id}/start` | +| `-e ALLOW_STOP=0` | `/containers/{id}/stop` | +| `-e ALLOW_RESTARTS=0` | `/containers/{id}/stop`, `/containers/{id}/restart`, and `/containers/{id}/kill` | | `-e AUTH=0` | `/auth` | | `-e BUILD=0` | `/build` | | `-e COMMIT=0` | `/commit` | | `-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 EVENTS=1` | `/events` | | `-e EXEC=0` | `/exec` & `/containers/{id}/exec` | | `-e IMAGES=0` | `/images` | @@ -220,26 +223,26 @@ Below are the instructions for updating containers: * All images: ```bash - docker-compose pull + docker compose pull ``` * Single image: ```bash - docker-compose pull socket-proxy + docker compose pull socket-proxy ``` * Update containers: * All containers: ```bash - docker-compose up -d + docker compose up -d ``` * Single container: ```bash - docker-compose up -d socket-proxy + docker compose up -d socket-proxy ``` * You can also remove the old dangling images: @@ -301,5 +304,6 @@ Once registered you can define the dockerfile to use with `-f Dockerfile.aarch64 ## Versions +* **15.04.24:** - Allow disabling IPv6 support for legacy devices. * **08.04.24:** - Use nginx due to haproxy's wonky websockets handling. * **07.04.24:** - Initial Release. diff --git a/readme-vars.yml b/readme-vars.yml index d949f45..656c2c0 100644 --- a/readme-vars.yml +++ b/readme-vars.yml @@ -56,7 +56,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). + 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. 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`. @@ -67,9 +67,9 @@ full_custom_readme: | ## Usage - To help you get started creating a container from this image you can either use docker-compose or the docker cli. + To help you get started creating a container from this image you can either use docker compose or the docker cli. - ### docker-compose (recommended, [click here for more info](https://docs.linuxserver.io/general/docker-compose)) + ### docker compose (recommended, [click here for more info](https://docs.linuxserver.io/general/docker compose)) ```yaml --- @@ -86,6 +86,7 @@ full_custom_readme: | - COMMIT=0 #optional - CONFIGS=0 #optional - CONTAINERS=0 #optional + - DISABLE_IPV6=0 #optional - DISTRIBUTION=0 #optional - EVENTS=1 #optional - EXEC=0 #optional @@ -126,6 +127,7 @@ full_custom_readme: | -e CONFIGS=0 `#optional` \ -e CONTAINERS=0 `#optional` \ -e DISTRIBUTION=0 `#optional` \ + -e DISABLE_IPV6=0 `#optional` \ -e EVENTS=1 `#optional` \ -e EXEC=0 `#optional` \ -e IMAGES=0 `#optional` \ @@ -156,15 +158,16 @@ full_custom_readme: | | Parameter | Function | | :----: | --- | - | `-e ALLOW_START=0` | `/containers/id/start` | - | `-e ALLOW_STOP=0` | `/containers/id/stop` | - | `-e ALLOW_RESTARTS=0` | `/containers/id/stop`, `/containers/id/restart`, and `/containers/id/kill` | + | `-e ALLOW_START=0` | `/containers/{id}/start` | + | `-e ALLOW_STOP=0` | `/containers/{id}/stop` | + | `-e ALLOW_RESTARTS=0` | `/containers/{id}/stop`, `/containers/{id}/restart`, and `/containers/{id}/kill` | | `-e AUTH=0` | `/auth` | | `-e BUILD=0` | `/build` | | `-e COMMIT=0` | `/commit` | | `-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 EVENTS=1` | `/events` | | `-e EXEC=0` | `/exec` & `/containers/{id}/exec` | | `-e IMAGES=0` | `/images` | @@ -224,26 +227,26 @@ full_custom_readme: | * All images: ```bash - docker-compose pull + docker compose pull ``` * Single image: ```bash - docker-compose pull socket-proxy + docker compose pull socket-proxy ``` * Update containers: * All containers: ```bash - docker-compose up -d + docker compose up -d ``` * Single container: ```bash - docker-compose up -d socket-proxy + docker compose up -d socket-proxy ``` * You can also remove the old dangling images: @@ -305,6 +308,7 @@ full_custom_readme: | ## Versions + * **15.04.24:** - Allow disabling IPv6 support for legacy devices. * **08.04.24:** - Use nginx due to haproxy's wonky websockets handling. * **07.04.24:** - Initial Release. diff --git a/root/docker-entrypoint.sh b/root/docker-entrypoint.sh index 46a6072..27df897 100755 --- a/root/docker-entrypoint.sh +++ b/root/docker-entrypoint.sh @@ -1,6 +1,10 @@ #!/bin/bash -if [[ $POST == 1 ]]; then +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 else envsubst "$(printf '${%s} ' $(bash -c "compgen -A variable"))" < /templates/default_nopost.template > /run/default.conf diff --git a/root/templates/default_nopost_ipv4.template b/root/templates/default_nopost_ipv4.template new file mode 100644 index 0000000..9e50c5c --- /dev/null +++ b/root/templates/default_nopost_ipv4.template @@ -0,0 +1,61 @@ +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; + + location ~* ^(/v[\d\.]+)?/containers/[a-zA-Z0-9_.-]+/((stop)|(restart)|(kill)) {limit_except GET HEAD {deny all;}if ($path_restarts = 0){return 403;}proxy_pass http://unix:$dockersocket;} + location ~* ^(/v[\d\.]+)?/containers/[a-zA-Z0-9_.-]+/start {limit_except GET HEAD {deny all;}if ($path_start = 0){return 403;}proxy_pass http://unix:$dockersocket;} + location ~* ^(/v[\d\.]+)?/containers/[a-zA-Z0-9_.-]+/stop {limit_except GET HEAD {deny all;}if ($path_stop = 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;} + +} diff --git a/root/templates/default_post_ipv4.template b/root/templates/default_post_ipv4.template new file mode 100644 index 0000000..b8a0643 --- /dev/null +++ b/root/templates/default_post_ipv4.template @@ -0,0 +1,61 @@ +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; + + 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\.]+)?/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\.]+)?/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;} + +}