Tyler's Site

Abstract

“CryptPad is a collaborative office suite that is end-to-end encrypted and open-source.” - CryptPad’s website

I’ve been hosting a CryptPad instance for a few years, but have been using it a lot more recently for things like notes and calendaring as it is easier than keeping everything synced between devices. It operates a lot like Office 365 or Google Drive’s office suite, however, CryptPad is self-hosted, open source, and puts privacy first.

Setting up a CryptPad instance is not particularly difficult depending on what your security concerns are. For example, my original CryptPad instance was self-hosted on my LAN inside of a FreeBSD jail. The concern for security and was less than if my instance would have been public, so, I just got it working rather than configuring it to production quality. However, for a public instance, there is a lot more tweaking involved to make sure the server itself is secure and has as few holes as possible for attackers. In this post I will be going over my experience with both an “insecure” setup and a “production” setup. The insecure setup is not recommended, but might make the most sense for someone only concerned about having access to it on their LAN rather than across the Internet. For a public CryptPad instance available on the Internet, please do your research. CryptPad has a very good guide on setting up a public instance for CryptPad, before trying anything in this blog post, start there. This post is more so recounting some issues that I had (that were likely self-imposed).

Insecure CryptPad setup

My “insecure” CryptPad instance is running inside of a FreeBSD jail, so all of the commands will assume FreeBSD. However, this should not be terribly difficult to translate into Linux (s/pkg/apt/g and s//usr/local/${dir}/\/${dir}/g should suffice in most cases). When setting up any new server, making sure everything is up-to-date is highly important. After that, install Nginx, node20, npm-node20, and git.

# Run the following as root
pkg update && pkg upgrade
pkg install -y git nginx node20 npm-node20

Note: Nginx is the recommended web server for use with CryptPad. Other web servers will work, but the documentation will references Nginx configs which might make getting the setup complete easier

Then download CryptPad and install dependencies.

git clone https://github.com/cryptpad/cryptpad.git cryptpad && cd cryptpad
npm install
npm run install:components

From here, copy the example config file by running cp config/config.example.js config/config.js then run node server to start CryptPad. While CryptPad will technically run like this, it will not actually be useful until modifying config/config.js. Within the config file, there are some variables that must be changed for CryptPad to actually be accessible from other machines on the network. The first set of variables that must be changed are: httpUnsafeOrigin and httpSafeOrigin. What these variables do is not particularly important in this section, however, will become much more important during the “Production” section of this post. For now, just set the variable to whatever domain name that the instance will be used from (i.g. localdocs.internal). The next configuration item that must be changed is httpAddress. By default it only listens on localhost and should be changed to whatever the IP address of the server is going to be. Alternatively, it can listen on all ports, but that creates much more attack surface on the server than necessary. All of the other defaults should be fine to get CryptPad working; though it is worth reading through the different configuration options available.

Next we configure the web server to be able to proxy the correct ports. Nginx has some configuration examples in the default config file, but it is just as easy to add another server block to do the proxy. The following example assumes that the domain name being used for the CryptPad instance is ‘localdocs.internal’, the IP address of the server is 192.168.1.100, and that the ‘httpPort’ in CryptPad’s config file has remained unchanged.

server {
    listen: 80;
    server_name localdocs.internal;

    location / {
        proxy_pass http://192.168.1.100:3000;
    }

# If this is not set, then CryptPad will not load properly,
# and the application will be unusable
    location = /cryptpad_websocket {
        proxy_pass http://localhost:3000;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection upgrade;
    }

}

Then just make sure that Nginx is enabled by adding nginx_enable="YES" to /etc/rc.conf, then start by running service nginx start as root. From there, run node server in the cryptpad directory, then attempt to visit the page at localdocs.internal. Assuming it loads, the last thing to do is to make CryptPad run as a daemon. This can be done by using the daemon utility in FreeBSD, or by using the example rc.d file to create a service.

Production CryptPad setup

The production instance is similar to the insecure instance, however, you will also need to have a domain with an SSL certificate. I used certbot for this as it is quick and easy while also costing nothing (Go EFF!). Also for this, we must have two domains (at least subdomains) to help prevent XSS attacks on the CryptPad instance. This section of the blog post will be in more general terms as there is quite a bit of information that will vary from instance to instance, plus the example Nginx config does quite a good job of documenting what everything does. The first thing to do is to make sure that each of the domain names is registered so that they point to the server, and thus can get an SSL cert.

# All commands must be run as root

# Install certbot
pkg install py-certbot-nginx
# Then get the certificates for the domains
certbot --nginx
# Alternatively you can just get the certs,
# but it will be more work
certbot certonly --nginx

The next step is to copy the example Nginx config file into the current Nginx config file so it can be modified to fit the instance we are trying to set up. While there are likely 100 ways to do this in FreeBSD, the way that made sense to me was to fetch the file, then as root run cat example.nginx.conf >> /usr/local/etc/nginx/nginx.conf. This command will copy the example.nginx.conf file to the end of the current nginx config file. It can then be opened in ${EDITOR} and the server block for CryptPad can be moved to a more suitable location and the editing process can begin. Again, this file will vary from person to person a bit, and there will be a bit of trial and error to get the configuration correct. The ‘main_domain’ is the domain (or subdomain) that the site will be accessed from. The ‘sandbox_domain’ is a secondairy domain that is used strictly as a security measure against XSS attacks. There will also be some SSL items that will have to be commented out as the example file has some SSL configuration that should have been handled already if you installed your certs with it.

Once nginx is configured, enabled, and started, we can then start working with CryptPad itself to get it configured and working. First, as in the other section of this post, copy the config.example.js to config.js in the config folder in CryptPad. Then open config.js in ${EDITOR} and begin configuring it for your instance. Change httpUnsafeOrigin to the same as the main_domain in the Nginx config file, change httpSafeOrigin to the same as the sandbox_domain in the Nginx config file. Most everything else can be left as default, however, it is worth a look at the rest of the config file as there are some other useful configuration items in there. From there, run node server and attempt to access the page. If it loads and you are able to login and access the drive or another app, the configuration works. Now just use the rc.d script to make CryptPad a service and manage it as such.

More Documentation

CryptPad is a very well documented project with a lot of helpful resources to get started. Because of that, if you are interested in setting up your own public instance, I recommend starting there rather than this documentation. These pages are good for starting out with CryptPad and asking for help.