Apache運維中經常使用功能配置筆記梳理

 

Apache 是一款使用量排名第一的 web 服務器,LAMP 中的 A 指的就是它。因爲其開源、穩定、安全等特性而被普遍使用。下邊記錄了使用 Apache 以來常常用到的功能,作此梳理,做爲平常運維筆記所用。javascript

1、Apache的工做模式
Apache 目前一共有三種MPM 模式(多進程處理模塊),它們分別是prefork、worker、enent,主要用到前兩種工做模式,且默認的工做模式是prefork。能夠經過 httpd -V 來查看。php

[root@uatweb01 ~]# /usr/local/apache/bin/httpd -V | grep -i "server mpm"    
Server MPM:     prefork

編譯的時候,能夠經過 configure 的參數來指定:css

--with-mpm=prefork|worker|event

1)prefork 工做模式
Apache在啓動之初,就預先fork一些子進程,而後等待請求進來。之因此這樣作,是爲了減小頻繁建立和銷燬進程的開銷。每一個子進程只有一個線程,在一個時間點內,只能處理一個請求。
優勢:成熟穩定,兼容全部新老模塊。同時,不須要擔憂線程安全的問題。
缺點:一個進程相對佔用更多的系統資源,消耗更多的內存。並且,它並不擅長處理高併發請求。html

2)worker 工做模式
使用了多進程和多線程的混合模式。它也預先fork了幾個子進程(數量比較少),而後每一個子進程建立一些線程,同時包括一個監聽線程。每一個請求過來,會被分配到1個線程來服務。線程比起進程會更輕量,由於線程一般會共享父進程的內存空間,所以,內存的佔用會減小一些。在高併發的場景下,由於比起prefork有更多的可用線程,表現會更優秀一些。
優勢:佔據更少的內存,高併發下表現更優秀。
缺點:必須考慮線程安全的問題。java

3)event 工做模式
它和worker模式很像,最大的區別在於,它解決了keep-alive場景下,長期被佔用的線程的資源浪費問題。event MPM中,會有一個專門的線程來管理這些keep-alive類型的線程,當有真實請求過來的時候,將請求傳遞給服務線程,執行完畢後,又容許它釋放。這樣加強了高併發場景下的請求處理能力。程序員

HTTP採用keepalive方式減小TCP鏈接數量,可是因爲須要與服務器線程或進程進行綁定,致使一個繁忙的服務器會消耗完全部的線程。Event MPM是解決這個問題的一種新模型,它把服務進程從鏈接中分離出來。在服務器處理速度很快,同時具備很是高的點擊率時,可用的線程數量就是關鍵的資源限 制,此時Event MPM方式是最有效的,但不能在HTTPS訪問下工做。web

2、Apache的用戶認證
有時候,須要給apache一些特殊的訪問設置一個用戶認證機制,增長安全。好比公司網站,通常都是有一個管理後臺的,雖然管理後臺自己就有密碼,但爲了更加安全,能夠再設置一層用戶認證。正則表達式

1)編輯配置文件)
# vim /usr/local/apache2/conf/extra/httpd-vhosts.conf
 
在對應的虛擬主機配置中加入以下配置:
<VirtualHost *:80>
    DocumentRoot "/usr/local/apache2/htdocs"
ServerName www.kevin.com
ServerAlias www.bobo.com
    <Directory /usr/local/apache2/htdocs/>
        AllowOverride AuthConfig
        AuthName "Please input you acount."
        AuthType Basic
        AuthUserFile /usr/local/apache2/htdocs/.htpasswd
        require valid-user
    </Directory>
</VirtualHost>
 
說明:首先指定要對哪一個目錄進行驗證,AuthName自定義,AuthUserFile指定用戶密碼文件在哪裏。
 
2)建立加密用的用戶名和密碼文件)
# htpasswd -c /usr/local/apache2/htdocs/.htpasswd liwei
# htpasswd -m /usr/local/apache2/htdocs/.htpasswd admin
 
建立第一個用戶時-c選項建立.htpasswd文件,-m選項增長用戶,根據提示輸入密碼。
 
3)重啓apache服務
# apachectl -t
# apachectl graceful
 
先檢查配置是否正確,而後用graceful至關因而reload配置,不用重啓apache服務,效果同樣。
如上配置後,經過瀏覽器輸入網址,訪問就會提示輸入密碼。

========================================================
在子目錄中放寬安全限制
也就是說,好比咱們如今已經在/usr/local/apache2/htdocs/這個目錄上加上了用戶名和密碼的認證。
但若是想在/usr/local/apache2/htdocs/php這個目錄中不須要認證,使用戶能夠直接訪問。
要達到上面的要求,就須要在配置文件中加入:
  
<Directory "/usr/local/apache2/htdocs/php">
Satisfy Any
Order Deny,Allow
Allow from all
</Directory>
  
或者:
  
在/usr/local/apache2/htdocs/php目錄下創建.htaccess文件,把
Satisfy Any
Order Deny,Allow
Allow from all

=================================================
若是已經限制了一個目錄的訪問,須要用戶名和密碼,但想要放開這個目錄中的其中一個文件(例如:back.html)
的權限,使其能夠任意訪問,在配置文件中添加:
  
<Files back.html>
Satisfy Any
Order Deny,Allow
Allow from all
</Files>

=================================================
查看經過驗證的用戶名稱:
能夠查看REMOTE_USER環境變動。在access_log中也能夠看到。

=================================================
禁止經過代理服務器訪問特定的URL

<Directory proxy:http://192.168.10.10/music/>
Order Allow,Deny
Deny from all
Satisfy All
</Directory>
  
上述方法都沒法知足要求時,能夠使用正則表達式的方式,使用Rewrite指令。

================================================
想拒絕全部對目錄中文件的訪問,除了特殊指定擴展名的文件(好比.html文件)

<Directory "/usr/local/apache2/htdocs/test">
Satisfy all
Order Allow,Deny
Deny from all
        <Files *.html>
          Order Deny,Allow
          Allow from all
          Satisfy any
        </Files>
</Directory>
  
以上指令,使得test目錄及其子目錄下的全部非.html文件沒法訪問,只有.html的文件能夠訪問。

3、設置默認虛擬主機
默認虛擬主機就是配置文件裏的第一個虛擬主機。關於默認虛擬主機有個特色,凡是解析到這臺服務器的域名,無論是什麼域名,只要在配置文件中沒有配置,那麼都會訪問到這個主機上來。若是直接用IP訪問,會訪問到這個站點上來。爲了不別人亂解析,因此應該把默認也就是第一個虛擬主機給禁止掉。使用allow,deny語句就能夠禁止掉了。chrome

1)配置默認虛擬主機
# vim /usr/local/apache2/conf/extra/httpd-vhosts.conf
 
添加一個虛擬主機的記錄:
<VirtualHost *:80>
    DocumentRoot "/data/www"
    ServerName www.kevin.com
    <Directory /data/www>
        Order allow,deny
        Deny from all
    </Directory>
</VirtualHost>
 
建立/data/www目錄,而且設置600權限,daemon用戶沒法訪問:
 
# mkdir /data/www
# chmod -R 600 /data/www
 
2)重啓apache服務器
# apachectl -t
# apachectl graceful
 
若是用IP或其它解析的域名訪問,發現提示:
Forbidden
You don't have permission to access / on this server.

=================================================
只有一個IP,但想在系統上支持多個網站:
  
NameVirtualHost *
<VirtualHost *:80>
    ServerAdmin webmaster@www.kevin.com
    DocumentRoot /www/docs/www.kevin.com
    ServerName www.kevin.com
    ServerAlias www.bobo.com                    ######p這條指令可對虛擬主機設定多個名稱
    ErrorLog logs/www.kevin.com-error_log
    CustomLog logs/www.kevin.com-access_log common
</VirtualHost>
  
其中:
"*" 表示所設定的主機可在全部的地址上運行。對於只有單一地址的機器,這表示會在該地址上運行,同時也會在loopback地址上運行。
若是NameVirtualHost 後面放置主機名稱可能會在啓動服務器時停用虛擬主機的機制。
虛擬主機會使用戶沒法再訪問配置文件中的主服務器。若是想讓主服務器成爲默認服務器,則必須在虛擬主機區塊中先將它列出。
對於每一個虛擬主機名稱,還須要在DNS中添加相關記錄。

=================================================
# /usr/local/apache2/bin/httpd -S    顯示虛擬主機的配置

=================================================
ErrorDocument 404 /err.html    這個指令可讓沒有打到指定網頁的時候,不顯示404錯誤,而是err.html頁面。
錯誤號能夠是其它的號碼,如40三、500等
  
例如:
<VirtualHost *>
    ServerAdmin webmaster@www.kevin.com
    DocumentRoot /www/docs/kevin.com
    ServerName kevin.com
    ErrorLog logs/kevin.com-error_log
    CustomLog logs/kevin.com-access_log combined
    ErrorDocument 404 /err.html
</VirtualHost>
  
根據以上配置,訪問kevin.com/index.html時,若是/www/docs/kevin.com目錄下沒有index.html文件時,
則會顯示/www/docs/kevin.com目錄下的err.html文件

=================================================
若是是有多個IP的狀況下,想在每一個地址上支持一個網站:
  
NameVirtualHost 127.0.0.1
<VirtualHost 172.16.50.230>
    ServerAdmin webmaster@www.kevin.com
    DocumentRoot /www/docs/bobo.bobo.com
    ServerName bobo.bobo.com
    ErrorLog logs/bobo.bobo.com-error_log
    CustomLog logs/bobo.bobo.com-access_log combined
</VirtualHost>

<VirtualHost 172.16.50.231>
    ServerAdmin webmaster@www.kevin.com
    DocumentRoot /www/docs/kevin.com
    ServerName kevin.com
    ErrorLog logs/kevin.com-error_log
    CustomLog logs/kevin.com-access_log combined
</VirtualHost>
  
以上配置根據所訪問的IP地址不一樣,會訪問不一樣的虛擬主機。若是服務器上還有其它的IP地址,可是沒有在配置文件的虛擬主機區塊列出來時,
這時訪問這個其它的IP地址,請求會被送至在配置文件主設定區的虛擬主機

=================================================
創建以IP尋址的默認虛擬主機,以配置文件中加入下面代碼:
  
<VirtualHost _default_>
    DocumentRoot /www/htdocs
    ErrorDocument 404 /err.html
</VirtualHost>
  
加入以上代碼後,若是訪問本地的IP,可是該IP確沒有在配置文件中配置時,則會訪問以上代碼指定的頁面

=================================================
混用以IP尋址及以名稱尋址虛擬主機:
  
ServerName 127.0.0.1
NameVirtualHost 172.16.50.10
NameVirtualHost 172.16.50.230
<VirtualHost 172.16.50.10>                             ################此處不一樣
    ServerAdmin webmaster@www.kevin.com
    DocumentRoot /www/docs/kevin.com
    ServerName kevin.com                                   ################此處不一樣
    ErrorLog logs/kevin.com-error_log
    CustomLog logs/kevin.com-access_log combined
</VirtualHost>
<VirtualHost 172.16.50.230>                            ################此處不一樣
    ServerAdmin webmaster@www.kevin.com
    DocumentRoot /www/docs/kevin.com
    ServerName kevin.bobo.com                          ################此處不一樣
    ErrorLog logs/kevin.bobo.com-error_log
    CustomLog logs/kevin.bobo.com-access_log combined
</VirtualHost>
<VirtualHost 172.16.50.230>                          ################此處不一樣
    ServerAdmin webmaster@www.kevin.com
    DocumentRoot /www/docs/kevin.com
    ServerName bobo.bobo.com                          ################此處不一樣
    ErrorLog logs/bobo.bobo.com-error_log
    CustomLog logs/bobo.bobo.com-access_log combined
</VirtualHost>

=================================================
mod_vhost_alias   模塊能夠創建大量的虛擬主機

=================================================
將URL對應至特定目錄。好比說:
訪問http://172.16.50.10/bobo,若是不想讓它訪問/usr/local/apache2/htdocs/bobo,
而是讓它訪問其它的目錄中的內容,能夠在配置文件中加入以下:
Alias /bobo /home/bobo/apache_bobo
  
而後還要把指定的目錄加入到配置文件中,以讓apache能夠訪問,默認狀況下apache是不訪問DocumentRoot之外的目錄的。
<Directory "/home/bobo/apache_bobo">
    Order allow,deny
    Allow from all
</Directory>
  
這種用Alias的目錄指定,實際上是用Alias的第二個參數去替換第一個參數。
本例中就是用/home/bobo/apache_bobo去替換/bobo
所以,咱們訪問http://172.16.50.10/bobo
其實上是訪問http://172.16.50.10/home/bobo/apache_bobo
  
這種方法對"/"符號要求很是嚴格,若是上例咱們寫成Alias /bobo/ /home/bobo/apache_bobo,
而咱們在訪問http://172.16.50.10/bobo/index.html,實際上是訪問http://172.16.50.10/home/bobo/apache_boboindex.html,
這是錯誤的,由於/home/bobo/apache_bobo替換的是/bobo/,
注意,這裏把最後的「/」也替換了,因此轉換後就是前面所說那樣錯誤的URL。
  
Alias也能夠爲現有的網頁內容建立新的URL,例如要想原來http://172.16.50.10/php/phpinfo.php內容,
經過http://172.16.50.10/newphp/phpinfo.php也能夠訪問,
只要在配置文件中加入以下一行:
Alias /newphp /usr/local/apache2/htdocs/php
  
Alias隻影響本地URI,不會影響URL的主機名部分。

4、域名301跳轉
一個站點不免會有多個域名,而多個域名總得有一個主次,好比個人網站能夠用兩個域名訪問:www.kevin.cn 和 www.bobo.cn 但你們發現無論我用哪一個域名訪問,最終都會跳轉到www.bobo.con 上來。這個行爲就叫作域名跳轉,這裏的301只是一個狀態碼,跳轉除了301還有302,301是永久跳轉,302是臨時跳轉,網站上必定要設置爲301,這樣對搜索引擎是比較友好的。apache

1)配置域名跳轉
# vim /usr/local/apache2/conf/extra/httpd-vhosts.conf

<IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteCond %{HTTP_HOST} ^www.abc.com$
    RewriteRule ^/(.*)$ http://www.123.com/$1 [R=301,L]
</IfModule>

配置爲:當訪問abc時,跳轉到123的網站。

2)配置多個域名跳轉

<IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteCond %{HTTP_HOST} ^www.abc.com$ [OR]
    RewriteCond %{HTTP_HOST} ^www.abcd.com$
    RewriteRule ^/(.*)$ http://www.123.com/$1 [R=301,L]
</IfModule>

3)重啓服務器並測試
# apachectl -t
# apachectl graceful

4)測試:
# curl -x 192.168.0.8:80  www.abc.com -I
HTTP/1.1 301 Moved Permanently
Date: Tue, 25 Oct 2016 15:48:10 GMT
Server: Apache/2.2.31 (Unix) PHP/5.5.38
Location: http://www.123.com/
Content-Type: text/html; charset=iso-8859-1

# curl -x 192.168.0.8:80  www.abcd.com -I
HTTP/1.1 301 Moved Permanently
Date: Tue, 25 Oct 2016 15:48:49 GMT
Server: Apache/2.2.31 (Unix) PHP/5.5.38
Location: http://www.123.com/
Content-Type: text/html; charset=iso-8859-1

經過上述測試,發現不管是abc或abcd均可以跳轉到 www.123.com 域名上來,經過瀏覽器訪問也同樣。

5、Apache日誌

指定日誌記錄格式,組合日誌格式(combined)或通用日誌格式(common),修改配置文件:
CustomLog logs/access_log combined    組合日誌格式
CustomLog logs/access_log common      通用日誌格式

通用日誌格式與組合日誌格式的"%h"控制符表示遠程請求用戶的身份,依據HostNameLookups指令的設定值,
多是主機名也多是IP地址。
若是想永遠記錄IP地址,則使用「%a」控制符。

記錄從客戶端收到的cookie
CustomLog logs/cookies_in.log "%{UNIQUE_ID}e %{Cookie}i"
CustomLog logs/cookies2_in.log "%{UNIQUE_ID}e %{Cookie2}i"
  
記錄由服務器設定並傳送給客戶端的cookie值:
CustomLog logs/cookies_out.log "%{UNIQUE_ID}e %{Set-Cookie}o"
CustomLog logs/cookies2_out.log "%{UNIQUE_ID}e %{Set-Cookie2}o"

不記錄來自本機網頁的圖像請求:
<FilesMatch \.(jpg|gif|png$)>
SetEnvIfNoCase Referrer "^http://www.kevin.com/" local_referrer=1
</FilesMatch>
Customlog logs/access_log combined env=!local_referrer

按照日或小時來記錄請求:
CustomLog "| /usr/local/apache2/bin/rotatelogs /usr/local/apache2/logs/access_log.%Y-%m-%d 86400" combined
  
其中:
rotatelogs的第一個參數是主日誌文件名若是有%字符,則表示日誌文件名中時間的格式,若是沒有指定時間格式,則是以秒爲單位,
從1970.1.1日算起的秒數
第二個參數是產生新日誌的間隔是多少秒。也能夠是大小若是把上例中的86400換成5M,則表時日誌達到5M時,就會產生一個新的日誌,
日誌的名字是access_log.%Y-%m-%d格式的

logresolve 將日誌中記錄的IP地址解析爲主機名
例如:
# logresolve -c < /usr/local/apache2/logs/access_log.raw > access_log.resolved
  
也可讓apache在處理過程當中使用IP地址,而後在記錄日誌時,以管道方式的日誌記錄進程來解析,修改配置文件:
HostnameLookups off
CustomLog "|/usr/local/apache2/bin/logresolve -c >> /usr/local/apache2/logs/access_log.resolved" combined

Apache日誌切割
每訪問一次網站,那麼就會記錄若干條日誌。固然前提是已經設置了日誌,日誌不去管理,時間長了日誌文件會愈來愈大,如何避免產生這麼大的日誌文件?其實apache有相關的配置,使日誌按照咱們的需求進行歸檔,好比天天一個新日誌,或者每小時一個新的日誌。

1)首先簡單設置日誌的路徑名稱
# vim /usr/local/apache2/conf/extra/httpd-vhosts.conf

ErrorLog "logs/error.log"
CustomLog "logs/access.log" combined
 
指定了日誌存放在/usr/local/apache2/logs目錄下分別爲error.log和access.log,combined爲日誌顯示的格式,
日誌格式能夠參考配置文件httpd.conf中格式的指定,以下:
 
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
 
2)設置apache日誌分割
一樣編輯配置文件httpd-vhosts.conf
 
ErrorLog "|/usr/local/apache2/bin/rotatelogs -l /usr/local/apache2/logs/aaa-error_%Y%m%d.log 86400"
CustomLog "|/usr/local/apache2/bin/rotatelogs -l /usr/local/apache2/logs/aaa-access_%Y%m%d.log 86400" combined
 
ErrorLog是錯誤日誌,CustomLog是訪問日誌。|就是管道符,意思是把產生的日誌交給rotatelog這個工具,而這個工具就是apache自帶的切割日誌的工具。
-l 的做用是校準時區爲UTC,也就是北京時間。86400,單位是秒,正好是一天,那麼日誌會天天切割一次。而最後面的combined爲日誌的格式,在httpd.conf中有定義。

Apache不記錄指定文件類型的日誌
若是一個網站訪問量特別大,那麼訪問日誌就會不少,但有一些訪問日誌咱們實際上是能夠忽略掉的,好比網站的一些圖片,還有js、css等靜態對象。而這些文件的訪問每每是巨量的,並且即便記錄這些日誌也沒有什麼用,那麼如何過濾掉(不記錄)這些日誌呢?

配置日誌不記錄圖片的訪問
# vim /usr/local/apache2/conf/extra/httpd-vhosts.conf
 
相關配置爲:
SetEnvIf Request_URI ".*\.gif$" image-request
SetEnvIf Request_URI ".*\.jpg$" image-request
SetEnvIf Request_URI ".*\.png$" image-request
SetEnvIf Request_URI ".*\.bmp$" image-request
SetEnvIf Request_URI ".*\.swf$" image-request
SetEnvIf Request_URI ".*\.js$"  image-request
SetEnvIf Request_URI ".*\.css$" image-request
CustomLog "|/usr/local ... _%Y%m%d.log 86400" combined env=!image-request
 
說明:
在原來日誌配置基礎上,增長了一些image-request的定義,好比把gif、jpg、bmp、swf、js、css等結尾的全標記爲image-request,
而後在配置日誌後加一個標記env=!image-request,表示取反。

6、Apache配置靜態緩存
所說的靜態文件指的是圖片、js、css等文件,用戶訪問一個站點,其實大多數元素都是圖片、js、css等,這些靜態文件實際上是會被客戶端的瀏覽器緩存到本地電腦上的,目的就是爲了下次再請求時再也不去服務器上下載,這樣就加快了速度,提升了用戶體驗。但這些靜態文件總不能一直緩存,它總有一些時效性,那麼就得設置這個過時時間。

1)配置靜態緩存
# vim /usr/local/apache2/conf/extra/httpd-vhosts.conf

<IfModule mod_expires.c>
    ExpiresActive on
    ExpiresByType image/gif "access plus 1 days"
    ExpiresByType image/jpeg "access plus 24 hours"
    ExpiresByType image/png "access plus 24 hours"
    ExpiresByType text/css "now plus 2 hour"
    ExpiresByType application/x-javascript "now plus 2 hours"
    ExpiresByType application/javascript "now plus 2 hours"
    ExpiresByType application/x-shockwave-flash "now plus 2 hours"
    ExpiresDefault "now plus 0 min"
</IfModule>


或者使用 mod_headers 模塊實現:

<IfModule mod_headers.c>
    # htm,html,txt 類的文件緩存一個小時
    <filesmatch "\.(html|htm|txt)$">
        header set cache-control "max-age=3600"
    </filesmatch>
    
    # css, js, swf 類的文件緩存一個星期
    <filesmatch "\.(css|js|swf)$">
        header set cache-control "max-age=604800"
    </filesmatch>
    
    # jpg,gif,jpeg,png,ico,flv,pdf 等文件緩存一年
    <filesmatch "\.(ico|gif|jpg|jpeg|png|flv|pdf)$">
        header set cache-control "max-age=29030400"
    </filesmatch>
</IfModule>

說明:
這裏的時間單位能夠 days、 hours 甚至是 min,兩種不一樣的方法,上面使用的是mod_expires,
而下面用的是 mod_headers,要想使用這些模塊,必需要事先已經支持。如何查看是否支持,使用命令:

# /usr/local/apache2/bin/apachectl -M

2)重啓服務器並驗證
# apachectl -t
# apachectl graceful

3)驗證:
# curl -x127.0.0.1:80 'http://www.kevin.com/static/image/common/online_admin.gif' -I
HTTP/1.1 200 OK
Date: Wed, 26 Oct 2016 03:51:26 GMT
Server: Apache/2.2.31 (Unix) PHP/5.5.38
Last-Modified: Tue, 31 May 2016 03:08:36 GMT
ETag: "46891b-16b-5341ab0597500"
Accept-Ranges: bytes
Content-Length: 363
Cache-Control: max-age=86400
Expires: Thu, 27 Oct 2016 03:51:26 GMT
Content-Type: image/gif

7、Apache配置防盜鏈
盜鏈,全稱是盜取連接,假如咱們的網站有不少好看的圖片,別人能夠查看咱們網站圖片的連接,而後應用在他的網站上,這樣的話,去訪問他的網站,實際上消耗的是咱們的流量(由於實際連接在咱們這裏),這樣咱們就不得不去配置防盜鏈,使得別人不能複製咱們圖片的連接。

防盜鏈的實現原理就不得不從HTTP協議提及,在HTTP協議中,有一個表頭字段叫referer,採用URL的格式來表示從哪兒連接到當前的網頁或文件。換句話說,經過referer,網站能夠檢測目標網頁訪問的來源網頁,若是是資源文件,則能夠跟蹤到顯示它的網頁地址。有了referer跟蹤來源就好辦了,
這時就能夠經過技術手段來進行處理,一旦檢測到來源不是本站即進行阻止或者返回指定的頁面。

若是想對本身的網站進行防盜鏈保護,則須要針對不一樣的狀況進行區別對待。若是網站服務器用的是apache,那麼使用apache自帶的Url Rewrite功能能夠很輕鬆地防止各類盜鏈,其原理是檢查refer,若是refer的信息來自其餘網站則重定向到指定圖片或網頁上。

若是網站有不少漂亮的圖片,好比網站域名 www.kevin.com,圖片地址爲 www.kevin.com/image/111.jpg,那麼其它人就能夠直接把這個地址放到他
本身的網站上,他的用戶能夠直接從他網站查看這張圖片,而實際圖片是從你的網站訪問的,所產生的帶寬消耗對你沒有任何意義,應該對這些圖片限制一下,
凡是在第三方站點上,嚴禁訪問你站點的圖片,如何配置呢?

# vim /usr/local/apache2/conf/extra/httpd-vhosts.conf

SetEnvIfNoCase Referer "^http://.*\.kevin\.com" local_ref
SetEnvIfNoCase Referer ".*\.abc\.com" local_ref
SetEnvIfNoCase Referer "^$" local_ref
<filesmatch "\.(txt|doc|mp3|zip|rar|jpg|gif)">
    Order Allow,Deny
    Allow from env=local_ref
</filesmatch>
 
說明:
在這段配置中涉及到一個名詞referer,其實就是上次訪問的網站連接。配置referer是根據來源連接作限制的,
若是來源連接不是咱們想要的,就直接拒絕,這就是防盜鏈的原理。固然不止是圖片,mp三、rar、zip等文件一樣支持。
上述配置中默認是除了定義的列表中的referer,其它都拒絕。

Directory表示指定哪一個目錄,咱們設置防盜鏈確定是針對本站點,因此直接寫站點。
SetEnv開頭的是referer的白名單
local_ref    表示空的Refer
filesmatch開頭的指的後面這些格式的文件不設置白名單,(就是說針對這些文件作防盜鏈)
order定義訪問控制的,order定義順序,是先容許仍是先拒絕。
allow一行的意思是把上面末尾帶有local_ref的白名單referer作一個容許。其餘的使用上一行的order給deny掉

而後保存檢查錯誤,而後重啓。
# apachectl -t
# apachectl graceful


再看以前用到的一例:
<Directory /data/wwwroot/boke>
        SetEnvIfNoCase Referer "http://kevin.com"; local_ref
        SetEnvIfNoCase Referer "http://xiaobo.com"; local_ref
        SetEnvIfNoCase Referer "^$" local_ref                        
        <filesmatch "\.(txt|doc|mp3|zip|rar|jpg|gif)">
            Order Allow,Deny
            Allow from env=local_ref
        </filesmatch>
 </Directory>


來作一個測試,測試一下http://kevin.com/ai.png瀏覽器看看能不能打開,或者把它以超連接的形式發到論壇,而後點開。
發現點開後出現"Forbidden"的報錯頁面,這種狀況就是空referer,就是防盜鏈起了做用!

8、Apache訪問控制
其實能夠對apache的訪問進行控制,能夠設置白名單或黑名單(經過allow和deny的規則來配置)。

1)示例一
Order deny,allow
deny from all
allow from 127.0.0.1
 
判斷依據是這樣的:
看Order後面的,哪一個在前,哪一個在後
若是deny在前,那麼就須要看deny from這句,而後看allow from這句
規則是一條一條匹配的,無論是deny在前仍是allow在前,都會生效的。
 
2)示例二
Order allow,deny
deny from all
allow from 127.0.0.1
 
這個就會deny全部了,127.0.0.1也會被deny。由於順序是先allow而後deny,雖然開始allow了127,可是後面又拒絕了它。
 
3)示例三
Order allow,deny
deny from all
 
上面的規則就表示,所有都不能經過。
 
4)示例四
Order deny,allow
deny from all
 
上面的規則表示,所有都不能通。
 
Order deny,allow
只有順序,沒有具體規則,表示所有均可以通行(默認的),由於allow在最後了。
 
Order allow,deny
這個表示,所有都不能通行(默認的),由於deny在最後。
 
5)針對某個目錄限制
好比這個目錄很重要,只容許咱們公司的IP訪問,固然這個目錄能夠是網站根目錄,也就是整個站點。
<Directory /usr/local/apache2/htdocs>
    Order deny,allow
    Deny from all
    Allow from 127.0.0.1
</Directory>
 
6)針對請求的URL去限制
<filesmatch "(.*)admin(.*)">
    Order deny,allow
    Deny from all
    Allow from 127.0.0.1
</filesmatch>
 
這裏用到了filesmatch語法,表示匹配的意思。
 
驗證
# curl -x 192.168.0.8:80 www.kevin.com/admin.php -I
HTTP/1.1 403 Forbidden
Date: Wed, 26 Oct 2016 06:24:54 GMT
Server: Apache/2.2.31 (Unix) PHP/5.5.38
Content-Type: text/html; charset=iso-8859-1
 
# curl -x 127.0.0.1:80 www.kevin.com/admin.php -I
HTTP/1.1 401 Authorization Required
Date: Wed, 26 Oct 2016 06:25:03 GMT
Server: Apache/2.2.31 (Unix) PHP/5.5.38
WWW-Authenticate: Basic realm="Please input you acount."
Content-Type: text/html; charset=iso-8859-1

7)Apache防盜鏈主要是防止本網站的連接被別人盜用。能夠使用Apache訪問控制,禁用來源IP訪問
# vim /usr/local/apache2/conf/extra/httpd-vhosts.conf

<VirtualHost *:80>
...........
    <Directory "/data/www">
        AllowOverride None
        Options None
        Order allow,deny
        Allow from all                                               #容許全部訪問
        Deny from 127.0.0.1                                     #禁用127.0.0.1訪問
    </Directory>
...........
</VirtualHost>

測試
# curl -x 127.0.0.1:80 -I www.kevin.com                 #127.0.0.1被禁止訪問
HTTP/1.1 403 Forbidden
Date: Wed, 02 Oct 2018 02:47:23 GMT
Server: Apache/2.2.31 (Unix) PHP/5.4.45
Content-Type: text/html; charset=iso-8859-1

# curl -x 192.168.101.230:80 -I www.kevin.com      #192.168.101.230正常訪問
HTTP/1.1 301 Moved Permanently
Date: Wed, 02 Oct 2018 02:47:42 GMT
Server: Apache/2.2.31 (Unix) PHP/5.4.45
X-Powered-By: PHP/5.4.45
location: forum.php
Cache-Control: max-age=0
Expires: Wed, 02 Oct 2018 02:47:42 GMT
Content-Type: text/html

# curl -x 192.168.101.230:80 -I www.kevin.com/forum.php      #正常訪問
HTTP/1.1 200 OK


8)若是但願白名單限制管理員登陸網頁URI:http://www.kevin.com/xiaobo.php,怎麼作?)
<VirtualHost *:80>
........
   <filesmatch "(.*)xiaobo(.*)">
        Order deny,allow
         Deny from all                         #禁用全部訪問
         Allow from 127.0.0.1              #容許127.0.0.1訪問  
         Allow from 192.168.101.230
   </filesmatch>

...........
</VirtualHost>

重啓Apache服務後,用PC機器(192.168.101.175)訪問http://www.kevin.com/xiaobo.php,報錯403Forbidden。
# curl -x 192.168.101.230:80 -I http://www.kevin.com/xiaobo.php
HTTP/1.1 200 OK                    200,可是192.168.101.230能夠正常訪問

9、禁止解析PHP
某個目錄下禁止解析PHP,這個頗有做用,咱們作網站安全的時候,這個用的不少,好比某些目錄能夠上傳文件,爲了不上傳的文件有木馬,因此咱們禁止這個目錄下面的訪問解析PHP。

配置禁止解析php

<Directory /usr/local/apache2/htdocs/data>
    php_admin_flag engine off 
    <filesmatch "(.*)php">
        Order deny,allow
        Deny from all 
    </filesmatch>
</Directory>

說明:
php_admin_flag engine off 這個語句就是禁止解析php的控制語句,但只這樣配置還不夠,由於這樣配置後用戶依然能夠訪問php文件,
只不過不解析了,但能夠下載,用戶下載php文件也是不合適的,因此有必要再禁止一下。

10、禁止指定user_agent
user_agent叫作瀏覽器標識,目前主流的瀏覽器有IE、chrome、Firefox、360、iphone的Safari、Android手機上的、百度搜索引擎、google搜索引擎等不少,每一種瀏覽器都有對應的user_agent。爲了不一些無用的搜索引擎或機器爬蟲之類引發的帶寬的無辜消耗。

<IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteCond %{HTTP_HOST} ^www.kevin.com$ [OR]
    RewriteCond %{HTTP_HOST} ^www.abcd.com$
    RewriteRule ^/(.*)$ http://www.123.com/$1 [R=301,L]

    RewriteCond %{HTTP_USER_AGENT} ".*Firefox.*" [NC,OR]
    RewriteCond %{HTTP_USER_AGENT} ".*Tomato Bot.*" [NC]
    RewriteRule .* - [F] 
</IfModule>

一樣是使用rewrite模塊來實現限制指定user_agent。本例中:
RewriteRule .* - [F]    能夠直接禁止訪問;
rewritecond用user_agent來匹配,NC表示不區分大小寫,OR表示或者,鏈接下一個條件。

假如咱們要把百度的搜索引擎限制掉,能夠加一條這樣的規則:
RewriteCond %{HTTP_USER_AGENT} ^.*Baiduspider/2.0.* [NC]
RewriteRule .* - [F]

11、限制某個目錄
能夠allow和deny去如今網站根目錄下的某個子目錄,固然這個rewrite也能夠實現。

<IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteCond %{REQUEST_URI} ^.*/shibo/* [NC]
    RewriteRule .* - [F]
</IfModule>

這段配置,會把只要是包含 /shibo/ 字樣的請求都限制了。

12、讓Apache服務器的用戶都有本身的URL,有本身的網頁空間

配置文件裏添加下面一行內容:
UserDir public_html    
  
配置文件中有這行指令後,再在用戶主目錄下建立public_html目錄,裏面放入網頁就能夠了。
訪問的URL,以kevin這個用戶爲例:http://192.168.10.10/~kevin/

還要將配置文件中一段註釋去掉:
#<Directory /home/*/public_html>
#    AllowOverride FileInfo AuthConfig Limit Indexes
#    Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
#    <Limit GET POST OPTIONS PROPFIND>
#        Order allow,deny
#        Allow from all
#    </Limit>
#    <LimitExcept GET POST OPTIONS PROPFIND>
#        Order deny,allow
#        Deny from all
#    </LimitExcept>
#</Directory>
  
以配置訪問權限。


另外一種方式是在配置文件中添加下面一行內容:
UserDir /www/user/*/htdocs

這種方法後的參數是完整的路徑名,把用戶的頁面文件都放在了統一的目錄下(/www/usr/下),
後面的*號是用戶名命名的目錄。訪問方法和上面第一種方法同樣。

十3、Apache的.htaccess文件配置說明
.htaccess文件是Apache服務器中的一個配置文件,它負責相關目錄下的網頁配置。經過對.htaccess文件進行設置,能夠幫咱們實現:網頁301重定向、自定義400/403/404/500錯誤頁面、改變文件擴展名、容許/阻止指定IP用戶訪問、禁止目錄列表、配置默認文檔等功能,能夠說是功能很是強大。

設置網站錯誤頁面
ErrorDocument 400 /error_pages/400.html
ErrorDocument 401 /error_pages/401.html
ErrorDocument 403 /error_pages/403.html
ErrorDocument 404 /error_pages/404.html
ErrorDocument 500 /error_pages/500.html
  
設置網頁301重定向
#從 old_dir 目錄重定向到 new_dir 目錄
Redirect /old_dir/ http://www.yourdomain.com/new_dir/index.html
#把經過二級目錄訪問的請求301重定向到二級域名
RedirectMatch 301 /dir/(.*) http://dir.yourdomain.com/$1
  
禁止指定IP段用戶的訪問
#禁止 IP 爲 255.0.0.0 和 123.45.6.區段的 IP 訪問
order allow,deny
deny from 255.0.0.0
deny from 123.45.6.
allow from all
  
禁止指定來源網頁訪問
#禁止從 otherdomain.com 和 anotherdomain.com 的來源訪問
RewriteEngine on
# Options +FollowSymlinks
RewriteCond %{HTTP_REFERER} otherdomain\.com [NC,OR]
RewriteCond %{HTTP_REFERER} anotherdomain\.com
RewriteRule .* – [F]
  
圖片防盜鏈設置
#從本站之外的域名訪問圖片,一概顯示 feed.jpg
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www\.)?yourdomain.com/.*$ [NC]
RewriteRule \.(gif|jpg|png)$ http://www.yourdomain.com/feed.jpg [R,L]
  
設置文件夾首頁
#防止顯示文件夾列表,當訪問文件夾時,服務器會查找index.html,並將其作爲首頁文件,如不存在依次向後查找
DirectoryIndex index.html index.cgi index.php
  
設置多媒體文件爲可下載而非播放
AddType application/octet-stream .mp3 .mp4
  
自定義HTTP報頭
Header set X-Pingback 「http://www.yourdomain.com/xmlrpc.php」
Header set article-by 「yourdomain.com」
  
設置文件過時時間 Cache Control
# 啓用有效期控制
ExpiresActive On
# gif/png/jpg 有效期爲1個月
ExpiresByType image/gif 「access plus 1 month」
ExpiresByType image/png 「access plus 1 month」
ExpiresByType image/jpg 「access plus 1 month」
# js/css 有效期爲1星期
ExpiresByType text/javascript 「access plus 1 week」
ExpiresByType text/css 「access plus 1 week」
  
WordPress建站程序僞靜態代碼
# BEGIN WordPress          #這是一行註釋,表示 WordPress 的 htaccess 從這裏開始
#若是Apache加載了mod_rewrite.c模塊,則運行如下代碼
RewriteEngine On             #啓用 mod_rewrite 引擎
RewriteBase /                    #設置目錄重寫的基準URL爲 /
RewriteRule ^index\.php$ – [L]              #若是請求路徑是 index.php,中止重寫操做(避免死循環)
RewriteCond %{REQUEST_FILENAME} !-f               #若是請求的不是一個文件,繼續處理
RewriteCond %{REQUEST_FILENAME} !-d              #若是請求的不是一個目錄,繼續處理
RewriteRule . /index.php [L]                 #把全部的請求指向 /index.php
#結束 IfModule
# END WordPress #WordPress 的 htaccess 到這裏結束
  
Discuz x3/x3.1通用僞靜態代碼
#若是Apache加載了mod_rewrite.c模塊,則運行如下代碼
RewriteEngine On
RewriteBase /discuz
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule ^topic-(.+)\.html$ portal.php?mod=topic&topic=$1&%1
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule ^article-([0-9]+)-([0-9]+)\.html$ portal.php?mod=view&aid=$1&page=$2&%1
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule ^forum-(\w+)-([0-9]+)\.html$ forum.php?mod=forumdisplay&fid=$1&page=$2&%1
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule ^thread-([0-9]+)-([0-9]+)-([0-9]+)\.html$ forum.php?mod=viewthread&tid=$1&extra=page\%3D$3&page=$2&%1
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule ^group-([0-9]+)-([0-9]+)\.html$ forum.php?mod=group&fid=$1&page=$2&%1
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule ^space-(username|uid)-(.+)\.html$ home.php?mod=space&$1=$2&%1
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule ^blog-([0-9]+)-([0-9]+)\.html$ home.php?mod=space&uid=$1&do=blog&id=$2&%1
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule ^archiver/(fid|tid)-([0-9]+)\.html$ archiver/index.php?action=$1&value=$2&%1
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule ^([a-z]+[a-z0-9_]*)-([a-z0-9_\-]+)\.html$ plugin.php?id=$1:$2&%1

#http強轉爲https配置
RewriteEngine on         
RewriteBase /            
RewriteCond %{SERVER_PORT} !^443$   
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R]   

----------------------------------------------其餘注意點---------------------------------------------

AliasMatch指令:能夠用正則表達式的方式將多個URL對應至同一個目錄。
例如配置以下:
AliasMatch ^/testph(p|ps) /usr/local/apache2/htdocs/php
 
以上配置表示:
能夠用
http://www.kevin.com/testphp/phpinfo.php
和
http://www.kevin.com/testphps/phpinfo.php
來訪問同一個目錄/usr/local/apache2/htdocs/php中的內容
================================
重定向至其餘URL:
修改配置文件:
Redirect /xueer http://www.bo.com/yiner
 
以上指令表示訪問http:www.kevin.com/xueer時,實際訪問的是http://www.bo.com/yiner
   
Redirect指令有幾個參數:
temp:表示文件當前不在原來所請求的位置上,能夠未來還會在這個位置上,如今只是臨時的。這樣,客戶端會記住原始請求的URL。
permanent:表示被請求的文件不在指定位置上,而是永久在新的位置上。這樣,客戶端會記住新的URL
gone:表示文件不在此位置,並且之後也不在新的位置上。至關於404錯誤。但服務器會認可所請求的文件原來在此位置。因此不會被視爲錯誤。
seeother:表示文件不在所請求的位置,並且被不一樣位置的其它文件取代了(前三個參數都是指同一個文件,這個參數請是不一樣位置的不一樣文件取代了原來位置的原來文件)
   
默認狀況下是使用temp參數
用RedirectMatch指令能夠用正則表達式的方式將多個URL重定向至同一位置。
================================
Apache接受不區分大小寫的URL:
1) 安裝mod_speling模塊
2) 在配置文件中添加:
CheckSpelling On
================================
mod_rewrite模塊用途:
能夠重寫URL請求中的文件,替換成指定的;
能夠拒絕訪問未被引用的請求;
能夠依據查詢字符串來重寫;
能夠將全部請求重定向是單一主機;
將服務器的所有或部分請求重定向至SSL等相關工做
================================
Apache性能測試:
# ab -n 1000 -c 20 http://www.baidu.com/back.html     
其中:
-n  1000 表示請求的數目
-c  20 表示一次送出20 個請求
-h  能夠查看幫助
================================
Apache取得網站快照:
修改配置文件:
<Location /server-status>
    SetHandler server-status
#    Order deny,allow
#    Deny from all
#    Allow from .example.com
</Location>
ExtendedStatus On
================================
將常常查看的文件存入高速緩存區:
修改配置文件:
MMapFile /usr/local/apache2/htdocs/index.html           
須要安裝mod_file_cache模塊
================================
將目錄列表存入高速緩存區
修改配置文件:
IndexOptions +TrackModified

==============一個簡單的apache跳轉頁面配置的小示例=================

示例以下:
假設apache的域名(ServerName)爲www.kevin.com
 
下面配置表示:
訪問http://www.kevin.com/shibo/admin/下匹配的path資源不存在時,頁面跳轉到 http://www.kevin.com/missing.html 的404錯誤頁面。
要是admin下匹配的path資源存在,則不會跳轉!
<IfModule proxy_module>
  ProxyPass /shibo/admin/*  http://www.kevin.com/missing.html
  ProxyPassMatch  /shibo/admin/*  !
</IfModule>
 
下面配置表示:
訪問http://www.kevin.com/shibo/admin/下匹配的全部資源時,頁面跳轉到 http://www.kevin.com/missing.html 的404錯誤頁面。
無論admin下匹配path資源存在仍是不存在,都會跳轉!
<IfModule proxy_module>
  ProxyPass /shibo/admin/  http://www.kevin.com/missing.html
  ProxyPassMatch  /shibo/admin/  !
</IfModule>

以上的配置:
能夠禁止在外網使用域名訪問時跳轉到missing.html的提示頁面。
可是在內網使用ip+port方式訪問,不會跳轉到missing.html提示頁面,會正常訪問。

十4、Apache Rewrite重寫規則總結

1)介紹
Apached的重寫功能,便是mod_rewrite模塊功能,它是apache的一個模塊。它的功能很是強大,能夠操做URL中的全部部分。所以咱們就能夠改寫url,給用戶提供一個簡介大方的url,當用戶訪問時能夠經過mod_rewrite模塊功能轉換爲真正的資源路徑。經過mod_rewrite能實現的功能還有不少,例如隱藏真實地址、實現URL跳轉、域名跳轉、防盜鏈、限制訪問資源類型等等。

2)工做流程
mod_rewrite模塊在運行時會使用兩個Hook程序。
a)第一個是從URL到文件名轉換的Hook。當有訪問到達Apache服務器的時,服務器會確認相應主機(或虛擬主機),這時mod_rewrite模塊就開始工做,它將會先處理服務器全局中mod_rewrite模塊所提供的指令,而後根據用戶提供的指令進行改寫。
b)第二個是修正URL的Hook。在此階段mod_rewrite模塊會處理非全局的設置。例如,目錄中的.htaccess文件中的設置。可是此時已經完成URL的翻譯(由URL轉換爲文件名),所以是沒法在次對目錄級別的URL進行改寫操做,可是moe_rewrite模塊會將已翻譯的URL再次轉換爲URL的狀態,繼續進行目錄級別的URL改寫。(mod_rewrite模塊將會使用讀後請求階段的回叫函數從新開始一個請求的循環處理)

Rewirte模塊規則集的處理
當mod_rewrite在這兩個API階段中開始執行時,它會讀取配置結構中配置好的 (或者是在服務啓動時創建的服務器級的,或者是在遍歷目錄採集到的目錄級的)規則集,而後,啓動URL重寫引擎來處理(帶有一個或多個條件的)規則集。不管是服務器級的仍是目錄級的規則集,都是由同一個URL重寫引擎處理,只是最終結果處理不一樣而已。
規則集中規則的順序是很重要的,由於重寫引擎是按一種特殊的順序處理的:逐個遍歷每一個規則(RewriteRule指令),若是出現一個匹配條件的規則,則可能回頭遍歷已有的規則條件(RewriteCond指令)。因爲歷史的緣由,條件規則是前置的,因此控制流程略顯冗長,細節見下圖-1。

可見,URL首先與每一個規則的Pattern匹配,若是匹配失敗,mod_rewrite將當即終止此規則的處理,繼而處理下一個規則。若是匹配成功,mod_rewrite將尋找相應的規則條件,若是一個條件都沒有,則簡單地用Substitution構造的新值來替換URL,而後繼續處理其餘規則;可是若是條件存在,則開始一個內部循環按其列出的順序逐個處理。對規則條件的處理有所不一樣:URL並不與模式進行匹配,而是首先經過擴展變量、反向引用、查找映射表等步驟創建一個TestString字符串,而後用它來與CondPattern匹配。若是匹配失敗,則整個條件集和對應的規則失敗;若是匹配成功,則執行下一個規則直到全部條件執行完畢。若是全部條件得以匹配,則以Substitution替換URL,而且繼續處理。(本部分引用譯者:金步國)

網絡圖片:

3)URL重寫指令
只須要兩步就能夠完成了。第一使用RewriteEngine開啓mod_rewrite模塊功能;第二經過RewriteRule定義URL重寫規則。
3.1)URL重寫指令套路

RewriteEngine on                 #開啓mod_rewrite模塊功能
RewriteBase 路徑                  #基準URL(使用alias設置別名則需使用這個)
RewriteCond TestString CondPattern [flags]          #重寫條件(能夠多個)
RewriteRule Pattern Substitution [flags]                 #重寫規則

#最後兩行能夠能夠多個
#按順序一個一個執行RewriteRule([flags不終止狀況下])
##以上是經常使用的指令,還有一些不多見的指令,須要的本身去查資料瞭解

3.2)RewriteRule Pattern Substitution [flags]
a)pattern是做用於當前URL的perl兼容的正則表達式。當前URL是指該規則生效時刻的URL的值。它可能與被請求時的URL大相徑庭,由於以前可能被其餘RewriteRule或者alias指令修改過。
b)Substitution是當URL與Pattern匹配成功後。用來代替的字符串。
- 能夠對pattern反向引用$N(N=0~9),表示正則表達式中第N個括號中的內容
- 對最後匹配的RewriteCond反向引用%N(N=0~9),表示最後匹配的RewriteCond第N對括號中的內容
- 服務器變量%{VARNAME}
- 映射函數調用${mapname:key|default} (經過RewriteMap指令定義映射輔助完成)

c)[flags],標誌符,多個則用逗號隔開。

redirect|R [=code] (強制重定向 redirect)
以 http://thishost[:thisport]/(使新的URL成爲一個URI) 爲前綴的Substitution能夠強制性執行一個外部重定向。 若是code沒有指定,則產生一個HTTP響應代碼302(臨時性移動)。若是須要使用在300-400範圍內的其餘響應代碼,只需在此指定這個數值便可, 另外,還能夠使用下列符號名稱之一: temp (默認的), permanent, seeother. 用它能夠把規範化的URL反饋給客戶端,如, 重寫「/~」爲 「/u/」,或對/u/user加上斜槓,等等。

注意: 在使用這個標記時,必須確保該替換字段是一個有效的URL! 不然,它會指向一個無效的位置! 而且要記住,此標記自己只是對URL加上 http://thishost[:thisport]/的前綴,重寫操做仍然會繼續。一般,你會但願中止重寫操做而當即重定向,則還須要使用’L’標記.

forbidden|F (強制URL爲被禁止的 forbidden)
強制當前URL爲被禁止的,即,當即反饋一個HTTP響應代碼403(被禁止的)。使用這個標記,能夠連接若干RewriteConds以有條件地阻塞某些URL。

gone|G(強制URL爲已廢棄的 gone)
強制當前URL爲已廢棄的,即,當即反饋一個HTTP響應代碼410(已廢棄的)。使用這個標記,能夠標明頁面已經被廢棄而不存在了.

proxy|P (強制爲代理 proxy)
此標記使替換成分被內部地強制爲代理請求,並當即(即, 重寫規則處理當即中斷)把處理移交給代理模塊。你必須確保此替換串是一個有效的(好比常見的以 http://hostname開頭的)可以爲Apache代理模塊所處理的URI。使用這個標記,能夠把某些遠程成分映射到本地服務器名稱空間, 從而加強了ProxyPass指令的功能。

注意: 要使用這個功能,代理模塊必須編譯在Apache服務器中。 若是你不能肯定,能夠檢查「httpd -l」的輸出中是否有mod_proxy.c。 若是有,則mod_rewrite能夠使用這個功能;若是沒有,則必須啓用mod_proxy並從新編譯「httpd」程序。

last|L (最後一個規則 last)
當即中止重寫操做,並再也不應用其餘重寫規則。 它對應於Perl中的last命令或C語言中的break命令。這個標記能夠阻止當前已被重寫的URL爲其後繼的規則所重寫。 舉例,使用它能夠重寫根路徑的URL(’/’)爲實際存在的URL, 好比, ‘/e/www/’.

next|N (從新執行 next round)
從新執行重寫操做(從第一個規則從新開始). 這時再次進行處理的URL已經不是原始的URL了,而是經最後一個重寫規則處理的URL。它對應於Perl中的next命令或C語言中的continue命令。 此標記能夠從新開始重寫操做,即, 當即回到循環的頭部。
可是要當心,不要製造死循環!

chain|C (與下一個規則相連接 chained)
此標記使當前規則與下一個(其自己又能夠與其後繼規則相連接的, 並能夠如此反覆的)規則相連接。 它產生這樣一個效果: 若是一個規則被匹配,一般會繼續處理其後繼規則, 即,這個標記不起做用;若是規則不能被匹配,則其後繼的連接的規則會被忽略。好比,在執行一個外部重定向時, 對一個目錄級規則集,你可能須要刪除「.www」 (此處不該該出現「.www」的)。

type|T=MIME-type(強制MIME類型 type)
強制目標文件的MIME類型爲MIME-type。 好比,它能夠用於模擬mod_alias中的ScriptAlias指令,之內部地強制被映射目錄中的全部文件的MIME類型爲「application/x-httpd-cgi」。

nosubreq|NS (僅用於不對內部子請求進行處理 no internal sub-request)
在當前請求是一個內部子請求時,此標記強制重寫引擎跳過該重寫規則。好比,在mod_include試圖搜索可能的目錄默認文件(index.xxx)時, Apache會內部地產生子請求。對子請求,它不必定有用的,並且若是整個規則集都起做用,它甚至可能會引起錯誤。因此,能夠用這個標記來排除某些規則。

根據你的須要遵循如下原則: 若是你使用了有CGI腳本的URL前綴,以強制它們由CGI腳本處理,而對子請求處理的出錯率(或者開銷)很高,在這種狀況下,能夠使用這個標記。

nocase|NC (忽略大小寫 no case)
它使Pattern忽略大小寫,即, 在Pattern與當前URL匹配時,’A-Z’ 和’a-z’沒有區別。

qsappend|QSA (追加請求串 query string append)
此標記強制重寫引擎在已有的替換串中追加一個請求串,而不是簡單的替換。若是須要經過重寫規則在請求串中增長信息,就能夠使用這個標記。

noescape|NE (在輸出中不對URI做轉義 no URI escaping)
此標記阻止mod_rewrite對重寫結果應用常規的URI轉義規則。 通常狀況下,特殊字符(如’%’, ‘$’, ‘;’等)會被轉義爲等值的十六進制編碼。 此標記能夠阻止這樣的轉義,以容許百分號等符號出如今輸出中,如:
RewriteRule /foo/(.*) /bar?arg=P1=$1 [R,NE] 能夠使’/foo/zed’轉向到一個安全的請求’/bar?arg=P1=zed’.

passthrough|PT (移交給下一個處理器 pass through)
此標記強制重寫引擎將內部結構request_rec中的uri字段設置爲 filename字段的值,它只是一個小修改,使之能對來自其餘URI到文件名翻譯器的 Alias,ScriptAlias, Redirect 等指令的輸出進行後續處理。舉一個能說明其含義的例子:若是要經過mod_rewrite的重寫引擎重寫/abc爲/def,而後經過mod_alias使/def轉變爲/ghi,能夠這樣:
RewriteRule ^/abc(.*) /def$1 [PT]
Alias /def /ghi

若是省略了PT標記,雖然mod_rewrite運做正常, 即, 做爲一個使用API的URI到文件名翻譯器,它能夠重寫uri=/abc/…爲filename=/def/…,可是,後續的mod_alias在試圖做URI到文件名的翻譯時,則會失效。

注意: 若是須要混合使用不一樣的包含URI到文件名翻譯器的模塊時, 就必須使用這個標記。。混合使用mod_alias和mod_rewrite就是個典型的例子。

For Apache hackers
若是當前Apache API除了URI到文件名hook以外,還有一個文件名到文件名的hook, 就不須要這個標記了! 可是,若是沒有這樣一個hook,則此標記是惟一的解決方案。 Apache Group討論過這個問題,並在Apache 2.0 版本中會增長這樣一個hook。

skip|S=num (跳事後繼的規則 skip)
此標記強制重寫引擎跳過當前匹配規則後繼的num個規則。 它能夠實現一個僞if-then-else的構造: 最後一個規則是then從句,而被跳過的skip=N個規則是else從句. (它和’chain|C’標記是不一樣的!)

env|E=VAR:VAL (設置環境變量 environment variable)
此標記使環境變量VAR的值爲VAL, VAL能夠包含可擴展的反向引用的正則表達式$N和%N。 此標記能夠屢次使用以設置多個變量。這些變量能夠在其後許多狀況下被間接引用,但一般是在XSSI (via ) or CGI (如 $ENV{’VAR’})中, 也能夠在後繼的RewriteCond指令的pattern中經過%{ENV:VAR}做引用。使用它能夠從URL中剝離並記住一些信息。

cookie|CO=NAME:VAL:domain[:lifetime[:path]] (設置cookie)
它在客戶端瀏覽器上設置一個cookie。 cookie的名稱是NAME,其值是VAL。 domain字段是該cookie的域,好比’.apache.org’, 可選的lifetime是cookie生命期的分鐘數,可選的path是cookie的路徑。

3.3)RewriteCond TestString CondPattern [flags]
Rewritecond指令定義一條規則條件。在一條rewriterule指令前面可能會有一條或者多條rewritecond指令,只有當自身模板匹配成功且這些條件也知足時(即RewriteRule中的pattern匹配成功),規則條件才被應用於當前URL處理。

3.3.1)TestString是一個純文本的字符串
能夠對pattern反向引用$N(N=0~9),緊跟在RewriteCond後面的RewriteRule正則表達式中第N個括號中的內容
反向引用%N(N=0~9),表示RewriteCond中CondPattern中第N對括號中的內容
服務器變量%{VARNAME}

3.3.2)CondPattern是條件pattern,一個應用於當前實例TestString的正則表達式。即TestString與條件pattern條件進行匹配。若是匹配則RewriteCond的值爲Rrue,反之爲False

能夠使用如下特殊變量(可以使用'!'實現反轉)
'>CondPattern’ (大於) 將condPattern看成一個普通字符串,將它和TestString進行比較,當TestString 的字符大於CondPattern爲真。
‘=CondPattern’ (等於) 將condPattern看成一個普通字符串,將它和TestString進行比較,當TestString 與CondPattern徹底相同時爲真.若是CondPattern只是 「」 (兩個引號緊挨在一塊兒) 此時需TestString 爲空字符串方爲真。
‘-d’ (是否爲目錄) 將testString看成一個目錄名,檢查它是否存在以及是不是一個目錄。
‘-f’ (是不是regular file) 將testString看成一個文件名,檢查它是否存在以及是不是一個regular文件。
‘-s’ (是否爲長度不爲0的regular文件) 將testString看成一個文件名,檢查它是否存在以及是不是一個長度大於0的regular文件。
‘-l’ (是否爲symbolic link) 將testString看成一個文件名,檢查它是否存在以及是不是一個 symbolic link。
‘-F’ (經過subrequest來檢查某文件是否可訪問) 檢查TestString是不是一個合法的文件,並且經過服務器範圍內的當前設置的訪問控制進行訪問。這個檢查是經過一個內部subrequest完成的, 所以須要當心使用這個功能以下降服務器的性能。
‘-U’ (經過subrequest來檢查某個URL是否存在) 檢查TestString是不是一個合法的URL,並且經過服務器範圍內的當前設置的訪問控制進行訪問。這個檢查是經過一個內部subrequest完成的, 所以須要當心使用這個功能以下降服務器的性能。

3.3.3)[flags]是第三個參數,多個標誌之間用逗號隔開)
’nocase|NC’ (不區分大小寫) 在擴展後的TestString和CondPattern中,比較時不區分文本的大小寫。注意,這個標誌對文件系統和subrequest檢查沒有影響.
’ornext|OR’ (創建與下一個條件的或的關係) 默認的狀況下,二個條件之間是AND的關係,用這個標誌將關係改成OR。

4)Rewrite時服務器變量(僅列出少數)
HTTP headers:HTTP_USER_AGENT, HTTP_REFERER, HTTP_COOKIE, HTTP_HOST, HTTP_ACCEPT
connection & request:REMOTE_ADDR, QUERY_STRING
server internals::DOCUMENT_ROOT, SERVER_PORT, SERVER_PROTOCOL
system stuff: TIME_YEAR, TIME_MON, TIME_DAY

5)簡單正則表達式規則
. 匹配任何單字符
[chars]   匹配字符串:chars
[^chars]   不匹配字符串:chars
text1|text2   可選擇的字符串:text1或text2
?   匹配0到1個字符
*   匹配0到多個字符
匹配1到多個字符
^   字符串開始標誌
$   字符串結束標誌
\n   轉義符標誌

注意:一代Apache要求URL有斜槓而二代Apache卻不容許,所以使用 ^/?

6)Rewirte主要的功能就是實現URL的跳轉,它的正則表達式是基於Perl語言。
可基於服務器級的(httpd.conf)和目錄級的 (.htaccess)兩種方式。若是要想用到rewrite模塊,必須先安裝或加載rewrite模塊,方法有兩種:
一種是編譯apache的時候就直接 安裝rewrite模塊。
另外一種是編譯apache時以DSO模式安裝apache,而後再利用源碼和apxs來安裝rewrite模塊。

基於服務器級的(httpd.conf)有兩種方法,一種是在httpd.conf的全局下直接利用RewriteEngine on來打開rewrite功能;另外一種是在局部裏利用RewriteEngine on來打開rewrite功能,下面將會舉例說明,須要注意的是,必須在每一個virtualhost裏用RewriteEngine on來打開rewrite功能。不然virtualhost裏沒有RewriteEngine on它裏面的規則也不會生效。

基於目錄級的(.htaccess),要注意一點那就是必須打開此目錄的FollowSymLinks屬性且在.htaccess裏要聲明 RewriteEngine on。

rewrite跳轉舉列說明

示例一:
下面是在一個虛擬主機裏定義的規則。功能是把client請求的主機前綴不是www.kevin.cn和192.168.10.20都跳轉到主機前綴爲http://www.bobo.cn, 避免相同
內容的網頁有多個指向的域名,如http://kevin.cn。

配置以下:
NameVirtualHost 192.168.10.20:80
ServerAdmin slj@bobo.cn
DocumentRoot 「/web」
ServerName kevin.cn

RewriteEngine on  #打開rewirte功能
RewriteCond %{HTTP_HOST} !^www.kevin.cn [NC]  #聲明Client請求的主機中前綴不是www.kevin.cn, 其中 [NC] 的意思是忽略大小寫
RewriteCond %{HTTP_HOST} !^192.168.10.20 [NC]    #聲明Client請求的主機中前綴不是192.168.10.20,其中 [NC] 的意思是忽略大小寫
RewriteCond %{HTTP_HOST} !^$  #聲明Client請求的主機中前綴不爲空
RewriteRule ^(.*) http://www.bobo.cn/ [L]    

#最後一行含義是若是Client請求的主機中的前綴符合上述條件,則直接進行跳轉到http://www.bobo.cn/,[L]意味着當即中止重寫操做,並再也不應用其餘重寫規則。
這裏的.*是指匹配全部URL中不包含換行字符,()括號的功能是把全部的字符作一個標記,以便於後面的應用.就是引用前面裏的 (.*)字符。

=============================================
示例二:將輸入 hui.com 的域名時跳轉到http://www.kevin.cn

配置以下:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^hui.com [NC]
RewriteRule ^(.*) http://www.kevin.cn/ [L]

=============================================
示例三:
近期更換了域名,新域名爲www.grace.com, 更加簡短好記。這時須要將原來的域名ss.bobo.cn, 以及論壇所在地址ss.bobo.cn/bbs/定向到新的域名,
以便用戶能夠找到,而且使原來的論壇URL繼續有效而不出現404未找到,好比原來的http://ss.bobo.cn/bbs/tread-60.html, 讓它在新的域名下繼續
有效,點擊後轉發到http://bbs.grace.com/tread-60.html,而其餘網頁,如原先的http: //ss.bobo.cn/purchase不會到二級域名bbs.grace.com/purchase上,
而是到 www.grace.com/purchase按照這樣的要求重定向規則應該這樣寫:

RewriteEngine On
RewriteCond %{REQUEST_URI} ^/bbs/
RewriteRule ^bbs/(.*) http://bbs.grace.com/$1 [R=permanent,L]
RewriteCond %{REQUEST_URI} !^/bbs/
RewriteRule ^(.*) http://www.grace.com/$1 [R=permanent,L]

=============================================
示例四:同時達到下面兩個要求:
用http://www.kevin.cn/xxx.php 來訪問http://www.kevin.cn/xxx/
用http://xiaoye.kevin.cn 來訪問 http://www.kevin.cn/user.php?username=xiaoye的功能

配置以下:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www.kevin.cn
RewriteCond %{REQUEST_URI} !^user.php$
RewriteCond %{REQUEST_URI} .php$
RewriteRule (.*).php$ http://www.kevin.cn/$1/ [R]
RewriteCond %{HTTP_HOST} !^www.kevin.cn
RewriteRule ^(.+) %{HTTP_HOST} [C]
RewriteRule ^([^.]+).kevin.cn http://www.kevin.cn/user.php?username=$1

=============================================
示例五:實現下面要求:
/type.php?typeid=* –> /type*.html
/type.php?typeid=*&page=* –> /type*page*.html

配置以下:
RewriteRule ^/type([0-9]+).html$ /type.php?typeid=$1 [PT]
RewriteRule ^/type([0-9]+)page([0-9]+).html$ /type.php?typeid=$1&page=$2 [PT]

=============================================
示例六:使用Apache的URL Rewrite配置多用戶虛擬服務器

要實現這個功能,首先要在DNS服務器上打開域名的泛域名解析(本身作或者找域名服務商作)。
好比,把 *.bobo.us和 *.bobo.cn所有解析到IP地址爲70.40.213.183上。Apache中關於*.bobo.us的虛擬主機的設定以下:

ServerAdmin webmaster@bobo.us
DocumentRoot /home/www/www.bobo.us
ServerName dns.bobo.us
ServerAlias dns.bobo.us bobo.us *.bobo.us
CustomLog /var/log/httpd/osa/access_log.log」 common
ErrorLog /var/log/httpd/osa/error_log.log」
AllowOverride None
Order deny,allow

#AddDefaultCharset GB2312
RewriteEngine on
RewriteCond %{HTTP_HOST} ^[^.]+.bobo.(cn|us)$
RewriteRule ^(.+) %{HTTP_HOST}$1 [C]
RewriteRule ^([^.]+).bobo.(cn|us)(.*)$ /home/www/www.bobo.us/sylvan$3?un=$1&%{QUERY_STRING} [L]

配置說明:
在上面這段設定中,把*.bobo.cn和*.bobo.us 的Document Root都設定到了 /home/www/www.bobo.us
繼續看下去,這裏配置了URL Rewrite規則。
倒數第四行表示:打開URL Rewrite功能
倒數第三行表示:匹配條件,若是用戶輸入的URL中主機名是相似 xxxx.bobo.us 或者 xxxx.bobo.cn 就執行下面一句
倒數第二行表示:把用戶輸入完整的地址(GET方式的參數除外)做爲參數傳給下一個規則,[C]是Chain串聯下一個規則的意思
倒數第一行:最關鍵的是這一句,使用證則表達式解析用戶輸入的URL地址,把主機名中的用戶名信息做爲名爲un的參數傳給/home/www/dev.bobo.us 目錄下的腳本,
並在後面跟上用戶輸入的GET方式的傳入參數。並指明這是最後一條規則([L]規則)。注意,在這一句中指明的重寫後的地址用的是服務器上 的絕對路徑,這是內部跳轉。
若是使用http://xxxx這樣的URL格式,則被稱爲外部跳轉。使用外部跳轉的話,瀏覽着的瀏覽器中的URL地址會改變成新的地址,而使用內部跳轉則瀏覽器中的地址不發生
改變,看上去更像實際的二級域名虛擬服務器。

=============================================
示例七:Rewrite 防盜鏈正則
不容許www.im286.com和www.chinaz.com 這兩個網站盜鏈 , 其它的網站均可以盜鏈。

配置以下:
RewriteEngine On
RewriteCond %{HTTP_REFERER} chinaz.com [NC]
RewriteCond %{HTTP_REFERER} im286.com [NC]
RewriteRule .*\.(jpg|jpeg|gif|png|rar|zip|txt|ace|torrent|gz|swf)$ http://www.xxx.com/fuck.png [R,NC,L]

=============================================
示例七:關於判斷 USER AGENT 。配置以下:

RewriteEngine on
RewriteCond %{HTTP_USER_AGENT} ^MSIE [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^Opera [NC]
RewriteRule ^.* – [F,L] 

#這裏」-」表示沒有替換,瀏覽器爲IE和Opera的訪客將被禁止訪問。 

=============================================
示例八:自動添加.php擴展名及自動換.html到.php擴展名。

配置以下:
RewriteEngine On
RewriteBase /test
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ([^/]+)$ /test/$1.php
#for hui: /test/admin => /test/admin.php

RewriteRule ([^/]+)\.html$ /test/$1.php [L]
#for hui: /test/admin.html => /test/admin.php

=============================================
示例九:限制目錄只能顯示圖片

配置以下:
< IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !^.*\.(gif|jpg|jpeg|png|swf)$
RewriteRule .*$ – [F,L]
< /IfModule> 

7)apache重寫規則的示例解析                                                                                                                                                                

在.htaccess裏進行規制重寫:
RewriteEngine ON
RewriteRule  ^user/(w+)/?$user.php?id=$1
 
配置說明:
^:輸入的開頭  以user/開頭請求的地址
(w+):提取全部的字母,傳給$1
/?:可選斜槓
$:結束符
替換爲:user.php?id=*
 
注意:
有些apache不兼容簡寫模式 w+ => [a-zA-Z_-]
 
===============================
禁止IE和Opera瀏覽器訪問
 
RewriteEngine on
RewriteCond %{HTTP_USER_AGENT} ^MSIE [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^Opera [NC]
RewriteRule ^.* - [F,L]       #'-'表示不替換URL
 
===============================
不合法路徑返回首頁
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
 
==============================
防盜鏈
 
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^http://(.+.)?mysite.com/ [NC]          #判斷請求的是不是本身的域名
RewriteCond %{HTTP_REFERER} !^$                        #{HTTP_REFERER}不爲空
RewriteRule .*.(jpe?g|gif|bmp|png)$ /images/nohotlink.jpg [L]         #返回警告圖片
 
==============================
改變訪問URL目錄名),即隱藏真實的目錄名字
 
RewriteEngine On
RewriteRule ^/?old_dir/([a-z\.]+)$  new_dir/$1 [R=301,L]
#new_dir爲真正目錄
 
==============================
建立無文件後綴連接
 
RewriteEngine On
RewriteCond %{REQUEST_FILENAME}.php -f                #判斷該後綴文件是否存在
RewriteRule ^/?([a-zA-Z0-9]+)$ $1.php [L]
RewriteCond %{REQUEST_FILENAME}.html -f               #判斷該後綴文件是否存在
RewriteRule ^/?([a-zA-Z0-9]+)$ $1.html [L]
 
==============================
限制只能顯示圖片
 
RewriteEngine on
RewriteCond %{REQUEST_FILENAME}  !^.*\.(gif|jpg|jpeg|png|swf)$
RewriteRule .*$ - [F,L]
 
==============================
文件不存在重定向404
 
RewriteEngine on
RewriteCond  %{REQUEST_FILENAME}  !f
RewriteCond  %{REQUEST_FILENAME}  !d
RewriteRule .? /404.php [L]

====================================其餘配置示例====================================
1)去掉域名中的www標記
RewriteCond %{HTTP_HOST} !^jkevin\.net$ [NC]
RewriteRule .? http://jkevin.net%{REQUEST_URI} [R=301,L]
  
2)去掉www標記,可是保存子域名
RewriteCond %{HTTP_HOST} ^www\.(([a-z0-9_]+\.)?jkevin\.net)$ [NC]
RewriteRule .? http://%1%{REQUEST_URI} [R=301,L]
  
這裏,當匹配到1%變量之後,子域名纔會在%2(內部原子)中抓取到,而咱們須要的正是這個%1變量。
  
3)給子域名加www標記
RewriteCond %{HTTP_HOST} ^([a-z.]+)?jkevin\.net$ [NC]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule .? http://www.%1jkevin.net%{REQUEST_URI} [R=301,L]
  
這個規則抓取二級域名的%1變量,若是不是以www開始,那麼就加www,之前的域名以及{REQUEST_URI}會跟在其後。
  
4)防止圖片盜鏈
一些站長不擇手段的將你的圖片盜鏈在他們網站上,耗費你的帶寬。你能夠加一下代碼阻止這種行爲。
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www\.)?jkevin\.net/ [NC]
RewriteRule \.(gif|jpg|png)$ – [F]
  
若是{HTTP_REFERER}值不爲空,或者不是來自你本身的域名,這個規則用[F]FLAG阻止以gif|jpg|png 結尾的URL
若是對這種盜鏈你是堅定鄙視的,你還能夠改變圖片,讓訪問盜鏈網站的用戶知道該網站正在盜用你的圖片。
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www\.)?jkevin\.net/.*$ [NC]
RewriteRule \.(gif|jpg|png)$ 你的圖片地址 [R=301,L]
  
除了阻止圖片盜鏈連接,以上規則將其盜鏈的圖片所有替換成了你設置的圖片。
你還能夠阻止特定域名盜鏈你的圖片:
RewriteCond %{HTTP_REFERER} !^http://(www\.)?leech_site\.net/ [NC]
RewriteRule \.(gif|jpg|png)$ – [F,L]
  
這個規則將阻止域名黑名單上全部的圖片連接請求。
固然以上這些規則都是以{HTTP_REFERER}獲取域名爲基礎的,若是你想改用成IP地址,用{REMOTE_ADDR}就能夠了。
  
5)若是文件不存在重定向到404頁面
若是你的主機沒有提供404頁面重定向服務,那麼咱們本身建立。
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .? /404.php [L]
  
這裏-f匹配的是存在的文件名,-d匹配的存在的路徑名。
這段代碼在進行404重定向以前,會判斷你的文件名以及路徑名是否存在。
你還能夠在404頁面上加一個?url=$1參數:
RewriteRule ^/?(.*)$ /404.php?url=$1 [L]
  
這樣,你的404頁面就能夠作一些其餘的事情,例如發一個郵件提醒,加一個搜索等等。
  
6)重命名目錄
若是你想在網站上重命名目錄,試試這個:
RewriteRule ^/?old_directory/([a-z/.]+)$ new_directory/$1 [R=301,L]
  
在規則裏我添加了一個「.」(注意不是表明得全部字符,前面有轉義符)來匹配文件的後綴名。
  
7)將.html後綴名轉換成.php
前提是.html文件能繼續訪問的狀況下,更新你的網站連接。
RewriteRule ^/?([a-z/]+)\.html$ $1.php [L]
  
這不是一個網頁重定向,因此訪問者是不可見的。讓他做爲一個永久重定向(可見的),將FLAG修改[R=301,L]。
  
8)建立無文件後綴名連接
若是你想使你的PHP網站的連接更加簡潔易記-或者隱藏文件的後綴名,試試這個:
RewriteRule ^/?([a-z]+)$ $1.php [L]
  
若是網站混有PHP以及HTML文件,你能夠用RewriteCond先判斷該後綴的文件是否存在,而後進行替換:
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^/?([a-zA-Z0-9]+)$ $1.php [L]
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^/?([a-zA-Z0-9]+)$ $1.html [L]
  
若是文件是以.php爲後綴,這條規則將被執行。
  
9)檢查查詢變量裏的特定參數
若是在URL裏面有一個特殊的參數,你可用RewriteCond鑑別其是否存在:
複製代碼 代碼以下:
RewriteCond %{QUERY_STRING} !uniquekey=
RewriteRule ^/?script_that_requires_uniquekey\.php$ other_script.php [QSA,L]
  
以上規則將檢查{QUERY_STRING}裏面的uniquekey參數是否存在,若是{REQUEST_URI}值爲script_that_requires_uniquekey,將會定向到新的URL。
  
10)刪除查詢變量
Apache的mod_rewrite模塊會自動辨識查詢變量,除非你作了如下改動:
a).分配一個新的查詢參數(你能夠用[QSA,L]FLAG保存最初的查詢變量)
b).在文件名後面加一個「?」(好比index.php?)。符號「?」不會在瀏覽器的地址欄裏顯示。
  
11)用新的格式展現當前URI
如 果這就是咱們當前正在運行的URLs:/index.php?id=nnnn。咱們很是但願將其更改爲/nnnn而且讓搜索引擎以新格式展示。首先,咱們 爲了讓搜索引擎更新成新的,得將舊的URLs重定向到新的格式,可是,咱們還得保證之前的index.php照樣可以運行。是否是被我搞迷糊了?
實 現以上功能,訣竅就在於在查詢變量中加了一個訪問者看不到的標記符「marker」。咱們只將查詢變量中沒有出現「marker」標記的連接進行重定向, 而後將原有的連接替換成新的格式,而且經過[QSA]FLAG在已有的參數加一個「marker」標記。
  
如下爲實現的方式:
RewriteCond %{QUERY_STRING} !marker
RewriteCond %{QUERY_STRING} id=([-a-zA-Z0-9_+]+)
RewriteRule ^/?index\.php$ %1? [R=301,L]
RewriteRule ^/?([-a-zA-Z0-9_+]+)$ index.php?marker &id=$1 [L]
  
這 裏,原先的URL:http://www.jkevin.net/index.php?id=nnnn,不包含marker,因此被第一個規則永久重定向到 http://www.jkevin.net/nnnn,
第二個規則將http://www.jkevin.net/nnnn反定向到http: //www.jkevin.net/index.php?marker&id=nnnn,而且加了marker以及id=nnnn兩個變量,
最後 mod_rewrite就開始進行處理過程。
第二次匹配,marker被匹配,因此忽略第一條規則,這裏有一個「.」字符會出如今http://www.jkevin.net/index.php?marker&id=nnnn中,因此第二條規則也會被忽略,這樣咱們就完成了。
  
注意,這個解決方案要求Apache的一些擴展功能,因此若是你的網站放於在共享主機中會遇到不少障礙。
  
12)保證安全服務啓用
Apache能夠用兩種方法辨別你是否開啓了安全服務,分別引用{HTTPS}和{SERVER_PORT}變量:
RewriteCond %{REQUEST_URI} ^secure_page\.php$
RewriteCond %{HTTPS} !on
RewriteRule ^/?(secure_page\.php)$ https://www.jkevin.net/$1 [R=301,L]
  
以上規則測試{REQUEST_URI}值是否等於咱們的安全頁代碼,而且{HTTPS}不等於on。
若是這兩個條件同時知足,請求將被重定向到安全服務URI.另外你可用{SERVER_PORT}作一樣的測試,443是經常使用的安全服務端口
RewriteCond %{REQUEST_URI} ^secure_page\.php$
RewriteCond %{SERVER_PORT} !^443$
RewriteRule ^/?(secure_page\.php)$ https://www.jkevin.net/$1 [R=301,L]
  
13)在特定的頁面上強制執行安全服務
遇到同一個服務器根目錄下分別有一個安全服務域名和一個非安全服務域名,因此你就須要用RewriteCond 判斷安全服務端口是否佔用,而且只將如下列表的頁面要求爲安全服務:
RewriteCond %{SERVER_PORT} !^443$
RewriteRule ^/?(page1|page2|page3|page4|page5)$ https://www.jkevin.net/%1[R=301,L]
  
如下是怎樣將沒有設置成安全服務的頁面返回到80端口:
RewriteCond %{ SERVER_PORT } ^443$
RewriteRule !^/?(page6|page7|page8|page9)$http://www.jkevin.net%{REQUEST_URI} [R=301,L]
其實Rewrite裏運用最多的還應該是正則表達式,若是瞭解點兒正則的話,寫起這個規則仍是比較簡單的。
  
14) ProxyPass規則示例
  
訪問http://www.kevin.com/shibo/admin/下匹配的全部資源時,頁面跳轉到 http://www.kevin.com/missing.html 的404錯誤頁面。
<IfModule proxy_module>
  ProxyPass /shibo/admin/  http://www.kevin.com/missing.html
  ProxyPassMatch  /shibo/admin/  !
</IfModule>

===================其餘補充=========================
Apache的URL地址重寫的方法:
--------------第一種方法--------------
Apache環境中若是要將URL地址重寫,正則表達式是最基本的要求,但對於通常的URL地址來講,基本的匹配就能實現咱們大部分要求,所以除非是很是特殊的URL地址,
但這不是我要討論的範圍,簡單幾招學會Apache中URL地址重寫,經過實例展現,輕鬆學會URL地址重寫:
 
URL實例
重寫URL:http://www.baidu.com/?p=152
原始URL:http://www.baidu.com/p152.html
 
重寫規則:
^p([0-9]+)\.html      /?p=$1     [L]
 
正則基礎知識:
^ 匹配行的開始,匹配URL地址的開頭部分,對於RewriteRule而言,域名(http://www.biuuu.com)不是URL地址的一部分,如上:?p=152
() 分隔一個被捕獲的表達式,如上:([0-9]+)
[] 定義字符類,如上:[0-9] 表示從0-9的數字
+ 說明前面的字符能夠被重複匹配1次或數次,如上:[0-9]+,表示任何數字組合
\ 字符轉義,如上:轉義.
 
其它:
[L] 表示last,中止匹配其它
 
方法以下:
1)打開httpd.conf文件,找到
#LoadModule rewrite_module modules/mod_rewrite.so 註釋前面#
2)打開httpd-vhosts.conf文件,在VirtualHost添加劇寫規則,
RewriteEngine On
RewriteRule ^p([0-9]+)\.html      /?p=$1     [L]
 
基本上就上面這兩個步驟,其實總的來講,Apache中URL地址重寫仍是比較簡單的,比看文檔學習要快的多,不過要想深刻了解仍是有必要看看相關文檔的,其它規則能夠
自定義。記住一點:任何匹配其實就是一個正則表達式的替換過程。
 
建立友好的搜索引擎URL地址對於PHP程序員來講很是重要,所以簡單學會Apache中URL地址重寫將是一項最基本的要求。
 
--------------第二種方法--------------
1)首先檢查是否已安裝rewrite模塊:
cat httpd.conf | grep rewrite
LoadModule rewrite_module modules/mod_rewrite.so
 
2)生成僞靜態html鏈接:
生成僞靜態html
在<VirtualHost>段最後加入
RewriteEngine on
RewriteRule /goods([0-9]+).html /goods.php?id=$1 [PT] 
 
更標準的寫法爲:
RewriteRule ^(.*)/goods([0-9]+).html$ $1/goods.php?id=$2 [PT]
 
更簡潔的寫法:
/goods(\d+)\.html /goods\.php\?id=$1
 
第一個(0-9]+)對應參數$1,以此類推第二個對應$2
 
舉例:
RewriteRule /forum-([0-9]+)-([0-9]+)\.html /forumdisplay.php?fid=$1&page=$2 [PT]
 
測試http://www.xxx.com/goods1.html 是否與/goods.php?id=1的內容相同。
最後將全部連接換成設置後的僞靜態html地址方式。
[PT]:url全局轉換,即轉換過的goods31.html對應goods.php?id=31 (默認就是這個不加參數)
[R]:    url重定向  即便用goods31.html訪問時跳轉到goods.php?id=31
 
3)防盜鏈:
RewriteCrond %{HTTP_HOST} !upkiller.com [R=301,L]
RewriteRule ^(.*)$ http://www.upkiller.com/warning.html [R=301,L]
 
把不是來自upkiller.com的請求重定向到http://www.upkiller.com
 
更好的作法:
RewriteCond %{HTTP_REFERER} !^http://(www\.)?upkiller\.com/.*$ [NC]
RewriteRule \.(mp3|rar|jpe|gif)$ http://www.upkiller.com/warning.jpg [R=301,L]
 
4)防百度爬蟲:
RewriteCond %{HTTP_USER_AGENT} ^Baiduspider [OR]
RewriteRule ^(.*)$ http://www.google.com [R=301,L]
 
把來自百度的爬蟲轉到goole

=====================Apache的ProxyPass使用小結=====================
該指令能夠將遠程服務器映射到本地服務器的URL空間;本地的服務器並非扮演傳統意義上的代理服務器的角色,而是表現爲遠程服務器的一個鏡像。此本地服務器常被成爲反向代理(reversed proxy)或者是網關(gateway)。路徑是指本地虛擬路徑的名字;url指遠程服務器的一個部分URL,不能包含查詢字符串。

描述:將遠程服務器映射到本地服務器的URL空間
語法:ProxyPass [路徑] !|url [鍵=值 鍵=值 ...]] [nocanon]
上下文: server config, virtual host, directory
狀態:擴展
模塊:mod_proxy

apache中的mod_proxy模塊主要做用就是進行url的轉發,即具備代理的功能。應用此功能,能夠很方便的實現同tomcat等應用服務器的整合,甚者能夠很方便的實現web集羣的功能。httpd.conf配置:

#保證如下模塊加載  
LoadModule proxy_module modules/mod_proxy.so  
LoadModule proxy_http_module modules/mod_proxy_http.so  
#配置ProxyPass  
ProxyPass /new/ http://kevincom/  
ProxyPass /new2/ http://192.168.0.169:8080/  

須要注意:
順序很重要:排除的指令必須在通常的ProxyPass指令以前。上面的配置已經能夠實現大部分功能了,要控制細節!

例子:
使用apache做爲域名www.kevin.com代理服務器,讓其暴露在公網上,即DNS解析到本機器上,真正提供web服務器的是另外一臺位於同一內網的機器上,假設起IP是172.16.50.40,那麼只須要以下配置就能夠了。

ProxyPass / http://172.16.50.40/ 
ProxyPassReverse / http://172.16.50.40/

-   ProxyPass 很好理解,就是把全部來自客戶端對http://www.kevin.com的請求轉發給http://172.16.50.40上進行處理;
-   ProxyPassReverse的配置老是和ProxyPass 一致,但用途很讓人費解。彷佛去掉它很能很好的工做,事實真的是這樣麼,其實否則,若是響應中有302重定向,ProxyPassReverse就派上用場。舉例說明,假設用戶訪問http://www.kevin.com/exam.php,經過轉發交給http://172.16.50.40 /exam.php處理,假定exam.php處理的結果是實現redirect到login.php(使用相對路徑,即省略了域名信息),若是沒有配置反向代理,客戶端收到的請求響應是重定向操做,而且重定向目的url爲http://172.16.50.40/login.php ,而這個地址只是代理服務器能訪問到的,可想而知,客戶端確定是打不開的,反之若是配置了反向代理,則會在轉交HTTP重定向應答到客戶端以前調整它爲 http://www.kevin.com/login.php,便是在原請求以後追加上了redirect的路徑。當客戶端再次請求http: //www.kevin.com/login.php,代理服務器再次工做把其轉發到http://172.16.50.40/login.php。
-   客戶端到服務器稱之爲正向代理,那服務器到客戶端就叫反向代理。

ProxyPass與ProxyPassReverse及ProxyPassMatch這幾個都是Apache的代理指令
1)ProxyPass
語法:ProxyPass [path] !|url
它主要是用做URL前綴匹配,不能有正則表達式,它裏面配置的Path其實是一個虛擬的路徑,在反向代理到後端的url後,path是不會帶過去的。

示例一
ProxyPass / images/ !

這個示例表示,/images/的請求不被轉發。

=======================================
示例二:
ProxyPass /mirror/foo/ http://backend.kevin.com/

假設當前的服務地址是http://kevin.com/,若是作上面的配置,那麼訪問http://kevin.com/mirror/foo/bar將被轉成http://backend.kevin.com/bar
注:配置的時候,不須要被轉發的請求,要配置在須要被轉發的請求前面。

2)ProxyPassMatch
語法:ProxyPassMatch [regex] !|url
這個其實是url正則匹配,而不是簡單的前綴匹配,匹配上的regex部分是會帶到後端的url的,這個是與ProxyPass不一樣的。

示例一
ProxyPassMatch ^/images !

這個示例表示對/images的請求,都不會被轉發。

=======================================
示例二:
ProxyPassMatch ^(/.*.gif)  http://backend.kevin.com

這個示例表示對全部gif圖片的請求,都被會轉到後端,如此時請求,訪問http://kevin.com/foo/bar.gif 那內部將會轉換爲 http://backend.kevin.com/foo/bar.gif。

3)ProxyPassReverse
語法:ProxyPassReverse [路徑] url)
它通常和ProxyPass指令配合使用,此指令使Apache調整HTTP重定向應答中Location, Content-Location, URI頭裏的URL,這樣能夠避免在Apache做爲反向代理使用時。
後端服務器的HTTP重定向形成的繞過反向代理的問題。好比:

80端口的Proxypass跳轉
<IfModule proxy_module>
     ProxyPass  /companyNews  http://192.168.10.149:8080/companyNews
     ProxyPassReverse  /companyNews  http://192.168.10.149:8080/companyNews
     ProxyPass  /companyNews/*  http://192.168.10.149:8080/companyNews/*
     ProxyPassReverse  /companyNews/*  http://192.168.10.149:8080/companyNews/*
</IfModule>
  
<IfModule proxy_module>
     ProxyPass  /mlslec  https://hao.kevin.com.com/cgi-bin
     ProxyPassReverse  /mlslec  https://hao.kevin.com.com/cgi-bin
</IfModule>

<IfModule proxy_module>
ProxyPass /kevin http://www.kevin.com/ 
ProxyPassReverse /kevin http://www.kevin.com/
</IfModule>

<IfModule proxy_module>
ProxyPass /bobo http://192.168.1.10:8080/bobo/
ProxyPassReverse /bobo http://192.168.1.10:8080/bobo/
</IfModule>
  
==================================================
443端口的Proxypass跳轉
<IfModule proxy_module>
SSLProxyEngine On
  
ProxyPass  /xyy  https://bobo.kevin.com/pay/orderquery
ProxyPassReverse  /xyy  https://bobo.kevin.com/pay/orderquery
  
ProxyPass  /getsignkey   https://bobo.kevin.com/sandbox/pay/getsignkey
ProxyPassReverse  /getsignkey   https://bobo.kevin.com/sandbox/pay/getsignkey
  
ProxyPass  /authorize   https://shibo.kevin.com/connect/oauth2/authorize
ProxyPassReverse  /authorize   https://shibo.kevin.com/connect/oauth2/authorize
</IfModule>
相關文章
相關標籤/搜索