保护在MacOS上的Docker中在0.0.0.0上本地运行的Flask / Celery应用程序的本地主机端口

时间:2020-09-02 15:48:05

标签: macos docker security flask docker-compose

我的应用程序具有Flask后端和Angular / Electron前端。该应用程序可在Mac Catalina上本地运行。 Flask,Celery和Redis位于单独的Docker容器中,而前端位于Docker外部。 Flask容器正在端口0.0.0.0:5078上侦听。我已将CORS策略设置为仅允许来自前端的“ 127.0.0.1:4200”中的消息。无需互联网连接。后端容器将通过模拟终端命令由前端启动。我将在非技术用户的Catalina MacBooks上远程安装该应用程序。

问题:根据Docker might be exposing ports to the worldBeware of exposing ports in DockerDocker not blocked by macOS firewall的说法,这种使用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: {}

尝试过: 我发现基于Docker的解决方案使用Linux iptables,例如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。和他们在一起,我必须以root身份运行。我已经尝试过特权模式和app_cap,但是由于我是Docker的新手,所以我没有这个功能。

我还研究了在Mac的PF防火墙中定义一个规则,以阻止与该端口的外部连接。但是,这对于要使用我的应用程序的人来说并不理想。类似的情况是安装付费的“ Little Snitch”应用。

在走这条路线之前,可能有基于代码或基于Docker的解决方案吗? (或者也许有启动后端的适当命令?)

1 个答案:

答案 0 :(得分:0)

一个有效的解决方案基于David Maze和Matt的评论以及此question。这些是步骤:

  1. 打开 Docker for Mac 首选项 Docker Engine 。将"ip": "127.0.0.1"添加到json配置文件中。
  2. docker-compose 中,将ports服务的 "127.0.0.1:5078:5078"设置为web
  3. 像以前一样保留Dockerfile和python代码:即flask主机仍为0.0.0.0

当我检查时,来自Electron的localhost 4201的消息通过了。另外,运行 netstat -anvp tcp | awk 'NR<3 || /LISTEN/显示不安全的端口0.0.0.0.5078不再暴露于外部。 `