如何使用Django開發OpenRASP報警接收Web應用

2021-03-02 FreeBuf
一、引言

百度的Open­RASP將Gartner在2014年提出的RASP(Run­time Ap­pli­ca­tion Self-Pro­tec­tion)安全防護技術進行了開源實現,使其迅速成為企業Web安全防護中的一個重要武器,有效增強防禦體系縱深和對漏洞防護的適應能力。OpenRASP相較與傳統WAF具有誤報率低、高性能等優點。Django是Python實現的Web開發框架,最初被設計用於具有快速開發需求的新聞類站點,目的是要實現簡單快捷的網站開發。

本文介紹了OpenRASP和Django的一些基本內容,在搭建好OpenRASP測試實驗環境的基礎上編寫官方測試用例的自動化漏洞驗證腳本,最後通過Django快速開發報警接收Web應用。

二、OpenRASP和Django概述1. RASP(Run­time Ap­pli­ca­tion Self-Pro­tec­tion)

企業部署的應用程式通常在一個複雜且分散的環境中,包括有網絡、作業系統和資料庫。這樣通常導致應用程式的安全體系結構碎片化,缺乏精確和可靠的安全路線圖。開發運行時應用程式自我保護(RASP)的概念主要是為了解決開發人員面對威脅時所採用的特殊方法。

開發人員常常傾向於採用靜態和傳統的AppSec方法,而不是解決應用程式的設計缺陷,這些方法在面對複雜的安全威脅時往往會失敗。這種完全不同的安全控制層常常成為應用程式、基礎設施和安全層的多個組件的瓶頸,但隨著RASP解決方案的出現,應用程式安全不再是對威脅的一種隨意反應。RASP是應用程式安全生態系統中的一項創新,通過提供對隱藏的漏洞的更多可見性來處理運行時對軟體應用層的攻擊。它本質上是與應用程式或其運行時環境集成的安全軟體,並不斷攔截對應用程式的調用,以檢查其安全性。RASP軟體不會等待威脅影響應用程式。相反,它會在進入應用程式的流量中主動搜索惡意軟體,防止欺詐性調用在應用程式內部執行。通過留在應用程式內,RASP解決方案中和已知的漏洞,並保護應用程式免受未知的0day攻擊,無需任何人工幹預。因此,RASP提供了一種與傳統安全方法(如web應用程式防火牆(WAF))在概念上不同的安全範式,後者通過阻止所有可疑流量來保護應用程式。

RASP已經發展成為一種成熟的應用程式內安全概念,它允許開發者以多種方式對威脅進行防禦。根據開發人員想要在應用程式或伺服器中實現RASP安全層的方式,有四種方法可供選擇:

(1). Servlet filters, SDKs and plugins

這種方法適用於監控和檢查到達應用程式代碼之前Apache Tomcat或其他Web伺服器傳入的HTTP請求和數據。

(2). Binary instrumentation

該方法適用於在應用程式中構建監視和控制元素,前者標識正在運行的應用程式中的安全事件,而後者記錄此類事件的日誌並阻止它們。

(3). JVM replacement

此方法採用RASP層替換標準庫(JAR或JVM(對於Java))來偵聽對支持庫的調用,並在調用被攔截時的應用規則。因此RASP對app代碼庫和系統調用路由框架有一個整體的了解,這使得RASP可以通過對應用調用的被動監控來了解機器行為和序列流。

(4). Virtualization

Virtualization,或者叫做containerized runtime protection,它創建一個應用程式副本,並通過使用規則來控制應用程式該如何被保護,同時控制應用程式在副本上的運行時行為。RASP監視和學習應用程式代碼路徑、邏輯構造、參數化和生成的輸出等,然後應用於應用程式請求。這種方法有助於區分清楚的請求和惡意請求,並允許採取適當的補救措施。

2. OpenRASP

OpenRASP是百度安全推出的一款免費、開源的應用運行時自我保護產品。

官網地址為:https://rasp.baidu.com

若要了解更多細節,請閱讀 謝么 - 百度安全的 OpenRASP 項目,究竟是什麼?以及 OpenRASP 最佳實踐

OpenRASP目前支持Java和PHP兩種類型的伺服器,其快速上手部署請參考官方文檔:https://rasp.baidu.com/doc/install/software.html

本文中,通過採用CentOS 8 + Tomcat在VM虛擬機中快速搭建好實驗環境,使用OpenRASP v1.3.5進行實驗。

3. Django

Django是一個由Python編寫的具有完整架站能力的開源Web框架。使用Django,只要很少的代碼,開發人員就可以輕鬆地完成一個正式網站所需要的大部分內容,並進一步開發出全功能的Web服務。Django本身基於MVC架構,即Model(模型)+View(視圖)+ Controller(控制器)設計模式,因此天然具有MVC的出色基因:開發快捷、部署方便、可重用性高、維護成本低等優點。除此之外,Django還具備自己的admin後臺,開發人員只需要通過簡單的幾行配置和代碼就可以實現一個完整的後臺數據管理控制平臺,是Django的亮點之一。但是Django由於Python性能的限制,無法作為大流量的伺服器使用。這裡我們只需要在內網中監控OpenRASP的報警,從業務場景上可以使用Django

三、OpenRASP示例的自動化攻擊腳本1. 搭建OpenRASP測試用例

在搭建好OpenRASP環境中,可以將官方給的測試用例部署在伺服器上,這裡筆者採用Java伺服器的測試用例:https://rasp.baidu.com/doc/install/testcase.html

重啟Tomcat伺服器後我們可以看到OpenRASP 官方測試用例集界面:

單擊進入每一個測試用例可以獲取到不同攻擊的完整URL:

2. 編寫自動化攻擊腳本

這裡我們使用Python來編寫自動化攻擊腳本,編寫該腳本的目的是方便後續開發報警接收應用時能夠更加高效率地去模擬攻擊並獲取報警信息。

首先,單擊每個非正常調用URL,異常調用會被OpenRASP攔截下來:

這樣我們可以將需要的攻擊URL(僅含參數)放入數組中:

class OpenRASPTest:definit(self, host):self.headers = {「User-Agent」: 「Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) 「「Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0」}self.host = host

self.AttackUrl =[『/vulns/001-dir-1.jsp?dirname=../../../../../../../../../../../../../../../var/log/『,『/vulns/002-file-read.jsp?file=../../../../../../../../../../../../../../../etc/passwd』,『/vulns/002-file-read.jsp?file=../../../conf/tomcat-users.xml』,『/vulns/004-command-2.jsp?cmd=ls+-la+/『,『/vulns/005-file-write.jsp?filename=reports/../123.jsp&filedata=some-webshell-data』,『/vulns/008-file-upload.jsp』,『/vulns/009-deserialize.jsp?id=whoami』,『/vulns/010-jstl-import.jsp?url=file:///etc/『,『/vulns/010-jstl-import.jsp?url=http://192.168.1.1『,『/vulns/011-ssrf-commons-httpclient.jsp?url=http://www.baidu.com『,『/vulns/011-ssrf-httpclient.jsp?url=http://127.0.0.1.xip.io『,『/vulns/011-ssrf-httpclient.jsp?url=http://uee.me/cFas3『,『/vulns/011-ssrf-urlconnection.jsp?url=http://127.0.0.1.xip.io『,『/vulns/011-ssrf-okhttp.jsp?url=http://127.0.0.1.xip.io『,『/vulns/011-ssrf-okhttp3.jsp?url=http://127.0.0.1.xip.io『,『/vulns/019-file-delete.jsp?filename=reports/../testfile.txt』,『/vulns/020-random-file.jsp?filename=reports/../123.jsp&filedata=some-webshell-data』,『/vulns/020-random-file.jsp?file=../../../../../../../../../../../../../../../etc/passwd』,『/vulns/021-nio-file.jsp?filename=reports/../123.jsp&filedata=some-webshell-data&mode=write』,『/vulns/021-nio-file.jsp?file=../../../../../../../../../../../../../../../etc/passwd&mode』『=read』,『/vulns/021-nio-file.jsp?filename=reports/../testfile.txt&mode=delete』,『/vulns/021-nio-file.jsp?filename=reports/../testfile.txt&dst=reports/../testfile.jsp&mode』『=link』,『/vulns/021-nio-file.jsp?dirname=../../../../../../../../../../../../../../../var/log/&mode』『=list』,『/vulns/021-nio-file.jsp?filename=reports/../rename.txt&dst=reports/../rename.jsp&mode=rename』]

其中,攻擊主機IP由對象創建者傳入。在攔截頁面中按下f12進行html頁面分析,找到400響應碼對應的標籤並複製該標籤的xpath。

這裡我們需要對比標籤內容判斷攻擊攔截情況,或者直接通過HTTP響應碼來判斷也行。接下來我們編寫兩個方法進行GET和POST請求:

def get_url(self, url):
req = urllib.request.Request(self.host + url, headers=self.headers)
html = urllib.request.urlopen(req).read().decode(『utf-8』)
content = etree.HTML(html)
print(self.load_page(content) +』 攻擊已被攔截』)

defpost_url(self, url):
files = {『file』: open(『1.jsp』, 『rb』)}
data = {}
res = requests.post(self.host + url, data=data, files=files)
reg = re.compile(r』400 - Request blocked by OpenRASP』)
resstr = reg.search(res.text)
print(resstr)

請求接收到的頁面可以傳給load_page方法,在該方法中使用上面複製的xpath獲取關鍵標籤中的內容。

def load_page(self, con):
xpath = 『/html/body/div[2]/div/div[2]/h2』
down = con.xpath(xpath)
try:
result = down[0].text
exceptIndexError:
result = 「ERROR」
print(「攻擊失敗」)
return result

最後,完整的代碼如下:

import urllib.request
from lxml import etree
import requests
import re
import datetime

class OpenRASPTest:
definit(self, host):
self.headers = {
「User-Agent」: 「Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) 「
「Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0」
}
self.host = host

攻擊Payload URL

self.AttackUrl =[『/vulns/001-dir-1.jsp?dirname=../../../../../../../../../../../../../../../var/log/『,
『/vulns/002-file-read.jsp?file=../../../../../../../../../../../../../../../etc/passwd』,
『/vulns/002-file-read.jsp?file=../../../conf/tomcat-users.xml』,
『/vulns/004-command-2.jsp?cmd=ls+-la+/『,
『/vulns/005-file-write.jsp?filename=reports/../123.jsp&filedata=some-webshell-data』,
『/vulns/008-file-upload.jsp』,
『/vulns/009-deserialize.jsp?id=whoami』,
『/vulns/010-jstl-import.jsp?url=file:///etc/『,
『/vulns/010-jstl-import.jsp?url=http://192.168.1.1『,
『/vulns/011-ssrf-commons-httpclient.jsp?url=http://www.baidu.com『,
『/vulns/011-ssrf-httpclient.jsp?url=http://127.0.0.1.xip.io『,
『/vulns/011-ssrf-httpclient.jsp?url=http://uee.me/cFas3『,
『/vulns/011-ssrf-urlconnection.jsp?url=http://127.0.0.1.xip.io『,
『/vulns/011-ssrf-okhttp.jsp?url=http://127.0.0.1.xip.io『,
『/vulns/011-ssrf-okhttp3.jsp?url=http://127.0.0.1.xip.io『,
『/vulns/019-file-delete.jsp?filename=reports/../testfile.txt』,
『/vulns/020-random-file.jsp?filename=reports/../123.jsp&filedata=some-webshell-data』,
『/vulns/020-random-file.jsp?file=../../../../../../../../../../../../../../../etc/passwd』,
『/vulns/021-nio-file.jsp?filename=reports/../123.jsp&filedata=some-webshell-data&mode=write』,
『/vulns/021-nio-file.jsp?file=../../../../../../../../../../../../../../../etc/passwd&mode』
『=read』,
『/vulns/021-nio-file.jsp?filename=reports/../testfile.txt&mode=delete』,
『/vulns/021-nio-file.jsp?filename=reports/../testfile.txt&dst=reports/../testfile.jsp&mode』
『=link』,
『/vulns/021-nio-file.jsp?dirname=../../../../../../../../../../../../../../../var/log/&mode』
『=list』,
『/vulns/021-nio-file.jsp?filename=reports/../rename.txt&dst=reports/../rename.jsp&mode=rename』]

defstart_attack(self):
print(「當前時間為 {0} 攻擊開始…」.format(datetime.datetime.now()))
print(「0x00. 完成File.listFiles 遍歷目錄攻擊,響應結果如下:」)
self.get_url(self.AttackUrl[0])
print(「0x01. 完成任意文件下載/讀取漏洞攻擊,讀取passwd文件,響應結果如下:」)
self.get_url(self.AttackUrl[1])
print(「0x02.完成任意文件下載/讀取漏洞攻擊,讀取tomcat-users文件,響應結果如下:」)
self.get_url(self.AttackUrl[2])
print(「0x03. 完成命令執行後門攻擊,響應結果如下:」)
self.get_url(self.AttackUrl[3])
print(「0x04. 完成任意文件寫入攻擊,響應結果如下:」)
self.get_url(self.AttackUrl[4])
print(「0x05. 完成任意文件上傳漏洞攻擊,採用commons.io 方式,響應結果如下:」)
self.post_url(self.AttackUrl[5])
print(「0x06. 完成使用 InvokerTransformer 反序列化並執行命令攻擊,響應結果如下:」)
self.get_url(self.AttackUrl[6])
print(「0x07. 完成JSTL import 任意文件包含/SSRF攻擊,file 協議讀取目錄,響應結果如下:」)
self.get_url(self.AttackUrl[7])
print(「0x08. 完成JSTL import 任意文件包含/SSRF攻擊,http 協議 SSRF,響應結果如下:」)
self.get_url(self.AttackUrl[8])
print(「0x09. 完成SSRF攻擊,通過commons.httpclient 方式,響應結果如下:」)
self.post_url(self.AttackUrl[9])
print(「0x0A. 完成SSRF攻擊,通過HttpClient調用方式,響應結果如下:」)
self.get_url(self.AttackUrl[10])
print(「0x0B. 完成SSRF攻擊,通過HttpClient重定向方式,響應結果如下:」)
self.get_url(self.AttackUrl[11])
print(「0x0C. 完成SSRF攻擊,通過jdk 中的 URL.openConnection 調用方式,響應結果如下:」)
self.post_url(self.AttackUrl[12])
print(「0x0D. 完成SSRF攻擊,通過okhttp方式,響應結果如下:」)
self.get_url(self.AttackUrl[13])
print(「0x0E. 完成SSRF攻擊,通過okhttp3方式,響應結果如下:」)
self.get_url(self.AttackUrl[14])
print(「0x0F. 完成任意文件刪除攻擊,響應結果如下:」)
self.get_url(self.AttackUrl[15])
print(「0x10. 完成RandomAccessFile 文件讀寫攻擊,響應結果如下:」)
self.get_url(self.AttackUrl[16])
print(「0x11. 完成RandomAccessFile 文件讀寫攻擊,讀取linux下的passwd文件,響應結果如下:」)
self.get_url(self.AttackUrl[17])
print(「0x12. 完成NIO 文件調用攻擊,響應結果如下:」)
self.get_url(self.AttackUrl[18])
print(「0x13. 完成linux下的NIO 文件讀取調用攻擊,響應結果如下:」)
self.get_url(self.AttackUrl[19])
print(「0x14. 完成NIO 文件刪除攻擊,響應結果如下:」)
self.get_url(self.AttackUrl[20])
print(「0x15. 完成NIO 文件硬連結攻擊,響應結果如下:」)
self.get_url(self.AttackUrl[21])
print(「0x16. 完成linux下的NIO 文件目錄遍歷攻擊,響應結果如下:」)
self.get_url(self.AttackUrl[22])
print(「0x17. 完成NIO 文件重命名攻擊,響應結果如下:」)
self.get_url(self.AttackUrl[23])

defget_url(self, url):
req = urllib.request.Request(self.host + url, headers=self.headers)
html = urllib.request.urlopen(req).read().decode(『utf-8』)
content = etree.HTML(html)
print(self.load_page(content) +』 攻擊已被攔截』)

defpost_url(self, url):
files = {『file』: open(『1.jsp』, 『rb』)}
data = {}
res = requests.post(self.host + url, data=data, files=files)
reg = re.compile(r』400 - Request blocked by OpenRASP』)
resstr = reg.search(res.text)
print(resstr)

defload_page(self, con):
xpath = 『/html/body/div[2]/div/div[2]/h2』
down = con.xpath(xpath)
try:
result = down[0].text
exceptIndexError:
result = 「ERROR」
print(「攻擊失敗」)
return result

if name == 「main「:
ORT= OpenRASPTest(「http://192.168.xx.xx:80xx「)
ORT.start_attack()

四、OpenRASP報警推送數據分析

OpenRASP報警可以通過HTTP、Syslog、Kafka、郵件和釘釘推送

報警至少每隔120秒發送一次,這個時間可以增加

這裡我們的實驗使用HTTP推送並在區域網內接收報警信息,這裡我們可以填寫報警接收伺服器的URL,不過我們的接收程序還沒開發,所以我們先點擊「推送數據格式說明」看看推送數據格式詳情

可以看到OpenRASP一個完整的JSON數據包格式如下:

當發生攻擊事件時,OpenRASP 將會記錄以下信息:

欄位說明rasp_idRASP agent idapp_id應用IDevent_type日誌類型,固定為 attack 字樣event_time事件發生時間request_id當前請求IDrequest_method請求方法intercept_state攔截狀態attack_source攻擊來源 IPtarget被攻擊目標域名server_hostname被攻擊的伺服器主機名server_ip被攻擊目標 IPserver_type應用伺服器類型server_version應用伺服器版本…………

詳情請參考:OpenRASP日誌說明

五、基於Django的報警接收Web應用開發1. 安裝Django

執行

pip install django

安裝Django

2. 新建Django項目

打開Pycharm,點擊new project。選擇Django,輸入項目名之後點擊CREATE按鈕新建Django項目:

Pycharm會自動幫我們把新建好的Django項目目錄結構初始化,這時我們需要自己在settings.py中將ALLOWED_HOSTS修改為,注意不要漏掉「,」:

ALLOWED_HOSTS = [『*』, ]

以保證區域網正常請求訪問,如何仍然無法訪問到Django伺服器,可以將

『django.middleware.csrf.CsrfViewMiddleware』,

給注釋掉

最後,在Django configuration中將host改為0.0.0.0,重啟Django伺服器之前記得在主機的防火牆中添加8000埠

3. 接收POST路由

在項目目錄下新建views.py,獲取POST請求

def openraspalarm(request):
if request.method ==』POST』:
postBody = request.body

之後在urls.py中添加路由:

path(『alarm/『, openraspalarm),

4. 讀取報警信息

使用JSON讀取POST請求體中的報警信息。首先引入json庫:

import json

然後使用json.loads方法將json格式數據轉換為字典

json_result = json.loads(postBody)
print(『完整的JSON字符串如下:\n {0}』.format(json_result))

並且可以直接輸出app_id鍵的值

print(json_result[『app_id』])

由於每隔120秒Agent會將所有還沒報警的事件進行推送,所有推送的數據包中可能會包含多個事件,這些事件的報警均在data鍵內。最後,我們循環輸出每個事件的json標籤內容:

data = json_result[『data』]
print(『data長度為{0}』.format(len(data)))
for i in range(len(data)):
print(『\033[45m第 {0} 個攻擊\033[0m』.format(i))
print(『攻擊源IP位址:{0}』.format(data[i][『attack_source』]))
print(『攻擊類型:{0}』.format(data[i][『attack_type』]))
print(『攻擊發生時間:{0}』.format(data[i][『event_time』]))
print(『事件類型:{0}』.format(data[i][『event_type』]))
print(『攻擊向量頭部:{0}』.format(data[i][『header』]))
print(『攔截狀態:{0}』.format(data[i][『intercept_state』]))
print(『當前URL:{0}』.format(data[i][『url』]))
print(『攻擊應用ID:{0}』.format(data[i][『app_id』]))
print(『攻擊定位:{0}』.format(data[i][『attack_location』]))
print(『攻擊變量信息:{0}』.format(data[i][『attack_params』]))
print(『插件檢測算法:{0}』.format(data[i][『plugin_algorithm』]))
print(『檢測準確率:{0} %』.format(data[i][『plugin_confidence』]))
print(『檢測報告:{0}』.format(data[i][『plugin_message』]))
print(『RASP agent ID:{0}』.format(data[i][『rasp_id』]))
print(『當前請求ID:{0}』.format(data[i][『request_id』]))
print(『請求方法:{0}』.format(data[i][『request_method』]))
print(『被攻擊伺服器主機名:{0}』.format(data[i][『server_hostname』]))
print(『被攻擊目標IP及網卡接口名稱:{0}』.format(data[i][『server_nic』]))
print(『應用伺服器類型:{0}』.format(data[i][『server_type』]))
print(『應用伺服器版本:{0}』.format(data[i][『server_version』]))
print(『被攻擊目標域名:{0}』.format(data[i][『target』]))

這時我們可以運行自動化攻擊腳本,為OpenRASP後臺創造報警數據,當一個報警周期(120秒)過後,就能接收到OpenRASP後臺傳來的報警數據:

我們可以將接收到的報警數據根據實際需要存入資料庫或做進一步的分析處理。

六、總結

有關RASP的理念,早在2014年就已經被提出,並且被世界頂級諮詢公司Gartner列為應⽤安全領域的「關鍵趨勢」。OpenRASP作為其落地的項目已經做到相對成熟的地步,儘管它還存在一些問題,但是相信在未來幾年我們能看到OpenRASP能夠帶來更好的表現。本文在搭建好OpenRASP測試實驗環境的基礎上編寫官方測試用例的自動化漏洞驗證腳本,最後通過Django快速開發報警接收Web應用。本文的主要目的在於更好地去使用和研究OpenRASP技術,希望這篇文章能夠給大家提供有用思路和方法。

附錄

參考:

https://www.freebuf.com/articles/web/217421.html
https://www.freebuf.com/articles/web/164413.html
https://www.appsealing.com/what-is-runtime-application-self-protection/
https://rasp.baidu.com/download/OpenRASP%20Internals.pdf?from=header
https://rasp.baidu.com/doc/install/software.html
https://rasp.baidu.com/doc/install/testcase.html
https://rasp.baidu.com/doc/setup/log/main.html#format

相關焦點

  • Docker化Python的Django Web應用程式
    了解如何使用Gunicorn web伺服器docker化Django應用程式,使該應用能夠並行處理數千個請求。介紹本文將涉及用Django建立一個簡單『Hello World』風格的web應用程式,並且運行在Docker中。
  • 如何 Docker 化 Python Django 應用程式 | Linux 中國
    Docker 是一個開源項目,為開發人員和系統管理員提供了一個開放平臺,可以將應用程式構建、打包為一個輕量級容器,並在任何地方運行。Docker 會在軟體容器中自動部署應用程式。Django 是一個用 Python 編寫的 Web 應用程式框架,遵循 MVC(模型-視圖-控制器)架構。它是免費的,並在開源許可下發布。
  • 使用 Docker 部署 Django
    Docker 部署 Django 應用可以通過兩種方式來完成:迭代構建和容器互聯。以下使用容器互聯的方式搭建 Django 容器棧。--link mysql:mysql \--link redis:redis \-p 12000:8000 \-d feiyu/django-app /usr/local/bin/uwsgi --http :8000 --chdir /usr/src/jianshu -w jianshu.wsgi上面使用 –link 選項來能夠進行容器間安全的交互通信,使用格式name:alias
  • Django 3 + Vue.js 前後端分離Web開發實戰
    Web開發項目。為了簡化,方便讀者理解,本文將以開發一個單體頁面應用作為實戰演示。在正式開始實戰示例之前,我們有必要先弄清楚一個概念:什麼是前後端分離?前後端分離目前已成為網際網路項目開發的業界標準使用方式,在聊前後端分離之前,相信也有很多讀者,對如何區分前端還是後端,還搞不清楚(是不是讓我戳中了你的痛處了)。本著「致良知」,先科譜一下知識。
  • Docker部署Django和Django國際化
    用 uwsgi啟動 django 服務# 6. tail空命令防止web容器執行腳本後退出while ! memory-report = true #設置平滑的重啟(直到處理完接收到的請求)的長等待時間(秒)reload-mercy = 10 #設置工作進程使用虛擬內存超過N MB就回收重啟reload-on-as= 1024 第三步:編寫Nginx鏡像和容器所需文件
  • python測試開發django-180.docker-compose部署django+mysql環境
    前言部署django項目需用到mysql資料庫,還需要自己寫一個Dockerfile文件部署django的容器。
  • Python Django + 前端Vue.js快速搭建web項目
    本篇使用Vue.js作為前端框架,代替Django本身較為孱弱的模板引擎,Django則作為服務端提供api接口,使得前後端實現完全分離,更適合單頁應用的開發構建。命令:pip install django即可安裝最新版本的django        或者pip install django==1.11.13安裝指定版本Vue.js系:Node.js 8.11.2有關Vue的模塊(包括vue)可以使用node自帶的npm包管理器安裝。
  • Python 3+Django 3 結合Vue.js框架構建前後端分離Web開發平臺實戰
    」,選擇設為「設為星標」本篇將基於Python 3.7+Django 3.0結合Vue.js前端框架,為大家介紹如何基於這三者的技術棧來實現一個前端後離的Web開發項目。為了簡化,方便讀者理解,本文將以開發一個單體頁面應用作為實戰演示。在正式開始實戰示例之前,我們有必要先弄清楚一個概念:什麼是前後端分離?
  • python測試開發django-11.模型models詳解
    當我們的web項目需要新增一張表和欄位內容時,需要在models.py裡面寫相關內容。配置資料庫django配置mysql資料庫教程參考前面一篇https://www.cnblogs.com/yoyoketang/p/9997520.html需先安裝mysql資料庫驅動 pip install mysqlclient==1.3.10settings.py 文件中找到 DATABASES 配置項, django
  • 原創Docker部署Django由淺入深系列(上):單容器部署Django + Uwsgi
    Django在生產環境的部署。使用sudo docker exec -it mysite1 /bin/bash即可進入容器內部。用 uwsgi啟動 django 服務, 不再使用python manage.py runserver python manage.py makemigrations&& python manage.py migrate&& uwsgi --ini /var/www/html/mysite2/uwsgi.ini # python manage.py
  • python測試開發django-104.form表單正則校驗(RegexValidator)
    收錄於話題 #djangoerror_messages中有』invalid』,會優先顯示這裡的提示 validators=[RegexValidator(r'^(\w)+$', '用戶名只能有字母數字下劃線組成!')]
  • 一篇文章帶你了解Django ORM操作(基礎篇)
    回復「書籍」即可獲贈Python從入門到進階共10本電子書前言在日常開發中
  • Django Admin數據表可視化
    當然開發人員自己也可以去構建管理界面,但是當系統越來越複雜,Model 越來越多的時候, 就會增加很多重複性的工作。綜上所述,Django 完全考慮到了這些問題,它可以讓開發人員幾乎不用寫代碼就能擁有一個功能強大的 Model 管理後臺。下面我們一起來學習 Django 提供的這個強大功能。1.
  • 讓你的項目更輕鬆——docker部署django項目
    當我們在本地開發完一個django項目後,如果需要供其他人來訪問,我們則必須將其部署到伺服器上(一般是linux),而要提供外部服務
  • Argo CD 優化以及使用釘釘接收狀態消息
    本文我們將介紹 Argo CD 通過 webhook 來優化應用檢測、使用 Prometheus 監控 Argo CD,已經使用釘釘來接收 Argo CD 應用狀態變化的消息通知。webhook 配置我們知道 Argo CD 會自動檢查到配置的應用變化,這是因為 Argo CD 會每隔三分鐘去輪詢一次 Git 存儲庫來檢測清單的變化,為了消除這種輪詢延遲,我們也可以將 API 服務端配置為接收 webhook 事件的方式,這樣就能實時獲取到 Git 存儲庫中的變化了。
  • Docker部署Django由淺入深系列(中): 雙容器部署Django + Uwsgi + Nginx
    我們將了解不同容器間是如何通信的,並學會正確配置uwsgi.ini和nginx.conf使整個項目跑起來。在閱讀本篇前,請先閱讀本系列上篇使用Docker單容器部署Django + Uwsgi。下篇我們會更進一步介紹如何使用docker-compose部署Django + Uwsgi + Nginx + MySQL + Redis(多容器組合), 歡迎關注我們的微信公眾號【Python Web與Django開發】。
  • Django+Vue.js構建前後端分離項目系列一:基礎篇
    但是大多數文章都只寫了項目搭建部分,然而在整個項目過程中,會遇到傳統的純後端渲染開發模式幾乎遇不到的問題,比如單頁應用中的路由問題、跨域問題、Session和Cookie失效問題、項目不能一次性遷移但又需要使用新框架(如Vue.js, Angular, React)的問題、第三方應用回調入口是前端服務的問題、Django認證接入問題等等等等,該系列文章也將圍繞這些問題進行討論
  • 基於Threejs的web 3D開發入門
    | 導語 隨著軟硬體的發展,在PC和移動端瀏覽器上進行web 3D開發的條件已經基本成熟了,出現了不少js 3D庫,Threejs是js 3D庫中的佼佼者。國內也有企業開始做一些應用嘗試,某寶2016年雙11就用ThreeJS做了一個比較酷炫的3D宣傳頁面刷爆了朋友圈。
  • Python Web 應用程式 Tornado 框架簡介 | Linux 中國
    我們為 Tornado 應用程式構造的每個基於類的視圖都必須繼承 tornado.web 中的 RequestHandler 對象。這將設置我們需要(但不想寫)的所有底層邏輯來接收請求,同時構造正確格式的 HTTP 響應。