給nginx配置https伺服器並反向代理php
昨天給php同事幫忙配置https,現在把過程記錄如下:
伺服器:CentOS
nginx版本:1.10.0
php版本:5.6.22
同事之前已經把http配置好的。
一、nginx https 配置
開始我真是不懂這方面的,於是百度---怎麼給php配置https,得到的答案是https與php無關,應該配置的是nginx,於是我找到了這個教程:http://blog.csdn.net/tiantiandjava/article/details/39077107 看樣子一點也不難啊。
生成證書和金鑰後,美滋滋開啟nginx.conf填入配置(在生成證書的時候需要填寫Comom Name 我隨便寫了一個jason.com 這個是你伺服器的根域名 比如 xxx.com 反正是自簽名證書 到時候客戶端做跳過域名驗證就可以了)
然後
curl -k https://localhost:443 (因為CentOS沒有瀏覽器呀 -k引數是忽略證書) 結果Conect Refuse
於是我從網上copy了一個模版修改了一下
server { listen 443; server_name www.XXX.com; ssl on; ssl_certificate /usr/local/nginx/conf/ssl/xxx.crt; ssl_certificate_key /usr/local/nginx/conf/ssl/xxx_nopwd.key; ssl_session_cache shared:SSL:1m; ssl_session_timeout 5m; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; location / { root html; index index.html index.htm; } }
然後curl -k https://localhost:443/index.html 成功返回/usr/local/nginx/html/index.html檔案
但是通過瀏覽器訪問這臺伺服器https://192.168.1.xxx:443/index.html 還是被拒絕。
弄了很久才發現是iptables防火牆的問題
service iptables status 檢視防火牆已開啟的埠,發現沒有443
加上後就可以了,具體可以參考這個連結:http://blog.csdn.net/youcharming/article/details/41986709
二、靜態伺服器https配置好了,現在是和php連線起來。
你需要在上面的配置裡面加上這幾行
location ~ \.php$ {
root php檔案的根目錄;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
什麼是fastcgi呢?這要從nginx與php結合的原理來說,nginx只是作靜態伺服器,而關於php指令碼解析要交給專門的程序,它就是fastcgi,
fastcgi_pass 127.0.0.1:9000 就是nginx通過tcp的形式與fastcgi通訊。(其實是和fastcgi的管理程序php-fpm進行通訊)
具體可以參考這個連結:http://www.nginx.cn/231.html
但是出錯了 伺服器沒響應 檢視9000埠根本沒開啟 再檢視php-fpm程序明明已經在執行啊 於是猜想應該是埠不匹配。
然後檢視php-fpm的埠資訊: netstat -anp | grep php-fpm
unix 2 [ ACC ] STREAM LISTENING 105785 23163/php-fpm /tmp/php-cgi.sock
開頭的unix說明是sock通訊而不是nginx.conf裡配置的127.0.0.1:9000 (tcp通訊) 我給個nginx的tcp通訊作為參照
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1986/nginx
於是返回nginx.conf修改配置如下:
location ~ \.php$ {
root php檔案的根目錄;
fastcgi_pass unix:/tmp/php-cgi.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
然後就完成了代理php的配置。
三、下面來講講什麼是https
我一直是以兩種加密方式來理解https通訊過程的:
1.客戶端發起https請求
2.伺服器返回證書(xxx.crt檔案)
3.客戶端驗證伺服器證書,如果沒問題將客戶端金鑰用這個證書加密
4.伺服器用自己的私鑰解密(xxx_nopwd.key) 從而拿到客戶端金鑰
(1-4步做了客戶端對伺服器的單向認證 1-4使用了非對稱加密進行認證通訊)
5.伺服器使用客戶端金鑰與客戶端通訊
(之後的通訊都是對稱加密通訊了)
四、給iOS App配置https
ios sdk9.0以後都是預設使用tsl1.2協議進行https通訊 但是為了能使用http 我就把App Transport Security Settings設定為允許http傳輸
現在我想https http 能同時使用 方法很簡單:
NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"證書名稱" ofType:@"cer"];//證書的路徑
NSData *certData = [NSData dataWithContentsOfFile:cerPath];
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
// 允許自簽名證書
securityPolicy.allowInvalidCertificates = YES;
// 不驗證域名
securityPolicy.validatesDomainName = NO;
securityPolicy.pinnedCertificates = [NSSet setWithObjects:certData, nil];
上面那個.cer證書就是你伺服器傳過來的那個.crt經過轉換為了.cer 具體獲取方法可以在這個連結裡面找 http://www.jianshu.com/p/fa65eb0460dc
其實如果只是做客戶端對伺服器的單向認證(比如我上面搭建的nginx),不認證客戶端的話可以不用在ios程式裡面放證書。
但是會被代理伺服器抓包。具體可以參考這篇文章:http://www.jianshu.com/p/97745be81d64
如果要做雙向認證nginx配置要加上一些東西,比如ssl_client_certificate xx/xxx/xx.crt
可以參考這篇文章:http://www.tuicool.com/articles/FrUZJze
這樣從伺服器到客戶端的配置就基本完成了
文中有很多個人理解的地方 所以難免出現錯漏 今天特意總結出來 僅供參考