So, you want to run Perl on the web, because it’s the 90s all over again. You want HTTPS, because… no, there’s no because. You want HTTPS. Who wouldn’t? Here’s what you do on a Debian Linux such as Ubuntu:
sudo apt-get install apache2 libapache2-mod-perl2
mod-perl
is an Apache module that allows Perl programs to be executed from Apache.
Our goal is to get /var/www/html/index.pl running at http://www.example.com/index.pl:
#!/usr/bin/perl
print "Hello World"
Disable the default Apache virtual host:
sudo a2dissite 000-default.conf
Create an example.com.conf
file in /etc/apache2/sites-available
with your text editor, replacing instances of example.com
with your own domain name in both the configuration file and in the file name /etc/apache2/sites-available/example.com.conf
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
<Directory /var/www/>
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
AllowOverride None
AddHandler cgi-script .pl
Require all granted
</Directory>
</VirtualHost>
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName example.com
ServerAlias www.example.com
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
<Directory /var/www/>
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
AllowOverride None
AddHandler cgi-script .pl
Require all granted
</Directory>
</VirtualHost>
</IfModule>
If you have multiple sites, you’ll want to do things with DocumentRoot
to isolate them from each other. But that’s for another post.
You might add in DirectoryIndex /index.pl
to make http://www.example.com/ execute your program.
The Directory
section above allows you to isolate executable code from served code, which is good practice. For this example we’re dumping the executable in with everything else, which is questionable.
Repeat this process for any other domains you host.
sudo a2ensite example.com.conf
sudo ln -r -s /etc/apache2/sites-available/example.com.conf /etc/apache2/sites-enabled/example.com.conf
sudo service apache2 restart
Punch holes in your firewall for ports 80 and 443. Navigate to http://www.example.com/index.pl to check all is okay. You ought to see Hello World displayed for your website.
Having security used to be a pain. SSL certificates signed by a recognised CA cost money, and then you’d have to keep them up to date, and there wasn’t process automation, so you’d do all that stuff by hand. LetsEncrypt address all these problems, handing out free certificates and scripted everything.
Now it’s time for the S part of HTTPS:
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install python-certbot-apache
sudo certbot --apache
certbot renew
If that works, we’ll automatically renew our 90-day certificates every month:
echo '@monthly root /usr/bin/certbot renew >> /var/log/letsencrypt/letsencrypt-auto-update.log' | sudo tee --append /etc/crontab
Done. You’ll never have to worry about certificates again. Now alter your Apache sites-available file (look in /etc/apache2/sites-available/) to include the (optional) redirect HTTP to HTTPS and the mandatory location of the SSL certificates:
<VirtualHost *:80>
....
# Only allow HTTPS
RewriteEngine on
RewriteCond %{SERVER_NAME} = example.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,QSA,R=permanent]
</VirtualHost>
<IfModule mod_ssl.c>
<VirtualHost *:443>
...
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>
Now make the secure version live, and in the process the insecure one… shy? When a request is made for a http page, like http://example.com/index.html, the response will be “Here’s https://example.com/index.html where what you asked for has moved to… forever!”:
sudo service apache2 restart
Now requesting http://www.example.com/index.pl ought to deliver you to https://www.example.com/index.pl