Apache mod_rewrite 筆記

官網的說明在此:
http://httpd.apache.org/docs/current/mod/mod_rewrite.html

mod_rewrite對我來說算是常用的一個功能, 但是網路上很少找到完整的教學. 所以就只好自己看官網的文件邊啃邊測試了.

注意事項:

  1. 要使用 mod_rewrite 的虛擬主機或資料夾, 必須設定 Options FollowSymLinks, 否則無法運作.
  2. Pattern 比對的可能是 URL, 也可能是檔案路徑, 這要看我們在何處使用 RewriteRule. 差別在於 URL 開頭會有斜線, 路徑不會, 因此在寫 Pattern 時要注意.
  3. 有可能形成無限迴圈. 這會嚴重影響效能. 在新版 Apache 若改寫前後的檔案相同, 會自動停止.

設定紀錄檔:

在 httpd.conf 中加入以上設定, 就可以開啟 log 功能. log 等級從 1 到 9, 數字越大越詳細. 開發或除錯時可以很方便的瞭解實際的運作情形. 我們可以給每個虛擬主機設定不同的紀錄檔, 但無法給資料夾設定紀錄檔. 例如以下這段設定, 上面的可以執行, 下面的則會出現錯誤訊息

錯誤訊息會抱怨說 RewriteLog 這個設定不能使用在這邊

基本語法:

這個設定就是 mod_rewrite 真正在做事情的地方了, Pattern 是用來比對我們想要改寫的原始內容, Substitution 則是我們要將其改寫成什麼樣子. 換句話說, 只有符合 Pattern 的情況下才會進行改寫的動作. flags 可以設定一些選項, 例如說不想區分大小寫, 就可以使用 [NC] 這個 flag.

在一般情況下, RewriteRule 是照順序一個一個執行下去的, 且前面一條改寫過的輸出會成為下一條的輸入, 所以安排好合理的順序會是很重要的關鍵. 下面的例子, 首先 about.htm 符合 Pattern, 變成 about1.php, 然後執行下一條規則, about1.php 又符合 Pattern, 所以最後會跑去 about2.php

兩種情境:

當使用在 VirtualHost 標籤中, 或是不在任何標籤中, 將會以 Host 情境執行. 在這個情況下, 拿來與 Pattern 比對的是 URL, 包含開頭的斜線. 反之, 若我們是在 Directory 或是 htaccess 檔案中使用, 則會以 per-directory 情境執行, 這時會用檔案路徑去與 Pattern 比對. 例如我們分別用上面的設定來執行以下例子, 會發現在 log 中它是用不同的字串去與 Pattern 比對:

Pattern 的用法:

Pattern 的部份是使用正則表達式(Regular Expression), 在大部分常見的用途當中, 其實並不會用到太複雜的語法. 然而它畢竟是個威力強大的表示方法, 一有不小心就可能產生預期之外的結果, 例如:

注意這個例子前後 url 的變化, 路徑不見了, 只剩下檔名. 這是因為 Pattern 給的不夠精確, 造成我們不管存取任何路徑的 about.htm, 都會符合 Pattern. 而改寫時, Substitution 又不包含路徑, 所以路徑也就自然不見了.

單一入口頁面:

另外, 一個經典的使用方法, 是將所有的網頁請求交給單一頁面處理, 例如:

但這邊用來判定檔案是否存在的方法需要注意, 若是在VirtualHost中使用, %{REQUEST_FILENAME}得到的是 /something.php 這樣的路徑, 於是rewrite會去檢查系統根目錄底下的something.php, 而不是網頁根目錄底下的檔案, 這會造成功能不正常, 可以說完全無法使用.
解決辦法, 就是加上<Location />, 並在其中設置rewrite的語法:

強制使用 https :

如果想要將整個網站改成使用 https, 這是其中一種方法

svn log 顯示 no author

今天在查 svn log 時,發現作者那一個欄位都顯示 no author,在官方 FAQ 裡面可以查到原因:http://subversion.apache.org/faq.html#no-author

就是當 svn 沒有做存取限制時,整個檔案庫是公開的,就會造成這個結果。
其實我是有做限制的,只是從 Apache 2.2 升級到 2.4 以後,權限設定的語法改變了。如果前面已經有 Require all granted,後面的 Require valid-user 就會失效。只要把這部份處理好就行了。

Apache log 與 Squid log 的流量差異

同時有 Apache 與 Squid 提供 proxy 服務
在看報表的時候,發現這兩個 proxy 的流量差異有點大
查到最後發現是 Apache 在處理 https 時,不會紀錄到真正的資料流量

60 KB 與 0 的差別…數量一多就會發現差距變很大。

另外,用 tcpdump 驗證了一下這些 log 的資料大小到底包含了哪些部份,結論是與 TCP 的資料長度一致,也就是包含了 HTTP Header,但不含 TCP/IP Header。

使用 Apache 做為 forward proxy

為了做點測試而需要架設 apache proxy server
按理說是挺簡單的東西,結果在 https 的地方卡了一下

以下安裝環境是 Debian 7:

就是少了那個 proxy_connect 害我 https 一直出現 500 錯誤。

如果少了 proxy_connect 的話就會出現這樣的錯誤訊息:

其它的像是 mod_ssl 之類的都不需要。

設定上層 proxy,導給 Squid:

注意這只是個人臨時測試用,架在區網內。若要用在正式的環境,需要對存取 proxy 的用戶做些控管,例如僅允許某些 IP 之類的。

在 Ubuntu Server 12.04 安裝 Redmine

寫這篇主要是簡化了官方的安裝教學
官方教學裡面包含了很多不同的情況,所以看起來複雜了一些。
如果你的 Ubuntu 是剛裝好的新系統,而且只是要將 Redmine 安裝起來,只打算跑 Redmine 一個網站,那只要把下面這些命令跑完就行了:

上面的命令會修改到 /etc/apache2/sites-available/default,讓 Redmine 成為預設網站,修改後的設定檔應該長成這樣:

另外,如果要安裝新版的 Redmine,那需要多一些步驟:

接著就可以用瀏覽器打開 Redmine 網頁了,記得先修改 admin 的密碼。
這篇算是最簡化的作法了,如果這個 Redmine 是放在網路上公開存取的話,建議還要加上 https 與其它安全性設定。