SSL證書卸載與SSI高級應用

http://netkiller.github.io/journal/ssi.html

Mr. Neo Chen (陳景峯), netkiller, BG7NYT


中國廣東省深圳市龍華新區民治街道溪山美地
518131
+86 13113668890


版權聲明

轉載請與作者聯繫,轉載時請務必標明文章原始出處和作者信息及本聲明。

文檔出處:
http://netkiller.github.io
http://netkiller.sourceforge.net

微信掃瞄二維碼進入 Netkiller 微信訂閲號

QQ群:128659835 請註明“讀者”

2014-09-17

摘要

目錄

1. 什麼是SSI(Server Side Include)

SSI是伺服器端頁麵包含,SSI工作在web伺服器上,web伺服器可以在一個頁面中包含另一個頁面,在用戶端看來是只有一個頁面。

2. 為什麼使用SSI

我們又很多個子站,所有網站的header與footer都相同,還有一些block區塊也存在共用。所以我們將這個共用的部分拆分,然後使用SSI按需包含。

3. 誰來負責SSI製作

稍有經驗的美工人員都可以靈活使用SSI,程序員也可在短時間內學會SSI.

4. 怎麼處理SSI包含

4.1. SSI 目錄規劃

			
/www/example.com
  |-- inc.example.com
  |-- www.example.com
  |-- images.example.com
  |-- acc.example.com
			
			

inc.example.com 是SSI共用檔案,存放shtml檔案。

www.example.com 是主站,會用到inc.example.com中的公共模組。

acc.example.com 與 www.example.com 類似。

注意

/www/inc.example.com是公共目錄,不需要配置nginx,不能通過瀏覽器訪問到該目錄.

為什麼要獨立公共檔案,而不是放在/www/www.example.com目錄下面呢?我是為了方便發佈代碼,分開的好處是我可以針對inc.example.com做發佈,而不影響其他項目。

			

由於include作用於web伺服器的$document_root目錄,例如當前$document_root是/www/example.com/www.example.com

<!--#include file="/example.shtml"--> 會引用 /www/example.com/www.example.com/example.shtml 檔案,而不是操作系統根目錄。

所以我們無法引用與www.example.com同級別的inc.example.com公共檔案。例如:

			
<!--#include file="/www/example.com/inc.example.com/example.shtml"--> 會引用 /www/example.com/www.example.com/www/example.com/inc.example.com/example.shtml 檔案,而不是操作系統根目錄。
<!--#include file="../inc.example.com/example.shtml"--> 會引用 也無法正常工作。
			
			

這是伺服器限制,如果SSI可能包含$document_root之外的檔案,將會帶來安全問題,例如

			
<!--#include file="/etc/passwd"-->
			
			

怎樣能突破限制呢?我想出了別名,通過別名/include引用/www/example.com/inc.example.com目錄中的公文模組,例如:

    location /include/ {
        root   /www/example.com/inc.example.com;
    }			
			

提示

Apache 與 Nginx 伺服器的 SSI 實現稍有不同include file與include virtual也有差異。

4.2. www.example.com 靜態內容伺服器

			
# cat /etc/nginx/conf.d/www.example.com.conf

server {
    listen       80;
    server_name  www.example.com;

    charset utf-8;
    access_log  /var/log/nginx/www.example.com.access.log;
    error_log	/var/log/nginx/www.example.com.error.log;

    location / {
        root   /www/example.com/www.example.com;
        index  index.html;
    }

    location /include/ {
        root   /www/example.com/inc.example.com;
    }
    location /info/ {
	proxy_pass http://info.example.com/;
    }


    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}
			
			

4.3. acc.example.com 動態網頁伺服器

			
server {
    listen       80;
    server_name  acc.example.com;
    charset utf-8;
    access_log  /var/log/nginx/acc.example.com.access.log;
    error_log	/var/log/nginx/acc.example.com.error.log;

    set $X_FORWARDED_FOR $http_x_forwarded_for;

    location / {
        root   /www/example.com/acc.example.com/htdocs;
        index  index.php;

        try_files $uri $uri/ /index.php?/$request_uri;
    }

    location /include/ {
        root   /www/example.com/inc.example.com;
    }

    location ^~ /images/ {
        rewrite /images/(.+)$ /$1 break;
        proxy_pass http://images.example.com;
        break;
    }
    location ~ \.php$ {
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  /www/example.com/acc.example.com/htdocs/$fastcgi_script_name;
        include        fastcgi_params;
	fastcgi_param  DOCUMENT_ROOT /www/example.com/acc.example.com/htdocs;
    }
}
			
			

注意

該伺服器不對外提供伺服器,只允許下面的SSL卸載伺服器通過反向代理連接

4.4. SSL卸載伺服器

將SSL證書處理,機密與解密操作轉移到該伺服器,不讓業務伺服器處理證書的加密與解密操作,上面的HTTP對內訪問,HTTPS對外訪問,HTTPS通過反向代理連接HTTP伺服器實現SSL證書卸載

			
upstream acc.example.com {
    server acc1.example.com;
    server acc2.example.com;
    server acc3.example.com;
}

server {
    listen       443;
    server_name  acc.example.com;

    ssl                  on;
    ssl_certificate      /etc/nginx/example.com/acc.example.com.pem;
    ssl_certificate_key  /etc/nginx/example.com/acc.example.com.key;

    ssl_session_timeout  5m;

    ssl_protocols  SSLv2 SSLv3 TLSv1;
    ssl_ciphers  HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers   on;

    location / {
	proxy_pass http://acc.example.com;
	proxy_http_version 1.1;
	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        break;
    }
}
			
			

4.5. /www/inc.example.com 公共包含檔案

/www/inc.example.com/include/cn/config.html

			
<!--#set var="HTML_HOST" value="http://www.example.com"-->
<!--#set var="INFO_HOST" value="http://info.example.com"-->
<!--#set var="NEWS_HOST" value="http://news.example.com"-->
<!--#set var="IMG_HOST" value="http://images.example.com"-->
<!--#set var="JS_HOST" value="http://images.example.com"-->
<!--#set var="CSS_HOST" value="http://images.example.com"-->

<!--#if expr="${X_FORWARDED_FOR}"-->

<!--#set var="ACC_HOST" value="https://myid.example.com"-->
<!--#set var="IMG_HOST" value="/images"-->
<!--#set var="JS_HOST" value="/images"-->
<!--#set var="CSS_HOST" value="/images"-->

<!--#else -->

<!--#set var="ACC_HOST" value="http://myid.example.com"-->
<!--#set var="IMG_HOST" value="http://images.example.com"-->
<!--#set var="JS_HOST" value="http://images.example.com"-->
<!--#set var="CSS_HOST" value="http://images.example.com"-->

<!--#endif -->
			
			

${X_FORWARDED_FOR} 用來判斷用戶是通過http還是https進入,由於images.example.com 沒有SSL證書,需要有區分的載入圖片的地址。/images 通過反向代理連接http://images.exampe.com.

4.6. 引用包含檔案實例

			
<!--#include file="/include/cn/config.html"-->
<!DOCTYPE>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<link rel="shortcut icon" href="<!--#echo var="IMG_HOST"-->/favicon.ico" type="image/x-icon" />
<link rel="stylesheet" href="<!--#echo var="CSS_HOST"-->/styles/common.css" />
<script type="text/javascript" src="<!--#echo var="JS_HOST"-->/scripts/jquery-1.7.1.min.js"></script>
</head>
<body>
<div id="homeNav"><!--#include virtual="/include/cn/header.html" --></div>
<a href="<!--#echo var='ACC_HOST'-->/register/" class="real">
	<h3><img src="<!--#echo var="IMG_HOST"-->/new/ico_real.png" />註冊賬戶</h3>
</a>
</body>
</html>