Setup a self-hosted privacy-focused encrypted note-keeping solution

Privacy Jan 13, 2021

Starting from the developments at Apple about introducing privacy features like making it harder for Facebook advertisers to track user's locations, 2020 wasn't a good year for Facebook . A lot of business owners ranging from small businesses who make apparels to commercial giants like Amazon make use of Facebook's advertising to boost sales and help them in gaining insights from analytics through Facebook or other third-party businesses (like Cambridge Analytica) that rely heavily on data gathered through platforms like Facebook or just Facebook or it's platforms like Instagram.

Somehow, WhatsApp was never exclusively a part of this whole system. (Really?)

UNTIL NOW! Recently, users have start seeing the below prompt on WhatsApp:

To challenge all of the above issues, Facebook recently took the decision to enable data sharing between itself and WhatsApp starting from 8th February 2020. The real kicker is: You can choose to give the control for Services that will ask for permissions on your device (like Location) including the data generated and its sharing to Facebook's platform OR you can choose to: NOT USING WHATSAPP anymore! Freaking out?

Now, it is practically impossible to convince everyone (Think how hard it will be, to convince our Grandparents to stop using WhatsApp, let alone Millennials or Gen-Z).

But one thing in our control is: Controlling the data that we share on WhatsApp!

A lot of folks use WhatsApp to store notes, even passwords and secret keys to their cryptocurrency wallets! So, in this tutorial, we will have a look at setting up a privacy-oriented self-hosted note keeping solution with encryption using Standard Notes.

Update: Standard Notes has updated its self-hosting stack completely which makes the use of the below (now legacy) system obsolete. Please find their steps here.

Standard Notes is an open source and completely encrypted solution that ensures you have control on your data: You can setup a Sync Server that will help sync notes stored between your different devices. (Apps available on: Mac, iOS, Android, Windows and Linux) This will make sure that notes stored on your device's storage are synced through your server.

For this tutorial, we will be setting up a sync server with 1-core CPU, 1GB RAM and 50GB Storage running Ubuntu 20.4 LTS.

Follow the below steps:

Step 1:  Install Ruby 2.6.6 with RVM and other gems (dependencies):

sudo apt update
sudo apt upgrade

sudo apt install gnupg2

gpg2 --keyserver hkp://keys.gnupg.net --recv-keys \\409B6B1796C275462A1703113804BB82D39DC0E3 \\7D2BAF1CF37B13E2069D6956105BD0E739499BDB

cd /tmp

curl -sSL https://get.rvm.io -o rvm.sh

sudo cat /tmp/rvm.sh | sudo bash -s stable --rails

source /home/sammy/.rvm/scripts/rvm

rvm install ruby-2.6.6

rvm use ruby-2.6.6

gem install rails -v 5.2.0

gem install bundler

gem install rubygems-update

update_rubygems

Step 2: Install MySQL 5.7 (This step can be skipped if you have access to a remote server with MySQL 5.7):

wget https://dev.mysql.com/get/mysql-apt-config_0.8.12-1_all.deb

sudo dpkg -i mysql-apt-config_0.8.12-1_all.deb

sudo apt-get update

sudo apt install -f mysql-client=5.7.32-1ubuntu18.04 mysql-community-server=5.7.32-1ubuntu18.04 mysql-server=5.7.32-1ubuntu18.04

Setup MySQL user and database:

sudo mysql -u root -p
<Click Enter as there no default root password after installation>

Use the below SQL commands to setup a database and user:

create database standard_notes_db;

<Replace localhost below 2 queries to the server's IP on which this sync server is being setup>
CREATE USER 'std_notes_user'@'localhost' IDENTIFIED BY 'yourpasswordhere';

GRANT ALL PRIVILEGES ON standard_notes_db.* TO 'std_notes_user'@'localhost';

flush privileges;

exit;

Step 3: Setup Standard Notes Sync Repository:

git clone --branch master https://github.com/standardnotes/syncing-server.git

cd syncing-server/

openssl rand -hex 64
<Copy the key generated for the last two lines of .env file>

vim .env

Click on "i" key to start inserting, Copy the following to the above opened .env file and after editing click on "Esc" key, type :w, hit Enter and finally type :q & hit Enter!

# Rails Settings
EXPOSED_PORT=3000
# change this to "production" for production use, otherwise the access token time is very short and forces re-login
RAILS_ENV=development
RAILS_LOG_TO_STDOUT=false
RAILS_LOG_LEVEL=info # "debug" | "info" | "warn" | "error" | "fatal"


ACTIVE_JOB_QUEUE_ADAPTER=async

# Database Settings - Use Remote MySQL 5.7 Setup if using Remote Server
DB_PORT=3306
DB_HOST=127.0.0.1
DB_DATABASE=standard_notes_db
DB_USERNAME=std_notes_user
# Please change this!
DB_PASSWORD=changeme123
DB_POOL_SIZE=30
DB_WAIT_TIMEOUT=180

# Secrets
# Use: "bundle exec rake secret" or "openssl rand -hex 64"
# To generate required secret key base below

SECRET_KEY_BASE=changeme123
PSEUDO_KEY_PARAMS_KEY=changeme456

Step 4: Install Standard Notes Sync Server:

bundle install

bundle exec rails db:create db:migrate

Run the following command to check if the above installation is working:

bundle exec rails server

Step 5: After successfully completing above steps, now the job is to setup the above server as a daemon process:

This is also where things get a little bit tricky: Normally, we can expand the rails server command up by -d for it to run as a daemon process, however, it does not seem to work in this setting. Lucky us, we have a workaround:

screen rails s

Now, press CTRL + A + D and you will end up back on your Command Prompt.

Step 6 [Optional]: Setup Nginx and open up ports 80, 443 and 3000 (the port on which sync server is running on):

sudo apt install nginx 

sudo systemctl enable nginx 
sudo systemctl start nginx 

sudo iptables -I INPUT 6 -m state --state NEW -p tcp --dport 80 -j ACCEPT 
sudo iptables -I INPUT 6 -m state --state NEW -p tcp --dport 443 -j ACCEPT  
sudo iptables -I INPUT 6 -m state --state NEW -p tcp --dport 3000 -j ACCEPT 

sudo netfilter-persistent save

And Voila, your sync server should be up now and you can test it out at:

curl http://localhost:3000

In case this is not working, feel free to comment on this blog post and I'll try to help out!

[Optional]

We can also setup this sync server instance as a domain/subdomain along with SSL configuration using the below post:

How To Secure Nginx with Let’s Encrypt on Ubuntu 18.04 | DigitalOcean
In this tutorial, we will show you how to use Let’s Encrypt to obtain a free SSL certificate and use it with Nginx on Ubuntu 18.04. We will also show you how to automatically renew your SSL certificate. If you’re running a different web server, simply follow your web server’s documentation to learn …

[Bonus]

Want to use a server with aforementioned configuration and don't want to pay for it...EVER?

Follow the below post to obtain forever free servers from Oracle Cloud:

How to get 2x Oracle Cloud servers free forever
This is a follow up to my How to get a Google server free forever post. In the comments selim13 let...

Use the above tutorial and #controlyourdata !

Cheers!

Tags