Greenhouse development update 1

🤔   Say that you have a computer and it has internet access

That computer can browse the web, but "the web" (or, web users around the globe) typically can't browse files or web applications running on the computer. Publishing a server on the internet takes work, costs money, and requires maintenance and upkeep. It can be especially difficult if you want to use your computer, not rent someone else's. If you live in a dormitory or if you get internet access via wifi from your neighbor or via tethering to your phone, you may not be able to perform the necessary modifications to your router's configuration even if you knew how.

Greenhouse provides an easy way to make one or more computers into servers that anyone in the world can connect to securely & reliably, regardless of where or how the servers are connected to the internet.

Greenhouse is being designed from the ground up as a trustless service, that is, you don't have to trust me or whoever's running the service to keep your data secure — it's designed so it can't access your data in the first place.

For more information about why I am building this, see The "Pragmatic Path" 4-Year Update: Introducing Greenhouse!

See the next post in this series: Greenhouse Development Update 2 - May


I have been striving to work on greenhouse every day. Of course, I can't always meet that standard, but I believe I've gotten more done than my activity heatmap might indicate, as I have a bad habit of working on elements and features for more than a day before I commit them.

I implemented basic registration and login with email address verification.

Some interesting notes about registration and login:

  • I built a cute little bit of PWA (Progressive Web Application) where registration and login work without javascript, but when javascript is enabled, the user's password is hashed before it is sent to the server.
  • I decided to implement my own sessions from scratch.
    • I chose to implement Server-side sessions.
    • Doing it myself was a bit indulgent, but I enjoyed the flexibility it gave me, because:
  • HTTP Cookie Security + Email verification can be a bit of a pain point
    • Have you ever registered for an account on a website, clicked the link in the verification email, only to be greeted by a login page?
    • This happens because of the SameSite attribute on the cookie. When set to Strict, the SameSite attribute will prevent the browser from sending the cookie on any request which is not "referred" from the same domain the cookie belongs to. So, for example, if you log into gmail and click the link, the request will be referred from gmail.com, not greenhouse.server.garden, and the browser won't send the cookie.
    • SameSite=Strict is really good at preventing CSRF (Cross Site Request Forgery) attacks, but not so good for usability when the user is trying to verify thier email address.
    • I decided on a solution where I have one cookie that uses SameSite=Lax and one cookie that uses SameSite=Strict. The LaxCookie is sufficient until the user verifies thier email address, after that the normal cookie (Strict) is required.
    • Best of both worlds: all relevant HTTP endpoints are protected from CSRF attacks by SameSite=Strict (as well as other measures), however, the user experience is seamless when verifying the email address.

I also built an admin panel for greenhouse, to help monitor and manage cloud VPS instances (worker nodes) that host the threshold reverse tunnel servers.

The admin panel requires login just like any other dynamic page on the site, except it also requires that the TenantId of the user be equal to 1. So, the admin user is simply the first user who signed up for an account on the site. I know that admin panels are typically easy targets for the red team, but I like my authentication/authorization solution -- especially because I am using server side sessions, I think this admin panel is airtight.

I implemented a small subsystem in the admin panel which allows Greenhouse to host itself relatively easily.

This was always the plan, per the architecture diagram:

I built some of the user interface for the management console landing page, including bandwidth monitoring, free greenhouseusers.com subdomains & basic API token management.

I started building a cross-platform desktop application to act as a user-friendly greenhouse client.

  • I experiemented with a couple different things, various Golang-based desktop application libraries, as well as electron
    • I don't like the golang-based desktop app stuff because it's simply not reliable enough to use. Too many bugs and issues. Most of the implementations require graphics acceleration to be functioning, preventing the app from being used on many virtual machines or computers that are lacking drivers.
    • I don't like electron because it builds 200MB application images, even for a hello-world application, and it uses a disgusting amount of RAM.
  • I settled on using fbs, the fman build system, a toolkit for building Python/QT cross platform desktop applications. It is much lighter weight, and appears to be more reliable than some of the other options.

I'm currently working out how I'm going to install the desktop application on all platforms, Mac, Windows, and Linux.

I want to have a greenhouse-daemon application that runs in the background, not just a GUI application, because it needs to operate an embedded caddy server which will generate and store TLS keys and certificates that are used to secure HTTPS connections. Those are very sensitive files, so they should probably not be readable by just any old user on the computer! This introduces a lot of complexity when it comes to installing and running the app, the greenhoue-daemon has to run as a special greenhouse user so it can retain exclusive ownership over its files.

That's all for now. Stay tuned for more Greenhouse updates!

See the previous post in this series: The "Pragmatic Path" 4-Year Update: Introducing Greenhouse!

See the next post in this series: Greenhouse Development Update 2 - May