ADMINISTERING APACHE

Theo kết quả survey mới nhất của trang http://news.netcraft.com/archives/category/web-server-survey/ (October 2014 Web Server Survey), Apache dẫn đầu trong số web server application với 385 triệu website sử dụng Apache, chiếm 37.45% tổng số các website. Điều đó cho thấy mức độ phổ biến của Apache, và dưới góc độ 1 web developer, cần có kiến thức vững chắc về web server application này. Tuy nhiên vì lý do nào đó, chúng ta chỉ biết đến Apache 1 cách rời rạc, không có hệ thống. Config đủ để thỏa mãn yêu cầu project nhưng lại yếu những kiến thức cơ bản là điều thường thấy ở developer.

Bài viết sau sẽ tổng hợp 1 số kiến thức cơ bản về Apache, cho người đọc có cái nhìn tổng quan về quản lý Apache cũng như 1 vài case studies cho việc config Apache trong thực tế.

Nội dung bài viết dựa theo chương 6: Administering Apache của cuốn Linux System Administration. 1 vài phần được lược bớt và 1 vài phần được thêm vào dựa trên kinh nghiệm của tác giả.

Cài đặt Apache

Trên CentOS hay Ubuntu thì đều có thể cài đặt Apache và modules 1 cách đơn giản với chỉ 1 dòng lệnh. Tuy nhiên server administrator có thể download file biên dịch rồi cài lần lượt. Làm cách này sẽ rất tiện cho việc thêm module cũng như bổ sung các option khi cài đặt. Bài viết sẽ không nêu ra cách cài Apache, vì việc cài rất đơn giản và có thể tham khảo dễ dàng trên Internet.

Apache Configuration Files

Vị trí của các file config

Tùy theo Linux Distribution mà thư mục config của Apache khác nhau. Sau đây là ví dụ trong Debian system. Thư mục: /etc/apache2.

  • apache2.conf File config chính. Includes thêm các file dựa theo các directive sau.
# Include module configuration:
Include /etc/apache2/mods-enabled/*.load
Include /etc/apache2/mods-enabled/*.conf
# Include all user configurations:
Include /etc/apache2/httpd.conf
# Include ports listing
Include /etc/apache2/ports.conf
# Include generic snippets of statements
Include /etc/apache2/conf.d/[^.#]*
  • conf.d/ Bất kỳ loại config nào mà người dùng muốn.

  • mods-enabled/*.conf Danh sách các module được enabled. Debian có 2 chương trình là a2enmod và a2dismod lần lượt để enable và disable 1 module của Apache. Về cơ bản thì quá trình này là chuyển file từ thư mục mods-available sang thư mục mods-enabled (lưu ý Apache chỉ load file trong mods-enabled, còn file trong mods-available chỉ có giá trị “tham khảo”.) Để hiểu được sâu hơn 1 chút thì có thể đọc nội dung của file trong thư mục mods-enabled. Sẽ thấy mỗi module đều có 2 file, 1 file .load để chỉ định file .so sẽ được load (trong ubuntu, file .so lưu ở /usr/lib/apache2/modules), và 1 file là .conf là các config cơ bản với module đó.

  • sites-enabled/*.conf Setup cho từng website trên server.

  • .htaccess File này nằm ngoài thư mục config của Apache, nó nằm trong chính thư mục web của người dùng. File này chỉ hoạt động khi AllowOverride được set khác none (mặc định là none). Ưu điểm của file này là giúp developer dễ dàng handle rewriting trong project của mình, cũng như tránh được 1 số hạn chế khi làm việc với webhosting không cho config trực tiếp Apache. Tuy nhiên nếu tất cả các thư mục đều được set AllowOverride khác none thì Apache sẽ phải check .htaccess với mỗi request tới directory. Việc đó có thể làm giảm tốc độ xử lý của Apache, do đó AllowOverride được set là none 1 cách mặc định. Chi tiết về config .htaccess sẽ được nói cụ thể ở phần mod_rewrite.

Configuration directive

File config của Apache chia thành 2 phần chính là directive(chỉ thị) và giá trị của nó. Nắm được các directive của Apache là điều rất quan trọng với Apache administrator. Directive chia làm 2 loại, 1 loại là có sẵn được xem như là core của Apache, 1 loại được thêm vào đi kèm với module. Apache sẽ không thể start được nếu directive không tồn tại hoặc module của directive đó chưa được cài đặt và enable. Sau đây là 1 số directive căn bản thuộc Apache core.

User and Group Directives

2 directive này cho biết apache sẽ chạy với user nào và group nào. Trong Debian default là www-data. Ví dụ với Apache/2.4.7 (Ubuntu)

# /etc/apache2/apache2.conf
# These need to be set in /etc/apache2/envvars
User ${APACHE_RUN_USER}
Group ${APACHE_RUN_GROUP}
# /etc/apache2/envvars
export APACHE_RUN_USER=www-data
export APACHE_RUN_GROUP=www-data

Đây là những config default của Apache, tuy nhiên người dùng đôi khi gặp khó khăn với vấn đề quyền user, nổi bật nhất là không thể đọc được file và ghi được file, do login user thường khác với apache_run_user.

Cũng phải nói thêm là không nên set apache_run_user là login user, bởi như thế thông qua nền web, người khác có thể đọc/ghi lên các file trong thư mục các nhân mà chỉ login user có quyền access. Config sai lầm hoặc thiếu kinh nghiệm khi quản lý trang web có thể gây ra hậu quả nghiêm trọng.

Listen Directive

Apache mặc định chỉ respond port 80. Tuy nhiên chúng ta có thể cho phép Apache respond ở các cổng khác nhau thông qua Listen directive. Phổ biến nhất là Port 443 khi sử dụng SSL Encryption. Ngoài ra khi config virtual host cũng thường sử dụng Listen Directive để có thể chạy nhiều trang web khác nhau phân biệt qua cổng.

DocumentRoot Directive

Mỗi website cần có thư mục document root, bao gồm tất cả files và scripts. Ví dụ.

Listen 8888
<VirtualHost *:8888>
    DocumentRoot /var/www/html/rblog/
</VirtualHost>

Khi đó localhost:8888 sẽ trỏ đến thư mục /var/ww/html/rblog

Containers and Aliases

Apache cho phép sử dụng các directive với các thư mục được chỉ định rõ ràng. Để phân biện các thư mục, trong Apache có xác định các loại container directives. Sau đây sẽ là review về các container directive trong Apache.

Absolute Paths: Directory

Directive “Directory” chỉ định 1 thư mục của server, thông qua absolute path. Sau đây là 1 ví dụ

<Directory />
    Options FollowSymLinks
    AllowOverride None
</Directory>

Relative pathnames: Location

Directive “Location” chỉ định files hoặc directory bắt đầu từ document root.

<Location /cgi>
    Options ExecCGI
</Location>

Trong trường hợp trên, chúng ta cho phép chạy CGI trong thư mục: /var/www/cgi. (document root là /var/www)

Pattern matching: Files and FilesMatch

Đôi khi chúng ta muốn chỉ định files hoặc thư mục thông qua pattern, hơn là chỉ rõ 1 file hay thư mục cụ thể. Sau đây là 1 ví dụ config Apache, không cho phép download image từ server về mà không login, thông qua check nguồn gốc của request. Cụ thể là chúng ta sẽ check HTTP Referer. Nếu referer là site của chúng ta thì sẽ set biến env = 1, còn lại sẽ set là 0. Khi đó chỉ env = 1 mới có quyền access đến file.

<FilesMatch "\.(gif|jpg|jpeg|png)$">
    SetEnvIfNoCase Referer "^http://server1.centralsoft.org/" local=1
    Order Allow, Deny
    Allow from env=local
</FilesMatch>

Aliases

Alias set tên cho 1 thư mục trong server, đặc biết cho các trường hợp thư mục không nằm trong document root.

Alias /test /tmp/test

Khi đó, nếu chúng ta access: localhost/test/button.gif đồng nghĩa với việc chúng ta access file /tmp/test/button.gif.

Virtual Hosts

1 trong những khái niệm quan trọng khi làm việc với Apache là VirtualHosts. Mặc định thì trong Apache không có Virtual Hosts, nó chỉ thực sự cần thiết khi chúng ta muốn chạy nhiều hơn 1 website trên cùng 1 máy. Với sự hỗ trợ của HTTP 1.1, khi client request lên server bằng cách gửi đồng thời địa chỉ IP và server’s name, chúng ta có 2 kiểu virtual hosts trong Apache là name-based virtual hosts và IP-based virtual hosts.

Name-based virtual host

Như tên gọi name-based, chúng ta sẽ config virtual host dựa theo tên của host. So với IP-based virtual host thì Name-based virtual hosts có thể cài đặt dễ hơn. Chúng ta chỉ cần config DNS server trỏ đến địa chỉ IP của mình có. Còn khi làm việc trên localhost, chúng ta có thể config file /etc/hosts như sau

127.0.0.1 localhost rblog.localhost

Còn config Apache như sau

<VirtualHost *:80>
    ServerName rblog.localhost
    DocumentRoot /var/www/html/rblog
    <Directory /var/www/html/rblog>
        Allowoverride All
    </Directory>
</VirtualHost>

Như vậy là chúng ta có thể access trang web của mình từ trình duyệt qua đường link: http://rblog.localhost/.

IP-based virtual host

IP-based virtual host cho phép sử dụng các directive khác nhau lên cùng 1 địa chỉ URL dựa theo địa chỉ IP được client request lên. Để cài đặt IP-based virtual host, chúng ta cần 1 server có nhiều hơn 1 địa chỉ IP. Về cơ bản để làm được điều này, chúng ta cần 1 machine với nhiều đường kết nối internet hoặc sử dụng IP aliasing.

Sau đây là 1 ví dụ về config IP-based virtual host

<VirtualHost 192.168.6.1>
    ServerName "www1"
    DocumentRoot "/var/www/vhosts/www1.example.com"
</VirtualHost>
<VirtualHost 192.168.6.2>
    ServerName "www2"
    DocumentRoot "/var/www/vhosts/www2.example.com"
</VirtualHost>

Mod rewrite

Ở phần cuối bài viết, chúng ta sẽ cùng nhau tìm hiểu về mod_rewrite trong Apache, 1 trong những module phổ biến nhất của Apache. Để sử dụng mod rewrite, cần enable mod_rewrite (vì mặc định là bị disable). Sau đó chúng ta cần chỉ rõ thư mục muốn sử dụng mod rewrite

<Directory /var/www/rblog>
    AllowOverride All
</Directory>

Từ thời điểm này, Apache sẽ kiểm tra file .htaccess trong thư mục /var/www/rblog và thực thi các rewrite rule trong đó. Sau đây là 1 ví dụ đơn giản:

# /var/www/rblog/.htaccess
RewriteEngine On
RewriteRule ^/?test.html$ test.php [L]

Trong ví dụ đơn giản trên, chúng ta có thể thấy khi có request đến /test.html, Apache sẽ render file test.php. Điều đáng chú ý là nếu dùng redirect, Apache sẽ gửi response cho client thông báo redirect sang trang test.php. Trong khi đó nếu sử dụng mod_rewrite, server không cần trả lại bất kỳ gói tên nào với nội dung redirect mà vẫn show ra test.php như thể test.html tồn tại.

Câu hỏi được đặt ra là thực sự mod rewrite dùng để làm gì? Lý do phổ biến nhất có lẽ là để tạo ra các friendly URL, cụ thể là rút ngắn URL, xóa bỏ các ký tự không thân thiện với search-engine (như ?, = trong các HTTP GET request).

Dưới đây là 1 ví dụ:

RewriteRule ^/?(USA|Canada|Mexico)/(.*)/(.*)  display.php?country=$1&stage=$2&city=$3 [NC,L]

Ở ví dụ trên, chúng ta đã rewrite các URL dạng: /usa/california/los_angeles sẽ được rewrite thành: /display.php?country=usa&stage=california&city=los_angeles. Rõ ràng từ phía client người dùng chỉ thấy 1 đường link đơn giản còn server lại thấy được đầy đủ các GET Parameter cho quá trình xử lý sau này.

Ngoài việc chỉ dùng để rewrite URL cho “đẹp”, master về rewrite url có thể xử lý nhiều thao tác cao cấp với chỉ 1,2 dòng lệnh. Sau đây là 1 ví dụ không cho phép người dùng truy cập thư mục images thông qua hot link, bắt buộc truy cập từ 1 page thuộc trang web chưa image.

RewriteCond expr "! %{HTTP_REFERER} -strmatch '*://%{HTTP_HOST}/*'"
RewriteRule ^/?images - [F]

Nguyên lý làm việc khá giống với ví dụ về FileMatches ở trên, tuy nhiên có thể thấy là rất ngắn gọn và “khó đọc” với người chưa có kinh nghiệm. Để hiểu rõ ví dụ này, xin mời bạn đọc tham khảo documentation của Apache.

Tổng kết

Trên đây chúng ta đã cùng nhau tìm hiểu những khái niệm cơ bản của Apache. Trong các bài viết tới, chúng ta sẽ làm quen với những feature nâng cao hơn, các module phức tạp hơn của Apache.

Tài liệu tham khảo

Bài viết tham khảo ví dụ từ các nguồn sau


All Rights Reserved