Eddings Web Server

Oct 29, 2023

This Eddings sub-guide describes the steps necessary to make the computer a web server, using Apache httpd.

Previously, I’d been using tolkien as a web server, which has now been decommissioned. The documentation for the old tolkien web server is archived in the following pages:

Please note that all of those services (SVN, Trac, WebDAV, and WordPress) are no longer being used. I was uncomfortable with their security and usabilty and have opted for the following alternatives:

  • My SVN repositories were all migrated to GitHub and bitbucket.
  • My Trac projects have all been either converted into this nanoc-powered site or archived.
  • My WebDAV shares were all decommissioned.
  • My WordPress blog was migrated into this nanoc-powered site: Blog.

The portions of my web content now generated by nanoc are all hosted by the Apache httpd server described in this page.

Much of the content for this page was derived from Ubuntu’s Apache web server documentation: https://help.ubuntu.com/10.04/serverguide/httpd.html.

Installing Apache httpd

Apache’s httpd seems to be, by far, the most popular web server package for Linux. I’ve had good success with it, myself. Installing it is as simple as:

$ sudo apt-get install apache2

Basic Configuration

The Apache web server supports virtual hosts: the ability to serve different web sites based on the URL and/or IP used to access the site. The default Ubuntu install of Apache will create and enable a default virtual site that displays a basic “It Works!” message. We want to disable this site:

$ sudo a2dissite default
$ sudo /etc/init.d/apache2 reload

SSL Encryption

References:

By default, Apache uses unencrypted HTTP for all traffic. This means that all of the traffic, including any usernames and passwords entered, are sent out as (essentially) clear text, viewable by anyone who happens to be listening. For security, it’s best to force all traffic to instead use encrypted HTTPS.

First, enable Apache’s mod_ssl module:

$ sudo a2enmod ssl

Enable SSL virtual hosts by adding a NameVirtualHost *:443 directive to the /etc/apache2/ports.conf file, as follows:

# ... snip

<IfModule mod_ssl.c>
    # If you add NameVirtualHost *:443 here, you will also have to change
    # the VirtualHost statement in /etc/apache2/sites-available/default-ssl
    # to <VirtualHost *:443>
    # Server Name Indication for SSL named virtual hosts is currently not
    # supported by MSIE on Windows XP.
    Listen 443
    NameVirtualHost *:443
</IfModule>

<IfModule mod_gnutls.c>
    Listen 443
    NameVirtualHost *:443
</IfModule>

# ... snip

The rest of the SSL configuration is provided below, as part of the justdavis.com site configuration.

Create Site: justdavis.com

References:

The justdavis.com domain will be used to serve static web content generated by nanoc.

Create the folders that will be used to store the content, logs, etc. for the site:

$ sudo mkdir -p /var/apache2/justdavis.com/www/
$ sudo mkdir -p /var/apache2/justdavis.com/logs/
$ sudo chown -R root:root /var/apache2/justdavis.com/
$ sudo chmod -R u=rwX,g=rX,o=rX /var/apache2/justdavis.com/

Create the SSL site configuration in /etc/apache2/sites-available/justdavis.com-ssl:

<VirtualHost *:443>
	ServerName justdavis.com

	DocumentRoot /var/apache2/justdavis.com/www/
	LogLevel warn
	ErrorLog /var/apache2/justdavis.com/logs/error_log
	TransferLog /var/apache2/justdavis.com/logs/access_log

	ServerAdmin webmaster@justdavis.com

	Options FollowSymLinks

	# Configure SSL for this virtual host (derived from /etc/apache2/sites-available/default-ssl)
	SSLEngine on
	SSLCertificateFile /etc/ssl/certs/justdavis.com-wildcard.crt
	SSLCertificateKeyFile /etc/ssl/private/justdavis.com-wildcard.key
	SSLCertificateChainFile /etc/ssl/certs/justdavis.com-wildcard-ca-intermediate.pem
	SSLCACertificateFile /etc/ssl/certs/justdavis.com-wildcard-ca-root.pem
	<FilesMatch "\.(cgi|shtml|phtml|php)$">
		SSLOptions +StdEnvVars
	</FilesMatch>
	<Directory /usr/lib/cgi-bin>
		SSLOptions +StdEnvVars
	</Directory> 
	BrowserMatch "MSIE [2-6]" \
		nokeepalive ssl-unclean-shutdown \
		downgrade-1.0 force-response-1.0
	# MSIE 7 and newer should be able to use keepalive
	BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown

	# Configure mod_proxy to be used for proxying URLs on this site to other URLs/ports on this server.
	ProxyRequests Off
	ProxyVia Off
	ProxyPreserveHost On
	<Proxy *>
		AddDefaultCharset off
		Order deny,allow
		Allow from all
	</Proxy>

	# Proxy the Java web application running at http://localhost:8080/nexus/
	<Location /nexus/>
		ProxyPass http://localhost:8080/nexus/
		ProxyPassReverse http://localhost:8080/nexus/
		SetEnv proxy-nokeepalive 1
	</Location>
</VirtualHost>

Create the non-SSL site configuration in /etc/apache2/sites-available/justdavis.com:

<VirtualHost *:80>
        ServerName justdavis.com

        DocumentRoot /var/apache2/justdavis.com/www/
        LogLevel warn
        ErrorLog /var/apache2/justdavis.com/logs/error_log
        TransferLog /var/apache2/justdavis.com/logs/access_log

        ServerAdmin webmaster@justdavis.com

        # Redirect all HTTP (port 80) traffic for this virtual host to HTTPS.
        RewriteEngine on
        RewriteCond %{HTTPS} off
        RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
</VirtualHost>

Enable the sites as follows:

$ sudo a2ensite justdavis.com-ssl
$ sudo a2ensite justdavis.com
$ sudo service apache2 restart

Create Site: madrivercode.com

References:

The madrivercode.com domain isn’t really hosting anything directly at this time; it’s been mostly replaced by justdavis.com (at least for the time being). Accordingly, it just needs to redirect some of its old content to the appropriate new justdavis.com URL.

Create the folders that will be used to store the content, logs, etc. for the site:

$ sudo mkdir -p /var/apache2/madrivercode.com/www/
$ sudo mkdir -p /var/apache2/madrivercode.com/logs/
$ sudo chown -R root:root /var/apache2/madrivercode.com/
$ sudo chmod -R u=rwX,g=rX,o=rX /var/apache2/madrivercode.com/

Create the site configuration in /etc/apache2/sites-available/madrivercode.com:

<VirtualHost *:80>
	ServerName madrivercode.com
	ServerAlias madriverdevelopment.com
	ServerAlias simplepersistence.com

	DocumentRoot /var/apache2/madrivercode.com/www/
	LogLevel warn
	ErrorLog /var/apache2/madrivercode.com/logs/error_log
	TransferLog /var/apache2/madrivercode.com/logs/access_log

	ServerAdmin webmaster@madrivercode.com

	Options FollowSymLinks

	# Redirects from http://madrivercode.com/blog/ to https://justdavis.com/karl/blog/
	RewriteEngine on
	# Redirect: resume:
	RewriteRule ^/blog/wp-content/uploads/2009/03/karlmdavis-resume.pdf(.*) https://justdavis.com/karl/downlo$
	# Redirect: 2009-03-21 article:
	RewriteRule ^/blog/coding/native-libraries-vcs-and-maven(.*) https://justdavis.com/karl/blog/2009/03/21/i$
	# Redirect: 2009-09-05 article:
	RewriteRule ^/blog/uncategorized/a-sad-tale-of-vpn-troubles-on-intrepid/(.*) https://justdavis.com/karl/b$
	# Redirect: everything else:
	RewriteRule ^/blog(.*) https://justdavis.com/karl/blog/ [R=permanent,L]
</VirtualHost>

Enable the site as follows:

$ sudo a2enmod rewrite
$ sudo a2ensite madrivercode.com
$ sudo service apache2 restart

SSL Certificate

Note that the configuration above references an SSL certificate and key file. Originally, this site used a certificate generated from a self-signed CA. However, this got to be annoying as most browsers require users to accept a click-through warning when using such certificates.

To solve this annoyance, the site now uses a commercial SSL certificate with justdavis.com and *.justdavis.com as DNS names. This certificate was obtained from StartSSL, which provides reasonably priced certificates.

After purchase, the certificates were stored in the following AFS directory: /afs/justdavis.com/user/karl/id/startcom/justdavis.com-wildcardCert-2013-03-30. The following commands were then run on eddings to copy the certificate files to the directories used by Apache and other services:

$ kinit karl
$ aklog
$ mkdir ~/justdavis.com-wildcard-staging
$ cp /afs/justdavis.com/user/karl/id/startcom/justdavis.com-wildcardCert-2013-03-30/* ~/justdavis.com-wildcard-staging
$ cd ~/justdavis.com-wildcard-staging
$ sudo cp justdavis.com-wildcardCert-2013-03-30-keyWithoutPassword.key /etc/ssl/private/justdavis.com-wildcard.key
$ shred -u justdavis.com-wildcardCert-2013-03-30-keyWithoutPassword.key
$ sudo chmod u=rw,g=r,o= /etc/ssl/private/justdavis.com-wildcard.key
$ sudo chown root:ssl-cert /etc/ssl/private/justdavis.com-wildcard.key
$ sudo cp justdavis.com-wildcardCert-2013-03-30-ca-root.pem /etc/ssl/certs/justdavis.com-wildcard-ca-root.pem
$ sudo cp justdavis.com-wildcardCert-2013-03-30-ca-intermediate.pem /etc/ssl/certs/justdavis.com-wildcard-ca-intermediate.pem
$ sudo cp justdavis.com-wildcardCert-2013-03-30.crt /etc/ssl/certs/justdavis.com-wildcard.crt
$ cd ~
$ rm -rf ~/justdavis.com-wildcard-staging

SSL Certificate for justdavis.com in 2015

References:

When I went to renew my StartSSL certificate for justdavis.com in 2015, their site appeared to be down. As an alternative, I purchased a new wildcard certificate through gandi.net.

A CSR for this certificate was generated on eddings, as follows:

$ kinit karl
$ aklog
$ cd /afs/justdavis.com/user/karl/id/ssl-for-justdavis.com
$ mkdir 2015-gandi-wildcard-for-justdavis.com && cd $_
$ openssl req -nodes -newkey rsa:2048 -sha256 -keyout justdavis.com-wildcard-2015-04-13.key -out justdavis.com-wildcard-2015-04-13.csr
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:Maryland
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Davis
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:*.justdavis.com
Email Address []:karl.michael.davis@gmail.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

This CSR was then submitted to Gandi. Once the purchase and verification process was complete, the certificate files were downloaded and saved to the following locations:

  • The issued wildcard certificate: /afs/justdavis.com/user/karl/id/ssl-for-justdavis.com/2015-gandi-wildcard-for-justdavis.com/justdavis.com-wildcard-2015-04-13.crt
  • The intermediate certificate required for the wildcard certificate: /afs/justdavis.com/user/karl/id/ssl-for-justdavis.com/2015-gandi-wildcard-for-justdavis.com/COMODOExtendedValidationSecureServerCA2.pem

The following was then done to deploy the new certificate to the appropriate locations on eddings:

$ sudo cp /afs/justdavis.com/user/karl/id/ssl-for-justdavis.com/2015-gandi-wildcard-for-justdavis.com/justdavis.com-wildcard-2015-04-13.key /etc/ssl/private/justdavis.com-wildcard-2015-04-13.key
$ sudo chmod u=r,g=r,o= /etc/ssl/private/justdavis.com-wildcard-2015-04-13.key
$ sudo chown root:ssl-cert /etc/ssl/private/justdavis.com-wildcard-2015-04-13.key
$ sudo cp /afs/justdavis.com/user/karl/id/ssl-for-justdavis.com/2015-gandi-wildcard-for-justdavis.com/COMODOExtendedValidationSecureServerCA2.pem /etc/ssl/certs/justdavis.com-wildcard-2015-04-13-ca-intermediate.pem
$ sudo cp /afs/justdavis.com/user/karl/id/ssl-for-justdavis.com/2015-gandi-wildcard-for-justdavis.com/justdavis.com-wildcard-2015-04-13.crt /etc/ssl/certs/justdavis.com-wildcard-2015-04-13.crt

Apache’s SSL configuration in /etc/apache2/sites-available/justdavis.com-ssl was then updated to reference these files:

	# Configure SSL for this virtual host (derived from /etc/apache2/sites-available/default-ssl)
	SSLEngine on
	SSLCertificateFile /etc/ssl/certs/justdavis.com-wildcard-2015-04-13.crt
	SSLCertificateKeyFile /etc/ssl/private/justdavis.com-wildcard-2015-04-13.key
	SSLCertificateChainFile /etc/ssl/certs/justdavis.com-wildcard-2015-04-13-ca-intermediate.pem
	SSLCACertificateFile /etc/ssl/certs/ca-certificates.crt

This configuration change was then applied to Apache:

$ sudo service apache2 reload

Kerberos Authentication

References:

By default, Apache on Ubuntu will be installed with mod_auth_kerb available and enabled. This allows Kerberos to be used for Apache authentication where desired. First, though, a Kerberos principal keytab for Apache needs to be created and secured:

$ sudo kadmin -p karl/admin
kadmin>  addprinc -policy services -randkey HTTP/eddings.justdavis.com
kadmin>  ktadd -k /etc/apache2/apache2.keytab HTTP/eddings.justdavis.com
kadmin>  quit
$ sudo chown www-data:www-data /etc/apache2/apache2.keytab
$ sudo chmod u=r,g=,o= /etc/apache2/apache2.keytab

With this in place, any <Directory/> or <Location/> entry in Apache could be secured, as follows:

<Location /foo>
	AuthType Kerberos
	AuthName "Kerberos Login"
	KrbAuthRealm JUSTDAVIS.COM
	Krb5Keytab /etc/apache2/apache2.keytab
	KrbMethodK5Passwd off #optional--makes GSSAPI SPNEGO a requirement
	Require valid-user
</Location>