šŸ’¾ Archived View for gemini.omarpolo.com ā€ŗ post ā€ŗ one-year-of-gmid.gmi captured on 2024-03-21 at 15:31:04. Gemini links have been rewritten to link to archived content

View Raw

More Information

ā¬…ļø Previous capture (2023-01-29)

-=-=-=-=-=-=-

One year of gmid

We can reach our destination, but we're still a ways away

Written while listening to ā€œDriver 8ā€ by R.E.M..

Published: 2021-10-12

Tagged with:

#gemini

#gmid

The first commit in gmid git repository was the 2 October of the last year, with the 1.0 being tagged a couple of days later 2020-10-07. I wanted to publish this on some days ago, exactly one year after the first release, but I couldnā€™t make it in time.

gmid has been my introduction to Gemini. I think Iā€™ve wrote about it before, but the first time Iā€™ve used a Gemini client (I think it was amfora, not sure) was to see if gmid was acting correctly. Overall, Iā€™m happy of how gmid has grown in this year. Itā€™s also the first bit of code I wrote that gave me the impression it was useful to others, and it still make my day when I hear someone says that theyā€™re using it.

Incidentally, Iā€™ve also uploaded this capsule a year ago, on the 4th of October. (I can tell thanks to a certain TLS certificate expiring.)

I took it as a chance to think about the project and where Iā€™m headed.

The first version, compared to what gmid is now, is almost a joke. It was a single C file, ~500 LOC, with a hand-written loop around poll(2) to serve multiple clients using a single thread. Nothing fancy, but it worked. No CGI scripts, no FastCGI, no directory listings, no configuration, just serving static files.

Then it slowly grew. First with CGI scripts support, then by adding a flexible configuration file, later by improving the performance (and the code!) thanks to libevent and finally by adding FastCGI support.

The configuration file was added at the beginning of this year, around the 15 January. Looking back, I can say that adding a configuration file was the major turning point for gmid. It allowed it to become one of the most featureful gemini servers available today, but it also kinda shifted the point: gmid was not merely a simple zero-conf gemini server, but something more complex.

Adding a configuration file was the right choice I think, after all Iā€™m developing gmid so it can be useful *to me* in the first place, and I needed more flexibilty, but once you have a configuration file itā€™s difficult to say ā€œnoā€ and donā€™t add features. This was one of the lessons learned. In some sense, a configuration file is a way to add ā€œinfinite extensibilityā€ to a program.

Sandboxing by default

Developing gmid allowed me to study and apply the idea of sandboxing a process. Iā€™m talking about ā€œself-sandboxingā€, that is when a process voluntarily restricts itself, not to ā€œexternalā€ sandboxes like a jail, LXC, apparmor or SELinux or ā€¦ Iā€™m more interested in the former kind more than the latter because itā€™s 1) primarily under the control of the developer and 2) doesnā€™t require any kind of setup on the users part.

gmid is the only server I know that sandboxes itself on multiple OSes. On OpenBSD uses pledge and unveil, on FreeBSD capsicum and on linux seccomp and landlock (if available).

To be honest, this is not something Iā€™m particularly happy of. It would be better if the whole ecosystem employed these techniques. OpenBSDā€™ unveil and the new Linuxā€™ landlock API in particular shouldnā€™t be hard to use even in high level languages.

If youā€™re using OpenBSD I know two other Gemini server that are are properly sandboxed:

twind

vger

Future plans

I like the idea of ā€œfinished softwareā€. I donā€™t think that finishing a project means throwing it in the trash can and ignoring it, it still needs attentions, but most of the work should be the occasional bug fixing and documentation improvements. Or at least thatā€™s the idea.

I have a long plan to finish gmid. It should take two releases. Hope Iā€™m not too optimistic, but Iā€™m serious about finishing this project.

The next release, v1.8 still without a code name, would be probably the last version to introduce a bunch of new features, other than the usual improvements.

Iā€™ve restructured the server internally and reworked the FastCGI implementation: I still havenā€™t done any benchmarking even if I expect improvements, but more importantly the code is more clear, easier to follow, and possible bugs will stand out more.

The test suite was also restructured and now is easier to reply only a subset of the tests, something thatā€™s really useful during debugging sessions, but also doesnā€™t stop anymore at the first error. Instead, it continues with the next test and produce a nice report with the falling tests.

Talking about new features, Iā€™m drafting the proxying code: gmid will be able to relay gemini requests to other servers if configured to do so. Iā€™m particularly exited for this because itā€™ll allow to deploy the duckling-proxy on my server, protect it with the ā€˜require client caā€™ rule and use it from all my devices.

Once thatā€™s in place, Iā€™d like to find a way to allow gmid proxy *other protocols* stream to some backend application. The idea would be to allow to easily set up a, say, titan server and have gmid relay the data. (Iā€™m still not sure whether titan is a good idea or not, but Iā€™d like to play a bit with it.) There will probably be limitation on the kinds of protocols gmid will be able to relay, but thatā€™s OK.

(This is not a comprehensive list of the improvements; as always, check out the ChangeLog.)

The last release, v1.9 will instead focus only on internal changes. I want to bring gmid up to the same level of quality of the OpenBSD daemons. Well, at least thatā€™s the goal ;-)

This means that 1.9 will focus on re-execā€™ing the children process, improve the imsg message passing and making it fully asynchronous (which will also improve the overall performance.) These three points seems really easy when written, but due to how the server expects the data to flow internally, will take some time.

I already have a diff that rewrites how the gmid process are managed, but itā€™s not complete and simply too complex.

In the meantime Iā€™m also trying to improve the documentation. Iā€™ve imported the sources of the official gemini capsule and web site into the repository to simplify my workflow and make easier for other people to contribute. Iā€™ve also started to write a quickstart page that covers how to set up a capsule using gmid:

[gemini] gmid quickstart

[http] gmid quickstart

and added two scripts to the ā€˜contribā€™ directory: gencert and renew-certs. Gencerts is a simple wrapper around openssl to create self-signed certificates, while renew-certs is something meant to be run in a cronjob and checks for certificate expiration. It can renew and restart the server too. I think Iā€™ll write more about these in the following days.

-- text: CC0 1.0; code: public domain (unless specified otherwise). No copyright here.