Saturday, 22 December 2012

Config Apache2 và CGI

ngày xưa, cách đây tầm 6,7 năm, tớ trẩu tre đi đọc mấy bài của các anh hacker thấy nhắc nhiều đến cgi-bin, thật sự đến tận bây giờ mới tìm hiểu nó là cái gì mà sao toàn bị hack thế :D


Bài này sẽ giới thiệu 1 chút về CGI và hướng dẫn debug khi config apache2 bị lỗi (mấy hôm nay debug mệt lắm rồi).
Thực hiện trên:
hvn@lappy: /etc/apache2 $ uname -a; lsb_release -a
Linux lappy 3.2.0-30-generic #48-Ubuntu SMP Fri Aug 24 16:52:48 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
No LSB modules are available.
Distributor ID:    Ubuntu
Description:    Ubuntu 12.04.1 LTS
Release:    12.04
Codename:    precise

1. CGI 
The CGI (Common Gateway Interface) defines a way for a web server to interact with external content-generating programs, which are often referred to as CGI programs or CGI scripts. It is the simplest, and most common, way to put dynamic content on your web site.

http://httpd.apache.org/docs/2.2/howto/cgi.html

The Common Gateway Interface (CGI) is a standard (see RFC 3875: CGI Version 1.1) method for web server software to delegate the generation of web content to executable files. Such files are known as CGI scripts; they are programs, often stand-alone applications, usually written in a scripting language.

http://en.wikipedia.org/wiki/Common_Gateway_Interface

Như vậy CGI script sẽ là các file chạy được, điều này phải chú ý khi debug.

Viết script CGI:
First, all output from your CGI program must be preceded by a MIME-type header. This is HTTP header that tells the client what sort of content it is receiving. Most of the time, this will look like:
Content-type: text/html
Secondly, your output needs to be in HTML, or some other format that a browser will be able to display...
http://httpd.apache.org/docs/2.2/howto/cgi.html
Một CGI script chỉ cần thoả mãn 2 điều kiện : bắt đầu  bằng MIME-type header như ở trên, và output ra mã html (nói chung là ra text)

Tạo CGI script "hello thon" với 4 ngôn ngữ script phổ biến:

1.1. PHP
Không cần viết CGI script do máy tớ đã cài mod hỗ trợ php rồi, để lúc nào có điều kiện sẽ thử trên máy khác

1.2. Python
#!/usr/bin/python
print "Content-type: text/html"
print
print "hello thon"
1.3. Perl
#!/usr/bin/perl
print "Content-type: text/html\n\n";
print "Hello, thon."
1.4. TCL 
later

rất đơn giản, bây giờ thì chẳng thấy ai phải viết CGI script nữa, chắc nó đã là 1 phần lịch sử rồi.


2. Config, debug Apache2
cài :
sudo apt-get install apache2 

sau khi cài xong, hãy vào /etc/apache2 để khám phá
Apache2 sau khi cài xong sẽ có 1 file config chính là `apache2.conf`, 1 file khác là `httpd.conf` và thư mục sites-available/ chứa các file config.
Nếu bạn đọc file apache2.conf sẽ thấy có dòng:

# Include all the user configurations:
Include httpd.conf
# Include ports listing
Include ports.conf
# Include generic snippets of statements
Include conf.d/
# Include the virtual host configurations:
Include sites-enabled/
hãy xem kỹ file này để biết chỗ đặt config của bạn vào đâu. Nếu bạn sử dụng virtual host (không giải thích ở đây), hãy đặt vào `sites-enabled/`, nếu không, hãy viết vào `httpd.conf`. Nói chung cái này là tự do, không ai ép buộc cả.

Sau khi bạn cài đặt xong bạn có thể phóng vào localhost luôn là bởi đã có sẵn file config năm trong `sites-available/`, tên là `default` và đã được link (hiểu sơ là tạo shortcut sang thư mục `sites-enabled/`
Nội dung phần đầu file này như sau:

hvn@lappy: /etc/apache2 $ cat sites-available/default
<VirtualHost *:80>
    ServerAdmin webmaster@localhost

    DocumentRoot /var/www
    <Directory />
        Options FollowSymLinks
        AllowOverride none
    </Directory>

    <Directory /var/www/>
        Options Indexes FollowSymLinks MultiViews
        AllowOverride all
        Order allow,deny
        allow from all
    </Directory>

    ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
    <Directory "/usr/lib/cgi-bin">
        AllowOverride None
        Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
        Order allow,deny
        Allow from all
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/error.log

    # Possible values include: debug, info, notice, warn, error, crit,
    # alert, emerg.
    LogLevel warn

    CustomLog ${APACHE_LOG_DIR}/access.log combined

quay lại chủ đề CGI, bạn sẽ thấy dòng
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
hãy đặt các script ở phần 1 vào trong thư mục này, chmod chúng thành các file chạy được (chmod a+x tenfile)
Sau đó mở trình duyệt ra và gõ:
http://localhost/cgi-bin/index.py
hay http://localhost/cgi-bin/index.pl mà xem kết quả hello thon ^^ .

Toàn bộ phần trên nói về việc viết, config CGI script thế nào cho chạy được, nó đã là một phần của quá khứ và chỉ đọc cho biết thôi :D .

3. Debug apache2.
Phần này dành cho những ai đã "hơi hơi" biết config Apache2.

Nói đến debug bất kỳ service nào của Linux, hãy nghĩ đến file log đầu tiên. Về cơ bản thì đọc xong log là bạn đã có thể giải quyết vấn đề rồi (trừ những trường hợp rất oái oăm). Nơi đặt log error  bạn cũng có thể dễ dàng thấy trong file config trên, nó ở /var/log/apache2/error.log

Các lỗi thường gặp:
403 Forbidden : thường bạn sẽ gặp lỗi này khi trong thư mục bạn vào không có file index.html hay index.php.
Bạn có thể thêm directive

Options Indexes
để apache2 hiện danh sách các file trong thư mục đó thay thông báo 403.

Nếu vấn đề là do permission, bạn sẽ dễ dàng tìm thấy trong log :D

...

Và cuối cùng, hãy nhớ chmod 755 là an toàn, 777 là ngớ ngẩn (trừ khi bạn biết mình không ngớ ngẩn :D )
hvn@lappy: /usr/lib/cgi-bin $ ls -lt
-rwxr-xr-x 1 root root 37 Dec 22 17:31 test.py đây là 755
-rw-r--r-- 1 root root  0 Dec 22 17:27 index.cgi
-rwxrwxrwx 1 root root  5 Dec 22 17:17 index.xxx đây là 777


Hãy google và tự học config apache2, cũng không loằng ngoằng lắm, hoặc nếu muốn ăn "sổi" thì hãy học lệnh (directive) Alias để map link đến các site khác nhau trên máy mình.

Tắm rồi ăn thôi, chưa học được gì cả :((
PS: để luyện đọc mã nhị phân / hexa với smartphone android của bạn, hãy cài ứng dụng này vào :v https://play.google.com/store/apps/details?id=com.hvn.geekgame nhớ +1 và 5 sao nhóe :x )