python 列表比较不同物质的吸热能力_飘着雪花的冬天
這兩天在折騰這個(gè)問題,google中英文的介紹都只提到一部分,所以決定寫一篇blog講一下整個(gè)配置過程,全當(dāng)做筆記。
SSL連接(HTTPS)是普遍使用的安全的HTTP連接方式,它通過證書認(rèn)證的方式來保證訪問安全。通常的方式是:在服務(wù)器端設(shè)置一張證書,證書由具有公信力的數(shù)字證書認(rèn)證機(jī)構(gòu)(CA)辦法給網(wǎng)站對(duì)應(yīng)的域名;用戶訪問網(wǎng)站的時(shí)候?yàn)g覽器首先會(huì)檢查證書,既檢查證書的合法性(簽發(fā)機(jī)構(gòu)可靠),也檢查證書的對(duì)象和網(wǎng)站域名是否匹配(比如證書發(fā)給www.foo.com但是用的證書是發(fā)給www.bar.com的,那證書很可能是偷來的^^)。如果檢查出錯(cuò),瀏覽器會(huì)詢問用戶是否繼續(xù)訪問,即使繼續(xù)訪問也會(huì)在瀏覽器地址欄顯示一個(gè)警告。舉個(gè)例子,12306購票網(wǎng)站的證書就是它們自己生成的,不是CA頒發(fā)的,所以訪問12306就會(huì)看到
除了認(rèn)證訪問站點(diǎn)的合法性,這張證書還會(huì)用來對(duì)傳輸?shù)臄?shù)據(jù)進(jìn)行加密,這樣攻擊者就沒法通過網(wǎng)絡(luò)抓包的方式輕易得到用戶的賬戶密碼等敏感信息。--雖然12306到證書是自己簽的,仍然可以用來加密傳輸數(shù)據(jù)。
除了上述服務(wù)器端證書認(rèn)證以外,有時(shí)候還會(huì)有額外的一步稱為客戶端證書認(rèn)證。如果某個(gè)站點(diǎn)或某些URL并不希望所有的人訪問,可以在建立連接的時(shí)候要求客戶端也提供證書,只有證書在白名單之列的客戶才可以建立連接。這種認(rèn)證方法在前端并不常用,因?yàn)榫W(wǎng)站給每個(gè)注冊(cè)用戶發(fā)一張證書很困難,用戶保存這張證書也很麻煩。但是在后端比較常用,比如網(wǎng)站的web服務(wù)器和后臺(tái)其他服務(wù)器之間進(jìn)行數(shù)據(jù)通信的時(shí)候。
現(xiàn)在就假設(shè)在Apache上運(yùn)行了一個(gè)Django的虛擬站點(diǎn),這個(gè)站點(diǎn)提供一些Rest API,我們只希望擁有證書的客戶端能夠調(diào)用這些Rest API,不對(duì)外開放。
設(shè)置過程分為以下幾步:
1. 生成證書
對(duì)于服務(wù)器端證書,通常需要從CA去申請(qǐng),申請(qǐng)的證書和域名是綁定的。如果服務(wù)器只是內(nèi)部使用,并不暴露在Internet下供大家訪問,也可以自己生成。客戶端證書可以自己生成,并只頒發(fā)給信任的客戶端使用。因此這里略去向CA申請(qǐng)的過程,只講怎么自己生成:
a.生成一個(gè)host key
$ssh-keygen -f foo.com.key
1
$ssh-keygen-ffoo.com.key
b.用這個(gè)host key創(chuàng)建一個(gè)證書申請(qǐng)
$openssl req -new -key foo.com.key -out foo.com.csr
1
$opensslreq-new-keyfoo.com.key-outfoo.com.csr
c.由前兩步得到的key和證書申請(qǐng)產(chǎn)生一張證書
$openssl x509 -req -days 365 -in foo.com.csr -signkey foo.com.key -out foo.com.crt
1
$opensslx509-req-days365-infoo.com.csr-signkeyfoo.com.key-outfoo.com.crt
二三步也可以合成一個(gè)命令
$openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout foo.com.key -out foo.com.key.crt
1
$opensslreq-x509-nodes-days365-newkeyrsa:2048-keyoutfoo.com.key-outfoo.com.key.crt
用同樣的方法可以生成另一張客戶端證書。如果情況再稍微復(fù)雜一點(diǎn),你有多個(gè)客戶并且需要一一區(qū)分它們,那需要給每個(gè)客戶單獨(dú)生成一張證書。這時(shí)通常的做法是:先生成一張自己的CA證書(就是自己做自己的權(quán)威機(jī)構(gòu)),然后再用這張CA證書分別生成多張不同的客戶端證書。關(guān)于這一點(diǎn),我看到一篇很好的reference,可以參考。
2. 在Apache上配置使用SSL
先貼出一個(gè)完整的虛擬站點(diǎn)配置文件
Apache
ServerName hwind-linux.cloudapp.net
ServerAdmin webmaster@localhost
DocumentRoot /var/www/pyvideo_project
Alias /static /var/www/pyvideo_project/staticfiles
Order allow,deny
Allow from all
WSGIScriptAlias / /var/www/pyvideo_project/pyvideo/wsgi.py
# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
LogLevel debug
#ssl:warn
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
SSLEngine On
SSLCertificateFile /etc/apache2/ssl/crt/hwind-linux.cloudapp.net.crt
SSLCertificateKeyFile /etc/apache2/ssl/key/hwind-linux.cloudapp.net.key
SSLCACertificateFile /etc/apache2/ssl/crt/dev@hwind-linux.cloudapp.net.crt
RequestHeader set SSL_CLIENT_S_DN ""
RequestHeader set SSL_CLIENT_I_DN ""
RequestHeader set SSL_SERVER_S_DN_OU ""
RequestHeader set SSL_CLIENT_VERIFY ""
RequestHeader set SSL_CLIENT_V_START ""
RequestHeader set SSL_CLIENT_V_END ""
RequestHeader set SSL_CLIENT_M_VERSION ""
RequestHeader set SSL_CLIENT_M_SERIAL ""
RequestHeader set SSL_CLIENT_CERT ""
RequestHeader set SSL_CLIENT_VERIFY ""
RequestHeader set SSL_SERVER_M_SERIAL ""
RequestHeader set SSL_SERVER_M_VERSION ""
RequestHeader set SSL_SERVER_I_DN ""
RequestHeader set SSL_SERVER_CERT ""
SSLVerifyClient Require
SSLVerifyDepth 1
SSLOptions +StdEnvVars
RequestHeader set SSL_CLIENT_S_DN "%{SSL_CLIENT_S_DN}s"
RequestHeader set SSL_CLIENT_I_DN "%{SSL_CLIENT_I_DN}s"
RequestHeader set SSL_SERVER_S_DN_OU "%{SSL_SERVER_S_DN_OU}s"
RequestHeader set SSL_CLIENT_VERIFY "%{SSL_CLIENT_VERIFY}s"
RequestHeader set SSL_CLIENT_V_START "%{SSL_CLIENT_V_START}s"
RequestHeader set SSL_CLIENT_V_END "%{SSL_CLIENT_V_END}s"
RequestHeader set SSL_CLIENT_M_VERSION "%{SSL_CLIENT_M_VERSION}s"
RequestHeader set SSL_CLIENT_M_SERIAL "%{SSL_CLIENT_M_SERIAL}s"
RequestHeader set SSL_CLIENT_CERT "%{SSL_CLIENT_CERT}s"
RequestHeader set SSL_CLIENT_VERIFY "%{SSL_CLIENT_VERIFY}s"
RequestHeader set SSL_SERVER_M_VERSION "%{SSL_SERVER_M_VERSION}s"
RequestHeader set SSL_SERVER_I_DN "%{SSL_SERVER_I_DN}s"
RequestHeader set SSL_SERVER_CERT "%{SSL_SERVER_CERT}s"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
ServerNamehwind-linux.cloudapp.net
ServerAdminwebmaster@localhost
DocumentRoot/var/www/pyvideo_project
Alias/static/var/www/pyvideo_project/staticfiles
Orderallow,deny
Allowfromall
WSGIScriptAlias//var/www/pyvideo_project/pyvideo/wsgi.py
# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
LogLeveldebug
#ssl:warn
ErrorLog${APACHE_LOG_DIR}/error.log
CustomLog${APACHE_LOG_DIR}/access.logcombined
SSLEngineOn
SSLCertificateFile/etc/apache2/ssl/crt/hwind-linux.cloudapp.net.crt
SSLCertificateKeyFile/etc/apache2/ssl/key/hwind-linux.cloudapp.net.key
SSLCACertificateFile/etc/apache2/ssl/crt/dev@hwind-linux.cloudapp.net.crt
RequestHeadersetSSL_CLIENT_S_DN""
RequestHeadersetSSL_CLIENT_I_DN""
RequestHeadersetSSL_SERVER_S_DN_OU""
RequestHeadersetSSL_CLIENT_VERIFY""
RequestHeadersetSSL_CLIENT_V_START""
RequestHeadersetSSL_CLIENT_V_END""
RequestHeadersetSSL_CLIENT_M_VERSION""
RequestHeadersetSSL_CLIENT_M_SERIAL""
RequestHeadersetSSL_CLIENT_CERT""
RequestHeadersetSSL_CLIENT_VERIFY""
RequestHeadersetSSL_SERVER_M_SERIAL""
RequestHeadersetSSL_SERVER_M_VERSION""
RequestHeadersetSSL_SERVER_I_DN""
RequestHeadersetSSL_SERVER_CERT""
SSLVerifyClientRequire
SSLVerifyDepth1
SSLOptions+StdEnvVars
RequestHeadersetSSL_CLIENT_S_DN"%{SSL_CLIENT_S_DN}s"
RequestHeadersetSSL_CLIENT_I_DN"%{SSL_CLIENT_I_DN}s"
RequestHeadersetSSL_SERVER_S_DN_OU"%{SSL_SERVER_S_DN_OU}s"
RequestHeadersetSSL_CLIENT_VERIFY"%{SSL_CLIENT_VERIFY}s"
RequestHeadersetSSL_CLIENT_V_START"%{SSL_CLIENT_V_START}s"
RequestHeadersetSSL_CLIENT_V_END"%{SSL_CLIENT_V_END}s"
RequestHeadersetSSL_CLIENT_M_VERSION"%{SSL_CLIENT_M_VERSION}s"
RequestHeadersetSSL_CLIENT_M_SERIAL"%{SSL_CLIENT_M_SERIAL}s"
RequestHeadersetSSL_CLIENT_CERT"%{SSL_CLIENT_CERT}s"
RequestHeadersetSSL_CLIENT_VERIFY"%{SSL_CLIENT_VERIFY}s"
RequestHeadersetSSL_SERVER_M_VERSION"%{SSL_SERVER_M_VERSION}s"
RequestHeadersetSSL_SERVER_I_DN"%{SSL_SERVER_I_DN}s"
RequestHeadersetSSL_SERVER_CERT"%{SSL_SERVER_CERT}s"
a.服務(wù)器端SSL
打開服務(wù)器端SSL主要由這幾行配置指定:
SSLEngine On
SSLCertificateFile /etc/apache2/ssl/crt/hwind-linux.cloudapp.net.crt
SSLCertificateKeyFile /etc/apache2/ssl/key/hwind-linux.cloudapp.net.key
1
2
3
SSLEngineOn
SSLCertificateFile/etc/apache2/ssl/crt/hwind-linux.cloudapp.net.crt
SSLCertificateKeyFile/etc/apache2/ssl/key/hwind-linux.cloudapp.net.key
b.客戶端SSL
客戶端SSL認(rèn)證主要由這幾行配置指定:
SSLVerifyClient Require
SSLVerifyDepth 1
1
2
SSLVerifyClientRequire
SSLVerifyDepth1
其中SSLVerifyDepth的含義是在證書鏈中檢查的深度。證書是層層簽發(fā)的,最頂層是CA,因?yàn)檫@里使用的證書都是直接由CA簽發(fā),因此是1就可以了。
c.設(shè)置Apache把證書信息傳給Django應(yīng)用程序
通常除了在Apache上設(shè)置,我們很可能還需要在Django應(yīng)用程序里根據(jù)證書信息做更細(xì)致多處理。例如根據(jù)證書簽名判斷訪問來自哪個(gè)客戶,每個(gè)客戶可能會(huì)有不同的權(quán)限,看到不同的東西。有兩種方案:一個(gè)是通過SSLOptions +StdEnvVars的設(shè)置把證書信息放進(jìn)環(huán)境變量,再在Apache調(diào)用wsgi.py的時(shí)候傳遞過去。這個(gè)方案在網(wǎng)上看到有人提到,但是我不知道怎么在wsgi.py中修改request object;如果通過全局變量或者環(huán)境變量的方法傳遞信息,那只能處理單個(gè)證書的情形,因?yàn)槿肿兞恐荒躧old一份信息;另一個(gè)方案是通過RequestHeader的設(shè)置把證書信息加到HTTP request header中去。這個(gè)方案經(jīng)過嘗試很好用,示例如下:
在view收到post請(qǐng)求的時(shí)候,通過檢查存放在request.META中的header信息就可以知道證書是頒發(fā)給誰的,之后就可以針對(duì)不同的人做不同的響應(yīng)。
Python
def post(self, request, format=None):
if 'SSL_CLIENT_S_DN_CN' in request.META:
cn = request.META['SSL_CLIENT_S_DN_CN']
1
2
3
defpost(self,request,format=None):
if'SSL_CLIENT_S_DN_CN'inrequest.META:
cn=request.META['SSL_CLIENT_S_DN_CN']
3. 瀏覽器訪問
當(dāng)Apache,Django設(shè)置好之后,就可以通過瀏覽器進(jìn)行訪問了。首先需要在客戶端的電腦上安裝客戶端證書,然后在訪問的時(shí)候?yàn)g覽器會(huì)彈出窗口,這時(shí)選擇對(duì)應(yīng)的證書就可以打開網(wǎng)站了。例如,在Chrome中,選擇settings-show advanced settings就可以看到
然后在訪問的時(shí)候選擇剛才安裝的證書
安裝證書的時(shí)候需要提供同時(shí)包含公鑰和私鑰的文件,pfx或者p12格式。之前我們提到生成證書的過程生成的是獨(dú)立的公鑰和私鑰文件。可以通過以下命令做轉(zhuǎn)換
$openssl pkcs12 -export -out foo.name.pfx -inkey foo.name.key -in foo.name.crt
1
$opensslpkcs12-export-outfoo.name.pfx-inkeyfoo.name.key-infoo.name.crt
4.Python訪問需要客戶端證書認(rèn)證的Rest API
Python跟http相關(guān)的模塊比較混亂, urllib2, httplib2, requests, pycurl都可以用來訪問RestAPI,但是使用起來的復(fù)雜程度各不相同。有興趣可以參考這篇blog,它對(duì)這幾個(gè)模塊訪問RestAPI的方式做了詳細(xì)的比較。總之,結(jié)論是requests用起來很方面。
requests天然提供對(duì)客戶端證書認(rèn)證的支持,直接這發(fā)送請(qǐng)求到時(shí)候帶上證書的路徑作為參數(shù)就可以:
Python
def _post(self, url, data):
cert_path = config.get_client_cert_path()
return requests.post(url, verify=False, cert=cert_path, data=data)
1
2
3
def_post(self,url,data):
cert_path=config.get_client_cert_path()
returnrequests.post(url,verify=False,cert=cert_path,data=data)
上面的cert參數(shù)可以是一個(gè)指向pem格式證書的字符串,也可以是一個(gè)tuple,分別包含cert和key的路徑。
requests的一個(gè)缺點(diǎn)是它只支持pem格式的證書(不包含密碼),但是通常我們得到的都是倒出時(shí)包含密碼的證書,比如pfx。把pem放在機(jī)器里看起來不是很安全。Github上這個(gè)open issue也有討論。
可以通過以下命令把pfx轉(zhuǎn)成pem格式:
$openssl pkcs12 -in foo.com.pfx -out foo.com.pem -nodes
1
$opensslpkcs12-infoo.com.pfx-outfoo.com.pem-nodes
這就是end-to-end全過程,大功告成。
總結(jié)
以上是生活随笔為你收集整理的python 列表比较不同物质的吸热能力_飘着雪花的冬天的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电脑内存升级攻略:三招教你轻松提升性能
- 下一篇: 科技巨头的力量:至强CPU和傲腾内存引领