aboutsummaryrefslogtreecommitdiff
path: root/README.md
blob: e97394dc5e5f3cf3f16a20e7cc268c6ee64a8b5c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# gmid

> **Warning**
> The `master` branch is WIP: it's what gmid 2.0 will be, with
> breaking changes et al.  Please use the latest release from the 1.8
> branch for a stable and documented experience, thank you.

gmid is a full-featured Gemini server written with security in mind.
It can serve static files, has optional FastCGI and proxying support,
and a rich configuration syntax.

A few helper programs are shipped as part of gmid:

 - `gg` is a simple command-line Gemini client.

 - `gemexp` is a stripped-down config-less version of gmid to quickly
   serve a directory from the command line.

 - `titan` is a command-line titan client.


## Internationalisation (IRIs, UNICODE, punycode, all that stuff)

Even thought the current Gemini specification doesn't mention anything
in this regard, I do think these are important things and so I tried
to implement them in the most user-friendly way I could think of.

For starters, gmid has full support for IRI (RFC3987 —
Internationalized Resource Identifiers).  IRIs are a superset of URIs,
so there aren't incompatibilities with URI-only clients.

There is full support also for punycode.  In theory, the user doesn't
even need to know that punycode is a thing.  The hostname in the
configuration file can (and must be) in the decoded form (e.g. `naïve`
and not `xn--nave-6pa`), gmid will do the rest.

The only missing piece is UNICODE normalisation of the IRI path: gmid
doesn't do that (yet).


## Configuration

[httpd]: https://man.openbsd.org/httpd.8

gmid has a rich configuration file, heavily inspired by OpenBSD'
[httpd(8)][httpd], with every detail carefully documented in the
manpage.  Here's a minimal example of a config file:

```conf
server "example.com" {
	listen on * port 1965
	cert "/path/to/cert.pem"
	key  "/path/to/key.pem"
	root "/var/gemini/example.com"
}
```

and a slightly more complex one

```conf
cert_root = "/path/to/keys"

server "example.com" {
	listen on * port 1965

	alias "foobar.com"

	cert $cert_root "/example.com.crt"
	key  $cert_root "/example.com.pem"
	root "/var/gemini/example.com"

	# lang for text/gemini files
	lang "en"

	# only for locations that matches /files/*
	location "/files/*" {
		# generate directory listings
		auto index on
	}

	location "/repo/*" {
		# change the index file name
		index "README.gmi"
		lang "it"
	}
}
```


## Building

gmid depends on libevent2, OpenSSL/LibreSSL and libtls (provided
either by LibreSSL or libretls).  At build time, yacc (or GNU bison)
is also needed.

The build is as simple as

	$ ./configure
	$ make

If the configure scripts fails to pick up something, please open an
issue or notify me via email.

To install execute:

	# make install

Please keep in mind that the master branch, from time to time, may be
accidentally broken on some platforms.  gmid is developed primarily on
OpenBSD/amd64 and commits on the master branch don't get always tested
in other OSes.  Before tagging a release however, a comprehensive
testing on various platform is done to ensure that everything is
working as intended.


### Testing

Execute

	$ make regress

to start the suite.  Keep in mind that the regression tests needs to
create a few file inside the `regress` directory and bind the 10965
port.


## Contributing

Any form of contribution is welcome, not only patches or bug reports.
If you have a sample configuration for some specific use-case, a
script or anything that could be useful to others, consider adding it
to the `contrib` directory.


## Architecture/Security considerations

The internal architecture was revisited for the 2.0 release.  For
previous releases, please refer to previous revision of this file.

gmid has a privsep design, where the operations done by the daemon are
splitted into multiple processes:

 - main: the main process is the only one that keeps the original
   privileges.  It opens the TLS certificates on the behalf of the
   `server` and `crypto` processes and reloads the configuration upon
   `SIGHUP`.

 - logger: handles the logging with syslog and/or local files.

 - server: listen on the binded ports and serves the request.  This
   also include speaking FastCGI and proxying requests.

 - crypto: holds the TLS private keys to avoid a compromised `server`
   process to disclose them.