A few weeks ago I posted an article on ProjectSend, which is a great alternative to FTPS / SFTP when it comes to transferring files to and from your clients. Today, I’ll be doing a bit of a technical post that you can pass on to your IT team in order to setup your own ProjectSend server. As a quick recap, ProjectSend is an open source, web-based tool that allows you to securely send and receive files between clients or accounts, while centrally managing access, downloads and so forth. It’s incredibly lightweight, as you’ll see by the low-cost hardware I’ve used in this tutorial. While I’ve opted to configure on a Raspberry Pi, this tutorial should apply to any computer or VM running Ubuntu linux.
For my configuration, I’ve used a Raspberry Pi 3B+ with 16GB industrial SD card (around R1000 all-in) and an external USB hard drive (from about R500 up). The system is running the latest Raspberry Pi OS, but this tutorial should apply to any computer or VM (even in Azure or AWS) running Ubuntu linux.
Setup the Prerequisites
First, setup the basics of what you will need. To configure the Raspberry Pi, you’ll need to load up the SD Card with the “Lite” version of the OS. Download Raspberry Pi OS from the Raspberry Pi Foundation. You can by all means use their own imager, however, I prefer to get the SD card loaded up with balenaEtcher. Once you’ve loaded the OS onto the card, create a blank file called “ssh” (with no extension) in the smaller (boot) partition created on the SD card. This file enables the SSH server from the start for a headless configuration.
From a DNS point of view, this tutorial does rely on the Pi being accessible from the outside world on a fully qualified domain name. Set up your subdomain or however you’d prefer it, and allow access to the Pi via ports 80 and 443. Later we’ll configure the Pi to automatically redirect from 80 to 443 for security.
Once your Pi is up and running, SSH to it via PuTTY or similar, and let’s get cracking. Go through the initial Raspberry Pi config by running the below command. This will allow you to change your password and assign the appropriate regional settings etc.
Next up, update apt, upgrade the current packages, and download the prerequisites for ProjectSend.
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install php7.3 php7.3-fpm php7.3-mysql apache2 mariadb-server mariadb-client certbot python3-certbot-apache software-properties-common libapache2-mod-php7.3 cryptsetup
That should do it for all the prerequisite applications, next we move on to configuring the stack.
Configure MySQL (MariaDB)
First, let’s secure the SQL installation by running the following command:
Then, let’s log in to MariaDB and create the database. The following commands will create the database, add a database user, and then allocate full permissions for the user to the new database.
sudo mysql -u root -p
CREATE DATABASE myProjectSendDB;
CREATE USER ‘myprojectsenduser’@’localhost’ IDENTIFIED BY ‘insertpasswordhere’;
GRANT ALL ON myProjectSendDB.* TO ‘myprojectsenduser’@’localhost’;
Configure Apache, PHP and LetsEncrypt
Our next steps are to configure Apache. First, let’s enable PHP 7.3.
sudo a2enmod php7.3
Next, using Certbot we’ll get a LetsEncrypt certificate issued, and simultaneously configure autorenewal of the certificate and security of the Apache server. Be sure to follow the instructions that are presented on screen, and be sure to opt for the redirect to HTTPS.
sudo certbot –apache
If you browse to your fully qualified domain name using a browser, you should now be redirected to HTTPS and see the Apache landing page.
Setup an Encrypted External Drive as well as auto mounting
This configuration is optional, but I’d highly recommend it. If you have client data stored on a drive that can be easily lifted, you want to have that drive encrypted. The below instructions are for encrypting an external hard drive, but can be adapted to any partition really. Ideally, you’d want the entire machine encrypted, as this would secure the auto mount keys as well. In the example here, I’m going to be encrypting partition sda1, this may be different depending on your machine configuration. On a PC (instead of a Raspberry Pi), you’d more likely be looking at sdb1 for an external drive.
Before continuing with these steps, reboot the Raspberry Pi to allow Cryptsetup to make the necessary changes to the kernel. If you miss this step, you’ll get errors on encryption.
Next, let’s setup the encrypted partition. The below commands do the following; 1) initialise the partition and set the initial key, 2) open the device and set up a mapping name (sda1crypt), 3) format the partition to EXT4.
sudo cryptsetup –cipher aes-xts-plain –key-size 512 –hash sha512 -v luksFormat /dev/sda1
sudo cryptsetup -v luksOpen /dev/sda1 sda1crypt
sudo mkfs -t ext4 -L LuksPartition /dev/mapper/sda1crypt
Next up, for ProjectSend we’ll be redirecting the /var/www/ folder to the external drive. This means that the whole of Apache’s web root will be redirected to the external. We’ll mount the drive to a temporary spot (/mnt), copy the html folder from /var/www/ to the root of the external drive, set up the correct folder ownership, and then unmount the drive.
sudo mount /dev/mapper/sda1crypt /mnt/
sudo cp -R /var/www/html /mnt/
sudo chown -R www-data:www-data /mnt/html/
sudo umount /mnt
sudo cryptsetup -v luksClose sda1crypt
Next, backup the encrypted volume’s headers. Apparently, the encryption goes wrong “surprisingly often” and you may need to recover the headers. We back these up to the root user’s home folder to protect them as best as possible from other users.
cryptsetup -v luksHeaderBackup /dev/sda1 –header-backup-file LuksHeaderBackup.bin
Our next step is to create a file based key (instead of a password) to unlock the drive. We need this step to ensure that the volume can be mounted on boot.
sudo mkdir /etc/luks-keys
sudo dd if=/dev/urandom of=/etc/luks-keys/disk_secret_key bs=512 count=8
sudo cryptsetup -v luksAddKey /dev/sda1 /etc/luks-keys/disk_secret_key
Test that the volume can be mounted with the file, and then close the volume again.
sudo cryptsetup -v luksOpen /dev/sda1 sda1crypt –key-file=/etc/luks-keys/disk_secret_key
sudo cryptsetup -v luksClose sda1crypt
The last thing to do now, providing that the volume mounted correctly, is to configure the auto mount. To do this, we will refer to the drive’s Universally Unique Identifier (or UUID). To get the UUID, run the following command:
sudo cryptsetup luksDump /dev/sda1 | grep “UUID”
Edit the /etc/crypttab file using nano, vi, or whatever your preference is, and add the line below:
sda1crypt UUID=[insertuuidhere] /etc/luks-keys/disk_secret_key luks
Test the automount by running the following:
sudo cryptdisks_start sda1crypt
If all is successful, the last step is to add the correct line to fstab. Edit the /etc/fstab file using again, your preference of nano, vi, or anything else, and add the following line:
/dev/mapper/sda1_crypt /var/www ext4 defaults,nofail 0 2
I would recommend having “nofail” in the line as you don’t want the Pi to not boot if there’s a problem with the external drive. Reboot the Pi when you have completed these steps.
Lastly, install ProjectSend. Given the way ProjectSend do their zip file download, I found it easier to download to a PC first, unzip it, and copy the files across to /var/www/html using WinSCP. If you want to use wget, the below should see you through.
sudo wget https://www.projectsend.org/download/310/ -O projectsend.zip
sudo unzip projectsend.zip
Lastly, make sure that the ownership is correctly set on the ProjectSend folders, and that permissions on the files are a bit more secure:
sudo chown -R www-data:www-data /var/www/html/
sudo chmod -R 644 /var/www/html/
All you need to do now is navigate to the landing page for your FQDN, and you’re good to go to complete ProjectSend’s setup wizard by entering all the SQL details from above. Voila! Once you’re up and running, files that you send and receive will be available in the /var/www/html/uploads/ folder.
Ross G Saunders Consulting offers a number of solutions that can drive your compliance; from affordable 16 week group coaching programmes to comply on your own, through to advisory retainers and full programme management. To find out more about the offerings available, book time directly with Ross using the calendar below.