1
0
mirror of https://github.com/Tecnativa/docker-socket-proxy synced 2024-12-22 06:38:07 +00:00

Apply autoprettier

This commit is contained in:
João Marques 2020-11-25 07:52:57 +00:00
parent 7bd86a5425
commit 0206be67e5
3 changed files with 80 additions and 87 deletions

View File

@ -32,12 +32,12 @@ jobs:
- name: Install python - name: Install python
uses: actions/setup-python@v1 uses: actions/setup-python@v1
with: with:
python-version: '3.9' python-version: "3.9"
- name: Generate cache key CACHE - name: Generate cache key CACHE
run: run:
echo "CACHE=${{ secrets.CACHE_DATE }} ${{ runner.os }} echo "CACHE=${{ secrets.CACHE_DATE }} ${{ runner.os }} $(python -VV |
$(python -VV | sha256sum | cut -d' ' -f1) ${{ hashFiles('pyproject.toml') }} sha256sum | cut -d' ' -f1) ${{ hashFiles('pyproject.toml') }} ${{
${{ hashFiles('poetry.lock') }}" >> $GITHUB_ENV hashFiles('poetry.lock') }}" >> $GITHUB_ENV
- uses: actions/cache@v2 - uses: actions/cache@v2
with: with:
path: | path: |

135
README.md
View File

@ -11,36 +11,36 @@ This is a security-enhanced proxy for the Docker Socket.
## Why? ## Why?
Giving access to your Docker socket could mean giving root access to your host, Giving access to your Docker socket could mean giving root access to your host, or even
or even to your whole swarm, but some services require hooking into that socket to your whole swarm, but some services require hooking into that socket to react to
to react to events, etc. Using this proxy lets you block anything you consider events, etc. Using this proxy lets you block anything you consider those services should
those services should not do. not do.
## How? ## How?
We use the official [Alpine][]-based [HAProxy][] image with a small We use the official [Alpine][]-based [HAProxy][] image with a small configuration file.
configuration file.
It blocks access to the Docker socket API according to the environment It blocks access to the Docker socket API according to the environment variables you
variables you set. It returns a `HTTP 403 Forbidden` status for those dangerous set. It returns a `HTTP 403 Forbidden` status for those dangerous requests that should
requests that should never happen. never happen.
## Security recommendations ## Security recommendations
- Never expose this container's port to a public network. Only to a Docker - Never expose this container's port to a public network. Only to a Docker networks
networks where only reside the proxy itself and the service that uses it. where only reside the proxy itself and the service that uses it.
- Revoke access to any API section that you consider your service should not - Revoke access to any API section that you consider your service should not need.
need. - This image does not include TLS support, just plain HTTP proxy to the host Docker
- This image does not include TLS support, just plain HTTP proxy to the host Unix socket (which is not TLS protected even if you configured your host for TLS
Docker Unix socket (which is not TLS protected even if you configured your protection). This is by design because you are supposed to restrict access to it
host for TLS protection). This is by design because you are supposed to through Docker's built-in firewall.
restrict access to it through Docker's built-in firewall. - [Read the docs](#suppported-api-versions) for the API version you are using, and
- [Read the docs](#suppported-api-versions) for the API version you are using, **know what you are doing**.
and **know what you are doing**.
## Usage ## Usage
1. Run the API proxy (`--privileged` flag is required here because it connects with the docker socket, which is a privileged connection in some SELinux/AppArmor contexts and would get locked otherwise): 1. Run the API proxy (`--privileged` flag is required here because it connects with the
docker socket, which is a privileged connection in some SELinux/AppArmor contexts
and would get locked otherwise):
$ docker container run \ $ docker container run \
-d --privileged \ -d --privileged \
@ -80,85 +80,84 @@ requests that should never happen.
Request forbidden by administrative rules. Request forbidden by administrative rules.
</body></html> </body></html>
The same will happen to any containers that use this proxy's `2375` port to The same will happen to any containers that use this proxy's `2375` port to access the
access the Docker socket API. Docker socket API.
## Grant or revoke access to certain API sections ## Grant or revoke access to certain API sections
You grant and revoke access to certain features of the Docker API through You grant and revoke access to certain features of the Docker API through environment
environment variables. variables.
Normally the variables match the URL prefix (i.e. `AUTH` blocks access to Normally the variables match the URL prefix (i.e. `AUTH` blocks access to `/auth/*`
`/auth/*` parts of the API, etc.). parts of the API, etc.).
Possible values for these variables: Possible values for these variables:
- `0` to **revoke** access. - `0` to **revoke** access.
- `1` to **grant** access. - `1` to **grant** access.
### Access granted by default ### Access granted by default
These API sections are mostly harmless and almost required for any service that These API sections are mostly harmless and almost required for any service that uses the
uses the API, so they are granted by default. API, so they are granted by default.
- `EVENTS` - `EVENTS`
- `PING` - `PING`
- `VERSION` - `VERSION`
### Access revoked by default ### Access revoked by default
#### Security-critical #### Security-critical
These API sections are considered security-critical, and thus access is revoked These API sections are considered security-critical, and thus access is revoked by
by default. Maximum caution when enabling these. default. Maximum caution when enabling these.
- `AUTH` - `AUTH`
- `SECRETS` - `SECRETS`
- `POST`: When disabled, only `GET` and `HEAD` operations are allowed, meaning - `POST`: When disabled, only `GET` and `HEAD` operations are allowed, meaning any
any section of the API is read-only. section of the API is read-only.
#### Not always needed #### Not always needed
You will possibly need to grant access to some of these API sections, which are You will possibly need to grant access to some of these API sections, which are not so
not so extremely critical but can expose some information that your service extremely critical but can expose some information that your service does not need.
does not need.
- `BUILD` - `BUILD`
- `COMMIT` - `COMMIT`
- `CONFIGS` - `CONFIGS`
- `CONTAINERS` - `CONTAINERS`
- `DISTRIBUTION` - `DISTRIBUTION`
- `EXEC` - `EXEC`
- `IMAGES` - `IMAGES`
- `INFO` - `INFO`
- `NETWORKS` - `NETWORKS`
- `NODES` - `NODES`
- `PLUGINS` - `PLUGINS`
- `SERVICES` - `SERVICES`
- `SESSION` - `SESSION`
- `SWARM` - `SWARM`
- `SYSTEM` - `SYSTEM`
- `TASKS` - `TASKS`
- `VOLUMES` - `VOLUMES`
## Logging ## Logging
You can set the logging level or severity level of the messages to be logged with the You can set the logging level or severity level of the messages to be logged with the
environment variable `LOG_LEVEL`. Defaul value is info. Possible values are: debug, environment variable `LOG_LEVEL`. Defaul value is info. Possible values are: debug,
info, notice, warning, err, crit, alert and emerg. info, notice, warning, err, crit, alert and emerg.
## Supported API versions ## Supported API versions
- [1.27](https://docs.docker.com/engine/api/v1.27/) - [1.27](https://docs.docker.com/engine/api/v1.27/)
- [1.28](https://docs.docker.com/engine/api/v1.28/) - [1.28](https://docs.docker.com/engine/api/v1.28/)
- [1.29](https://docs.docker.com/engine/api/v1.29/) - [1.29](https://docs.docker.com/engine/api/v1.29/)
- [1.30](https://docs.docker.com/engine/api/v1.30/) - [1.30](https://docs.docker.com/engine/api/v1.30/)
- [1.37](https://docs.docker.com/engine/api/v1.37/) - [1.37](https://docs.docker.com/engine/api/v1.37/)
## Feedback ## Feedback
Please send any feedback (issues, questions) to the [issue tracker][]. Please send any feedback (issues, questions) to the [issue tracker][].
[Alpine]: https://alpinelinux.org/ [alpine]: https://alpinelinux.org/
[HAProxy]: http://www.haproxy.org/ [haproxy]: http://www.haproxy.org/
[issue tracker]: https://github.com/Tecnativa/docker-socket-proxy/issues [issue tracker]: https://github.com/Tecnativa/docker-socket-proxy/issues

View File

@ -1,10 +1,7 @@
import pytest
import logging import logging
from plumbum import ProcessExecutionError, local from plumbum import ProcessExecutionError
from plumbum.cmd import docker from plumbum.cmd import docker
from plumbum.machines.local import LocalCommand
logger = logging.getLogger() logger = logging.getLogger()
@ -13,18 +10,19 @@ SOCKET_PROXY = "127.0.0.1:2375"
def _start_proxy( def _start_proxy(
container_name=CONTAINER_NAME, container_name=CONTAINER_NAME, socket_proxy=SOCKET_PROXY, extra_args=None
socket_proxy=SOCKET_PROXY,
extra_args=None
): ):
logger.info(f"Starting {container_name} with args: {extra_args}...") logger.info(f"Starting {container_name} with args: {extra_args}...")
docker( docker(
"run", "run",
"-d", "-d",
"--name", container_name, "--name",
container_name,
"--privileged", "--privileged",
"-v", "/var/run/docker.sock:/var/run/docker.sock", "-v",
"-p", f"{socket_proxy}:2375", "/var/run/docker.sock:/var/run/docker.sock",
"-p",
f"{socket_proxy}:2375",
extra_args, extra_args,
"tecnativa/docker-socket-proxy", "tecnativa/docker-socket-proxy",
) )
@ -86,7 +84,6 @@ def test_default_permissions():
_check_permission("forbidden", ["build", "."]) _check_permission("forbidden", ["build", "."])
_check_permission("forbidden", ["swarm", "init"]) _check_permission("forbidden", ["swarm", "init"])
finally: finally:
pass
_stop_and_delete_proxy() _stop_and_delete_proxy()
@ -100,7 +97,6 @@ def test_container_permissions():
_check_permission("forbidden", ["rm", "-f", CONTAINER_NAME]) _check_permission("forbidden", ["rm", "-f", CONTAINER_NAME])
_check_permission("forbidden", ["restart", CONTAINER_NAME]) _check_permission("forbidden", ["restart", CONTAINER_NAME])
finally: finally:
pass
_stop_and_delete_proxy() _stop_and_delete_proxy()
@ -112,7 +108,6 @@ def test_post_permissions():
_check_permission("forbidden", ["run", "--rm", "alpine"]) _check_permission("forbidden", ["run", "--rm", "alpine"])
_check_permission("forbidden", ["network", "create", "foobar"]) _check_permission("forbidden", ["network", "create", "foobar"])
finally: finally:
pass
_stop_and_delete_proxy() _stop_and_delete_proxy()
@ -123,5 +118,4 @@ def test_network_post_permissions():
_check_permission("allowed", ["network", "create", "foo"]) _check_permission("allowed", ["network", "create", "foo"])
_check_permission("allowed", ["network", "rm", "foo"]) _check_permission("allowed", ["network", "rm", "foo"])
finally: finally:
pass _stop_and_delete_proxy()
_stop_and_delete_proxy()