Samir Parikh · Blog · Git


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.

Prepare the Environment

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.

Install Apache

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.

Configure Apache

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.

Obtain Let’s Encrypt Certificate

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.

Enable CGI Script Execution

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

Create and Run CGI Script

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.