49

我希望使用 Flower ( https://github.com/mher/flower ) 来监控我的 Celery 任务,而不是他们的文档 ( http://docs.celeryproject.org/en/latest中推荐的 django-admin ) /userguide/monitoring.html#flower-real-time-celery-web-monitor)。但是,因为我是新手,所以我对 Flower 的页面仅基于 HTTP 而不是 HTTPS 的方式有点困惑。如何为我的 Celery 任务启用安全性,以使任何老用户都不能只访问不需要登录的网站http://flowerserver.com:5555并进行更改?

我已经考虑过 Celery自己的文档,但不幸的是,他们没有提到如何保护 Flower 的 api 或 web ui。它说:[Need more text here]

谢谢!

更新:我的问题部分与此处重复:如何将身份验证和端点添加到 Django Celery Flower Monitoring?

但是,我在这里通过询问如何使用包含 nginx、gunicorn 和 celery 的环境运行它来澄清他的问题,这些环境都在同一台远程机器上。我也想知道如何设置 Flower 的外部可访问 url,但如果可能的话,我更喜欢 https 而不是 http(或某种保护 webui 并远程访问它的方式)。我还需要知道让Flower运行对于任何可能访问Flower的内部API的人来说是否是一个相当大的安全风险,以及保护它的最佳方法是什么,或者它是否应该完全禁用并仅在as-需要的依据。

4

7 回答 7

52

您可以使用 --auth 标志运行花,它将使用特定的谷歌电子邮件进行身份验证:

celery flower --auth=your.email@gmail.com

编辑 1

新版本的 Flower 需要更多标志和使用Google Developer Console注册的 OAuth2 客户端:

celery flower \
    --auth=your.email@gmail.com \
    --oauth2_key="client_id" \
    --oauth2_secret="client_secret" \
    --oauth2_redirect_uri="http://example.com:5555/login"

oauth2_redirect_uri必须是实际的花登录 url,并且还必须添加到 Google 开发控制台中的授权重定向 url。

不幸的是,此功能在当前稳定版本中无法正常工作0.7.2,但现在已0.8.0-dev通过此提交在开发版本中修复。

编辑 2

您可以使用基本身份验证配置 Flower :

celery flower --basic_auth=user1:password1,user2:password2

然后为除 localhost 之外的所有端口阻止 5555 端口,并为nginx或 apache 配置反向代理:

ProxyRequests off
ProxyPreserveHost On
ProxyPass / http://localhost:5555

然后确保代理模式已打开:

sudo a2enmod proxy
sudo a2enmod proxy_http

如果您无法在单独的子域上设置它,例如:(flower.example.com上面的配置),您可以将其设置为example.com/flower

运行花url_prefix

celery flower --url_prefix=flower --basic_auth=user1:password1,user2:password2

在 Apache 配置中:

ProxyPass /flower http://localhost:5555

当然,确保配置了SSL,否则没有意义:)

于 2014-06-11T05:18:08.383 回答
14

我已经在 Django 端https://pypi.org/project/django-revproxy/上使用代理解决了这个问题。所以Flower隐藏在Django auth后面,它比basic auth更灵活。你不需要在 NGINX 中重写规则。

花 0.9.5 及更高版本

URL 前缀必须移动到代理路径:https ://github.com/mher/flower/pull/766

网址.py

urlpatterns = [
    FlowerProxyView.as_url(),
    ...
]

视图.py

class FlowerProxyView(UserPassesTestMixin, ProxyView):
    # `flower` is Docker container, you can use `localhost` instead
    upstream = 'http://{}:{}'.format('flower', 5555)
    url_prefix = 'flower'
    rewrite = (
        (r'^/{}$'.format(url_prefix), r'/{}/'.format(url_prefix)),
     )

    def test_func(self):
        return self.request.user.is_superuser

    @classmethod
    def as_url(cls):
        return re_path(r'^(?P<path>{}.*)$'.format(cls.url_prefix), cls.as_view())

花 0.9.4 及更低版本

网址.py

urlpatterns = [
    re_path(r'^flower/?(?P<path>.*)$', FlowerProxyView.as_view()),
    ...
]

视图.py

from django.contrib.auth.mixins import UserPassesTestMixin
from revproxy.views import ProxyView


class FlowerProxyView(UserPassesTestMixin, ProxyView):
    # `flower` is Docker container, you can use `localhost` instead
    upstream = 'http://flower:5555'

    def test_func(self):
        return self.request.user.is_superuser
于 2020-05-25T06:37:54.693 回答
11

我想在我的网络服务器的子目录上放花,所以我的 nginx 反向代理配置如下所示:

location /flower/ {
    proxy_pass http://localhost:5555/;
    proxy_redirect off;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Protocol $scheme;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_http_version 1.1;

    auth_basic  "Restricted";
    auth_basic_user_file  /etc/nginx/.htpasswd;
}

现在我可以通过 www.example.com/flower 访问花(受密码保护)

其中大部分来自关于配置 nginx 反向代理的 Flower 文档页面:

http://flower.readthedocs.org/en/latest/reverse-proxy.html

于 2014-11-10T13:52:31.910 回答
3

我使用代理视图遵循@petr-přikryl 的方法。但是我无法通过它来验证身份验证(我认为test_func从来没有被调用过)。相反,我选择将其嵌入到 Django Admin 视图中,并使用AdminSite.admin_view()(如此处所述)使用 Django Admin 身份验证来包装视图。

具体来说,我做了以下更改:

# Pipfile
[packages]
...
django-revproxy="*"
# admin.py
class MyAdminSite(admin.AdminSite):
    # ...
    def get_urls(self):
        from django.urls import re_path

        # Because this is hosted in the root `urls.py` under `/admin` this 
        # makes the total prefix /admin/flower
        urls = super().get_urls()
        urls += [
            re_path(
                r"^(?P<path>flower.*)$",
                self.admin_view(FlowerProxyView.as_view()),
            )
        ]
        return urls
# views.py
from __future__ import annotations

from django.urls import re_path

from revproxy.views import ProxyView


class FlowerProxyView(ProxyView):
    # Need `/admin/` here because the embedded view in the admin app drops the
    # `/admin` prefix before sending the URL to the ProxyView
    upstream = "http://{}:{}/admin/".format("localhost", 5555)

最后,我们需要确保--url_prefix在运行 Flower 时设置了它,所以我将它设置为在我们的生产和开发环境中像这样运行:

celery flower --app=my_app.celery:app --url_prefix=admin/flower
于 2021-01-04T17:37:02.683 回答
1

是的,Flower 上没有身份验证,因为它只是在与经纪人交谈,但如果你通过 SSL 运行它,那么基本身份验证应该足够好了。

于 2013-11-28T01:11:54.787 回答
1

要卸载 django 应用程序,我建议您使用X-Accel-Redirect标头以便使用 nginx 代理 Flower 服务器。它如下:

  1. 用户请求花路(例如/task
  2. 像往常一样nginxproxy_pass对你的应用的请求
  3. 您的 django 应用程序选择接受或拒绝请求(例如基于身份验证)
  4. 如果您的应用程序接受请求,它会返回带有X-Accel-RedirectHTTP 标头的响应以及内部位置字符串,即用户无法直接访问的路径
  5. nginx 拦截响应而不是将其转发给用户,并将其用作新路径,这一次有可能访问内部位置,在我们的例子中是 Flower 服务器

如果请求被拒绝,请不要X-Accel-Redirect像您要实施的任何其他被拒绝请求一样使用和处理该案例。

nginx.conf:

upstream celery_server {
    server /var/run/celery/flower.sock;
}

upstream app_server {
    server /var/run/gunicorn/asgi.sock;
}

server {
    listen 80;

    location /protected/task {
        internal;  # returns 404 if accessed directly
        proxy_http_version 1.1;
        proxy_redirect off;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header Upgrade $http_upgrade;

        proxy_pass http://celery_server/task;
    }

    location / {
        proxy_http_version 1.1;
        proxy_redirect off;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host $server_name;

        proxy_pass http://app_server;
    }
}

视图.py:

from django.contrib.admin.views.decorators import staff_member_required
from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponse


class XAccelRedirectResponse(HttpResponse):
    def __init__(self, path, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self['X-Accel-Redirect'] = '/protected' + path
        del self['Content-Type']  # necessary


# I chose to only allow staff members, i.e. whose who can access the admin panel
@staff_member_required
@csrf_exempt
def task_app(request, path):
    query_str = request.META['QUERY_STRING']  # you must keep the query string
    return XAccelRedirectResponse(f'/task/{path}?{query_str}')

网址.py:

from django.urls import re_path
from app import views


urlpatterns = [
    re_path('task/(?P<path>.*)', views.task_app, name='task'),
]

url-prefix改变Flower的很重要:

celery flower --unix-socket="/var/run/celery/flower.sock" --url-prefix="task"
于 2021-09-27T14:44:26.307 回答
0

HTTP 和 HTTPS 将如何影响 Celery 的安全性?你指的是什么用户登录?

Flower 通过附加到工作人员来监控 Celery 队列。设置 Flower 时,您需要提供连接字符串 [broker]://[user_name]:[password]@[database_address]:[port]/[instance]。用户名和密码是登录您选择的数据库的凭据。

如果您指的是此登录名,那么简单地禁用/删除他们的登录名就足够了吗?

于 2013-10-30T18:38:55.687 回答