Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# socket-proxy

## Latest image
- `wollomatic/socket-proxy:1.11.4` / `ghcr.io/wollomatic/socket-proxy:1.11.4`
- `wollomatic/socket-proxy:1.12.0` / `ghcr.io/wollomatic/socket-proxy:1.12.0`
- `wollomatic/socket-proxy:1` / `ghcr.io/wollomatic/socket-proxy:1`

> [!IMPORTANT]
Expand Down Expand Up @@ -93,17 +93,22 @@ Use Go's regexp syntax to create the patterns for these parameters. To avoid ins
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'` use allow `GET` multiple times

Examples (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"'` use allow `GET` multiple times

For more information, refer to the [Go regexp documentation](https://golang.org/pkg/regexp/syntax/).

An excellent online regexp tester is [regex101.com](https://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 can set multiple -allow* in params, environment, or docker labels.

#### Setting up bind mount restrictions

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.
Expand Down Expand Up @@ -135,6 +140,8 @@ services:
- 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
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Minor: clarify the second HEAD label example.

The trailing comment "another HEAD exec requests to socket-proxy" is missing a verb and reads awkwardly. Consider tightening to something like "allow HEAD /exec requests to socket-proxy". Also note that the prefix in the second label uses .1; depending on the label parser's prefix matching this may or may not be required to disambiguate from the first one — see the related comment in internal/config/config.go.

📝 Proposed wording
-      - 'socket-proxy.allow.head=/version' # HEAD `/version` requests to socket-proxy
-      - 'socket-proxy.allow.head.1=/exec' # another HEAD `exec` requests to socket-proxy
+      - 'socket-proxy.allow.head=/version' # allow HEAD `/version` requests to socket-proxy
+      - 'socket-proxy.allow.head.1=/exec'  # also allow HEAD `/exec` requests to socket-proxy
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@README.md` at line 144, Update the README example label
'socket-proxy.allow.head.1=/exec' to a clearer phrasing by changing the trailing
comment to "allow HEAD `/exec` requests to socket-proxy" (or similar concise
wording) and add a short parenthetical note calling out the '.1' prefix
ambiguity so readers know it may be required depending on the label parser;
reference the label-parsing logic in internal/config/config.go to verify whether
the '.1' suffix is necessary and adjust the example or wording accordingly.

```

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.
Expand Down Expand Up @@ -227,15 +234,15 @@ To log the API calls of the client application, set the log level to `DEBUG` and
socket-proxy can be configured via command-line parameters or via environment variables. If both command-line parameters and environment variables are set, the environment variable will be ignored.

| Parameter | Environment Variable | Default Value | Description |
|--------------------------------|----------------------------------|------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| ------------------------------ | -------------------------------- | ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `-allowfrom` | `SP_ALLOWFROM` | `127.0.0.1/32` | Specifies the IP addresses or hostnames (comma-separated) of the clients or the hostname of one specific client allowed to connect to the proxy. The default value is `127.0.0.1/32`, which means only localhost is allowed. This default configuration may not be useful in most cases, but it is because of a secure-by-default design. To allow all IPv4 addresses, set `-allowfrom=0.0.0.0/0`. Alternatively, hostnames can be set, for example `-allowfrom=traefik`, or `-allowfrom=traefik,dozzle`. Please remember that socket-proxy should never be exposed to a public network, regardless of this extra security layer. |
| `-allowbindmountfrom` | `SP_ALLOWBINDMOUNTFROM` | (not set) | Specifies the directories (comma-separated) that are allowed as bind mount sources. If not set, no bind mount restrictions are applied. When set, only bind mounts from the specified directories or their subdirectories are allowed. Each directory must start with `/`. For example, `-allowbindmountfrom=/home,/var/log` allows bind mounts from `/home`, `/var/log`, and any subdirectories. |
| `-allowhealthcheck` | `SP_ALLOWHEALTHCHECK` | (not set/false) | If set, it allows the included health check binary to check the socket connection via TCP port 55555 (socket-proxy then listens on `127.0.0.1:55555/health`) |
| `-listenip` | `SP_LISTENIP` | `127.0.0.1` | Specifies the IP address the server will bind on. Default is only the internal network. |
| `-logjson` | `SP_LOGJSON` | (not set/false) | If set, it enables logging in JSON format. If unset, socket-proxy logs in plain text format. |
| `-loglevel` | `SP_LOGLEVEL` | `INFO` | Sets the log level. Accepted values are: `DEBUG`, `INFO`, `WARN`, `ERROR`. |
| `-proxyport` | `SP_PROXYPORT` | `2375` | Defines the TCP port the proxy listens to. |
| `-shutdowngracetime` | `SP_SHUTDOWNGRACETIME` | `10` | Defines the time in seconds to wait before forcing the shutdown after SIGTERM or SIGINT (socket-proxy first tries to gracefully shut down the TCP server) | |
| `-shutdowngracetime` | `SP_SHUTDOWNGRACETIME` | `10` | Defines the time in seconds to wait before forcing the shutdown after SIGTERM or SIGINT (socket-proxy first tries to gracefully shut down the TCP server) |
| `-socketpath` | `SP_SOCKETPATH` | `/var/run/docker.sock` | Specifies the UNIX socket path to connect to. By default, it connects to the Docker daemon socket. |
| `-stoponwatchdog` | `SP_STOPONWATCHDOG` | (not set/false) | If set, socket-proxy will be stopped if the watchdog detects that the unix socket is not available. |
| `-watchdoginterval` | `SP_WATCHDOGINTERVAL` | `0` | Check for socket availability every x seconds (disable checks, if not set or value is 0) |
Expand Down Expand Up @@ -269,6 +276,7 @@ socket-proxy can be configured via command-line parameters or via environment va

1.11 - add per-container allowlists specified by Docker container labels (thanks [@amanda-wee](https://github.com/amanda-wee))

1.12 - support use of allow* multiple times in env, flag and docker labels (thanks [@qianlongzt](https://github.com/qianlongzt))

## License

Expand Down
12 changes: 11 additions & 1 deletion cmd/socket-proxy/handlehttprequest.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"log/slog"
"net"
"net/http"
"regexp"

"github.com/wollomatic/socket-proxy/internal/config"
)
Expand All @@ -24,7 +25,7 @@ func handleHTTPRequest(w http.ResponseWriter, r *http.Request) {
communicateBlockedRequest(w, r, "method not allowed", http.StatusMethodNotAllowed)
return
}
if !allowed.MatchString(r.URL.Path) { // path does not match regex -> not allowed
if !matchURL(allowed, r.URL.Path) { // path does not match regex -> not allowed
communicateBlockedRequest(w, r, "path not allowed", http.StatusForbidden)
return
}
Expand All @@ -40,6 +41,15 @@ func handleHTTPRequest(w http.ResponseWriter, r *http.Request) {
socketProxy.ServeHTTP(w, r) // #nosec G704 - Request target is always the specified socket
}

func matchURL(allowedURIs []*regexp.Regexp, requestURI string) bool {
for _, allowedURI := range allowedURIs {
if allowedURI.MatchString(requestURI) {
return true
}
}
return false
}

// return the relevant allowlist
func determineAllowList(r *http.Request) (config.AllowList, bool) {
if cfg.ProxySocketEndpoint == "" { // do not perform this check if we proxy to a unix socket
Expand Down
Loading
Loading