{"id":29782069,"url":"https://github.com/tecnativa/docker-whitelist","last_synced_at":"2025-07-27T14:11:51.911Z","repository":{"id":48862075,"uuid":"122336938","full_name":"Tecnativa/docker-whitelist","owner":"Tecnativa","description":"A socat service to whitelist network connections","archived":false,"fork":false,"pushed_at":"2025-06-11T10:06:14.000Z","size":94,"stargazers_count":10,"open_issues_count":1,"forks_count":8,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-06-11T10:54:29.856Z","etag":null,"topics":["docker-image","isolation","networking","socat","whitelist"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Tecnativa.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2018-02-21T13:01:47.000Z","updated_at":"2025-06-11T10:06:16.000Z","dependencies_parsed_at":"2024-02-07T21:35:48.142Z","dependency_job_id":"96fb3cb2-d76b-4591-9dcd-445d0442e1b4","html_url":"https://github.com/Tecnativa/docker-whitelist","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/Tecnativa/docker-whitelist","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tecnativa%2Fdocker-whitelist","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tecnativa%2Fdocker-whitelist/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tecnativa%2Fdocker-whitelist/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tecnativa%2Fdocker-whitelist/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Tecnativa","download_url":"https://codeload.github.com/Tecnativa/docker-whitelist/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tecnativa%2Fdocker-whitelist/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267368932,"owners_count":24076093,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-27T02:00:11.917Z","response_time":82,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker-image","isolation","networking","socat","whitelist"],"created_at":"2025-07-27T14:11:32.497Z","updated_at":"2025-07-27T14:11:51.898Z","avatar_url":"https://github.com/Tecnativa.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Last image-template](https://img.shields.io/badge/last%20template%20update-v0.1.3-informational)](https://github.com/Tecnativa/image-template/tree/v0.1.3)\n[![GitHub Container Registry](https://img.shields.io/badge/GitHub%20Container%20Registry-latest-%2324292e)](https://github.com/orgs/Tecnativa/packages/container/package/docker-whitelist)\n[![Docker Hub](https://img.shields.io/badge/Docker%20Hub-latest-%23099cec)](https://hub.docker.com/r/tecnativa/whitelist)\n[![Docker Pulls](https://img.shields.io/docker/pulls/tecnativa/whitelist.svg)](https://hub.docker.com/r/tecnativa/whitelist)\n[![Layers](https://images.microbadger.com/badges/image/tecnativa/whitelist.svg)](https://microbadger.com/images/tecnativa/whitelist)\n[![Commit](https://images.microbadger.com/badges/commit/tecnativa/whitelist.svg)](https://microbadger.com/images/tecnativa/whitelist)\n[![License](https://images.microbadger.com/badges/license/tecnativa/whitelist.svg)](https://microbadger.com/images/tecnativa/whitelist)\n\n# Docker Whitelister\n\n## What?\n\nA whitelist proxy that uses socat. 🔌😼\n\n## Why?\n\ntl;dr: To workaround https://github.com/moby/moby/issues/36174.\n\nBasically, Docker supports internal networks; but when you use them, you simply cannot\nopen ports from those services, which is not very convenient: you either have full or\nnone isolation.\n\nThis proxy allows some whitelist endpoints to have network connectivity. It can be used\nfor:\n\n-   Allowing connection only to some APIs, but not to the rest of the WWW.\n-   Exposing ports from a container while still not letting the container access the\n    WWW.\n\n## How?\n\nUse these environment variables:\n\n### `TARGET`\n\nRequired. It's the host name where the incoming connections will be redirected to.\n\n### `HTTP_HEALTHCHECK`\n\nDefault: `0`\n\nSet to `1` to enable healthcheck with pycurl http requests. This is useful if the target\nuses a deployment where the ip of the service gets changed frequently (e.g.\n`accounts.google.com`) and you are using [`PRE_RESOLVE`](#pre_resolve)\n\n#### Automatically restarting unhealthy proxies\n\nWhen you enable the http healthcheck the container marks itself as unhealthy but does\nnothing. (see https://github.com/moby/moby/pull/22719)\n\nIf you want to restart your proxies automatically, you can use\nhttps://github.com/willfarrell/docker-autoheal.\n\n### `HTTP_HEALTHCHECK_URL`\n\nDefault: `http://$TARGET/`\n\nUrl to use in [`HTTP_HEALTHCHECK`](#http_healthcheck) if enabled. `$TARGET` gets\nreplaced inside the url by the configured [`TARGET`](#target).\n\n### `HTTP_HEALTHCHECK_TIMEOUT_MS`\n\nDefault: `2000`\n\nTimeout in milliseconds for http healthcheck. This is used as a timeout for connecting\nand receiving an answer. You may end up with twice the time spend.\n\n### `MODE`\n\nDefault: `tcp`\n\nSet to `udp` to proxy in UDP mode.\n\n### `MAX_CONNECTIONS`\n\nDefault: `100`\n\nLimits the maximum number of accepted connections at once per port.\n\n#### Setting \"unlimited\" connections\n\nFor each port and open connection a subprocess is spawned. Setting a number too high\nmight make your host system unresponsive and prevent you from logging in to it. So be\nvery careful with setting this setting to a large number.\n\nThe typical linux system can handle up to 32768 so if you need a lot more parallel open\nconnections make sure to also set the corresponding variables on your host system. See\nhttps://stackoverflow.com/questions/6294133/maximum-pid-in-linux for reference. And\ndivide this number by at least the number of ports you are running through\ndocker-whitelist.\n\n#### What happens when the limit is hit?\n\ndocker-whitelist basically starts `socat` so the behaviour is the same. In case no more\nsubprocesses can be forked:\n\n-   UDP mode: You won't see a difference on the connecting side. But no more packets are\n    forwarded for new connections until the number of connections for this port is\n    reduced.\n-   TCP mode: docker-whitelist no longer accepts the connection and your connection will\n    wait until the number of connections for this port is reduced. Your connection may\n    time out.\n\n### `NAMESERVERS`\n\nDefault: `208.67.222.222 8.8.8.8 208.67.220.220 8.8.4.4` to use OpenDNS and Google DNS\nresolution servers by default.\n\nOnly used when [pre-resolving](#pre-resolve) is enabled.\n\n### `PORT`\n\n**Default:** `80 443` Ports on which the proxy will listen and forward requests.\n\n-   For standard HTTP/HTTPS services, you **do not** need to change anything (the\n    default covers both port 80 and 443).\n-   If you only need to proxy HTTPS (or your service listens on a different port, or you\n    want to restrict the proxy to TLS only), specify:\n    ```yaml\n    environment:\n        PORT: \"443\"\n    ```\n\n### `PRE_RESOLVE`\n\nDefault: `0`\n\nSet to `1` to force using the specified [nameservers](#nameservers) to resolve the\n[target](#target) before proxying.\n\nThis is especially useful when using a network alias to whitelist an external API.\n\n### `SMTP_HEALTHCHECK`\n\nDefault: `0`\n\nSet to `1` to enable healthcheck with pycurl smtp requests. This is useful if the target\nuses a deployment where the ip of the service gets changed frequently (e.g.\n`smtp.eu.sparkpostmail.com`) and you are using [`PRE_RESOLVE`](#pre_resolve)\n\n#### Automatically restarting unhealthy proxies\n\nsee [HTTP_HEALTHCHECK](#http_healthcheck)\n\n### `SMTP_HEALTHCHECK_URL`\n\nDefault: `smtp://$TARGET/`\n\nUrl to use in [`SMTP_HEALTHCHECK`](#smtp_healthcheck) if enabled. `$TARGET` gets\nreplaced inside the url by the configured [`TARGET`](#target).\n\n### `SMTP_HEALTHCHECK_COMMAND`\n\nDefault: `HELP`\n\nEnables changing the healthcheck command for servers that do not support `HELP` (e.g.\nfor [MailHog](https://github.com/mailhog/MailHog) you can use `QUIT`)\n\n### `SMTP_HEALTHCHECK_TIMEOUT_MS`\n\nDefault: `2000`\n\nTimeout in milliseconds for smtp healthcheck. This is used as a timeout for connecting\nand receiving an answer. You may end up with twice the time spend.\n\n### `UDP_ANSWERS`\n\nDefault: `1`\n\n`1` means the process will wait for an answer from the server before the forked child\nprocess terminates (until this happens the connection counts towards the connection\nlimit). Set to `0` if no answers are expected from the server, this prevents\nsubprocesses waiting for an answer indefinitely.\n\nSetting to `0` is recommended if you are using this to connect to a syslog server like\ngraylog.\n\n### `VERBOSE`\n\nDefault: `0`\n\nSet to `1` to log all connections.\n\n## Example\n\nSo say you have a production app called `coolapp` that sends and reads emails, and uses\nGoogle Font APIs to render some PDF reports.\n\nIt is defined in a `docker-compose.yaml` file like this:\n\n```yaml\n# Production deployment\nversion: \"2.0\"\nservices:\n    app:\n        image: Tecnativa/coolapp\n        ports:\n            - \"80:80\"\n        environment:\n            DB_HOST: db\n        depends_on:\n            - db\n\n    db:\n        image: postgres:alpine\n        volumes:\n            - dbvol:/var/lib/postgresql/data:z\n\nvolumes:\n    dbvol:\n```\n\nNow you want to set up a staging environment for your QA team, which includes a fresh\ncopy of the production database. To avoid the app to send or read emails, you put all\ninto a safe internal network:\n\n```yaml\n# Staging deployment\nversion: \"2.0\"\nservices:\n    proxy:\n        image: traefik\n        networks:\n            default:\n            public:\n        ports:\n            - \"8080:8080\"\n        volumes:\n            # Here you redirect incoming connections to the app container\n            - /etc/traefik/traefik.toml\n\n    app:\n        image: Tecnativa/coolapp\n        environment:\n            DB_HOST: db\n        depends_on:\n            - db\n\n    db:\n        image: postgres:alpine\n\nnetworks:\n    default:\n        internal: true\n    public:\n```\n\nNow, it turns out your QA detects font problems. Logic! `app` cannot contact\n`fonts.google.com`. Yikes! What to do? 🤷\n\n`tecnativa/whitelist` to the rescue!! 💪🤠\n\n```yaml\n# Staging deployment\nversion: \"2.0\"\nservices:\n    fonts_googleapis_proxy:\n        image: tecnativa/whitelist\n        environment:\n            TARGET: fonts.googleapis.com\n            PRE_RESOLVE: 1 # Otherwise it would resolve to localhost\n        networks:\n            # Containers in default restricted network will ask here for fonts\n            default:\n                aliases:\n                    - fonts.googleapis.com\n            # We need public access to \"open the door\"\n            public:\n\n    fonts_gstatic_proxy:\n        image: tecnativa/whitelist\n        networks:\n            default:\n                aliases:\n                    - fonts.gstatic.com\n            public:\n        environment:\n            TARGET: fonts.gstatic.com\n            PRE_RESOLVE: 1\n\n    proxy:\n        image: traefik\n        networks:\n            default:\n            public:\n        ports:\n            - \"8080:8080\"\n        volumes:\n            # Here you redirect incoming connections to the app container\n            - /etc/traefik/traefik.toml\n\n    app:\n        image: Tecnativa/coolapp\n        environment:\n            DB_HOST: db\n        depends_on:\n            - db\n\n    db:\n        image: postgres:alpine\n\nnetworks:\n    default:\n        internal: true\n    public:\n```\n\nAnd voilà! `app` has fonts, but nothing more. ✋👮\n\n## Development\n\nAll the dependencies you need to develop this project (apart from Docker itself) are\nmanaged with [poetry](https://python-poetry.org/).\n\nTo set up your development environment, run:\n\n```bash\npip install pipx  # If you don't have pipx installed\npipx install poetry  # Install poetry itself\npoetry install  # Install the python dependencies and setup the development environment\n```\n\n### Testing\n\nTo run the tests locally, add `--prebuild` to autobuild the image before testing:\n\n```sh\npoetry run pytest --prebuild\n```\n\nBy default, the image that the tests use (and optionally prebuild) is named\n`test:docker-whitelist`. If you prefer, you can build it separately before testing, and\nremove the `--prebuild` flag, to run the tests with that image you built:\n\n```sh\ndocker image build -t test:docker-whitelist .\npoetry run pytest\n```\n\nIf you want to use a different image, pass the `--image` command line argument with the\nname you want:\n\n```sh\n# To build it automatically\npoetry run pytest --prebuild --image my_custom_image\n\n# To prebuild it separately\ndocker image build -t my_custom_image .\npoetry run pytest --image my_custom_image\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftecnativa%2Fdocker-whitelist","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftecnativa%2Fdocker-whitelist","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftecnativa%2Fdocker-whitelist/lists"}