1. 程式人生 > >http切換至https相關配置

http切換至https相關配置

為了更好的使用者體驗,啟用了https,需要去各大主機商那裡購買SSL證書,https的好處大概以下幾點: 1.資料傳輸加密,防止資訊被竊取; 2.防止被欺詐,增加網站信任,防釣魚; 3.防止被劫持;

部署了https的整體結構如圖:



 

1.生成證書,使用openssl工具來生成對應的證書:
cd /etc/nginx
openssl genrsa -des3 -out server.key 1024         # 設定證書密碼
openssl req -new -key server.key -out server.csr  # 根據提示輸入各種資訊
cp server.key server.key.org
openssl rsa -in server.key.org -out server.key
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
 
  生成的csr檔案包含了主要的證書資訊,key檔案主要包含了金鑰交換和加密等資訊,屬於私鑰,要儲存好。將csr檔案提交給CA廠商,會在幾天後發給一份簽好的證書檔案 crt檔案,同時會給你CA的證書鏈。 2.設定https證書
server
{
        listen 80;
        listen 443 ssl;
        server_name staging_activity.zhen.com;
        ssl_certificate      /usr/local/nginx/ca/server.cer;
        ssl_certificate_key  /usr/local/nginx/ca/server.key;
 
        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;
 
        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;
  ssl_protocols,表示SSL的協議;ssl_ciphers引數指的是加密演算法,根據自身機器openssl版本不同,支援演算法也不同;ssl_prefer_server_ciphers表示服務端加密演算法優先於客戶端加密演算法,防止降級攻擊。 瀏覽器和nginx之間走的https,而nginx和tomcat之間是通過proxy_pass,走的是普通http連線。 在tomcat端的Host中需要增加:
<Valve className="org.apache.catalina.valves.RemoteIpValve"
                  remoteIpHeader="x-forwarded-for"
                  remoteIpProxiesHeader="x-forwarded-by"
                  protocolHeader="x-forwarded-proto"
            />
  配置方案是瀏覽器和 Nginx 之間走的 HTTPS 通訊,而 Nginx 到 Tomcat 通過proxy_pass 走的是普通 HTTP 連線。 環境基礎假定nginx、tomcat web服務已經安裝並部署,crt(證書)和key(私鑰)檔案已經生成(本示例是用openssl生成的,生產環境可到第三方購買)。 nginx允許一個server同時支援http和https兩種協議,可分別定義80和443兩個協議和埠號,也可能單獨配置使其僅支援https協議。 nginx收到請求後,將通過http協議轉發給tomcat,由於nginx和tomcat在同一臺伺服器中,因此nginx核tomcat之間無需使用https協議。而正由於對於tomcat來說,收到的是普通的http請求,當tomcat中的應用發生轉向請求時正常,我們需要告訴tomcat已被https代理,增加X-Forwarded-Proto和X-Forwarded-Port兩個HTTP頭資訊。 下面是詳細的配置(Nginx 埠 80/443,Tomcat 的埠 8080): Nginx 這一側的配置沒什麼特別的:
http {
    include       mime.types;
    default_type  application/octet-stream;
 
    sendfile        on;
  
keepalive_timeout  65;
 
    upstream tomcat {
      server 192.168.1.xxx:8080;
    }
        
       # HTTPS server
       server {
           listen       443 ssl;
           server_name  192.168.1.xxx;
        
           ssl_certificate      ca/server.crt;
          ssl_certificate_key  ca/server.key;
 
           #ssl_client_certificate  /opt/nginx/ca/private/ca.crt;
        
           #ssl_verify_client       on;伺服器驗證客戶端,暫時不開啟
           ssl_session_cache    shared:SSL:1m;
           ssl_session_timeout  5m;
        
           ssl_ciphers  HIGH:!aNULL:!MD5;
           ssl_prefer_server_ciphers  on;
        
           location / {
               proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
               proxy_set_header Host $http_host;
               proxy_set_header X-Forwarded-Proto https;
               proxy_redirect off;
               proxy_connect_timeout      240;
               proxy_send_timeout         240;
               proxy_read_timeout         240;
               # note, there is not SSL here! plain HTTP is used
               proxy_pass http://192.168.1.xxx:8080;
           }
       }
 
}
  其中最為關鍵的就是 ssl_certificate 和 ssl_certificate_key 這兩項配置檔案位置及相關訪問許可權請自行注意並更改,其他的按正常配置。不過多了一個 proxy_set_header X-Forwarded-Proto https; 配置。 最主要的配置來自 Tomcat,下面是我測試環境中的完整 server.xml:
<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"
               connectionTimeout="20000"
               redirectPort="443" proxyPort="443"
               URIEncoding="UTF-8"/>
  
  以及後面的hostname:
<Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
        <Valve className="org.apache.catalina.valves.RemoteIpValve"
                  remoteIpHeader="x-forwarded-for"
                  remoteIpProxiesHeader="x-forwarded-by"
                  protocolHeader="x-forwarded-proto" />
</Host>
   上述的配置中沒有什麼特別的,但是特別特別注意的是必須有proxyPort="443",當然 redirectPort 也必須是443。同時 <Value> 節點的配置也非常重要,否則你在 Tomcat 中的應用在讀取 getScheme() 方法以及在 web.xml 中配置的一些安全策略會不起作用。 需要值得注意的是,配置後tomcat的8080埠在外部依然可以直接訪問,如果是叢集環境,將會帶來極大的安全隱患且此次配置也毫無意義了。所以應該在整個伺服器區域網外圍切斷8080埠的訪問(之前與第三方有互動並已經預定8080埠訪問的服務可以酌情開放)並且在區域網內部開放8080埠的訪問。  http與https的自動跳轉 在我們使用baidu時,如果沒有使用http的話,也會直接轉換成https,不需要使用者手動操作,當前在我們的伺服器中,既能支援http,也支援https,如果是惡意使用者,可以不使用http進行操作,所以我們也需要增加這一功能。 需要將80和443拆開,443https埠仍然保持原樣,80埠,使用301 http code轉移至https:
server {
        listen  80;
        server_name home.xxx.com;
        access_log /usr/local/nginx/main.xxx.com.log  open1;
        return 301 https://home.xxx.com$request_uri;
}
  301和302之間的區別可以參考:http://blog.csdn.net/qmhball/article/details/7838989,一個表示永久轉移,一個表示暫時轉移,對於使用者來說,僅僅是一個跳轉,瀏覽器中舊的url變成了新的url,但302可能會有URL規範化和網站劫持的問題,被搜尋引擎判斷為可疑轉向,甚至認為是xx,因此我們這裡採用301。 https仍然按照之前的配置即可:
server {
        listen 443 ssl;
        ssl_certificate      /usr/local/nginx/ca/server.cer;
        ssl_certificate_key  /usr/local/nginx/ca/server.key;
 
        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;

...
   但內網我們使用的named服務,可以根據內網域名來進行請求分發,僅使用http,因此還需要為.net域名額外指定一個虛擬主機,因為是內網訪問,所以僅支援http。