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/";
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
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:
Then one these settings are updated navigate to the install directory of Cachet for me that is:
/var/www/html
certbot certificates
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
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.
That means auto-renew is possible and confirmed.