0x00前言
.htaccess文件是用於apache服務器下的控制文件訪問的配置文件,因此Nginx下是不會生效的
.htaccess可以控制錯誤重定向,初始頁面設置,文件夾的訪問權限,文件的跳轉等
Nginx如果直接訪問,可以下載該文件。如果是apache的話,正常情況下該文件是不可被訪問的,但是可以通過php的include之類的文件包含函數進行內容訪問
其實最好不要用.htaccess文件,因為目錄多了后,每個目錄都有個.htaccess很難管理。但是最近在審計類似thinkphp框架的時候遇到了這個配置文件,所以學習記錄一下用法
0x01環境准備
我是windows下的phpstudy搭的環境,使用的是apache服務器選項,實例目錄如下

特別注意.htaccess文件在windows下沒法直接命名,我這里是復制別人項目里面有的.htaccess,當然linux下就沒有這種限制
0x02設置文件訪問權限
我們可以在.htaccess中使用以下代碼拒絕1.php被訪問
<Files 1.php> order allow,deny deny from all </Files>

如果要允許訪問,那么把deny from all 改為allow from all即可
那么如果要禁止某個ip訪問該文件,比如我現在有台虛擬機的網卡信息如下

我的本機的ip是10.10.10.1
那么文件的過濾規則如下
<Files 1.php> order allow,deny deny from 10.10.10.128 </Files>
虛擬機不可訪問頁面

但是此時會發現本地也無法訪問頁面,因此還要對.htaccess文件進行修改
<Files 1.php> order allow,deny deny from 10.10.10.128 allow from all </Files>
可以看出這個訪問控制(ACL)的寫法和路由器的ACL寫法一樣
但是如果把上面的deny和allow順序進行交換,還是10.10.10.128還是無法訪問,因此和路由器配置的ACL還是稍微有點區別
限制ip對整個文件夾的訪問權限
order allow,deny
allow from all
deny from 10.10.10.128
和上面限制某個文件相比少了個<Files>的標簽,其他方法一樣的
文件名規則還支持正則表達式,開啟正則表達式要用~,比如所有的php文件都限制10.10.10.128的訪問
<Files ~ "^.*\.php$"> order allow,deny allow from all deny from 10.10.10.128 </Files>
~與"直接有個空格,不然不會生效
也可以支持通配符,比如
<Files *.php> order allow,deny allow from all deny from 10.10.10.128 </Files>
0x03錯誤重定向&重定向
這里我假設404的時候顯示2.php頁面
ErrorDocument 404 /test/2.php

注意這里有個坑,重定向的頁面的路徑是對於web站點的根目錄的路徑,因為我的代碼是在test文件夾下,但是它起始的路徑是WWW路徑下
普通的重定向,假設我要訪問1.php,要將訪問1.php的請求重定向到2.php,寫法如下,這個路徑規則和上面錯誤重定向一樣
Redirect /test/1.php /test/2.php

0x04 設置初始頁面
有時候沒有index.html或者index.php頁面,這里我使用1.php作為初始頁面的話,寫法如下,這個路徑規則就是從當前文件夾路徑開始的了
DirectoryIndex 1.php

0x05 RewriteEngine
RewriteEngine語法很多,這個功能的作用可以防止圖片盜鏈(也就是你服務器上的圖片,可以設置其他站點不能使用圖片的url掛在他們的頁面上),也可以配置重定向,還有很多可以做到的事
開啟這個功能需要一行代碼
RewriteEngine On
如果在這之后想要關閉,可以使用下面的代碼
RewriteEngine Off
這個功能具備幾個比較重要的關鍵字,他們是
RewriteEngine On|Off #設置功能的開啟與關閉 RewiteBase var1 #設置功能的路徑,這一步是設置范圍,var1是路徑,基於url的,也就是根目錄(不是當前目錄) RewriteCond var1 var2 [flag] #設置功能的匹配的條件,這一步是判斷,var1是傳入的字符串,var2是待匹配的字符串,[flag]是標志 RewriteRule var1 var2 [flag] #設置功能的重寫規則,這一步是執行,var1是改變前的樣子,var2是改變后的樣子,[flag]是標志
RewriteCond的var2和RewriteRule的var1是支持正則的
其中RewriteCond可以傳入系統變量比如 HTTP_REFERER 等,詳細有哪些可以用php把$_SERVER全局變量給遍歷一遍看看
RewriteCond可以理解成if的嵌套,因為可以寫多個RewriteCond,也就是要滿足所有的RewriteCond才會執行之后的RewriteRule
[flag]的用法,和舉例
因為RewriteCond是可以加[flag]的,但是我手動fuzz了下,發現只有[NC]能夠使用,其他的標簽如果被設置,服務器會返回500報錯,接下來就主要以RewriteRule中的[flag]用法講解
默認不加會把var1的文件解析成var2的文件,可以組合使用比如[R,L]表示又有[R]標簽又有[L]標簽
[R] -- Redirect 重定向跳轉,加了該標簽會從滿足var1的頁面跳轉到var2的頁面
RewriteEngine On RewriteBase /test/ RewriteCond %{HTTP_REFERER} ^127.0.0.1$ RewriteRule 1.php 2.php [R]
這段的意思是如果referer頭是127.0.0.1的話,就會跳轉到2.php,[R]表示重定向的302,效果如下


[F] -- Forbidden 對頁面的禁止訪問
其實有這個[flag], 后面一個匹配文件叫什么都無所謂了,但是必須要寫
RewriteEngine On RewriteBase /test/ RewriteCond %{HTTP_REFERER} ^127.0.0.1$ [NC] RewriteRule 1.php 2.php [F]

[G] -- Gone 返回頁面不存在,也就是返回410,即使頁面存在的時候
和[F]一樣,只會看前面的文件規則,后面匹配文件是什么無所謂
RewriteEngine On RewriteBase /test/ RewriteCond %{HTTP_REFERER} ^127.0.0.1$ [NC] RewriteRule 1.php 2.php [G]

[P] -- Proxy 告訴服務器通過mod_proxy模塊處理用戶請求
這個應該是如果服務器又代理設置的話,加上這個[flag]可以走代理去訪問第一個參數文件,同理第二個文件內容不用在意
[L] -- Last rule 最后條規則
我測試時默認情況加了[L]其實和跳轉[R]作用一樣,但是不是302,是直接以后面的文件解析,[L]之后的規則不會被執行
RewriteEngine On RewriteBase /test/ RewriteCond %{HTTP_REFERER} ^127.0.0.1$ [NC] RewriteRule 1.php 1.php [L] RewriteRule 1.php 2.php [R]
如果不加[L],那么會返回302,但是加了[L],任然返回1.php的內容

[N] -- Next 重寫
也就是從第一個RewriteRule再次執行,因為現在的環境(只有1.php和2.php)設計不出很復雜的應用,這里也就不直接舉例了,相當於循環一樣
[C] -- Chain 將當前的規則和后規則組合起來
道理都懂,局限於自己的認知,不太清楚具體使用orz
[T] -- Type-MIME 聲明目標資源所屬的MIME類型
強制目標文件的MIME類型為MIME-type,可以用來基於某些特定條件強制設置內容類型。比如,下面的指令可以讓.PHP文件在以.phps擴展名調用的情況下由mod_php按照PHP源代碼的MIME類型(application/x-httpd-php-source)顯示:
RewriteRule ^(.+\.php)s$ $1 [T=application/x-httpd-php-source]
這段話是學習某篇博客的,但是我本地可能是環境的文件並沒有回顯源碼
以下的使用的條件比較復雜,之后再研究,這里羅列一下
[NC] --Nocase 對url的輸入忽略大小寫
[NS] -- Nosubreq 沒有內部子請求時運行,也就是適用於cgi
[QAS] -- Qsappend 在新的url后追加內容
[PT] -- Passthrough 將url傳給下一個apache模塊進行處理
[S] -- Skip 忽略之后的規則
[E] -- Env 設置環境變量
0xff結語
參考
https://www.cnblogs.com/wumingcong/p/5044713.html
https://www.cnblogs.com/kenshinobiy/p/5040337.html
https://c7sky.com/htaccess-guide.html
