我的应用程序有一个 Flask 后端和一个 Angular/Electron 前端。该应用程序在 Mac Catalina 上本地运行。 Flask、Celery 和 Redis 位于单独的 docker 容器中,而前端位于 Docker 外部。 Flask 容器正在侦听端口 0.0.0.0:5078。我已将 CORS 策略设置为仅允许前端发送来自“127.0.0.1:4200”的消息。无需互联网连接。后端容器将由前端通过模拟终端命令来启动。我将在非技术用户的 Catalina MacBook 上远程安装该应用程序。
问题:根据Docker 可能会将端口暴露给世界 https://www.jeffgeerling.com/blog/2020/be-careful-docker-might-be-exposing-ports-world, 谨防 Docker 中暴露端口 https://www.tripwire.com/state-of-security/devops/psa-beware-exposing-ports-docker/ and Docker 未被 macOS 防火墙阻止 https://github.com/docker/for-mac/issues/729,这种使用 0.0.0.0:5078 是一种安全威胁。如何解决此威胁,例如通过阻止到此端口的任何外部连接?
这是一些 python 3.8 代码
# imports: waitress, flask_cors, blueprint
cors = CORS(blueprint, resources={r"/*": {"origins":["http://127.0.0.1:4200"]}})
if __name__ == "__main__":
serve(flask_app, host= '0.0.0.0', port=5078, threads=8)
这是 Dockerfile:
FROM python:3.8.3-slim-buster
WORKDIR /app
COPY requirements.txt requirements.txt
ENV BUILD_DEPS="build-essential" \
APP_DEPS="curl libpq-dev"
RUN apt-get update \
&& apt-get install -y ${BUILD_DEPS} ${APP_DEPS} --no-install-recommends \
&& pip install --default-timeout=10000 -r requirements.txt
ARG FLASK_ENV="development"
ENV FLASK_ENV="${FLASK_ENV}" \
FLASK_APP="back5x.api.app" \
PYTHONUNBUFFERED="true"\
FLASK_DEBUG=1
COPY . .
RUN ["chmod", "+x", "/app/docker-entrypoint.sh"]
ENTRYPOINT ["/app/docker-entrypoint.sh"]
EXPOSE 5078
CMD ["python", "main.py"]
和 docker-compose:
version: "3.8"
services:
redis:
# ...
web:
build:
context: "."
args:
- "FLASK_ENV=development"
depends_on:
- "redis"
- "worker"
env_file:
- ".env"
environment:
FLASK_DEBUG: 1
FLASK_APP: back5x.api.app.py
healthcheck:
test: "${DOCKER_HEALTHCHECK_TEST:-curl localhost:5078/healthy}"
...
ports:
- "5078:5078"
restart: "unless-stopped"
volumes:
- ".:/app"
worker: #celery worker
...
volumes:
redis: {}
Tried:我发现的基于 Docker 的解决方案使用 Linux iptables,例如禁止从 Docker for Mac 上的 Docker 容器出站 https://stackoverflow.com/questions/49419092/disallow-egress-from-docker-containers-on-docker-for-mac以及上面的参考资料。所以我将这些添加到 Dockerfile 中:
RUN apt-get install -y iptables --no-install-recommends #after pip install
RUN iptables -N DOCKER-USER #after COPY . .
RUN iptables -I FORWARD -j DOCKER-USER
RUN iptables -A DOCKER-USER -j RETURN
RUN iptables -I DOCKER-USER -i eth0 ! -s 0.0.0.0 -j DROP
没有中间三行,我得到了无法找到 DOCKER-USER 的错误;和他们在一起,我必须以根身份运行。我尝试过特权模式app_cap
,但由于我是 Docker 新手,所以我还没有让它工作。
我还研究了在 Mac 的 PF 防火墙中定义规则来阻止到相关端口的外部连接。但是,这对于将使用我的应用程序的人来说并不理想。安装付费的“Little Snitch”应用程序也有类似的情况。
在走这条路之前,是否有基于代码或基于 Docker 的解决方案? (或者也许有一个适当的命令来启动后端?)