安全
Introduction:引言
尽管Celery在编写时考虑到了安全,但它应该被视为不安全的组件。
根据你的安全策略,这儿有一些步骤可以让Celery更加安全
Areas of Concern:关注区域
Broker
必须保护broker免受不必要的访问,尤其是在公网的时候。默认情况下,workers相信从broker传过来的数据是未经篡改的。查看Message Signing获取关于如何让连接更可信的信息
第一道防线应该是一个放置在broker前的只允许白名单访问的防火墙。
很普遍的现象是防火墙配置错误或者被关闭。使用可靠的安全策略包括监控防火墙设备来检测它们是否被禁用,无论是意外还是故意的。
另一方面,也不能盲目信任防火墙。
如果你使用的broker有更细粒度的访问控制,比如RabbitMQ,那么你应该启用它。查看示例:http://www.rabbitmq.com/access-control.html
如果你使用的后端支持,你还可以使用broker_use_ssl来开启SSL加密和身份验证。
Client
In Celery, “client” refers to anything that sends messages to the broker, for example web-servers that apply tasks.
Having the broker properly secured doesn’t matter if arbitrary messages can be sent through a client.
[Need more text here]
Worker
tasks在worker中运行的权限和worker自身权限是一样的。这适用于资源,例如:内存、文件系统和设备。
此规则的一个例外是使用基于多处理的任务池时,这是当前的默认设置。在这种情况下,该任务将可以访问作为fork()
调用的结果而复制的任何内存,并可以访问由同一个工作者子进程中的父任务写入的内存内容。
通过给每个任务启动一个子进程(fork() + execve()
),可以限制对内存内容的访问。
限制文件系统的访问可以通过使用chroot
, jail
, sandboxing
, virtual machines
或其他由平台提供的特性或者第三方软件
Serializers:序列化
从4.0开始默认的序列化使用的是JSON,不过由于其数据类型受限,你可能希望使用 pickle
替代。
pickle 非常好用,它几乎可以序列化一切Python对象,甚至是包含work的函数。由于这个特性,其从根本上不安全[*],因此应该避免不受信任或未经身份验证的客户端使用。
通过在accept_content设置中指定接受的内容类型的白名单,可以禁用不受信任的内容:
3.0.18新增特性:
Note:
3.0.18以下不支持
accept_content = ['json']
它接受序列化名称和content-type的列表,因此您还可以指定json为content type:
accept_content = ['application/json']
Celery 还带有一个特殊的 auth 序列化程序,用于验证 Celery 客户端和workers之间的通信,确保消息来自可信来源。 使用公钥加密,auth 序列化程序可以验证发件人的真实性,要启用的话,阅读Message Signing获取更多信息。
Message Signing:消息签名
Celery可以使用cryptography库用公钥来对消息进行签名,客户端使用私钥对发送的消息进行签名,然后worker使用公开证书对其进行验证。
有正式的证书颁发机构签发的证书最好,当然自签名的也是可以的。
若要启用此功能,您应该将task_serializer设置为使用 auth 序列化程式。强制workers只接受签名消息,您应该将accept_content设置为*[']auth'*。For additional signing of the event protocol, set event_serializer to auth。还需要配置用于在文件系统上查找私钥和证书的路径:security_key、security_certificate和security_cert_store.您可以使用security_digest调整签名算法。
对于调用celery.setup_security() 函数来说这些配置是必要的。请注意,这还会禁用所有不安全的序列化程序,以便worker不会接受具有不受信任内容类型的消息。
这是一个配置了 auth 序列化程序的示例,私钥和证书位于 /etc/ssl
app = Celery()
app.conf.update(
security_key='/etc/ssl/private/worker.key'
security_certificate='/etc/ssl/certs/worker.pem'
security_cert_store='/etc/ssl/certs/*.pem',
security_digest='sha256',
task_serializer='auth',
event_serializer='auth',
accept_content=['auth']
)
app.setup_security()
Note:
虽然不禁止使用相对路径,但建议对这些文件使用绝对路径。
还要注意,auth 序列化程序不会加密消息的内容,因此如果需要,必须单独启用它。
Intrusion Detection:入侵侦测
保护您的系统免受入侵者攻击时,最重要的部分是能够检测系统是否已被破坏。
Logs
日志通常是第一个用来确认是否遭受攻击的地方,不过一旦被篡改,也就没用了。
好的解决办法是使用专用的日志收集服务器集中收集日志。它们的访问应该是受限的。除了将所有日志放在一个位置之外,如果配置正确,它还可以使入侵者更难篡改您的日志。
使用syslog应该比较容易设置(查看syslog-ng 和 rsyslog)。Celery使用的是logging库,并且已经支持syslog。
对偏执狂的一个提示是使用UDP发送日志,并切断日志服务器的网络电缆的传输部分:-)
Tripwire
Tripwire是一个数据完整性工具(现在是商业化工具),通过几个开源项目实现,用来监控文件系统上的hashes值,以便于管理员可以及时受到警告当文件被改变时。通过这种方式,当系统被破坏之后你可以知道那些文件被更改了(密码文件, 日志, 后门, root-kits, 等等)。通常,这是您能够检测到入侵的唯一方法。
一些开源实现包括:
此外,ZFS文件系统内置了完整性校验。