「譯」5 種方法構建安全的 Django Admin

z正小歪發表於2017-06-17

原文地址

擁有越大許可權,往往也就責任也越大。Django Admin 在擁有修改許可權的同時應該要更加註意安全。

本文提供了 5 種方法來保護 Django Admin 避免來自認為的錯誤或者攻擊者的攻擊。

「譯」5 種方法構建安全的 Django Admin

改變 URL

每種框架都有自己的特殊標識,Django 也不例外。經驗豐富的開發者、黑客、使用者都可以通過檢視 Cookie 和 Auth URL 來識別 Django Admin 的站點。

一旦網站被識別出是 Django 構建的,攻擊者很有可能嘗試從 /admin 登入。

為了增加獲取訪問許可權的難度,推薦把 URL 改成更難猜到的地址。

在 url.py 中修改 admin 的 URL 地址。

urlpatterns += i18n_patterns(
    url(r’^super-secret/’, admin.site.urls, name=’admin’),
)複製程式碼

super-secert 修改成你和你團隊可以記住的地址。這就完成了第一步,雖然不是唯一的防禦措施,但是確實一個好的開始。

從視覺上區分環境

使用者和管理員不可避免的會犯錯誤。當有多種環境時候可以避免管理員在正式的環境中執行破壞性的操作,你可以有 development、QA、staging、production 等多種不同的環境。

為了減少發生錯誤的機會,可以在 admin 中清楚的顯示不同的環境。

「譯」5 種方法構建安全的 Django Admin

首先你需要知道當前的環境是什麼。可以在部署期間使用一個名為 ENVIRONMENT_NAME 的環境變數。再新增一個 ENVIRONMENT_COLOR 的環境變數來區分顏色。

將以上兩個環境變數新增到 admin 的每個頁面中,覆蓋原先的基本模板。

# app/templates/admin/base_site.html

{% extends "admin/base_site.html" %}
{% block extrastyle %}
<style type="text/css">
    body:before {
        display: block;
        line-height: 35px;
        text-align: center;
        font-weight: bold;
        text-transform: uppercase;
        color: white;
        content: "{{ ENVIRONMENT_NAME }}";
        background-color: {{ ENVIRONMENT_COLOR }};
    }
</style>
{% endblock %}複製程式碼

settings.py 中獲取 ENVIRONMENT 變數,在模板的上下文處理中使用它們。

# app/context_processors.py
from django.conf import settings
def from_settings(request):
    return {
        'ENVIRONMENT_NAME': settings.ENVIRONMENT_NAME,
        'ENVIRONMENT_COLOR': settings.ENVIRONMENT_COLOR,
    }複製程式碼

settings.py 中註冊上下文處理器。

TEMPLATES = [{
    …
    'OPTIONS': {
        'context_processors': [
            …
            'app.context_processors.from_settings',
        ],
    …
    },
}]複製程式碼

現在開啟 Django admin 時,應該可以看到頂部的指示器。

命名 admin 站點

如果擁有多個 Django 服務,admin 看起來全部是一樣的,這很容易導致困惑。為了區分不同的 admin 可以修改標題:

# urls.py

from django.contrib import admin
admin.site.site_header = ‘Awesome Inc. Administration’
admin.site.site_title = ‘Awesome Inc. Administration’複製程式碼

你會看到如下內容:

「譯」5 種方法構建安全的 Django Admin

更多的配置可以在 文件 中查詢。

從主站從分離 Django Admin

使用相同的程式碼,可以部署 Django 應用程式的兩個例項,一個僅用於 admin,一個僅適用於其餘的應用程式。

這個是有爭議的,不像提示那樣容易。實現往往取決於配置(例如,使用 gunicorn 或者 uwsgi),所以不做詳細的介紹。

以下可能是想把 Django admin 分離出來的原因:

  • 在 VPN(virtual private network)中部署 Django admin —— 如果 admin 僅在內部使用,同時擁有 VPN,這會是一種很好的做法。
  • 從主站中刪除不必要的元件 —— 例如,在 Django admin 中使用了訊息框架,但是在主站中沒有使用。你可刪除這個中介軟體。另一個認證的例子是,如果主站使用的基於 token 的認證 API 後端,則可以刪除大量的模板配置,session 的 middleware 等,也可以刪除從請求到響應中不必要的部分。
  • 更強大的身份認證 —— 如果要加強 Django admin 安全性,可能會需要新增不同的身份認證機制。在不同的例項下使用不用配置會更加容易。

把 admin 從主站從分離出來,不干擾內部應用程式。把 admin 摻雜在其中只會是的部署更加複雜,對加強安全性沒有好處。

新增雙重方式認證(2FA)

雙重方式認證現在非常受歡迎,很多網站開始使用這種選項。2FA 基於兩種方式認證:

  • 你知道什麼 —— 通常是一個密碼。
  • 你有什麼 —— 通常是移動應用程式每 30 秒生成一個隨機數(如 Google 的 Authenticator)。

第一次註冊時候通常會要求使用身份認證應用程式掃描某種條碼,完成註冊後會生成一次性的程式碼。

通常不推薦使用第三方包,但是在幾個月前開始使用 django-otp 在 admin 中實現了 2FA。它在 Bitbucket 上託管,所以你可能錯過了。

我們可以很方便的使用:

pip install django-otp
pip install qrcode複製程式碼

將 django-otp 新增到已安裝的應用程式和中介軟體中:

# settings.py
INSTALLED_APPS = (
   ...
   ‘django_otp’,
   ‘django_otp.plugins.otp_totp’,
   ...
)
...
MIDDLEWARE = (
   ...
   ‘django.contrib.auth.middleware.AuthenticationMiddleware’,
   ‘django_otp.middleware.OTPMiddleware’,
   ...
)複製程式碼

命名發行人 - 這是使用者在認證時候看到的名稱,可以通過這個區分。

# settings.py

OTP_TOTP_ISSUER = ‘Awesome Inc.’複製程式碼

將 2FA 身份驗證新增到管理站點:

# urls.py

from django_otp.admin import OTPAdminSite
admin.site.__class__ = OTPAdminSite複製程式碼

現在你有如下所示安全的管理頁面:

「譯」5 種方法構建安全的 Django Admin

需要新增新使用者時,從 Django admin 從建立一個「TOTP 裝置」。點選完成 QR 連結後,將會看到如下螢幕:

「譯」5 種方法構建安全的 Django Admin

可以使用使用者的個人認證裝置掃描二維碼,每個 30 秒回生成一個新的程式碼。

最後的話

構建一個安全的 Django admin 只需要多多注意,文中的一些提示很容易實現,但是還有很多需要去做的。

相關文章