分類
系統技術

再談URL長度上限

先來看一下之前寫的:

由 browser 的上限來看是 2083, 而由 apache / iis 來看則是 8190 / 4096 兩個等級.

不過無論如何, 這個 url 上限的討論是個很熱門的問題:

https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers

除了 RFC / Browser / Web Server 外, 還多提出了 CDN (其中的 status code 414 (414 URI Too Long, https://tools.ietf.org/html/rfc7231#section-6.5.12) 就是在描述這個:

這個很重要, 因為 CDN 是轉遞內容的重要功能, 不過看起來長度也都放得很寬.

再來看個別瀏覽器利用測試的方式來查看長度:

Browser Address bar document.location or anchor tag
Chrome 32779 >64k
Android 2192 >64k
Firefox >64k >64k
Safari >64k >64k
IE11 2047 5120
Edge 16 2047 1024

也都有相當的長度.

不過由以上來看, 還是得保守地使用約在 2000 bytes 長度的 url 較為保險.

 

分類
FreeBSD/Linux

Apache使用.htaccess重導新網域

有時因為網域修改, 需要做網域級的重導, 建議使用 301 配合 .htaccess 的設定來進行, 可以使用以下語法:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^olddomain.com$ [OR]
RewriteCond %{HTTP_HOST} ^www.olddomain.com$
RewriteRule (.*)$ http://www.newdomain.com/$1 [R=301,L]

其中的 R=301 是使用了 301重導, 而新舊域名可以參考上面語法, 並且使用了 RewriteRule 將任意內容重導至新網域時, 維持相同的網址.

參考資料: https://wpscholar.com/blog/redirect-old-domain-to-new-domain-via-htaccess/

CentOS中apache與php寫入權限與SELinux設定

由於 CentOS 有 SELinux 的權限設限, 所以相對一些安全層級也都比較高, 最近有個需要用 php 寫入檔案(或是上傳檔案的應用), 原本的 php 在預設狀況下, 就會對 /tmp 有寫入的權限(預設是會在 /tmp/systemd-private-xxxxxx 下的私有 /tmp), 所以上傳時沒有問題, 但使用 move_uploaded_file() 至目的目錄時, 會有寫入的權限問題.

方式如下:

Method A
1. 要寫入需要有對應的權限, 建議方式是將要寫入的目錄給予 apache 執行用戶的擁有者, 如 CentOS 配 apache 時, user 為 apache

chown -R apache /var/www/mysite1/upload

2. 此時只需要給予對應目錄 755 的權限即可(通常預設也是這個).

chmod -R 755 /var/www/mysite1/upload

Method B (不建議)
1. 直接給予該目錄 global write 的權限, 777 即可, 不過會有安全性的考量

chmod -R 777 /var/www/mysite1/upload

完成之後, 若仍無法寫入, 則是因為 SELinux 的設限, 所以即使完成了上面的設定也無法寫入, 此時要再進一步設定 SELinux, 方式如下:

sudo chcon -t httpd_sys_rw_content_t /var/www/mysite1/upload -R

原因為預設的 webservice 能擁有的權限角色為 httpd_sys_content_t , 是無法寫入檔案的, 所以需要再進一步設定 SELinux 才行.

參考資料:
https://blog.lysender.com/2015/07/centos-7-selinux-php-apache-cannot-writeaccess-file-no-matter-what/

另外寫得很仔細的 SELinux 資料可以參考:
https://www.digitalocean.com/community/tutorials/an-introduction-to-selinux-on-centos-7-part-1-basic-concepts
https://www.digitalocean.com/community/tutorials/an-introduction-to-selinux-on-centos-7-part-2-files-and-processes
https://www.digitalocean.com/community/tutorials/an-introduction-to-selinux-on-centos-7-part-3-users

分類
系統技術

Apache與IIS Web Sever URL長度上限

之前有查過 browser 的 url 上限, 可以參考這篇: https://diary.tw/archives/455 , 當時是為了調查 referer 的 url 上限, 進而找出 browser 的 url 上限.

那 web server 上的上限呢? 在 Apache 下有個 LimitRequestLine 的設置, 可以設定 URL 上限, 參考: http://httpd.apache.org/docs/2.2/mod/core.html#limitrequestline

而該值預設為 8190 也就是大約在 8k 左右.

在 IIS 則是利用參數 requestLimits 中的參數, MaxUrl, 預設是 4096, 參考這篇: http://www.iis.net/configreference/system.webserver/security/requestfiltering/requestlimits

這樣看起來基本上都比 Browser 長得多.

LOG4NET的基本操作

這個 LOG4NET是用來做 .net 應用程式LOG使用的套件, 主要用來做除錯, 線上系統記錄, 稽查等應用時可以用來做記錄的套件, 是基於 Apache Project 下的專案, Open Source.

這裡做個簡單的基本介紹, 其實這套件功能十分強大, 可以只利用 config 檔就可以做得很多深層的設定, 並加以記錄, 而不用改到主程式. (當然, 前提是在主程式內必須要下對應的 log information 才行)

首先先到官方網站下載此專案, 這裡建議抓 compile 好的版本, 內含有說明文件:

http://logging.apache.org/log4net/download_log4net.cgi

這頁下的 log4net-1.2.11-bin-newkey.zip , 下載解開後, 裡面主要是 compile 好的 binary 檔, 找到 bin/net/[版本]/release 下的 log4net.dll 檔, 複製到自己的專案中, 就算初步完成了.

接下來就是在自己的專案裡加入參考 (reference), 並使用它的 namespace:

using log4net;

接下來就是設定 config file, 先列出下面 config xml內容:

<configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
</configSections>

<log4net>
    <logger name="loginfo">
        <level value="INFO" />
        <appender-ref ref="InfoAppender" />
    </logger>
    <appender name="InfoAppender" type="log4net.Appender.RollingFileAppender">
        <param name="File" value="Log//info.log" />
        <param name="AppendToFile" value="true" />
        <param name="MaxFileSize" value="4096" />
        <param name="MaxSizeRollBackups" value="10" />
        <param name="StaticLogFileName" value="false" />
        <layout type="log4net.Layout.PatternLayout">                
            <param name="ConversionPattern" value="%date [%thread] %-5level %logger - (%file:%line) %message%newline" />
        </layout>
    </appender>
</log4net>

其中的 section name = log4net 是用來說明會有一個 config section 是給 log4net 用的, 而下面的 log4net 才是真的 config 要寫的內容.

這裡只建了一個 logger, 名為 loginfo (名稱可以自訂), 然後 appender-ref 設為 InfoAppender 就是指向再下面的 appender , 這個 appender type 設為 RollingFileAppender 是用檔案來記錄用, 其他內容說明如下: (logger 也可以是 database 等其他的輸出裝置, 這裡以檔案為例)
File: 檔名
AppendToFile: 是否要寫到檔案
MaxFileSize: 單一 log 檔大小上限 (bytes)
MaxSizeRollBackups: 多少檔案一個循環, 當達到 MaxFileSize 時, 會自動附上 CurBackups 來檔案獨立出來, 並於達到這個數值時, 再重頭用(overwrite).
StaticLogFileName: 若設為 true, 則會以 File 名稱為 log檔名, false 則會以 [file].yyyy-mm-dd 的方式記錄
下面的 layout 則是用來設定 log 內容的欄位, %date 是日期時間, %thread 是執行緒, %level 是記錄層級, %logger 是 logger 名稱, %file %line 是原始程式檔名及行數, %message是 log的內容, %newline 就是換行了.

接下來就是在程式內呼叫的方式, 程式如下, 以 asp.net 為例:

protected void Page_Load(object sender, EventArgs e)
{
    log4net.Config.XmlConfigurator.Configure();  
    ILog infologger = LogManager.GetLogger("loginfo");

    infologger.Info("Page_Load - useragent:" + Request.UserAgent);
}

在 page_load 時, 使用 Config.XmlConfigurator.Configure() 將 log4net 的 config 載入, 然後建立一個 ILog 的 interface, 利用 LogManager.GetLogger(“logger name”) 來取得 logger, 再來利用 .Info(“message”) 方法來將要記錄的 log 內容寫入 log 檔.

而除 Info 方法外, 還有 Debug, Error, Fatal, Warn 共計5個 log level.

最後以 asp.net 做的 log 內容如下:

2013-03-13 15:30:37,925 [4] INFO loginfo – (d:\testlog4net\Default.aspx.cs:19) Page_Load – useragent:Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; MS-RTC LM 8; InfoPath.1; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C; .NET4.0E)
2013-03-13 15:37:42,721 [4] INFO loginfo – (d:\testlog4net\Default.aspx.cs:19) Page_Load – useragent:Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; MS-RTC LM 8; InfoPath.1; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C; .NET4.0E)
2013-03-13 15:37:46,456 [4] INFO loginfo – (d:\testlog4net\Default.aspx.cs:19) Page_Load – useragent:Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; MS-RTC LM 8; InfoPath.1; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C; .NET4.0E)
2013-03-13 15:37:46,800 [4] INFO loginfo – (d:\testlog4net\Default.aspx.cs:19) Page_Load – useragent:Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; MS-RTC LM 8; InfoPath.1; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C; .NET4.0E)
2013-03-13 15:37:47,112 [4] INFO loginfo – (d:\testlog4net\Default.aspx.cs:19) Page_Load – useragent:Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; MS-RTC LM 8; InfoPath.1; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C; .NET4.0E)
2013-03-13 15:37:47,393 [4] INFO loginfo – (d:\testlog4net\Default.aspx.cs:19) Page_Load – useragent:Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; MS-RTC LM 8; InfoPath.1; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C; .NET4.0E)
2013-03-13 15:37:52,065 [4] INFO loginfo – (d:\testlog4net\Default.aspx.cs:19) Page_Load – useragent:Mozilla/5.0 (Windows NT 5.2; rv:19.0) Gecko/20100101 Firefox/19.0

是不是很容易上手呢, 大家可以再試看看!

官方說明文件:
log4net SDK: https://logging.apache.org/log4net/release/sdk/
RollingFileAppender: https://logging.apache.org/log4net/release/sdk/log4net.Appender.RollingFileAppender.html
其他的 Appender: https://logging.apache.org/log4net/release/sdk/log4net.Appender.html

繼續閱讀:
http://biancheng.dnbcw.info/c/72275.html
http://blog.csdn.net/javc/article/details/4022677

分類
FreeBSD/Linux

apache deny ip設定

想要將 apache 的站台, 拒絕讓某個(某群ip)存取的方式, 有幾個方法, 其中最單純最俱體的方式就是直接利用 <Directory></Directory> 這個 tag 中的限制存取來操作最為單純方便 (當然, 虛擬主機可不行, 可以直接利用 .htaccess 設定該層目錄的存取權限)

一般來設, 設定如下:

<Directory "/usr/home/website1">
  order deny,allow
</Directory>

這樣即可. 就是判斷 deny , 預設為 allow 的條件, 也就是所謂公開站台的設定, 若有要限制某些 ip 存取, 可以這樣下:

<Directory "/usr/home/website1">
  order deny,allow
  deny from 1.2.3.4
  deny from 11.22.33.
</Directory>

其中的 deny from 1.2.3.4 是限制某個單一 ip, 而 deny from 11.22.33. 是指 11.22.33.* 都是拒絕存取的, 如此一來, 便能有效管理不想讓某些 ip (例如爬蟲類或是一些吃資源的 ip, 又或是攻擊的 ip)訪問做好限制.

不過發生了一個有趣的狀況, 也就是之前設了, 發現沒有用, 在多次交叉比對檢查後, 發現是這個原因, 就是在 <VirtualHost> 內的 DocumentRoot 指定為 /home/website1 而在 <Directory> 內的目錄指向是 /usr/home/website1 , 這樣一來, apache 在存取該 website1 的檔案時, 是走 /home/website1 下的檔案, 雖然和 /usr/home/website1 一樣, 不過對 apache 來說卻是不同, 這個要特別注意才行, 否則可能會有設定好的 <Directory> 的限制 ip, 但實際上沒有作用, 原因就有可能發生在這裡了.

又或反過來說, 設定的路徑一定要一致, 而且儘量用完整路徑, 不要用簡化的 link 路徑指向檔案, 也比較容易除錯一些. 所以原則上是這樣的:

<VirtualHost *:80>
  ServerName test.diary.tw
  Document /usr/home/www/test
.....
</VirtualHost>

<Directory "/usr/home/www/test">
  order deny,allow
  deny from 1.2.3.4
</Directory>

這樣就 ok 啦, 千萬要注意紅字部分要一致的這件事, 否則可能設了沒有作用, 原因就在這裡了..

另外補充一下, 若是這種方式限制存取的話, client 會拿到 403 的存取失敗代碼.

分類
程式技術

Apache的PreFork MPM功能

Apache, 用了很久, 但的確沒有好好研究過有關於 performance tuning 這塊. 事實上, 這個免費的 web server 功能真的十分強大, 尤其是可以載入的模組也多, 在使用上, 真的有許多沒有深入研究就學不到的內容.

首先我們來看有關於 MPM 的一些資料:
http://dz.adj.idv.tw/archiver/tid-214.html
在 MPM中, prefork 及 worker 是兩種不同的 multi-processing module, 在 apache 管方網站上分別有對這兩個 module 有深入的介紹:
http://httpd.apache.org/docs/2.0/mod/prefork.html
http://httpd.apache.org/docs/2.0/mod/worker.html
這二者只能擇其一來使用, 一般來說, 雖然 prefork 比較佔用記憶體, 但相容性及穩定性較佳, 也是在 FreeBSD 下安裝 Apache 的預設 MPM module.

事實上, 預設的 prefork mpm 參數如下:

<IfModule prefork.c>
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxClients 150
MaxRequestsPerChild 0
</IfModule>

IIS 7 BitRate Throttling 模組

在以往的 iis 限流功能上, 一直是以整個 web 站台的總流量來進行限流管理, 當然這也算是一種限流管理方式, 但在現今這種影音應用的環境下, 相信如何能有效應用頻寬並進一步來節省成本, 相信是很重要的課題.

以往要在 web server 上做流量管理, 最理想的方式是做 per connection 的限流, 這個功能在 iis 上並沒有提供, 不過在 apache 上有個 mod_bandwidth 模組可以做到, 他的原理就是進行單一 connection 的流量限制, 在這種狀況下, 就可以有效地管理每一個 connection 的流量, 簡單地說, 若是放在 web 上的影音內容, bitrate 是 300kbps 的話, 我們可以利用 mod_bandwidth 將流量限制在 330kbps左右, 讓這些影音內容能在邊下載邊看的速度下進行觀賞, 這樣最重要的是對 server 端能節省頻寬. 因為一般人也不見得會整個看完, 若是用很快的速度讓使用者下載, 事實上會蠻浪費頻寬的.

然而隨著在 iis 7 上提供 BitRate Throttling模組功能時, 這些狀況就會改觀了, 根據技術文件提到, 這個模組可以根據媒體檔案內容的 mime-type 及 bitrate header進行流量限制, 並提供了前面多少時間(幾秒)的快速下載, 之後根據 bitrate進行限流, 看起來彈性及功能遠比 apache 的 mod_bandwidth 模組有更大的彈性及好處.

實務上, 這將會是一個相當有效節省頻寬的一個管理方式, 這個部分相信對未來影音應用的普及下, 將會發揮更大的作用哦.

這篇介紹了如何偵測 bit-rate的方式及設置方式:
http://learn.iis.net/page.aspx/149/bit-rate-throttling-extensibility-walkthrough/

這篇介紹如何安裝這個模組:
http://learn.iis.net/page.aspx/147/bit-rate-throttling-setup-walkthrough/

這篇介紹如何設定及驗證:
http://learn.iis.net/page.aspx/148/bit-rate-throttling-configuration-walkthrough/

其他相關閱讀:

這篇有實作後的流量比較結果:

http://blogs.msdn.com/jijia/archive/2007/12/30/iis-7-0-bandwidth-throttling.aspx

分類
系統技術

apache加掛壓縮模組deflate/gzip

在阿駕零零壹站上看到這篇: [Apache] 壓縮你的網頁 – mod_deflate/mod_gzip、ob_gzhandler、zlib, 覺得效果不錯, 試著進行調整自己的主機, 加入這項功能.

由於 apache2 有自帶 mod_deflate 模組, 所以設定起來很快也很方便, 只要設定一下 httpd.conf:

LoadModule deflate_module modules/mod_deflate.so

將 # 拿到, 並加上

<IfModule mod_deflate.c>
  DeflateCompressionLevel 6
  AddOutputFilterByType DEFLATE text/html text/plain text/xml application/x-httpd-php
  AddOutputFilter DEFLATE html htm xml php css js
</IfModule>

並重啟一下服務即可順利完成.

但由於本站使用的是 apache 1.3x, 所以要麻煩一點, 配合的模組是 mod_gzip, 這個版本已經很久了, 可以先到 http://sourceforge.net/projects/mod-gzip/ 這裡進行下載.

若是 windows 下使用 dll 那組, linux/bsd則用 so 那組, 將檔案複製到 apache/modules 下, 設置 httpd.conf 檔案:

分類
程式技術

有趣的rewrite

之前在設定 apache rewrite 感覺很有趣, 可以做很多應用, 加上功能強大, 幾乎可以將網址改的很炫很讚, 後來也玩了一下 ISAPI_Rewrite (網址: http://www.isapirewrite.com/), HELICON提供的 ISAPI_Rewrite 功能也類似, 免費版本 ISAPI_Rewrite Lite 可以使用於該 iis 上全部的網站, 所以若要設定個別的虛擬主機的 rewrite rule 時, 就要花錢買 ISAPI_Rewrite FULL. 當然 apache 的 rewrite module 是完全免費的囉.