7

编辑:Tarun 的回答完全符合我的要求。Eugen的回答也是一个很好的解决方案。我最终接受了 Tarun 的答案是正确的,但使用了 Eugen 的答案。如果您有类似的问题并且担心其他容器访问 nginx 状态服务器,请使用 Tarun 的答案。如果您宁愿坚持使用 Docker 的正常主机名方案,请使用 Eugen 的。

+++ 原始问题 +++

我有一个使用 docker-compose 构建的应用程序。我正在尝试通过 DataDog 集成监控。我正在使用 DataDog 的代理容器,到目前为止一切正常。我正在尝试通过调整本教程来启动和运行 nginx 监控。

我的应用程序在 docker-compose 文件中定义,如下所示:

version: '2'
services:
  flask:
    restart: always
    image: me/flask-app
    command: /home/app/flask/start_app.sh
    expose:
      - "8080"

  nginx:
    restart: always
    build: ./nginx
    command: /runtime/start_nginx.sh
    ports:
      - "80:80"
      - "443:443"
    expose:
      - "81"
    volumes:
      - app-static:/app-static:ro
    links:
      - flask:flask

  datadog-agent:
    image: me/datadog-agent
    env_file: ./datadog-agent/dev.env
    links:
        - flask
        - nginx
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /proc/mounts:/host/proc/mounts:ro
      - /sys/fs/cgroup:/host/sys/fs/cgroup:ro

根据教程,我向 nginx 添加了一个服务器块,如下所示:

server {
  listen 81;

  location /nginx_status {
    stub_status on;
    access_log off;
    allow 127.0.0.1;
    deny all;
  }
}

使用此配置,我可以从 nginx 容器中检查 nginx 状态。到目前为止,一切都很好。现在我想更改位置块中的“允许”指令以仅允许访问 datadog-agent 服务。但是,我不知道 datadog-agent 的 IP。在配置对 Flask uwsgi 服务器的访问时,我可以使用如下指令:

location / {
    uwsgi_pass: flask:8080;
}

但这似乎不适用于允许指令;如果我尝试:

location /nginx_status {
    ...
    allow datadog-agent;
    ...
}

我收到以下错误:

nginx: [emerg] invalid parameter "datadog-agent" in /etc/nginx/sites-enabled/nginx-status:8

如何安全地将 nginx 状态暴露给我的监控容器?

4

3 回答 3

8

换个思路:)

另外在端口 10080 上绑定一个 nginx-server (vhost) - 该服务器确实提供了状态位置和您需要的内容。

80/443 上的服务器也在那里,并且只有一个绑定/暴露给主机(暴露给外部世界)。

由于 datadog 是你的 docker-network / service 网络的一部分,它仍然可以访问内部网络中的 10080,但不能访问外部网络中的其他人。

防弹,简单 - 没有附加条件。

于 2017-07-27T19:20:09.853 回答
5

由于我们正在运行服务docker-compose并且我们的问题是我们不知道代理的 IP。所以简单的解决方案是在开始之前知道IP。这意味着为我们的代理分配一个特定的 IP

docker-compose这是执行此操作的更新

version: '2'
services:
  flask:
    restart: always
    image: me/flask-app
    command: /home/app/flask/start_app.sh
    expose:
      - "8080"

  nginx:
    restart: always
    build: ./nginx
    command: /runtime/start_nginx.sh
    ports:
      - "80:80"
      - "443:443"
    expose:
      - "81"
    volumes:
      - app-static:/app-static:ro
    links:
      - flask:flask
    networks:
      agent:
        ipv4_address: 172.25.0.101
      default:

  datadog-agent:
    image: me/datadog-agent
    env_file: ./datadog-agent/dev.env
    links:
        - flask
        - nginx
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /proc/mounts:/host/proc/mounts:ro
      - /sys/fs/cgroup:/host/sys/fs/cgroup:ro
    networks:
      agent:
        ipv4_address: 172.25.0.100
networks:
  agent:
    driver: bridge
    ipam:
      config:
      - subnet: 172.25.0.0/24

现在你可以做两件事

server {
  listen 172.25.0.101:81;

  location /nginx_status {
    stub_status on;
    access_log off;
    allow 127.0.0.1;
    allow 172.25.0.100;
    deny all;
  }
}

您只能监听172.25.0.101在代理网络上运行的只能访问的容器。您也可以添加allow 172.25.0.100只允许代理容器能够访问它。

于 2017-07-27T19:38:08.307 回答
4

有两种(更简单的)方法可以解决这个问题。

第一个是docker-compose,但由于我已经有一个运行了 2 年且不使用 docker-compose 的设置,所以我选择了第二种方式。

第二种方式是Allow具有一系列 IP 的指令。

例如:

    location /stub_status {
        stub_status;

        allow 172.18.0.0/16;   # This is my local docker IP range
        allow 192.168.0.0/16;  $ This is my production server IP range
        deny all;              # deny all other hosts   
 }

我不是安全专家,但大多数192.168.*IP 范围是针对本地网络的,但不确定172.18.*范围。

要了解有关此 IP 范围和 CIDR 内容的更多信息,请参阅以下链接 http://nginx.org/en/docs/http/ngx_http_access_module.html

https://www.ripe.net/about-us/press-centre/understanding-ip-addressing

于 2020-04-17T17:27:04.977 回答