At the beginning of my career, we used e-mails to communicate with co-workers. We could explain an issue in details with a very long e-mail, but it was hard to follow live discussions. For synchronous communication, we used phones. We had to constantly switch between both systems. Have you ever received a call saying “have you seen my last e-mail?”.
Then instant messaging systems came to fill the gap. There was MSN at home to chat with your friends. Or XMPP at work. I have used this protocol for 10 years. OK there was no gif, limited support of emojis and you can’t call your colleagues but it could ran everywhere, even on a solarpunk phone.
Nowadays, we have Slack, Webex, Microsoft Teams, Discord. Maybe you have the chance to use an open source solution like Matrix or Mattermost. The decision to use one of another has probably been made before you joined the company and you don’t have enough power to introduce a major change because communication systems are central to companies. So we use Webex at work. We have to deal with all the limitations. One of them is the ability to paste long text without polluting the feed.
Pastebin service
In french, “paste” could be translated to “coller”. One day, I decided to start my own pastebin service based on sticky notes. I have ordered a VPS, an internal top-level domain, restricted network access. The coller la petite service was born (in reference to this song). The name was fun. The service was useful. I did no marketing campaign around it because I knew it could be used to store sensible data. I have contacted our security team to tell them the service existed and told every user that it’s an external service with no service level agreement (best effort mode).
This website had little to no maintenance. Upgrade Debian packages, dump and restore the database on a new major version every year, easy peasy. For fun, I have created a Perl client to learn this language (because I had to). Then a more portable Go client was created by one of my team mates. Why do we need clients when there’s already a website? Because sometimes we prefer to use a CLI and not a browser to share the content of our clipboard or the content of a file.
The service became so popular that the need was proven. The team responsible for managing collaboration tools came to me to see how could we move this external service and make it internal: hosted on private services with the enterprise security layer on top of it. I have explained the history, how it works and how I see the future to multiple people of that team. There is a high turnover rate apparently. Now I’m sick of explaining it over and over again.
What’s the problem?
There are multiple issues with this service today. Sticky notes is not maintained anymore. It’s written in PHP which makes it harder for us to fork, contribute and deploy. Last but not least, there is no encryption.
PrivateBin
The most popular and secure pastebin service out there is PrivateBin. They take security very seriously. The content is encrypted from the browser so the hosting provider never knows what’s inside. While this solution is awesome for the security, it makes it harder to use on a day to day basis. We can’t use curl to download the raw content of a note. I get the argument of users always making the poorest choice but I don’t want to set up a second solution to fill the gap or telling people to deal with it. I want a single solution for doing both. I want to paste public data. I also want to paste and download snippets securely.
I also don’t like long URLs because, unlike Mastodon where size doesn’t matter, they tend to bloat the message on those platforms. The fact that you have to use an URL shortener in the FAQ says it all.
Coller
So I created a pastebin server and clients to create and read notes. Yep. Yet another pastebin solution. Not because we definitely needed one more, but because I use it daily, I like simplicity, usability, security and I love doing side projects in Go.
Features
- Website
- Raw content by default
- Compatible with curl
- Encryption with password
- Compression on the backend
- Automatic retention
- PostgreSQL or sqlite database
- CLI to create notes (“coller”) from the clipboard or a file
- CLI to read encrypted notes (“copier”)
- Easy to deploy
Encryption levels
No encryption
It starts with no encryption. Sounds crazy in a world where everything has to be encrypted, right? Not so crazy. Sometimes, we just want to paste a bunch of characters that we could have been said publicly on social networks and that’s fine. The URL will be very short and easy to share.
Server side encryption
The next level is to use basic encryption by letting the website generate a password for you. You click on a checkbox and the content of the note is encrypted before being stored. The encryption key is the password. You can choose to keep the key for yourself and only you and the server know it. Or share it to other people you trust. Anyway, the server knows it.
Server side encryption with user key
Same solution as the server side encryption but this time, the user defines the password. Security could be lowered if the key is weak (too short, words from the dictionary) when the server will always generate strong enough keys. In the end, the server still knows your choosen key.
Client side encryption
If you don’t trust the server but you want to use the service anyway, you could tell the client to encrypt the content before sending it to the server. The client will generate a random (strong) key. This time, the key is private. Only you knows it. You can do whatever you want with the key, but you should keep it to yourself or share it carefully.
Accessing the encrypted note using the password in the URL will make the server aware of your password. You should use the “copier” client to download the encrypted note and decrypt outside of the server.
Client side encryption with user key
Same as client side encryption but you can choose the password you want.
Encryption summary
A picture is worth a thousand words:
What to choose?
Level | Usability | Confidentiality |
---|---|---|
No encryption | ⭐⭐ | ⭐ |
Server-side encryption | ⭐⭐⭐ | ⭐⭐ |
Client-side encryption | ⭐ | ⭐⭐⭐ |
If you can use the copier client (CLI) and keep the password for yourself, go for it. It’s the most secure solution. If you can’t, the website is designed to use the server-side encryption with a strong generated password.
Cipher
The most famous cipher is AES 256 with GCM. It would have been simpler to implement CBC like pgBackRest but the mode has been removed from TLS 1.3 for several flaws. I decided to use XChaha20-Poly1305 because it reminds me this banger from this year’s Eurovision and I wanted to use something different. Don’t worry, this cipher is one of the most secure in the world.
Source code
The source code is available on my forgejo instance under the permissive MIT license.
Demo
I have deployed a live instance on my self-hosted infrastructure using an Ansible role.
Conclusion
This little side project turned into a fully functional pastebin solution. It was also a great excuse to implement encryption in Go. If you find a security issue or want to implement a feature or fix bugs, contributions are welcomed.