Loading repository data…
Loading repository data…
wollomatic / repository
Secure-by-design and flexible Unix socket proxy. Built in memory-safe Go with zero dependencies, no shell or interpreter required in containers. A modern alternative to tecnativa/docker-socket-proxy and linuxserver/docker-socket-proxy, with powerful regex-based configuration.
wollomatic/socket-proxy:1.12.3 / ghcr.io/wollomatic/socket-proxy:1.12.3wollomatic/socket-proxy:1 / ghcr.io/wollomatic/socket-proxy:1[!IMPORTANT]
Usage with Traefik >= 2.11.31 / >= 3.6.1
Due to a change in how Traefik retrieves the Docker API version (traefik/traefik#12256), the Socket-Proxy configuration for Traefik must be updated to allow
HEADrequests to/_ping:- '-allowHEAD=/_ping'Otherwise, Traefik would fall back to API version 1.51, which would break the Docker provider on older Docker versions.
socket-proxy is a lightweight, secure-by-default unix socket proxy. Although it was created to proxy the docker socket to Traefik, it can also be used for other purposes.
It is heavily inspired by tecnativa/docker-socket-proxy.
As an additional benefit, socket-proxy can be used to examine the API calls of the client application.
The advantage over other solutions is the very slim container image (from-scratch-image) without any external dependencies (no OS, no packages, just the Go standard library). It is designed with security in mind, so there are secure defaults and an additional security layer (IP address-based access control) compared to most other solutions.
The allowlist is configured for each HTTP method separately using the Go regexp syntax, allowing fine-grained control over the allowed HTTP methods. In bridge network mode, each container that uses socket-proxy can be configured with its own allowlist.
The source code is available on GitHub: wollomatic/socket-proxy
Some examples can be found in the wiki and in the examples directory of the repo.
You should know what you are doing. Never expose socket-proxy to a public network. It is meant to be used in a secure environment only.
The container image is available on Docker Hub (wollomatic/socket-proxy) and on the GitHub Container Registry (ghcr.io/wollomatic/socket-proxy).
To pin one specific version, use the version tag (for example, wollomatic/socket-proxy:1.11.0 or ghcr.io/wollomatic/socket-proxy:1.11.0).
To always use the most recent version, use the 1 tag (wollomatic/socket-proxy:1 or ghcr.io/wollomatic/socket-proxy:1). This tag will be valid as long as there is no breaking change in the deployment.
There may be an additional docker image with the testing-tag. This image is only for testing. Likely, documentation for the testing image could only be found in the GitHub commit messages. It is not recommended to use the testing image in production.
Every socket-proxy release image is signed with Cosign. The public key is available on GitHub: wollomatic/socket-proxy/main/cosign.pub and https://wollomatic.de/socket-proxy/cosign.pub. For more information, please refer to the Security Policy. As of version 1.6, all multi-arch images are signed.
[!TIP] If you are coming from
tecnativa/docker-socket-proxyorlinuxserver/docker-socket-proxy, configuring a regular expression allowlist may seem more complex at first.To simplify migration, you can use the Socket Proxy Configuration Converter. The tool runs entirely in your browser and converts existing
docker-socket-proxyenvironment variable configurations into equivalent regular expression allowlists forwollomatic/socket-proxy.The converter is fully open source. Its source code is available at wollomatic/socket-proxy-configurator.
Because of the secure-by-default design, you need to allow every access explicitly.
This is meant to be an additional layer of security. It does not replace other security measures, such as firewalls, network segmentation, etc. Do not expose socket-proxy to a public network.
Socket-proxy listens per default only on 127.0.0.1. Depending on what you need, you may want to set another listener address with the -listenip parameter. In almost every use case, -listenip=0.0.0.0 will be the correct configuration when using socket-proxy in a docker image.
If you want to proxy/filter the unix socket to a new unix socket instead to a TCP listener,
you need to set the -proxysocketendpoint parameter or the SP_PROXYSOCKETENDPOINT env variable to the socket path of the new unix socket.
This will also disable the TCP listener.
For example -proxysocketendpoint=/tmp/filtered-socket.sock
[!NOTE] Versions prior to 1.10.0 of socket-proxy set the default file permissions of the Unix socket to 0400, instead of 0600 as stated in the documentation.
Per default, only 127.0.0.1/32 is allowed to connect to socket-proxy. You may want to set another allowlist with the -allowfrom parameter, depending on your needs.
Alternatively, not only IP networks but also hostnames can be configured. So it is now possible to explicitly allow one or more specific hostnames to connect to the proxy, for example, -allowfrom=traefik, or -allowfrom=traefik,dozzle.
Using the hostname is an easy-to-configure way to have more security. Access to the socket proxy will not even be permitted from the host system.
You must set up regular expressions for each HTTP method the client application needs access to.
The name of a parameter should be "-allow", followed by the HTTP method name (for example, -allowGET). The request will be allowed if that parameter is set and the incoming request matches the method and path matching the regexp. If unset, the corresponding HTTP method is disallowed.
It is also possible to configure the allowlist via environment variables. The variables are called "SP_ALLOW_", followed by the HTTP method (for example, SP_ALLOW_GET).
If both command-line parameter and environment variable are configured for a particular HTTP method, the environment variable is ignored.
Use Go's regexp syntax to create the patterns for these parameters. To avoid insecure configurations, ^ and $ are added automatically to the start and end of the pattern. Note: invalid regexp results in program termination.
Examples (command-line):
'-allowGET=/v1\..{1,2}/(version|containers/.*|events.*)' could be used for allowing access to the docker socket for Traefik v2.'-allowHEAD=.*' allows all HEAD requests.'-allowGET=/version -allowGET=/_ping' supports using -allowGET multiple timesExamples (env variables):
'SP_ALLOW_GET="/v1\..{1,2}/(version|containers/.*|events.*)"' could be used for allowing access to the docker socket for Traefik v2.'SP_ALLOW_HEAD=".*"' allows all HEAD requests.'SP_ALLOW_GET="/version" SP_ALLOW_GET_2="/_ping"' supports multiple SP_ALLOW_GET entriesFor more information, refer to the Go regexp documentation.
An excellent online regexp tester is regex101.com.
To determine which HTTP requests your client application uses, you could switch socket-proxy to debug log level and look at the log output while allowing all requests in a secure environment.
[!NOTE] Starting with version 1.12.0, the socket-proxy supports using multiple -allow* entries in params, environment, or docker labels.
By default, socket-proxy does not restrict bind mounts. If you want to add an additional layer of security by restricting which directories can be used as bind mount sources, you can use the -allowbindmountfrom parameter or the SP_ALLOWBINDMOUNTFROM environment variable.
When configured, only bind mounts from the specified directories or their subdirectories are allowed. Each directory must start with /. Multiple directories can be specified separated by commas.
For example:
-allowbindmountfrom=/home,/var/log allows bind mounts from /home, /var/log, and any subdirectories like /home/user/data or /var/log/appSP_ALLOWBINDMOUNTFROM="/app/data,/tmp" allows bind mounts from /app/data and /tmp directoriesBind mount restrictions are applied to relevant Docker API endpoints and work with both legacy bind mount syntax (-v /host/path:/container/path) and modern mount syntax.
Note: This feature only restricts bind mounts. Other mount types (volumes, tmpfs, etc.) are not affected by this restriction.
Allowlists for both requests and bind mount restrictions can be specified for particular containers. To do this:
-proxycontainername or the environment variable SP_PROXYCONTAINERNAME to the name of the socket proxy container.socket-proxy.allow., with socket-proxy.allow.bindmountfrom for bind mount restrictions. For example:services:
traefik:
# [...] see github.com/wollomatic/traefik-hardened for a full example
networks:
- traefik-servicenet # this is the common traefik network
- docker-proxynet # this should be only restricted to traefik and socket-proxy
labels:
- 'socket-proxy.allow.get=.*' # allow all GET requests to socket-proxy
- 'socket-proxy.allow.head=/version' # HEAD `/version` requests to socket-proxy
- 'socket-proxy.allow.head.1=/exec' # another HEAD `exec` requests to socket-proxy
When this is used, it is not necessary to specify the container in -allowfrom as the presence of the allowlist labels will grant corresponding access.
Health checks are disabled by default. As the socket-proxy container may not be exposed to a public network, a separate health check binary is included in the container image. To activate the health check, the -allowhealthcheck parameter or the environment variable SP_ALLOWHEALTHCHECK=true must be set. Then, a health check is possible for example with the following docker-compose snippet:
# [...]
healthcheck:
test: ["CMD", "./healthcheck"]
interval: 10s
timeout: 5s
retries: 2
# [...]
In certain circumstances (for example, after a Docker engine update), the socket connection may break, causing the client application to fail. To prevent this, the socket-proxy can be configured to check the socket availability at regular intervals. If the socket is not available, the socket-proxy will be stopped so the container orchestrator can restart it. This feature is disabled by default. To enable it, set the -watchdoginterval parameter (or SP_WATCHDOGINTERVAL env variable) to the desired interval in seconds and set the -stoponwatchdog parameter (or SP_STOPONWATCHDOG=true). If -stoponwatchdogis not set, the watchdog will only log an error message and continue to run (the problem would still exist in that case).
You need to know how to install Traefik in this environment. See [wollomatic/traefik2-hardened](https://github.com/wollomatic/traefik2-