CGI یا Common Gateway Interface قرارداد اجرای برنامه و تحویل خروجی آن به وب‌سرور است. امشب یک برنامهٔ ساده اجرا می‌کنیم تا تفاوت فایل ثابت، برنامهٔ اجراشدنی و FastCGI روشن شود.

این جلسه بخشی از دورهٔ آپاچی در ۵۰ شب است. قرارداد نام‌ها، مسیرها و روش اعمال تغییر را در راهنمای دوره بخوان.

محیط: Clone از سایت ثابت با event MPM؛ نمونه فقط برای .20 در دسترس باشد. اجرای CGI روی سایت اصلی لازم نیست.

برنامه بیرون از DocumentRoot#

پوشهٔ /var/www/apache-lab/cgi-bin را root-owned با حالت 755 بساز. فایل hello با حالت 755 و این محتوا:

#!/bin/sh
printf 'Content-Type: text/plain\r\n\r\n'
printf 'CGI lab OK\n'
printf 'REMOTE_ADDR=%s\n' "$REMOTE_ADDR"

خط خالی بعد از هدر لازم است. کد از ورودی کاربر فرمان shell نمی‌سازد؛ در برنامهٔ واقعی دادهٔ درخواست را به eval یا فرمان چسبانده‌شده نده.

در Debian با event ماژول cgid را فعال کن: sudo a2enmod cgid. در prefork از ماژول cgi مطابق بسته استفاده می‌شود. در RHEL ماژول بارگذاری‌شده را از -M تشخیص بده. در میزبان HTTPS www:

ScriptAlias /cgi-bin/ /var/www/apache-lab/cgi-bin/
<Directory /var/www/apache-lab/cgi-bin>
    Options +ExecCGI -Indexes
    AllowOverride None
    Require ip 192.168.56.20
</Directory>

ScriptAlias مسیر را برای اجرای CGI مشخص می‌کند؛ هر فایل این پوشه باید قابل اعتماد باشد. در RHEL نگاشت پایدار httpd_sys_script_exec_t برای همین پوشه بساز، restorecon کن و boolean httpd_enable_cgi را بررسی کن؛ سیاست امنیتی را برای کل سایت باز نکن.

آزمون پاسخ#

از .20 به https://www.example.test/cgi-bin/hello با CA و resolve صحیح درخواست بده. باید بدنهٔ برنامه را ببینی و .21 باید رد شود. فایل نباید به‌صورت سورس shell دانلود شود. خطای 500 را با shebang، مجوز اجرا، برچسب و هدر CGI در error log بررسی کن.

CGI معمولاً برای هر درخواست اجرای برنامه را آغاز می‌کند؛ FastCGI امکان فرایندهای ماندگار را می‌دهد و PHP-FPM مدیر این فرایندها برای PHP است. انتخاب مدل فقط به پسوند فایل وابسته نیست.

بازگشت: ScriptAlias و Directory را بردار و Clone را به Snapshot برگردان. اجازهٔ اجرا را در پوشهٔ upload هیچ‌وقت اضافه نکن؛ امکان نوشتن فایل و اجرای آن کنار هم خطر اجرای کد می‌سازند.

منبع: راهنمای CGI در Apache ، mod_cgid .