1. 程式人生 > >給nginx配置https伺服器並反向代理php

給nginx配置https伺服器並反向代理php

昨天給php同事幫忙配置https,現在把過程記錄如下:

伺服器:CentOS 

nginx版本:1.10.0 

php版本:5.6.22

同事之前已經把http配置好的

一、nginx https 配置

開始我真是不懂這方面的,於是百度---怎麼給php配置https,得到的答案是httpsphp無關,應該配置的是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

這樣從伺服器到客戶端的配置就基本完成了

文中有很多個人理解的地方 所以難免出現錯漏 今天特意總結出來 僅供參考