Status Page : Ubuntu 20.04 and Cachet


In another random post of requirements, I was asked about setting up the status page and while there are many companies that do these off the shelf, many of these companies use an open source solution and slap their branding on it and then you pay for that support and the hosting.

This got me thinking it might be easier to use the open source software, cut out the middleman and host it myself, obviously it goes without saying there’s more work to do in that scenario because you need to secure your server and manually install SSL certificates and set up the configuration, but sometimes sometimes learning how to do this is part of the fun.

Note : This guide recommended you to use Ubuntu 20.04, get your hardware built then we need to get configuring the application, I would download the ISO from here - I used the 20.04.04 file as shown below:


You also do not need the desktop version, there is no requirement for GUI with this guide or application.

PHP Warning

PHP wise you need to ensure that PHP is v7.4 which you can get with the command:

php --version


It needs to be v7.4, if you upgrade to v.8.1 or PHP then the software fails to install as it will not work, be warned.

Behind a proxy?

If you are behind a proxy you will need to ensure you set the apt command to use it, to complete the action first you need to create the file with this:

sudo apt /etc/apt/apt.conf.d/proxy.conf

Then the contents of that file need to be the below, obviously change the proxy.sever:port for the name of valid details:

Acquire::http::Proxy "http://proxy.server:port/";
Acquire::https::Proxy "http://proxy.server:port/";

Then for other commands before they are run you will need to copy this into the shell window to ensure they use the proxy as well:

export http_proxy=http://proxy.server:port/
export https_proxy=http://proxy.server:port/

Update OS

sudo apt-get update -y && sudo apt-get upgrade -y

Install Apache 2

sudo apt install apache2
sudo systemctl enable apache2 && sudo systemctl start apache2

Install PHP Components

sudo apt-get install zip unzip php7.4 php7.4-mysql php7.4-curl php7.4-json php7.4-cgi php7.4-xsl php7.4-sqlite php7.4-mbstring php-pear php7.4-mbstring libapache2-mod-php

Install MariaDB

apt install mariadb-server
sudo systemctl enable mariadb
sudo systemctl start mariadb

Install Table for Cachet

mysql

CREATE DATABASE cachet;
GRANT ALL PRIVILEGES ON cachet.* TO 'cachet'@'localhost' IDENTIFIED BY 'SecretBearPassword';
FLUSH PRIVILEGES;
exit;

Install Composer

curl -sS https://getcomposer.org/installer | php
chmod +x composer.phar
mv composer.phar /usr/local/bin/composer
composer -V

Pre-Flight Check

Once you have issued the command "composer -V" you might also want to run the command to diagose the setup you have, this is this command

composer diagnose

This should then show you something like this, pay attention to errors and warning here and fix them before moving on.

Checking platform settings: OK
Checking git settings: OK git version 2.25.1
Checking http connectivity to packagist: OK
Checking https connectivity to packagist: OK
Checking HTTP proxy with http: OK http://squid.bear.local:3129
Checking HTTP proxy with https: OK http://squid.bear.local:3129
Checking github.com rate limit: OK
Checking disk free space: OK
Checking pubkeys:
Tags Public Key Fingerprint: 57815BA2 7E54DC31 7ECC7CC5 573090D0  87719BA6 8F3BB723 4E5D42D0 84A14642
Dev Public Key Fingerprint: 4AC45767 E5EC2265 2F0C1167 CBBB8A2B  0C708369 153E328C AD90147D AFE50952
OK
Checking Composer version: OK
Checking Composer and its dependencies for vulnerabilities: OK
Composer version: 2.7.7
PHP version: 7.4.3
PHP binary path: /usr/bin/php7.4
OpenSSL version: OpenSSL 1.1.1f  31 Mar 2020
curl version: 7.68.0 libz 1.2.11 ssl OpenSSL/1.1.1f
zip: extension not loaded, unzip present, 7-Zip not available

Move HTML to Clone Cachet

cd /var/www/html
git clone https://github.com/CachetHQ/Cachet.git

Copy Environmental file to Production Name

cp .env.example .env

Edit .env File

nano .env

Update DB Data

DB_DRIVER=mysql
DB_HOST=localhost
DB_UNIX_SOCKET=null
DB_DATABASE=cachet
DB_USERNAME=cachet
DB_PASSWORD=SecretBearPassword (password used in the SQL table create)
DB_PORT=3306

Install PHP dependencies using Composer

composer install

Generate Keys for Cachet

php artisan key:generate

Install Cachet

php artisan cachet:install

Choose the defaults here of "no"

Publishing complete.
Nothing to migrate.
Database seeding completed successfully.
Clearing cache...
Application cache cleared!
Cache cleared!
The [public/storage] directory has been linked.

Set Rights and Folder permissions

cd /var/www/html/
chown -R www-data:www-data /var/www/html/
find . -type f -exec chmod 644 {} \;
find . -type d -exec chmod 755 {} \;

Create Apache Virtual Hosts Configuration

cd /etc/apache2/sites-available
sudo nano cachet.conf

<VirtualHost *:80>
ServerName status.bears.local
DocumentRoot /var/www/html/Cachet/public

<Directory /var/www/html/Cachet/public>
          Options FollowSymlinks
          AllowOverride All
          Require all granted
     </Directory>

ErrorLog ${APACHE_LOG_DIR}/status.bearlocal_error.log
CustomLog ${APACHE_LOG_DIR}/status.bearlocal_access.log combined
</VirtualHost>

Enable Site and restart Apache

sudo a2ensite cachet.conf
sudo a2enmod rewrite
sudo systemctl restart apache2

Secure MariaDB

cd /var/lib/mysql
mysql_secure_installation

This will then luanch the "secure process" as below, how you answer the questions is down to your requirements.

Set root password? [Y/n] y

New password: 

Re-enter new password: 

Password updated successfully!

Reloading privilege tables..

 ... Success!

Remove anonymous users? [Y/n] y

 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This

ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] y

 ... Success!

By default, MariaDB comes with a database named 'test' that anyone can

access.  This is also intended only for testing, and should be removed

before moving into a production environment.

Remove test database and access to it? [Y/n] y

 - Dropping test database...

 ... Success!

 - Removing privileges on test database...

 ... Success!

Reloading the privilege tables will ensure that all changes made so far

will take effect immediately.

Reload privilege tables now? [Y/n] y

 ... Success!
Cleaning up...

Secure Apache

cd /etc/apache2/conf-available/
nano security.conf

Now lets edit the security.conf file by add/edit these lines in the files for extra protection from outside influence.....

ServerTokens Prod 
ServerSignature Off

Then we need to edit the acahe2.conf file to set the Servername and DDos protection:

cd /etc/apache
nano apache2.conf

Then you need to add these values for maximum protection:

ServerName a6n.co.uk
RequestReadTimeout header=10-20,MinRate=500 body=20,MinRate=500

We also need to remove this from the directory configuration to stop directory browsing from occuring:

<Directory /var/www/>
        Options Indexes FollowSymLinks
        AllowOverride None
        Require all granted
</Directory>

Update Resolvers to Google DNS

nano /etc/resolv.conf

Then update the entries currently in that file to this:

nameserver 8.8.8.8
nameserver 8.8.4.4

Install Certbot

sudo apt install certbot python3-certbot-apache

Check Server Name and Alias

sudo nano /etc/apache2/sites-available/cachet.conf 

Then ensure you have a ServerName and ServerAlias set as below:

ServerName a6n.co.uk
ServerAlias test.a6n.co.uk

Check with ApacheConfig

sudo apache2ctl configtest

This should return OK as below:

root@Cachet:/etc/apache2# apachectl configtest
Syntax OK

If not confirm you have created the DNS record for this service and its valid, you can confirm with a ping to see if you get an address, if not you need to add this.

Generate Certificate

sudo certbot --apache

That will then ask you some questions, like e-mail and SAN names and CN names as below:

Saving debug log to /var/log/letsencrypt/letsencrypt.log

Plugins selected: Authenticator apache, Installer apache

Enter email address (used for urgent renewal and security notices) (Enter 'c' to

cancel): email@nightdave.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Please read the Terms of Service at

https://letsencrypt.org/documents/LE-SA-v1.4-April-3-2024.pdf. You must agree in

order to register with the ACME server at

https://acme-v02.api.letsencrypt.org/directory

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

(A)gree/(C)ancel: a

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Would you be willing to share your email address with the Electronic Frontier

Foundation, a founding partner of the Let's Encrypt project and the non-profit

organization that develops Certbot? We'd like to send you email about our work

encrypting the web, EFF news, campaigns, and ways to support digital freedom.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

(Y)es/(N)o: n

Which names would you like to activate HTTPS for?

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

1: test.a6n.co.uk

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Select the appropriate numbers separated by commas and/or spaces, or leave input

blank to select all options shown (Enter 'c' to cancel): 

Obtaining a new certificate
Performing the following challenges:
http-01 challenge for test.a6n.co.uk
Waiting for verification...
Cleaning up challenges
Created an SSL vhost at /etc/apache2/sites-available/cachet-le-ssl.conf
Enabled Apache socache_shmcb module
Enabled Apache ssl module
Deploying Certificate to VirtualHost /etc/apache2/sites-available/cachet-le-ssl.conf
Enabling available site: /etc/apache2/sites-available/cachet-le-ssl.conf

Add HTTP Headers

This is the last step to ensure the HTTP security headers are present and for this you need to navigate to this directory

cd /etc/apache2/sites-available

Then I had these files in this location:

000-default.conf  cachet-le-ssl.conf  cachet.conf  default-ssl.conf

If you look at the previous Certbot step you will notice that the we need here is cachet-le-ssl.conf, so lets open that in nano:

nano cachet-le-ssl.conf

Then inside the <VirtualHost> tag add this into the configuration file then save the file:

 #Add security headers
    Header always set X-XSS-Protection "1; mode=block"
    Header always set X-Content-Type-Options "nosniff"
    Header always set X-Frame-Options "SAMEORIGIN"
    Header always set Content-Security-Policy "default-src * https://test.a6n.co.uk; script-src * 'unsafe- eval' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' https://test.a6n.co.uk data:"
    Header always set Referrer-Policy "strict-origin-when-cross-origin"
   Header always set Permissions-Policy "fullscreen=(self 'https://test.a6n.co.uk'), geolocation=*, camera=()"
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
    Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure;SameSite=Strict

Then start Apache2 to make the changes live with this:

systemctl restart apache2

Then if you check the headers your should now see that reflected with a scanning tool like this:

Test the website

Now all you need to do is visit the website which in this example is https://test.a6n.co.uk and you should see the setup screen as below:


When asked for the Cache Driver, Queue Driver and Session Driver choose "Database" as below:

Then you need another couple of settings which include:

SMTP Data
Site Details

Then you are done and all is well!!!!!

Demo Site Example

This may or may not be live when you read this, but this is how it did look when it was online and operational.


I also quite like the incident pages that give you a "timeline" of what was updated when:


Subscription and SMTP Issue

I came across an issue where when you set the "mail" settings it would always default back to what was in the ".env" file, so to fix this update the .env file for the mail settings which look like this:

MAIL_DRIVER=smtp
MAIL_HOST=<server_name>
MAIL_PORT=587
MAIL_USERNAME=<username/API key>
MAIL_PASSWORD=<password/API secret>
MAIL_ADDRESS=<mail-from-address>
MAIL_NAME=null
MAIL_ENCRYPTION=tls

Then one these settings are updated navigate to the install directory of Cachet for me that is:

/var/www/html

Then once there run this command:

php artisan config:cache

This will then clear the cache, and the website will now show the details from the .env file not the "Testing (Logging) setting they did before, it would appear that the website does not update this file at all.

Certbot Certificate Auto Renew

Lets ensure that the certificate will auto renew, so to get the certificates use the command:

certbot certificates

This will show you all the valid certificates, which for me will be test.a6n.co.uk which the website uses as below:


Lets now do a dry run of this renewal using this command, this will simulate the "renewal" as if it was due:

certbot renew --cert-name test.a6n.co.uk --dry-run

However that fails as the http-01 challange is not there which is not good news, so we need to fix that, but why?

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/test.a6n.co.uk.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert not due for renewal, but simulating renewal for dry run
Plugins selected: Authenticator apache, Installer apache
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for test.a6n.co.uk
Waiting for verification...
Challenge failed for domain test.a6n.co.uk
http-01 challenge for test.a6n.co.uk
Cleaning up challenges
Attempting to renew cert (test.a6n.co.uk) from /etc/letsencrypt/renewal/test.a6n.co.uk.conf produced an unexpected error: Some challenges have failed.. Skipping.
All renewal attempts failed. The following certs could not be renewed:
  /etc/letsencrypt/live/test.a6n.co.uk/fullchain.pem (failure)

This is very simple, I was testing some non-HTTPS blocks so my firewall looked like this:



This challange is a http challange, so it does not use HTTPS as this process governs the SSL, which makes sense, so I have added the HTTP rule back in, as its not required to be blocked as all HTTP is redirect to HTTPS anyway.

 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/test.a6n.co.uk.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert not due for renewal, but simulating renewal for dry run
Plugins selected: Authenticator apache, Installer apache
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for test.a6n.co.uk
Waiting for verification...
Cleaning up challenges

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
new certificate deployed with reload of apache server; fullchain is
/etc/letsencrypt/live/test.a6n.co.uk/fullchain.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

That means auto-renew is possible and confirmed.
Previous Post Next Post

Ω†Ω…ΩˆΨ°Ψ¬ Ψ§Ω„Ψ§ΨͺΨ΅Ψ§Ω„