简体   繁体   English

使用“allow”指令将 nginx 服务器位置的访问权限限制为特定的 Docker 容器

[英]Restrict access to nginx server location to a specific Docker container with “allow” directive

Edit: Tarun's answer does exactly what I asked for.编辑:塔伦的回答完全符合我的要求。 Eugen's answer is also a very good solution. Eugen 的回答也是一个很好的解决方案。 I ended up accepting Tarun's answer as correct, but using Eugen's.我最终接受了 Tarun 的回答是正确的,但使用了 Eugen 的回答。 If you have a similar issue and are worried about other containers accessing the nginx status server, use Tarun's answer.如果您有类似的问题并且担心其他容器访问 nginx 状态服务器,请使用 Tarun 的答案。 If you'd rather stick to Docker's normal hostname scheme, use Eugen's.如果您更愿意坚持使用 Docker 的正常主机名方案,请使用 Eugen 的。

+++ Original Question +++ +++ 原始问题 +++

I have an application that I build with docker-compose.我有一个使用 docker-compose 构建的应用程序。 I am trying to integrate monitoring through DataDog.我正在尝试通过 DataDog 集成监控。 I'm using DataDog's Agent container, and so far everything is working.我正在使用 DataDog 的代理容器,到目前为止一切正常。 I am trying to get nginx monitoring up and running by adapting this tutorial .我正在尝试通过调整本教程来启动和运行 nginx 监控。

My application is defined in a docker-compose file like this:我的应用程序在 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

Per the tutorial, I've added a server block to nginx that looks like this:根据教程,我向 nginx 添加了一个服务器块,如下所示:

server {
  listen 81;

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

With this configuration, I can check the nginx status from within the nginx container.使用此配置,我可以从 nginx 容器内检查 nginx 状态。 So far, so good.到目前为止,很好。 Now I would like to change the "allow" directive in the location block to allow access to the datadog-agent service only.现在我想更改位置块中的“允许”指令,以仅允许访问 datadog-agent 服务。 However, I don't know the IP of the datadog-agent.但是,我不知道 datadog-agent 的 IP。 When configuring access to the Flask uwsgi server, I was able to use directives like this:在配置对 Flask uwsgi 服务器的访问时,我能够使用这样的指令:

location / {
    uwsgi_pass: flask:8080;
}

But this doesn't seem to work for allow directives;但这似乎不适用于允许指令; if I try:如果我尝试:

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

I get the following error:我收到以下错误:

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

How can I safely expose the nginx status to my monitoring container?如何安全地将 nginx 状态暴露给我的监控容器?

Think differently :)换位思考:)

Do bind a nginx-server (vhost) on port 10080 in addition - that server does offer the status location and what you need.此外,请在端口 10080 上绑定 nginx-server (vhost) - 该服务器确实提供状态位置和您需要的内容。

Server on 80/443 is also there and ONLY that one is bound/exposed to host ( exposed to the outer world ). 80/443 上的服务器也在那里,并且只有一个绑定/暴露给主机(暴露给外部世界)。

Since datadog is part of your docker-network / service network, it can still access 10080 in the internal network, but nobody else from the outer network.由于 datadog 是你的 docker-network/service 网络的一部分,它仍然可以访问内部网络中的 10080,但无法访问外部网络中的其他人。

Bulletproof, easy - no strings attached.防弹、简单 - 没有附加条件。

Since we are running the service through docker-compose and our issue being we don't know the IP of the agent.由于我们通过docker-compose运行服务,我们的问题是我们不知道代理的 IP。 So the simple solution is to know the IP before starting.所以简单的解决方案是在开始之前知道IP。 And that means assigning our agent a specific IP这意味着为我们的代理分配一个特定的 IP

Here is a update docker-compose to do that这是一个更新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

Now you can do two possible things现在你可以做两件事

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;
  }
}

You can listen only on 172.25.0.101 which is accessible only container running on agent network.您只能侦听172.25.0.101 ,它只能在代理网络上运行的容器访问。 Also you can add allow 172.25.0.100 to only allow the agent container to be able to access this.您也可以添加allow 172.25.0.100以仅允许代理容器能够访问它。

There are two (easier) ways to go about it.有两种(更简单的)方法可以解决这个问题。

First one is docker-compose but since I already have a setup running since 2 years which doesn't use docker-compose, I went for the 2nd way.第一个是docker-compose但由于我已经有一个自 2 年以来没有使用 docker-compose 的设置运行,我选择了第二种方式。

Second way is Allow Directive with a range of IPs.第二种方法是Allow使用一系列 IP 的指令。

Eg:例如:

    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   
 }

I am not security expert, but mostly 192.168.* IP range is for local networks, not sure about 172.18.* range though.我不是安全专家,但主要是192.168.* IP 范围用于本地网络,但不确定172.18.*范围。

To get more idea about this IP range thing and CIDR stuff, refer below links http://nginx.org/en/docs/http/ngx_http_access_module.html要获得有关此 IP 范围和 CIDR 内容的更多信息,请参阅以下链接http://nginx.org/en/docs/http/ngx_http_access_module.html

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM