A webserver to rule them all (update #1)

A webserver to rule them all (update #1)

ubuntu 18.04 hw2018 server apache mysql xsuperseded

Many services I use have a web interface, so here is my basic apache setup. When I say basic, but I mean apache with https, http/2, mysql and phpmyadmin

Needs

There are plenty of opensource webservers, but I’ve chosen apache httpd mainly for two reasons:

  • I know how to use it for years.
  • I even don’t know how to pronounce nginx.

Services

On my home server, a web interface is available for:

Service Description Type Related tag
backuppc rsync based on disk backup web-app/perl -
grafana data visualization and monitoring webserver grafana
phpmyadmin web interface for mysql web-app/php mysql
tvheadhend TV streaming and recording server webserver tvheadend
weewx weather station software generated files TBD
zabbix network monitoring web-app/php zabbix
jenkins continuous integration webserver TBD
gogs git services webserver TBD

Apparently the grafana and tvheadend guys thinks it’s a good idea to include a webserver… Please don’t, and here is why (IMHO):

  • The http/https ports are already used by another program.
  • There is already a lot of good opensource web servers, the time invested in your integrated web server could have been better spent.
  • A person that is able to setup grafana or tvheadend, is clearly able to install a webserver. Please have a look at phpmyadmin, it’s so easy to setup on apache.

https, http2, php, …

For performance reasons I want to enable http2, and this will affect which apache mpm to install.

Install

sudo apt-get install -y mysql-server php7.2-fpm phpmyadmin automysqlbackup
  • Http server : apache2
  • Configuring phpmyadmin : Yes
  • Password for phpmyadmin : empty

mysql use system password for root, but root has no password, so let’s use mysql password for root:

sudo mysql -u root mysql
UPDATE user SET plugin='mysql_native_password' WHERE User='root';
SET PASSWORD FOR root@'localhost' = PASSWORD('MyCoolPassword');
FLUSH PRIVILEGES;
exit;

Configure apache2

Get rid of http

The let’s encrypt site provides valid SSL certificates for web servers. I don’t want to write a post about that today, but at some point in the procedure, you must prove that you are running the server you want a certificate for, and the simplest challenge (HTTP-01) uses plain http for the transport.

So I would like to disable port 80, but it’s currently impossible since I want to use let’s encrypt certbot…

Redirecting all traffic from http to https may let me do stupid things, for instance forgetting the s from https and POSTing some critical data over unencrypted http, so my compromise is to redirect only the URL used in the HTTP-01 to https, and respond to other http URL with a 403 Forbidden error code.

Here is the the changes to be done at the beginning of in /etc/apache2/sites-available/default-ssl.conf to enable http2, and disable http unless for let’s encrypt:

	<VirtualHost *:80>
			Servername YOUR_SERVER_NAME_HERE
			ServerAlias YOUR_SERVER_NAME_HERE_ALIAS_1 YOUR_SERVER_NAME_HERE_ALIAS_2
            <Location />
				Order deny,allow
				Deny from all
			</Location>
			<Location /.well-known/acme-challenge/>
			Order deny,allow
			Allow from all
			</Location>
        </VirtualHost>

        <VirtualHost _default_:443>
			Protocols h2 http/1.1
			Servername YOUR_SERVER_NAME_HERE
			ServerAlias YOUR_SERVER_NAME_HERE_ALIAS_1 YOUR_SERVER_NAME_HERE_ALIAS_2
			ServerAdmin webmaster@localhost

			DocumentRoot /var/www/html
...

⚠ Servername and ServerAlias must be both in :80 and :433 for certbot.

Setup apache modules

sudo a2enmod proxy_fcgi setenvif
sudo a2enconf php7.2-fpm
sudo a2dismod mpm_prefork
sudo a2enmod mpm_event
sudo a2enmod http2
sudo a2enmod ssl
sudo a2ensite default-ssl
sudo a2dissite 000-default.conf
sudo systemctl reload apache2

Testing

Open this URL in your favorite browser : https://YOUR_SERVER_IP_HERE/phpmyadmin, then login a root/MyCoolPassword.

mysql backups

You may have noticed that automysqlbackup is installed. It will periodically backup all mysql databases into /var/lib/automysqlbackup.

It is configurable by modifying /etc/default/automysqlbackup.

Here is some recommendations extracted from the automysqlbackup script:

# Daily Backups are rotated weekly..
# Weekly Backups are run by default on Saturday Morning when
# cron.daily scripts are run...Can be changed with DOWEEKLY setting..
# Weekly Backups are rotated on a 5 week cycle..
# Monthly Backups are run on the 1st of the month..
# Monthly Backups are NOT rotated automatically...
# It may be a good idea to copy Monthly backups offline or to another

To be continued

Now that the infrastructure is in place, let’s do something with it : monitor system health.

~~~

Question, remark, bug? Don't hesitate to contact me or report a bug.