Hướng dẫn cài đặt và cấu hình SuEXEC, cho phép gọi lệnh CGI dưới quyền một user bất kỳ trong hệ thống.

Mặc định các lệnh CGI (bao gồm cả PHP) đều chạy dưới quyền của user www-data hoặc nobody. User này có quyền lực vô cùng giới hạn vì thế đương nhiên không thể can thiệp sâu vào hệ thống server.

suEXEC là một Module của Apache2 cho phép gọi lệnh CGI (Common Gateway Interface) và SSI (Server Side Includes) dưới quyền một user khác, khắc phục được vấn đề trên.

Cài đặt suEXEC trên Debian 9

Cài đặt gói apache2-suexec-custom :

$ sudo apt-get update
$ sudo apt-get install apache2-suexec-custom

Bật module suEXEC trong Apache2.

$ sudo a2enmod suexec
$ sudo systemctl restart apache2

Hướng dẫn cấu hình CGI với suEXEC

Tạo tài khoản mà CGI sẽ chạy dưới quyền, ví dụ tài khoản icreativ.

$ sudo useradd -m -d /home/icreativ -s /bin/sh icreativ

Tạo các thư mục cần thiết để lưu trữ website và CGI script.

$ sudo mkdir -p /home/icreativ/public_html/cgi-bin
$ sudo chown -R icreativ:icreativ /home/icreativ

Thêm đường dẫn thư mục CGI vào file cấu hình /etc/apache2/suexec/www-data của suEXEC.

$ sudo vi /etc/apache2/suexec/www-data
/home/icreativ/public_html/cgi-bin
/var/www
public_html/cgi-bin
# The first two lines contain the suexec document root and the suexec userdir
# suffix. If one of them is disabled by prepending a # character, suexec will
# refuse the corresponding type of request.
# This config file is only used by the apache2-suexec-custom package. See the
# suexec man page included in the package for more details.
$ sudo systemctl restart apache2

Tạo một VirtualHost cho phép CGI trong thự mục ~/public_html/cgi-bin. Sự khác biêt ở đây là có thêm directive SuexecUserGroup với 2 tham số là tên usertên group của user ta muốn chạy CGI.

/etc/apache2/sites-available/example.com.conf

<VirtualHost *:80>
    ServerName example.com
    ServerAdmin webmaster@example.com
    DocumentRoot /home/icreativ/public_html

    # Enable CGI
    ScriptAlias /cgi-bin/ /home/icreativ/public_html/cgi-bin/
    <Directory "/home/icreativ/public_html/cgi-bin">
        AllowOverride None
        Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
        Require all granted
    </Directory>

    # Let 'icreativ' a executing user
    SuexecUserGroup icreativ icreativ

</VirtualHost>

Bật cấu hình VirtualHost.

$ sudo a2ensite example.com.conf
$ sudo systemctl reload apache2

Cấp quyền sudo cho user icreativ. Lưu ý phải cho phép sudo ở chế độ không yêu cầu mật khẩu.

$ sudo visudo
...
icreativ    ALL=(ALL) NOPASSWD:ALL
...

Lưu ý: Nên giới hạn quyền sudo của user này, không nên để toàn quyền như trên.

/home/icreativ/public_html/cgi-bin/log.cgi

#!/bin/bash
printf "Content-type: text/html\n\n"
cat <<HTML
<html>
<body>
<pre>
$( sudo cat /var/log/apache2/access.log )
</pre>
</body>
</html>
HTML
exit 0
$ chown icreativ:icreativ /home/icreativ/public_html/cgi-bin/log.cgi
$ chmod 700 /home/icreativ/public_html/cgi-bin/log.cgi

Truy cập file CGI trên qua URL http://example.com/cgi-bin/log.cgi