Originally published on 26 August 2022
Contents
A few months ago, I documented how to install the Apache web server on FreeBSD to run Perl CGI scripts. Today, I’m documenting how I did this on Debian. Many of these steps were taken from the excellent tutorials at Digital Ocean.
When working with a fresh install of Debian 11 on Azure, I encountered a number of locale-related warnings anytime I ran an apt update
or apt upgrade
command:
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
LANGUAGE = (unset),
LC_ALL = (unset),
LC_ADDRESS = "en_GB.UTF-8",
LC_NAME = "en_GB.UTF-8",
LC_MONETARY = "en_GB.UTF-8",
LC_PAPER = "en_GB.UTF-8",
LC_IDENTIFICATION = "en_GB.UTF-8",
LC_TELEPHONE = "en_GB.UTF-8",
LC_MEASUREMENT = "en_GB.UTF-8",
LC_TIME = "en_GB.UTF-8",
LC_NUMERIC = "en_GB.UTF-8",
LANG = "C.UTF-8"
are supported and installed on your system.
perl: warning: Falling back to a fallback locale ("C.UTF-8").
To remedy these issues, run the following commands:
$ sudo apt-get purge locales $ sudo apt install locales $ sudo dpkg-reconfigure locales
You can confirm that the locales are properly configured by running
$ perl --version
without seeing any warnings or errors.
Run the following commands to install Apache and ensure it is running:
$ sudo apt update $ sudo apt install apache2 $ sudo systemctl status apache2 ● apache2.service - The Apache HTTP Server Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: > Active: active (running) since Fri 2022-08-26 14:25:06 UTC; 52min ago Docs: https://httpd.apache.org/docs/2.4/ Process: 29544 ExecStart=/usr/sbin/apachectl start (code=exited, status=0/SUCC> Main PID: 29548 (apache2) Tasks: 56 (limit: 470) Memory: 7.0M CPU: 155ms CGroup: /system.slice/apache2.service ├─29548 /usr/sbin/apache2 -k start ├─29549 /usr/sbin/apache2 -k start ├─29550 /usr/sbin/apache2 -k start └─29551 /usr/sbin/apache2 -k start Aug 26 14:25:06 localhost systemd[1]: Starting The Apache HTTP Server... Aug 26 14:25:06 localhost systemd[1]: Started The Apache HTTP Server.
Go to the server’s IP address in a a browser and you should see the standard Apache splash page. If you have a domain name and have properly configured your nameservers and DNS settings to point to your server, go to that URL and you should see the same thing.
Create the root directory from where we will serve our HTML files:
$ sudo mkdir -p /var/www/your_domain.com $ sudo chown -R $USER:$USER /var/www/your_domain.com $ sudo chmod -R 755 /var/www/your_domain.com
Create our new home page at /var/www/your_domain.com/index.html
:
<html>
<head>
<title>Welcome to your_domain!</title>
</head>
<body>
<h1>Success! The your_domain virtual host is working!</h1>
</body>
</html>
Set up our virtual host by configuring the file /etc/apache2/sites-available/your_domain.com.conf
:
<VirtualHost *:80>
ServerAdmin webmaster@localhost
ServerName your_domain.com
ServerAlias www.your_domain.com
DocumentRoot /var/www/your_domain.com
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Enable our new configurations:
$ sudo a2ensite your_domain.com $ sudo a2dissite 000-default.conf $ sudo apache2ctl configtest $ sudo systemctl restart apache2
Go back to the site’s URL (or server’s IP address) to view the new home page.
Install the Certbot snap:
$ sudo apt install snapd $ sudo snap install core $ sudo snap refresh core $ sudo snap install --classic certbot $ sudo ln -s /snap/bin/certbot /usr/bin/certbot $ sudo apache2ctl configtest $ sudo systemctl reload apache2
Obtain the certificate:
$ sudo certbot --apache -d your_domain.com
If successful, Certbot will have created a new file, /etc/apache2/sites-available/your_domain.com-le-ssl.conf
, which contains the names and locations of your Let’s Encrypt certificates.
Test the certificate renewal process:
$ sudo certbot renew --dry-run
If installed correctly, you can verify that a systemd
timer was also configured to automatically check if the certificate needs to be renewed:
$ systemctl list-timers NEXT LEFT LAST PASSED UNIT ACTIVATES Fri 2022-08-26 15:51:21 UTC 13min left Thu 2022-08-25 22:34:47 UTC 17h ago apt-daily.timer apt-daily.service Fri 2022-08-26 18:04:44 UTC 2h 26min left Thu 2022-08-25 18:04:44 UTC 21h ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service Sat 2022-08-27 00:00:00 UTC 8h left Fri 2022-08-26 00:00:18 UTC 15h ago logrotate.timer logrotate.service Sat 2022-08-27 00:00:00 UTC 8h left Fri 2022-08-26 00:00:18 UTC 15h ago man-db.timer man-db.service Sat 2022-08-27 06:44:10 UTC 15h left Fri 2022-08-26 06:38:34 UTC 8h ago apt-daily-upgrade.timer apt-daily-upgrade.service Sat 2022-08-27 10:08:00 UTC 18h left Fri 2022-08-26 13:19:12 UTC 2h 19min ago snap.certbot.renew.timer snap.certbot.renew.service Sun 2022-08-28 03:10:49 UTC 1 day 11h left Wed 2022-08-24 13:40:55 UTC 2 days ago e2scrub_all.timer e2scrub_all.service Mon 2022-08-29 00:13:16 UTC 2 days left Wed 2022-08-24 13:40:55 UTC 2 days ago fstrim.timer fstrim.service 8 timers listed. Pass --all to see loaded but inactive timers, too.
Update our two virtual host files to specify where we will store our CGI scripts.
/etc/apache2/sites-available/your_domain.com.conf
:
<VirtualHost *:80>
ServerAdmin webmaster@localhost
ServerName your_domain.com
ServerAlias www.your_domain.com
DocumentRoot /var/www/your_domain.com
ScriptAlias /cgi-bin/ /var/cgi-bin/
<Directory "/var/cgi-bin">
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
RewriteEngine on
RewriteCond %{SERVER_NAME} =www.your_domain.com [OR]
RewriteCond %{SERVER_NAME} =your_domain.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
/etc/apache2/sites-available/your_domain.com-le-ssl.conf
:
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerAdmin webmaster@localhost
ServerName your_domain.com
ServerAlias www.your_domain.com
DocumentRoot /var/www/your_domain.com
ScriptAlias /cgi-bin/ /var/cgi-bin/
<Directory "/var/cgi-bin">
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
SSLCertificateFile /etc/letsencrypt/live/your_domain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/your_domain.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>
Create the directory where we will store our CGI scripts:
$ sudo mkdir -p /var/cgi-bin $ sudo chown -R $USER:$USER /var/cgi-bin $ sudo chmod -R 755 /var/cgi-bin
Now we can create our CGI script. Within the /var/cgi-bin
directory, create a file called hello.cgi
:
#!/usr/bin/perl -wT
print <<END_OF_HTML;
Content-type: text/html
<HTML>
<HEAD>
<TITLE>Welcome to this Site!</TITLE>
</HEAD>
<BODY>
<H1>About this Site</H1>
<HR>
<p>This is a site where I am trying to learn about CGI programming using Perl.</p>
</BODY>
</HTML>
END_OF_HTML
Save it and change the permissions to allow it to be executed by the Apache server:
$ sudo chmod 755 /var/cgi-bin/hello.cgi
If all went well, you should now be able to go to https://your-domain.com/cgi-bin/hello.cgi and see the results of your script over HTTPS!
If you get any errors, you can try to validate the syntax of your Apache configuration by running sudo apache2ctl configtest
. In addition, you may have to restart the Apache service by running sudo systemctl restart apache2
. If you continue to get errors, check the contents of the access_log
and error_log
log files in /var/log/apache2
.