hazardous

thoughts, things, etc. from andrew snow

fastCGI and furious

for the sake of convenience, most development these days has been automated - and by no means am i about to launch into some rant about how this is bad. you'd have to be super out-of-touch to miss how useful this is in the day-to-day.

but like anything in this world there are tradeoffs and disadvantages, and this post is going to touch on one in particular as i detail the steps i took to disable the default method of PHP processing on an Apache2 webserver, and then set up PHP handling by way of a module called 'FastCGI'. yeah... that CGI. i still have no idea what it is, but over and over I find myself having to reconfigure my webserver across a variety of projects that require more utility from PHP than the stock setup provides for.

usecase


increasingly i have been using applications which require re-configuring the default PHP setup you normally start with after installing the apache2, php, and libapache2-mod-php packages. i promise to revisit this section when i understand the dark forces at work here, but for now i can only state with certainty that modern PHP programs tend to require components that PHP does not enable by default. the major ones are fpm, mbstring, zip, and fcgid aka fastCGI. i think the simple explanation is speed-based, and allows your webserver to process more commands simultaneously, with faster execution times.

after following the steps i will be laying out, hopefully i will be left with a LAMP server which will be able to run a vast majority of the modern software available that requires PHP, such as Wordpress, Jekyll, and others.

the environment


the stack i am most familiar with is the classic LAMP stack, though i've been mighty tempted to try swapping apache out with nginx. for now, this post will be covering a simple LAMPstack, freshly set up: a Linux operating system, running Apache2, MySQL, and PHP.

Assuming either a clean-slate install of Ubuntu 18.04 or 20.04, here's a barebones rundown to get going quick with a webserver, which is also given a basic level of adequate security.

install apache, firewall and certbot (for configuring https:// later)

sudo apt install apache2 ufw certbot python3-certbot-apache
sudo ufw allow "openssh"
sudo ufw allow "apache full"
sudo ufw enable

for a quick way to see why ufw and fail2ban are important, simply run cat /var/log/auth.log | grep "Failed password" for a sobering look at the list of failed login attempts from botnets and other malicious attackers running 'dictionary attacks', ie just trying out common words and common login usernames with different password combinations harvested from user:pw databases stolen from prior hackings.

configure local environment to work with the webserver directory:

sudo chown $(whoami):www-data /var/www
cd /var/www && mkdir -p yourwebsite.url/public_html 

you will want to then navigate to /etc/apache2/sites-available and make a copy of the default virtual host configuration file to customize. run sudo cp 000-default.conf yourwebsite.url.conf. the name of the .conf file does not matter much, but naming it after the website you intend to create a virtual host for is helpful.

if you do not intend of running more than one website from your server, you can skip the above and simply edit the default 000-default.conf, changing the variables discussed next:

open your newly created file and you will be greeted with a pretty short'n'simple configuration, and you only need to change 2 lines:

ServerName yourwebsite.url
ServerAlias www.yourwebsite.url

the above should be straightforward: you define the url used to point at your webserver - as well as an 'alias', ie the www prefix. On a side note, I am old enough to remember a time when the www was all but de facto, and i remember it being kind of a 'thing' when more and more websites became accessible even if you dropped the worldwide web prefix. guess i am ancient now...

a bit later down the road when you have configured and successfully launched your server, you might still have trouble accessing it via its domain name. sometimes going to /etc/apache2 and opening apache2.conf, and then adding:

ServerName yourwebsite.url

and then restarting the server with sudo systemctl restart apache2 will solve the problem.

alright, at this point you should have a configured bare minimum webserver. more often than not you likely will need to do some further tweaking, but we now have enough infrastructure running to play around with apache2 and get it setup for modern use.

Setting fastcgi and mbstring up on PHP


since i've been working on this article bit by bit as time allows, there has been a pleasant twist since i first started this article: it seems like the method to get this rolling has been even further simplified - though i will have to see how that plays out!

if you haven't already, make sure apache2 is running with PHP enabled. after that, we can then install the required dependencies for mbstring and fastcgi.

for the dependencies, i will be using a nifty feature builtin to your shell, and use a nice function to save some keystrokes:

sudo apt install -y libapache2-mod-php php php-cli &&
sudo apt install -y php-{bcmath,bz2,intl,gd,mbstring,mysql,zip,fpm} 

during install you should see the package manager spit out a note about enabling the newly installed packages for apache2 - so let's quickly enable our new modules, and reload the webserver.

sudo a2enmod proxy_fcgi setenvif
sudo a2enconf php7.2-fpm
sudo systemctl reload apache2.service

you might need to adjust the name of the configuration file as needed, if your php is a different version. here the php module is version 7.2.

and to enable mbstring, run a similar process using a different command:

sudo phpenmod mbstring
sudo systemctl reload apache.service

fingers crossed, but this should be all you need to bring your Apache server up to modern standards, running multibyte strings and FPM, which allows faster execution times.