一. 簡單實例介紹
一般來說,apache配置好http和https后,如果想要做http強轉到https,需要設置url重定向規則,大致需要下面幾個步驟即可完成配置:
1)在httpd.conf文件里使下面模塊生效 [root@back ~]# cat /usr/local/apache/conf/httpd.conf ..... LoadModule ssl_module modules/mod_ssl.so #如果使用https證書,這個模塊功能一定要打開! ..... LoadModule rewrite_module modules/mod_rewrite.so #如果要http強轉到https,這個模塊功能一定要打開! 2)httpd.conf配置文件或者是在httpd-vhost.conf文件里修改 [root@back ~]# cat /usr/local/apache/conf/httpd.conf ....... DocumentRoot "/data/vhosts" <Directory "/data/vhosts"> Options FollowSymLinks MultiViews Includes AllowOverride All Require all granted </Directory> 3)在你的網站根目錄下面添加該文件".htaccess"目錄訪問控制文件,並添加如下內容: RewriteEngine on RewriteBase / RewriteCond %{SERVER_PORT} !^443$ RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R] 含義是這樣的:為了讓用戶訪問傳統的http://轉到https://上來,用了一下rewrite規則: 第一句:啟動rewrite引擎 第三句:rewrite的條件是訪問的服務器端口不是443端口 第四句:這是正則表達式,^是開頭,$是結束,/?表示有沒有/都可以(0或1個),(.*)是任何數量的任意字符 整句的意思是講:啟動rewrite模塊,將所有訪問非443端口的域名請求,url地址內容不變,將http://變成https://。
下面這個是我自己的實際代碼:
RewriteEngine on ##開啟重定向
RewriteBase /
RewriteCond %{SERVER_PORT} !^443$ ###非443的端口的流量,經我測試即使沒有這句代碼,下面那句也是直接重定向將所有的域名(因為我是兩個域名指向這個網站目錄)跳轉到下面的https網站,剛好兩個域名同一個網站內容而我又知買了一個網站https。
RewriteRule ^(.*) https://www.youadmin.com/ [L]
上面的配置實現了將所有域名的http跳轉為https,如果只是針對某一個具體的url的https跳轉,則配置情況會有所不同,如下:
只要求訪問http://bo.kevin.com/beijing/ 時強制跳轉到https://bo.kevin.com/beijing/,其他的url訪問時都不做http到https的強轉! 在.htaccess文件中添加下面內容: [root@docker-test2 web]# cat .htaccess <IfModule mod_rewrite.c> RewriteEngine on RewriteBase / RewriteCond %{SERVER_PORT} 80 RewriteCond %{HTTP_HOST} ^bo.kevin.com/beijing/ [NC] RewriteRule ^(.*)$ https://bo.kevin.com/beijing/ [R,L] </IfModule> 上面的配置,就實現了只是針對http://bo.kevin.com/beijing/這一個單獨的url做https的強制跳轉,其他url訪問時都不做跳轉!
當然,除了上面的方法,還有其他的配置可以實現,比如通過匹配目錄規則實現跳轉需求,下面都會介紹到.
二. Apache中 RewriteRule跳轉規則參數
Apache模塊mod_rewrite提供了一個基於正則表達式分析器的重寫引擎來實時重寫URL請求。它支持每個完整規則可以擁有不限數量的子規則以及附加條件規則的靈活而且強大的URL操作機制。此URL操作可以依賴於各種測試,比如服務器變量、環境變量、HTTP頭、時間標記,甚至各種格式的用於匹配URL組成部分的查找數據庫。
mod_rewrite模塊可以操作URL的所有部分(包括路徑信息部分),在服務器級的(httpd.conf)和目錄級的(.htaccess)配置都有效,還可以生成最終請求字符串。此重寫操作的結果可以是內部子處理,也可以是外部請求的轉向,甚至還可以是內部代理處理。
以下重點介紹下RewriteRule 的規則以及參數說明。RewriteRule指令是重寫引擎的根本。此指令可以多次使用。每個指令定義一個簡單的重寫規則。這些規則的定義順序尤為重要——在運行時,規則是按這個順序逐一生效的。
配置格式:
RewriteRule Pattern Substitution [flags]
1) Pattern是一個作用於當前URL的perl兼容的正則表達式。
"當前URL"是指該規則生效時刻的URL的值。它可能與被請求的URL截然不同,因為其他規則可能在此之前已經發生匹配並對它做了改動。
2) Substitution是當原始URL與Pattern相匹配時,用來替代(或替換)的字符串。除了純文本,還可以包含:
- 對Pattern的反向引用($N)
- 對最后匹配的RewriteCond的反向引用(%N)
- 規則條件測試字符串(%{VARNAME})中的服務器變量
- 映射函數調用(${mapname:key|default})
3) [flags]標記作為RewriteRule指令的第三個參數,是一個包含以逗號分隔的下列標記的列表:
3.1) ‘chain|C‘(鏈接下一規則)
此標記使當前規則與下一個規則相鏈接。它產生這樣的效果:
如果一個規則被匹配,則繼續處理其后繼規則,也就是這個標記不起作用;
如果該規則不被匹配,則其后繼規則將被跳過。
比如:
在一個目錄級規則中執行一個外部重定向時,你可能需要刪除".www"(此處不應該出現".www")。
‘cookie|CO=NAME:VAL:domain[:lifetime[:path]]‘(設置cookie):在客戶端設置一個cookie。cookie的名稱是NAME,值是VAL。
domain是該cookie的域,比如‘.apache.org‘,可選的lifetime是cookie的有效期(分鍾),可選的path是cookie的路徑。
3.2) ‘env|E=VAR:VAL‘(設置環境變量)
此標記將環境變量VAR的值設為VAL,VAL可以包含可擴展的正則表達式反向引用($N和%N)。此標記可以多次使用以設置多個變量。
這些變量可以在其后許多情況下被間接引用,通常是在XSSI(<!--#echo var="VAR"-->)或CGI($ENV{‘VAR‘})中,也可以在后繼的
RewriteCond指令的CondPattern參數中通過%{ENV:VAR}引用。使用它可以記住從URL中剝離的信息。
3.3) ‘forbidden|F‘(強制禁止URL)
強制禁止當前URL,也就是立即反饋一個HTTP響應碼403(被禁止的)。使用這個標記,可以鏈接若干個RewriteConds來有條件地阻塞某些URL。
3.4) ‘gone|G‘(強制廢棄URL)
強制當前URL為已廢棄,也就是立即反饋一個HTTP響應碼410(已廢棄的)。使用這個標記,可以標明頁面已經被廢棄而不存在了。
3.5) ‘handler|H=Content-handler‘(強制指定內容處理器)
強自制定目標文件的內容處理器為Content-handler。例如,用來模擬mod_alias模塊的ScriptAlias指令,以強制映射文件夾內的所有文件都
由"cgi-script"處理器處理。
3.6) ‘last|L‘(結尾規則)
立即停止重寫操作,並不再應用其他重寫規則。它對應於Perl中的last命令或C語言中的break命令。
這個標記用於阻止當前已被重寫的URL被后繼規則再次重寫。例如,使用它可以重寫根路徑的URL(‘/‘)為實際存在的URL(比如:‘/e/www/‘)。
3.7) ‘next|N‘(從頭再來)
重新執行重寫操作(從第一個規則重新開始)。此時再次進行處理的URL已經不是原始的URL了,而是經最后一個重寫規則處理過的URL。
它對應於Perl中的next命令或C語言中的continue命令。此標記可以重新開始重寫操作(立即回到循環的開頭)。但是要小心,不要制造死循環!
3.8) ‘nocase|NC‘(忽略大小寫)
它使Pattern忽略大小寫,也就是在Pattern與當前URL匹配時,‘A-Z‘和‘a-z‘沒有區別。
3.9) ‘noescape|NE‘(在輸出中不對URI進行轉義)
此標記阻止mod_rewrite對重寫結果應用常規的URI轉義規則。 一般情況下,特殊字符(‘%‘, ‘$‘, ‘;‘等)會被轉義為等值的十六進制編碼(‘%25‘, ‘%24‘, ‘%3B‘等)。
此標記可以阻止這樣的轉義,以允許百分號等符號出現在輸出中,比如:RewriteRule /foo/(.*) /bar?arg=P1\%3d$1 [R,NE] ,可以使‘/foo/zed轉向到一個安全的請求‘/bar?arg=P1=zed‘。
3.10) ‘nosubreq|NS‘(不對內部子請求進行處理)
在當前請求是一個內部子請求時,此標記強制重寫引擎跳過該重寫規則。比如,在mod_include試圖搜索目錄默認文件(index.xxx)時,Apache會在內部產生子請求。對於子請求,重寫規則不一定有用,而且如果整個規則集都起作用,它甚至可能會引發錯誤。所以,可以用這個標記來排除某些規則。
使用原則:如果你為URL添加了CGI腳本前綴,以強制它們由CGI腳本處理,但對子請求處理的出錯率(或者資源開銷)很高,在這種情況下,可以使用這個標記。
3.11) ‘proxy|P‘(強制為代理)
此標記使替換成分被內部地強制作為代理請求發送,並立即中斷重寫處理,然后把處理移交給mod_proxy模塊。
你必須確保此替換串是一個能夠被mod_proxy處理的有效URI(比如以http://hostname開頭),否則將得到一個代理模塊返回的錯誤。
使用這個標記,可以把某些遠程成分映射到本地服務器域名空間,從而增強了ProxyPass指令的功能。
注意:要使用這個功能,必須已經啟用了mod_proxy模塊。