Big documentation push.

This commit is contained in:
Solderpunk 2020-06-29 21:08:29 +02:00
parent 18c056167f
commit 520e1ecc95
1 changed files with 261 additions and 43 deletions

304
README.md
View File

@ -1,9 +1,62 @@
# molly-brown
# Molly Brown
The Unsinkable Molly Brown: a full-featured Gemini server implemented in Go.
The Unsinkable Molly Brown is a full-featured Gemini server
implemented in Go.
For more info on Gemini see https://gemini.circumlunar.space or
gopher://gemini.circumlunar.space.
For more information on the Gemini protocol see:
* https://gemini.circumlunar.space
* gopher://gemini.circumlunar.space
* gemini://gemini.circumlunar.space
## Overview
Molly Brown is intended to be a full-featured Gemini server which is
suitable for use in pubnix or similar shared-hosting environments,
where users can upload their content but do not have access to the
main configuration file (of course, it is also perfectly suitable for
single user environments, but its multi-user supports sets it apart
from many other Gemini servers).
Molly Brown features:
* Support for traditional `~username` URLs.
* Automatic directory listings, with support for customised headers
and footers, control over file sorting order and the ability to
use headings from `text/gemini` content in place of filenames.
* Determination of MIME type via filename extension, which can be
manually overridden to allow, e.g., serving Atom feeds as
`application/atom+xml` instead of `application/xml` or `text/xml`.
The file extension for `text/gemini` defaults to `gmi`, but this can
be overrideen too.
* Support for temporary and permanent redirects, specified via regular
expressions.
* Dynamic content via CGI and SCGI.
* Support for "certificate zones", where access to certain paths is
restricted to clients providing TLS certificates whose SHA256
fingerprints have been added to a list of approved fingerprints,
analogous to SSH's `authorized_keys` file.
* The ability for users to override some configuration settings on a
per-directory basis using `.molly` files, analogous to Apache's
`.htaccess` files.
The follow features are planned for the future:
* Name-based virtual hosting
## System requirements
Molly Brown is known to run on:
* GNU/Linux
* FreeBSD
* 9Front
Please let us know if you get it to work on some other platform!
Molly Brown only has a single dependency beyond the Go standard
library, which is [this TOML parsing
library](https://github.com/BurntSushi/toml).
## Installation
@ -21,7 +74,7 @@ developer yourself in which case you surely already have this done)...
(you can in fact put your $GOPATH anywhere you like, but `~/go` is the
convention)
### Fetch and build MB
### Fetch and build Molly Brown
Run `go get tildegit.org/solderpunk/molly-brown`. If everything goes
well, the end result of this will be that you'll have the Molly Brown
@ -32,29 +85,45 @@ makes you happier or your life easier, you can copy that binary to
### Configuration
In the source directory mentioned above, you should find a file named
`example.conf`. Copy this to `/etc/molly.conf` and edit it to suit
your environment. The default values for all possible options are
specified in the file - just uncomment and change the ones which won't
work for you. All options are explained below in the Configuration
Options section.
Molly Brown can run without a configuration file, in which case it
will use compiled-in default settings. However, these settings are
oriented toward quick test runs with all files in the current
working directory. For regular use, you will want to override these
defaults with more suitable settings from a config file. An example
config file showing the syntax for all settings can be found in the
`~/go/src/tildegit.org/solderpunk/molly-brown/` directory with the
filename `example.conf`. You can copy this file to `/etc/molly.conf`
and edit it to suit your environment. All the options are explained
further below. If you put your configuration file somewhere other
than `/etc/molly.conf`, you will need to use Molly Brown's `-c`
command line option to tell Molly Brown where to find it.
### Daemonisation and launching
### Running
Currently Molly Brown just runs like an ordinary program, without
daemonising itself. You'll need to use another program, like the one
at `http://libslack.org/daemon/`, to handle daemonising.
Molly Brown does not handle details like daemonising itself, changing
the user it runs as, etc. You will need to take care of these tasks
by, e.g. integrating Molly Brown with your operating system's init
system. Some limited instructions on how to do this for common
systems follows.
Currently Molly Brown is only integrated with systemd, so if you're
using anything else you'll have to handle getting it to start on boot up
yourself. If you are using a sufficiently right-headed operating
system, the easiest way to do this is by putting your call to
`daemon` (or whatever else you use) in `/etc/rc.local`.
#### Manual management
Setting up with systemd should be reasonably easy; copy
`molly-brown.service.example` from this directory to
`/etc/systemd/system/molly-brown.service`. Then, make any necessary
changes for your setup, and run the following:
You can always use a tool like [daemon](`http://libslack.org/daemon/`)
to take care of daemonising the Molly Brown process, changing the user
it runs as, chrooting it to a particular location, etc. You can call
`daemon` from `/etc/rc.local` (if your OS still supports it) to start
it on system boot.
#### Systemd
An example systemd unit file for Molly Brown, named
`molly-brown.service.example`, can be found in the source directory.
After copying this file to `/etc/systemd/system/molly-brown.service`
or `/usr/lib/systemd/system/molly-brown.service` (consult your
system's documentation for the appropriate choice) and making any
necessary changes for your environment, you can run the follow
commands as root to start Molly Brown and make sure it starts
automatically on system boot.
```sh
# systemctl daemon-reload
@ -62,40 +131,189 @@ changes for your setup, and run the following:
# systemctl start molly-brown.service
```
Note that Golang programs are unable to reliably change their UID once
run (a source of constant frustration to me!). So don't start it as
root, or it'll remain as root forever. Run it as `nobody`, or a
dedicated `molly` user. Make sure that user has read access to the
TLS keys and write access to the specified log file.
#### OpenRC
Instructions coming soon.
## Configuration Options
The following options can be set in `/etc/molly.conf`:
The following sections detail all the options which can be set in
`/etc/molly.conf` or any other configuration file specified with the
`-c` option.
The format of the configuration file is
[TOML](https://github.com/toml-lang/toml), which bares some similarity
to the "INI" format. Remember that you can check `example.conf` for
examples of the appropriate syntax.
### Basic options
* `Port`: The TCP port to listen for connections on (default value
`1965`).
* `Hostname`: The hostname to respond to requests for (default value
`localhost`). Requests for URLs with other hosts will result in a
status 53 (PROXY REQUEST REFUSED) response.
* `CertPath`: Path to TLS certificate in .pem format (default value
* `CertPath`: Path to TLS certificate in PEM format (default value
`cert.pem`).
* `KeyPath`: Path to TLS private key in .pem format (default value
* `KeyPath`: Path to TLS private key in PEM format (default value
`key.pem`).
* `DocBase`: Base directory for Gemini content (default value
`/var/gemini/`).
`/var/gemini/`). Only world-readable files stored in or below this
directory will be served by Molly Brown.
* `HomeDocBase`: Requests for paths beginning with `~/username/` will
be looked up relative to `DocBase/HomeDocBase/username/` (default
value `users`). Note that Molly Brown does *not* look inside user's
actual home directories like you may expect based on experience with
other server software. Of course, you can symlink
`/var/gemini/users/gus/` to `/home/gus/public_gemini/` if you want.
* `AccessLog`: Path to access log file (default value `access.log`, i.e. in the current wrorking directory). Note that
all intermediate directories must exist, Molly Brown won't create
them for you.
* `ErrorLog`: Path to error log file (default value `error.log`, i.e. in the current wrorking directory). Note that
all intermediate directories must exist, Molly Brown won't create
them for you.
* `MimeOverrides`: A map from path regexs to MIME types. If the path of a file which is about to be served matches the regex, the specified MIME type will be used instead of one inferred from the filename extension.
* `DirectorySort`: A string specifying how to sort files in automatically generated directory listings. Must be one of "Name", "Size" or "Time" (default value "Name").
* `DirectoryReverse` (boolean): if true, automatically generated directory listings will list files in descending order of whatever `DirectorySort` is set to (default value false).
* `DirectoryTitles` (boolean): if true, automatically generated directory listings will use the first top-level heading (i.e. line beginning with "# ") in files with an extension of `GeminiExt` instead of the filename (default value false).
* `AccessLog`: Path to access log file (default value `access.log`,
i.e. in the current wrorking directory). Note that all intermediate
directories must exist, Molly Brown won't create them for you.
* `ErrorLog`: Path to error log file (default value `error.log`, i.e.
in the current wrorking directory). Note that all intermediate
directories must exist, Molly Brown won't create them for you.
* `GeminiExt`: Files with this extension will be served with a MIME
type of `text/gemini` (default value `gmi`).
* `MimeOverrides`: In this section of the config file, keys are path
regexs and values are MIME types. If the path of a file which is
about to be served matches one the regexs, the corresponding MIME type
will be used instead of one inferred from the filename extension.
* `DefaultLanguage`: If this option is set, it will be served as the
`lang` parameter of the MIME type for all `text/gemini` content.
### Directory listings
Molly Brown will automatically generate directory listings for
world-readable directories under `DocBase` which do not contain an
`index.gmi` file. Only world-readable files and directories will be
listed. If a world-readable file named `.mollyhead` is found in a
directory, it's contents will be inserted above the directory listing
instead of the default "Directory listing" title.
The following options allow users to configure various aspects of the
directory listing:
* `DirectorySort`: A string specifying how to sort files in
automatically generated directory listings. Must be one of "Name",
"Size" or "Time" (default value "Name").
* `DirectoryReverse` (boolean): if true, automatically generated
directory listings will list files in descending order of whatever
`DirectorySort` is set to (default value false).
* `DirectoryTitles` (boolean): if true, automatically generated
directory listings will use the first top-level heading (i.e. line
beginning with "# ") in files with an extension of `GeminiExt`
instead of the filename (default value false).
### Redirects
* `TempRedirects`: In this section of the config file, keys are path
regexs and values are strings. If the path component of a received
request matches one of the regexs, Molly Brown will serve a redirect
to a modified URL using the value string as a path, using status
code 30.
* `PermRedirects`: As per `TempRedirects` above, but Molly Brown will
use the 31 status code instead of 30.
### Dynamic content
Molly Brown supports dynamically generated content using an adaptation
of the CGI standard, and also the SCGI standard.
It is very important to be aware that programs written in Go are
*unable* to reliably change their UID once started, due to how
goroutines are implemented on unix systems. As an unavoidable
consequence of this, CGI processes started by Molly Brown are run as
the same user as the server process. This means CGI processes
necessarily have read and write access to the server logs and to the
TLS private key. There is no way to work around this. As such you
must be extremely careful about only running trustworthy CGI
applications, ideally only applications you have carefully written
yourself. Allowing untrusted users to upload arbitrary executable
files into a CGI path is a serious security vulnerability.
SCGI applications must be started separately, and as such can run e.g.
as their own user and/or chrooted into their own filesystem, and as
such are less of a security issue.
* `CGIPaths`: A list of path regexs. Any request which maps to a
world-executable file contained in a directory which matches one of
the regexs in this list will be executed and its standard output
will be sent as the response to the client. CGI applications are
responsible for generating their own response headers, and must
terminate within 10 seconds of being spawned to avoid being killed.
Details about the request are available to CGI applications through
environment variables.
* `SCGIPaths`: In this section of the config file, keys are path
regexs and values are paths to unix domain sockets. Any request
whose path matches one of the regexs will cause an SCGI request to
be sent to the corresponding domain socket, and anything sent back
from a program listening on the other end of the socket will be send
as the response to the client. SCGI applications are responsible
for generating their own response headers.
### Certificate zones
Molly Brown allows you to use client certificates to restrict access
to certain resources (which may be static or dynamic). The overall
workflow is highly reminiscent of OpenSSH's `authorized_keys`
facility.
* `CertificateZones`: In this section of the config file, keys are
path regexs and values are lists of hex-encoded SHA256 fingerprints
of client certificates. Any requests whose path matches one of the
regexs will only be served as normal if the request is made with a
client certificate whose fingerprint is in the corresponding list.
Requests made without a certificate will cause a response with a
status code of 60. Requests made with a certificate not in the list
will cause a response with a status code of 60.
## .molly files
In order to allow users of shared-hosting who do not have access to
the main Molly Brown configuration file to customise some aspects of
their Gemini site, Molly Brown features functionality much like
Apache's `.htaccess` files. If the main configuration file contains
the line `ReadMollyFiles = true`, then each directory in the path to a
resource will be checked for a file named `.molly`. These files
should be in exactly the same format as the main configuration file,
an their contents will override (some) settings from the main file.
Each `.molly` file will override settings specified in `.molly` files
from higher directories.
E.g. when handling a request which maps to
`/var/gemini/foo/bar/baz/file.gmi`, then:
* The settings in the file `/var/gemini/.molly`, if it exists, will
override those in `/etc/molly.conf`.
* The settings in the file `/var/gemini/foo/.molly`, if it exists,
will override those in `/var/gemini/.molly`.
* The settings in the file `/var/gemini/foo/bar/.molly`, if it exists,
will override those in `/var/gemini/foo/.molly`.
* The settings in the file `/var/gemini/foo/bar/baz/.molly`, if it
exists, will override those in `/var/gemini/foo/bar/.molly`.
Only the following settings can be overriden by `.molly` files. Any
other settings in `.molly` files will be ignored:
* `DefaultLang`
* `DirectorySort`
* `DirectoryReverse`
* `DirectoryTitles`
* `GeminiExt`
Future support is planned for `.molly` files to be able to override:
* `CertificateZones`
* `MimeOverrides`
* `TempRedirects`
* `PermRedirects`
## Trivia
Margaret Brown was an American philanthropist and socialite who
survived the sinking of the RMS Titanic, leading to a Broadway musical
and later a film about her life being titled "The Unsinkable Molly
Brown". The "unsinkable" moniker inspired NASA astronaut Gus Grissom
to name the Gemini 3 capsule he commanded "Molly Brown" - Grissom had
almost drowned a few years earlier when his Mercury 4 capsule "Liberty
Bell" sank after splashdown.