Environment:Ubuntu10.4 LTS
一、編譯Boa
1.安裝必要的library
如
Lex(A Lexical Analyzer Generator)和
Yacc(Yet Another Compiler-Compiler)
$ sudo apt-get install bison
$ sudo apt-get install flex
如果沒有安裝bison,在編譯時將會出現錯誤訊息如
yacc -d boa_grammar.y
make: yacc: Command not found
make: *** [y.tab.c] Error 127
如果沒有安裝flex,在編譯時將會出現錯誤訊息如
yacc -d boa_grammar.y
gcc -g -O2 -pipe -Wall -I. -c -o y.tab.o y.tab.c
y.tab.c: In function 'yyparse':
y.tab.c:1295: warning: implicit declaration of function 『yylex'
lex boa_lexer.l
make: lex: Command not found
make: *** [lex.yy.c] Error 127
2.下載Boa原始檔
$ cd ~
$ wget http://www.boa.org/boa-0.94.13.tar.gz
$ tar zxvf boa-0.94.13.tar.gz
3.先查看一下原始檔,注意原始檔的變化
$ cd boa-0.94.13/src
$ ls
acconfig.h boa.h check_struct_for.m4 configure.in globals.h Makefile.in read.c sublog.c
aclocal.m4 boa_lexer.l compat.h defines.h hash.c mmap_cache.c request.c timestamp.c
alias.c buffer.c config.c escape.c index_dir.c parse.h response.c util.c
boa.c cgi.c config.h.in escape.h ip.c pipe.c select.c webindex.pl
boa_grammar.y cgi_header.c configure get.c log.c queue.c signals.c
4.configure
$ ./configure
5.編譯,將會出現錯誤
$ make
...
gcc -g -O2 -pipe -Wall -I. -c -o util.o util.c
util.c:100:1: error: pasting "t" and "->" does not give a valid preprocessing token
make: *** [util.o] Error 1
6.修改Boa的原始檔
$ vim compat.h
120 #define TIMEZONE_OFFSET(foo) foo##->tm_gmtoff
改成
120 #define TIMEZONE_OFFSET(foo) (foo)->tm_gmtoff
7.再次編譯,並檢查編譯完成後的檔案
在編譯的過程中,有些c的source和header會動態產生,例如config.h, lex.yy.c, y.tab.c, y.tab.h,而完成編譯後,也會產生boa和boa_indexer等兩個二進位執行檔
$ make
$ ls
acconfig.h boa_lexer.l compat.h configure.in hash.o Makefile read.c signals.o y.tab.h
aclocal.m4 boa.o config.c defines.h index_dir.c Makefile.in read.o sublog.c y.tab.o
alias.c buffer.c config.cache escape.c index_dir.o mmap_cache.c request.c sublog.o
alias.o buffer.o config.h escape.h ip.c mmap_cache.o request.o timestamp.c
boa cgi.c config.h.in escape.o ip.o parse.h response.c timestamp.o
boa.c cgi_header.c config.log get.c lex.yy.c pipe.c response.o util.c
boa_grammar.y cgi_header.o config.o get.o lex.yy.o pipe.o select.c util.o
boa.h cgi.o config.status globals.h log.c queue.c select.o webindex.pl
boa_indexer check_struct_for.m4 configure hash.c log.o queue.o signals.c y.tab.c
8.編譯完成,啟動Boa
由於設定檔預設在/etc/boa目錄下的boa.conf,如果不存在,需手動複製過去,否則會出現錯誤訊息
$ sudo ./boa
Could not chdir to "/etc/boa": aborting
$ sudo mkdir /etc/boa
$ sudo ./boa
Could not open boa.conf for reading.
$ sudo cp ../boa.conf /etc/boa
$ sudo ./boa
由於Boa的log預設寫入到/var/log/boa下,若該目錄不存在會出現錯誤訊息
[10/Feb/2011:06:40:54 +0000] log.c:73 - unable to dup2 the error log: Bad file descriptor
$ sudo mkdir /var/log/boa
9.啟動Boa,檢查連線狀態(Boa預設綁在所有IP的80上)
$ sudo ./boa
$ netstat -nutlp
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN -
10.為了方便啟動/停止/重啟Boa,我寫了一個簡單的shell script幫助管理
$ vim ~/boa.sh
#!/bin/bash
BOA=~/boa-0.94.13/src/boa
start(){
$BOA
}
stop(){
PID=`pidof boa`
kill $PID
}
restart(){
stop
start
}
case "$1" in
stop)
stop
;;
start)
start
;;
restart)
restart
;;
*)
echo "{start|stop|restart}"
esac
$ chmod 755 ~/boa.sh
使用方式
$ sudo ~/boa.sh {start|stop|restart}
二、編譯PHP for Boa
1.下載PHP原始檔
$ cd ~
$ wget http://tw2.php.net/distributions/php-5.3.4.tar.gz
$ tar zxvf php-5.3.4.tar.gz
2.configure
在不確定PHP在Boa上能編譯進多少功能的情況下,先停用大多數的功能吧
$ cd php-5.3.4
$ ./configure --disable-all
3.編譯
由於PHP在Boa只能以
CGI的方式執行,因此我們只要編出php-cgi就可以了
這意思是說將PHP編譯成CGI解譯器,如此一來每次有PHP Script被解譯時,網站伺服器就衍生出(spawn)一個PHP解譯器的實體,由它負責解譯該Script,但是這種方式會降低執行效能
$ make
$ ls -al sapi/cgi/php-cgi
-rwxr-xr-x 1 owen owen 8786495 2011-02-10 05:03 sapi/cgi/php-cgi
三、將PHP以CGI的方式執行
1.寫個顯示組態的PHP網頁
$ sudo vim /var/www/info.php
<?php
phpinfo();
?>
2.修改cgi-bin的虛擬路徑
$ sudo vim /etc/boa/boa.conf
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
改成
ScriptAlias /cgi-bin/ /var/www/cgi-bin/
3.將php-cgi複製到cgi-bin目錄下
$ sudo cp ~/php-5.3.4/sapi/cgi/php-cgi /var/www/cgi-bin
4.以瀏覽器檢視該網頁
如果url的路徑包括cgi-bin,那麼Boa就會以cgi的方式處理,並把它後面的參數變成cgi的命令參數去執行,因此瀏覽的網址為 http://your.host.ip/cgi-bin/php-cgi/info.php
502 Bad Gateway
The CGI was not CGI/1.1 compliant.
檢查error_log
$ sudo cat /var/log/boa/error_log
[10/Feb/2011:16:24:37 +0000] cgi_header: unable to find LFLF
從這訊息看不出真正的錯誤原因,因此我們在/etc/boa/boa.conf裡多加上CGI的log
$ sudo vim /etc/boa/boa.conf
CgiLog /var/log/boa/cgi_log
重新啟動Boa
$ sudo ~/boa.sh restart
再用瀏覽器檢視該網頁,http://your.host.ip/cgi-bin/php-cgi/info.php,並檢查cgi_log
$ sudo cat /var/log/boa/cgi_log
<p>This PHP CGI binary was compiled with force-cgi-redirect enabled. This
means that a page will only be served up if the REDIRECT_STATUS CGI variable is
set, e.g. via an Apache Action directive.</p>
<p>For more information as to <i>why</i> this behaviour exists, see the <a href="http://php.net/security.cgi-bin">manual page for CGI security</a>.</p>
<p>For more information about changing this behaviour or re-enabling this webserver,
consult the installation file that came with this distribution, or visit
<a href="http://php.net/install.windows">the manual page</a>.</p>
這段錯誤主要的意思就是因為以CGI模式執行PHP程式有可能造成安全上的問題,因此預設編譯php-cgi是會開啟force-cgi-redirect的設定...
* 解決方式之一,是在configure時關閉此一設定(--disable-force-cgi-redirect),但是這招只在5.2以下的版本有用,5.3的configure就沒有此一選項
* 解決方式之二,就是在php.ini設定此一選項,預設php.ini的位置在/usr/local/lib下
$ sudo vim /usr/local/lib/php.ini
[PHP]
cgi.force_redirect = 0
在php.ini設定中的cgi.force_redirect,是因為有些網站伺服器(如Apache)在設定Action指令時,會將http://your.server.ip/protected/script.php這類請求重導至http://your.server.ip/cgi-bin/php/protected/script.php,其中的php就是PHP的CGI解譯器執行檔,前者會檢查protected目錄的存取行為,而後者如果本身有指定,它就不會去檢查這各被保護的目錄,這就可能發生安全性的問題,因此可利用--enable-force-cgi-redirect修正,並配合--enable-discard-path=/path/to/php-cgi(版本4.x以下有用),或是在php.ini設定cgi.redirect_status_env=/path/to/php-cgi
5.重新啟動Boa後以瀏覽器檢視該網頁將可看到PHP的組態設定
將PHP以CGI執行的方法可能還有一個,使用原生的cgi模式解析,雖然我沒成功完成,但是步驟大概如下
1.加入cgi的解析
$ sudo vim /etc/boa.boa.conf
AddType application/x-httpd-cgi .cgi
2.撰寫info.cgi
$ sudo vim /var/www/cgi-bin/info.cgi
#!/usr/local/bin/php-cgi
<?php
phpinfo();
?>
3.修改成可讀寫的權限
$ sudo chmod a+x /var/www/cgi-bin/info.cgi
references:
*
The Lex & Yacc Page
*
Linux系統編譯boa-0.94-13出錯信息問題
*
在嵌入式Linux架設Boa Webserver
*
嵌入式boa服務器移植
*
boa with php