Big documentation push.
This commit is contained in:
parent
18c056167f
commit
520e1ecc95
304
README.md
304
README.md
|
@ -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
|
For more information on the Gemini protocol see:
|
||||||
gopher://gemini.circumlunar.space.
|
|
||||||
|
* 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
|
## 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
|
(you can in fact put your $GOPATH anywhere you like, but `~/go` is the
|
||||||
convention)
|
convention)
|
||||||
|
|
||||||
### Fetch and build MB
|
### Fetch and build Molly Brown
|
||||||
|
|
||||||
Run `go get tildegit.org/solderpunk/molly-brown`. If everything goes
|
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
|
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
|
### Configuration
|
||||||
|
|
||||||
In the source directory mentioned above, you should find a file named
|
Molly Brown can run without a configuration file, in which case it
|
||||||
`example.conf`. Copy this to `/etc/molly.conf` and edit it to suit
|
will use compiled-in default settings. However, these settings are
|
||||||
your environment. The default values for all possible options are
|
oriented toward quick test runs with all files in the current
|
||||||
specified in the file - just uncomment and change the ones which won't
|
working directory. For regular use, you will want to override these
|
||||||
work for you. All options are explained below in the Configuration
|
defaults with more suitable settings from a config file. An example
|
||||||
Options section.
|
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
|
Molly Brown does not handle details like daemonising itself, changing
|
||||||
daemonising itself. You'll need to use another program, like the one
|
the user it runs as, etc. You will need to take care of these tasks
|
||||||
at `http://libslack.org/daemon/`, to handle daemonising.
|
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
|
#### Manual management
|
||||||
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`.
|
|
||||||
|
|
||||||
Setting up with systemd should be reasonably easy; copy
|
You can always use a tool like [daemon](`http://libslack.org/daemon/`)
|
||||||
`molly-brown.service.example` from this directory to
|
to take care of daemonising the Molly Brown process, changing the user
|
||||||
`/etc/systemd/system/molly-brown.service`. Then, make any necessary
|
it runs as, chrooting it to a particular location, etc. You can call
|
||||||
changes for your setup, and run the following:
|
`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
|
```sh
|
||||||
# systemctl daemon-reload
|
# systemctl daemon-reload
|
||||||
|
@ -62,40 +131,189 @@ changes for your setup, and run the following:
|
||||||
# systemctl start molly-brown.service
|
# systemctl start molly-brown.service
|
||||||
```
|
```
|
||||||
|
|
||||||
Note that Golang programs are unable to reliably change their UID once
|
#### OpenRC
|
||||||
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
|
Instructions coming soon.
|
||||||
dedicated `molly` user. Make sure that user has read access to the
|
|
||||||
TLS keys and write access to the specified log file.
|
|
||||||
|
|
||||||
## Configuration Options
|
## 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
|
* `Port`: The TCP port to listen for connections on (default value
|
||||||
`1965`).
|
`1965`).
|
||||||
* `Hostname`: The hostname to respond to requests for (default value
|
* `Hostname`: The hostname to respond to requests for (default value
|
||||||
`localhost`). Requests for URLs with other hosts will result in a
|
`localhost`). Requests for URLs with other hosts will result in a
|
||||||
status 53 (PROXY REQUEST REFUSED) response.
|
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`).
|
`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`).
|
`key.pem`).
|
||||||
* `DocBase`: Base directory for Gemini content (default value
|
* `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
|
* `HomeDocBase`: Requests for paths beginning with `~/username/` will
|
||||||
be looked up relative to `DocBase/HomeDocBase/username/` (default
|
be looked up relative to `DocBase/HomeDocBase/username/` (default
|
||||||
value `users`). Note that Molly Brown does *not* look inside user's
|
value `users`). Note that Molly Brown does *not* look inside user's
|
||||||
actual home directories like you may expect based on experience with
|
actual home directories like you may expect based on experience with
|
||||||
other server software. Of course, you can symlink
|
other server software. Of course, you can symlink
|
||||||
`/var/gemini/users/gus/` to `/home/gus/public_gemini/` if you want.
|
`/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
|
* `AccessLog`: Path to access log file (default value `access.log`,
|
||||||
all intermediate directories must exist, Molly Brown won't create
|
i.e. in the current wrorking directory). Note that all intermediate
|
||||||
them for you.
|
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
|
* `ErrorLog`: Path to error log file (default value `error.log`, i.e.
|
||||||
all intermediate directories must exist, Molly Brown won't create
|
in the current wrorking directory). Note that all intermediate
|
||||||
them for you.
|
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.
|
* `GeminiExt`: Files with this extension will be served with a MIME
|
||||||
* `DirectorySort`: A string specifying how to sort files in automatically generated directory listings. Must be one of "Name", "Size" or "Time" (default value "Name").
|
type of `text/gemini` (default value `gmi`).
|
||||||
* `DirectoryReverse` (boolean): if true, automatically generated directory listings will list files in descending order of whatever `DirectorySort` is set to (default value false).
|
* `MimeOverrides`: In this section of the config file, keys are path
|
||||||
* `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).
|
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.
|
||||||
|
|
Loading…
Reference in New Issue