调试在TLS / SSL之上运行的Django应用程序的最佳方法是什么?
背景:
我有一个Django Web应用程序,它使用X.509客户端证书进行身份验证。在Apache下运行时,我的应用程序只能通过HTTPS访问。连接到应用程序的客户端提供客户端证书,Apache验证该证书,然后在环境变量中转发到应用程序。该应用程序解析证书并提供访问受控内容。
到目前为止,我只能使用“./manage.py runserver”在常规HTTP下调试应用程序。我通过使用在调试模式下启动的自定义视图处理程序中间件来模拟HTTPS连接。视图处理程序向请求添加信息,类似于在HTTPS下运行时将从实际客户端证书解析的信息。
如果我可以使用客户端通过HTTPS连接时提供的实际客户端证书进行调试,这将使调试变得更加容易。
答案 0 :(得分:4)
我们在Django前面使用nginx,并进行客户端证书检查。 NGINX执行SSL终止,客户端证书验证以及检查吊销列表。客户端证书字段在标头变量中传递到django应用程序。
那么我们的django应用程序没有收到证书,它只是查看标题变量。我认为相同的机制适用于Apache。
对于访问开发服务器的客户(例如' ./ manage.py runserver'),我们只是在客户端中有一个特例。 python客户端的示例:
if (proto == "https"):
conn = http.client.HTTPSConnection( "cert."+webhost+":"+port,
key_file = certfile, cert_file = certfile)
headers = {}
else:
# fake client for local connections. pass cert info in headers, as it would come
# out of nginx
conn = http.client.HTTPConnection( webhost+":"+port)
headers = { 'X_SSL_CLIENT_S_DN':'/C=US/ST=California/O=yyyy/CN=zzzz',
'X_SSL_CLIENT_I_DN':'/C=US/ST=California/O=xxxx/CN=wwww',
'X_SSL_CLIENT_SERIAL':hex(serialnum),
'USER_AGENT':"test client user agent",}
对于单元测试,我们使用Django测试客户端执行相同的操作:
from django.test.client import Client
self.client = Client()
response = self.client.get(url, data,
**{
'HTTP_X_SSL_CLIENT_S_DN':'/C=US/ST=California/O=yyyy/CN=zzzz',
'HTTP_X_SSL_CLIENT_I_DN':'/C=US/ST=California/O=xxxx/CN=wwww',
'HTTP_X_SSL_CLIENT_SERIAL':hex(serialnum),
'HTTP_USER_AGENT':"test client user agent",
})
答案 1 :(得分:0)
我想出了一个对我来说效果很好的解决方法。我仍然使用HTTP进行调试,但是我通过HTTP标头传递了客户端证书。因此,当我使用HTTP调试Web应用程序时,我让客户端将客户端证书复制到HTTP标头中。在输入视图之前,Web应用程序将证书从标头复制到Apache使用HTTPS时将传递给它的常规位置。
客户端证书是PEM格式化的,为了能够在HTTP头中传递它们,唯一需要做的就是删除客户端上的换行符并将它们重新插入服务器。
如果使用此方法,请注意Apache对单个HTTP头字段大小的默认限制为8190字节,使用LimitRequestFieldSize
指令配置。对于大于该值的证书,必须更改配置或必须拆分证书并在多个标头中传递。