# Celery_Security ###### tags: `celery` `celery 5.2` `python` [官方連結_Security](https://docs.celeryq.dev/en/master/userguide/security.html) ## Security ### Introduction 雖然Celery在開創之初已經考慮到安全性,但它仍然應該被視為不安全的組件。 取決於你的[安全策略](https://en.wikipedia.org/wiki/Security_policy),你可以採取各種不同步驟來讓你的Celery安裝更加安全。 ### Areas of Concern #### Broker 保護Broker免受不需要的訪問是必要的,特別是如果公開可以訪問的Broker。預設情況下,Workers信任它們從Broker取得的資料是沒被篡改的。關於如何讓Broker連線更可靠的資訊可參考[Message Signing](https://docs.celeryq.dev/en/master/userguide/security.html#id2)。 第一線的防禦應該是在Broker前放一個防火牆,僅允許白名單機器訪問它。 請記住,防火牆配置錯誤以及暫時禁用防火牆在現實世界中是很常見的。可靠的安全性策略包含監控防火牆設備,以檢測它們是否已被禁用,無論是意外還是故意。 換句話說,也不應該盲目的信任防火牆(所以到底要我怎麼樣?)。 如果你的Broker支援細粒度訪問控制(fine-grained access control),像是RabbitMQ,那麼你應該考慮啟用它。參考範例http://www.rabbitmq.com/access-control.html 如果你的Broker backend支援,你可以使用[broker_use_ssl](https://docs.celeryq.dev/en/master/userguide/configuration.html#std-setting-broker_use_ssl)來啟用end-to-end SSL加密與認證。 #### Client 在Celery中,"client"指向Broker發送訊息的任何東西,像是應用任務的網頁服務。 如果可以從client發送任意訊息,那適當地保護Broker也不是那麼重要了。 (這邊官方預計再補更多說明) #### Worker 在Worker內執行任務的預設權限與Worker本身權限是相同的。這觀念可以套用到資源,像是記憶體、文件系統與設備。 這個規則的例外是,當使用基於multiprocessing的task pool(目前預設就是task pool)。這種情況下,任務將會因為`fork()`的調用而獲得所有的記憶體複本,並將有權限訪問由父任務(parenet tasks)於相同Worker child process中的寫入的記憶體內容。 可以透過啟動子程序(subprocess)(fork() + execve())中的每個任務來限制對其記憶體內容的訪問。 限制文件系統與設備訪問可以透過使用[chroot](https://en.wikipedia.org/wiki/Chroot),[jail](https://en.wikipedia.org/wiki/FreeBSD_jail),[sandboxing](https://en.wikipedia.org/wiki/Sandbox_(computer_security)),virtual machines,或像是透過平台或其它軟體啟用的其它機制來完成。 也注意到,Worker內執行的任何任務都有著與執行電腦相同的網路存取權限。如果Worker位於內網,那建議在防火牆outbound traffic(對外流量?)加入規則。 ### Serializers 從version 4.0開始的預設序列化是JSON,但是由於它只支援一組受限制的類型,因此你可能會考慮想用pickle來替代。 以pickle來序列化是方便的,它可以序列化幾乎所有Python的物件,甚至是一些工作函數,但基於相同的原因,pickle本質上是不安全的,所以不論是不受信任的用戶端或未經身份驗證的時候,都應該避免使用。 你可以通過在[accept_content](https://docs.celeryq.dev/en/master/userguide/configuration.html#std-setting-accept_content)設置中指定接受的內容類型的白名單來禁用不受信任的內容: *New in version 3.0.18.* :::info **Note:** 這個設置最早支援於3.0.18。如果你的執行版本是更早的,那設置會被忽略,因此確認你的執行版本是支援這設置的。 ::: ```python accept_content = ['json'] ``` 這接受序列化的名稱與內容類型的清單,因此你還可以為json指定內容類型: ```python accept_content = ['application/json'] ``` Celery還自帶一個特別的`auth serializer`(身份驗證序列化程式?),它可以驗證Celery的client與workers之間的通信,確保訊息來自可信任的來源。使用Public-key cryptography(公鑰加密技術),`auth serializer`可以驗證發送人員的真實性,要啟用這設置,請閱讀[Message Signing](http://docs.celeryproject.org/en/master/userguide/security.html#message-signinghttps://docs.celeryq.dev/en/master/userguide/security.html#message-signing)以取得更多資訊。 ### Message Signing Celery可以用套件[cryptograhpy](https://pypi.org/project/cryptography/)使用公鑰加密對訊息做簽章,client端發送的訊息使用私鑰,然後Worker用公鑰驗證。 最好的憑證應該是由正式的[憑證授權](https://en.wikipedia.org/wiki/Certificate_authority)單位來簽章,但它們也可以自簽章。 要啟用這個,你應該配置[task_serializer](https://docs.celeryq.dev/en/master/userguide/configuration.html#std-setting-task_serializer)設置來使用`auth serializer`。要強制Worker只能接收簽章訊息,你應該設置accept_content為['auth']。更進一步的事件協議簽章,將event_serializer設置為auth。還需要配置用於文件系統上的私鑰與憑證路徑,分別設置:[security_key](https://docs.celeryq.dev/en/master/userguide/security.html)、[security_certificate](https://docs.celeryq.dev/en/master/userguide/configuration.html#std-setting-security_certificate)、[security_cert_store](https://docs.celeryq.dev/en/master/userguide/configuration.html#std-setting-security_cert_store)。你可以用[security_digets](https://docs.celeryq.dev/en/master/userguide/configuration.html#std-setting-security_digest)來調整簽章演算法。如果使用加密的私鑰,那你可以用[security_key_password](https://docs.celeryq.dev/en/master/userguide/configuration.html#std-setting-security_key_password)來配置密碼。 上面配置好了以後,你還需要呼叫函數**celery.setup_security()**。注意到,這將禁用所有不安全的序列化程式,這樣Worker就不會接收到不受信任內容類型的訊息。 下面是一個使用`auth serializer`的配置範例,它的私鑰與憑證檔案位於`/etc/ssl` ```python 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() ``` :::info **Note:** 雖然不允許使用相對路徑,不過我們還是建議使用絕對路徑。 也注意到,`auth serializer`並不會對訊息的內容加密,如果需要,那你就要單獨的啟用它。 ::: ### Intrusion Detection 在保護系統對抗入侵者攻擊時,最重要的部分是能夠檢測系統是否已經遭到破壞。 #### Logs 日誌通常是尋找安全漏洞的第一個地方,但是,如果日誌是可以被篡改的話,那就沒有用了。 一個好的解決方案就是設置專用的日誌伺服器來集中日誌。應該禁止對日誌伺服器的存取。除了將所有的日誌集中在一個地方,如果配置正確,它可以讓入侵人員更難篡改你的日誌。 使用syslog應該是相對簡單的設置(參考[syslog-ng](https://en.wikipedia.org/wiki/Syslog-ng)與[rsyslog](http://www.rsyslog.com/))。Celery使用套件[logging](https://docs.python.org/dev/library/logging.html#module-logging),並且已經支援使用syslog。 一個瘋狂的技巧,就是使用UDP發送日誌並且切斷日誌記錄伺服器網路電纜的傳輸部分:-)。 #### Tripwire [Tripwire](http://tripwire.com/)(現在是商業性質)是一個資料完整性工具,有幾個開源實作,用於文件系統中保持文件的[密碼雜湊](http://terms.naer.edu.tw/detail/2354160/)(cryptographic hashes),因此當它們被改變的時候,系統管理員會收到警示通知。這樣的做法,當損失已經造成,系統已經被攻擊,你可以確切的知道那些文件被入侵者改變(password files、logs、back-doors、root-kits、…等等)。通常這是你偵測到入侵的唯一方法。 一些開源實作包含: * [OSSEC](http://www.ossec.net/) * [Samhain](http://la-samhna.de/samhain/index.html) * [Open Source Tripwire](https://sourceforge.net/projects/tripwire/) * [AIDE](http://aide.sourceforge.net/) 此外,[ZFS](https://en.wikipedia.org/wiki/ZFS)文件系統自帶內建完整性檢核可用。 ##### Footnotes https://blog.nelhage.com/2011/03/exploiting-pickle/ ## History 20190903_依據4.4版本說明翻譯 20220520_依據5.2版本說明翻譯
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up