summaryrefslogtreecommitdiff
path: root/readme.md
blob: 12ee8ecd9139cb6cf07ab40288fe4054acceddeb (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
155
156
157
158
159
160
# gnix

a simple stupid reverse proxy

## Features

- HTTP/1.1
- Simple to configure (see below)
- Composable modules
- Handles connection upgrades correctly by default (websocket, etc.)
- TLS support
- Configuration hot-reloading
- Client authentification (http basic auth, cookie)
- _TODO: h2; h3; match on uris; connection pooling; custom connection timeouts_

## Links

- [AUR Package](https://aur.archlinux.org/packages/gnix)
- [Matrix Room](https://matrix.to/#/#gnix:metamuffin.org) for questions,
  announcements and general discussion around the software.

## Quick Start

Run the binary with the a path to the configuration as the first argument. The
configuration file is written in YAML and could look like this:

```toml
# Both the 'http' and 'https' sections are optional
http:
  # the value for 'bind' can either be a string or a list of strings
  bind: "[::1]:8080"

https:
  bind: "[::1]:8443"
  tls_cert: "ssl/cert.pem"
  tls_key: "ssl/key.pem" # only accepts pkcs8

# !hosts multiplexes requests for different hostnames.
handler: !hosts
    # requests for `example.org` are forwarded to 127.0.0.1:8000
    "example.org": !proxy { backend: "127.0.0.1:8000" }
    # requests for `mydomain.com` will access files from /srv/http
    "mydomain.com": !files
        root: "/srv/http"
        index: true
    
    "panel.mydomain.com": !access_log
```

## Reference

The configuration uses YAML formatting. When the configuration file is changed,
it will automatically be loaded and applied if valid.

- **section `http`**
  - `bind`: string or list of strings with addresses to listen on.

- **section `https`**
  - `bind`: string or list of strings with addresses to listen on.
  - `tls_cert`: path to the SSL certificate. (Sometimes called `fullchain.pem`)
  - `tls_key`: path to the SSL key. (Often called `key.pem` or `privkey.pem`)

- **section `limits`**
  - Note: Make sure you do not exceed the maximum file descriptor limit on your
    platform.
  - `max_incoming_connections` number of maximum incoming (downstream)
    connections. excess connections are rejected. Default: 512
  - `max_outgoing_connections` number of maximum outgoing (upstream)
    connections. excess connections are rejected. Default: 256

- **section `handler`**
  - A module to handle all requests. Usually an instance of `hosts`.

- `watch_config`: boolean if to watch the configuration file for changes and
  apply them accordingly. Default: true (Note: This will watch the entire parent
  directory of the config since most editors first move the file. Currently any
  change will trigger a reload. TODO)

### Modules

Modules handle requests. Some of them have arguments which are modules
themselves; in that case the request is passed on.

- **module `hosts`**
  - Hands over the requests to different modules depending on the `host` header.
  - Takes a map from hostname (string) to handler (module)

- **module `proxy`**
  - Forwards the request as-is to some other server. the `x-real-ip` header is
    injected into the request. Connection upgrades are handled by direct
    forwarding of network traffic.
  - `backend`: socket address (string) to the backend server

- **module `files`**
  - Provides a simple built-in fileserver. The server handles `accept-ranges`.
    The `content-type` header is inferred from the file extension and falls back
    to `application/octet-stream`. If a directory is requested `index.html` will
    be served or else when indexing is enabled, `index.banner.html` will be
    prepended to the response.
  - `root`: root directory to be served (string)
  - `index`: enables directory indexing (boolean)

- **module `file`**
  - Replies with static content.
  - `path`: file path to the content. _This will be loaded into memory once!_
    (string)
  - `content`: inline declaration of the content. (string)
  - `type`: type of content reflected in `content-type` header. (string)

- **module `access_log`**
  - Logs requests to a file.
  - `file`: file path to log (string)
  - `reject_on_fail`: rejects requests if log could not be written (boolean)
  - `flush`: flushes log on every request (boolean)
  - `next`: module for further handling of the request (module)

- **module `error`**
  - Rejects every request with a custom error message.
  - Takes an error message (string)

- **module `http_basic_auth`**
  - Filters requests via HTTP Basic Authentification. Unauthorized clients will
    be challenged on every request.
  - `realm`: describes what the user is logging into (most modern browsers dont
    show this anymore -_-)
  - `users`: list of valid logins (credentials)
  - `next`: a module to handle this request on successfully authentificated.
    (module)

- **module `cookie_auth`**
  - Authentificates a client based on cookies. The cookies are set on login by a
    POST request to `/_gnix_login` with form fields `password` and `username`
    (optional, default: "user") in `x-www-form-urlencoded` format. In any case
    the users submitting this request will be directed back to the page they
    come from. Successful logins set two cookies: `gnix_username` containing the
    username and `gnix_auth` containing an opaque authentification token. The
    `gnix_username` cookie is authentificated by gnix and can therefore be used
    by applications.
  - `users`: list of valid logins (credentials)
  - `expire`: seconds before logins expire; not setting this option keeps the
    login valid forever on the server but cleared after the session on the
    client (optional number)
  - `secure`: makes the cookies accessable from secure contexts exclusively i.e.
    HTTPS (boolean)
  - `next`: a module to handle this request on successfully authentificated.
    (module)
  - `fail`: a module to handle the request when a user is not authorized. This
    could show an HTML form prompting the user to log in. An implementation of
    such a form is provided with the distribution of this software, usually in
    `/usr/share/gnix/login.html`

#### Credentials config format

Login credentials for `cookie_auth` and `http_basic_auth` are supplied as either
an object mapping usernames to PHC strings or a file path pointing to a file
that contains that map in YALM format. Currently only `argon2id` is supported.

## License

AGPL-3.0-only; see [COPYING](./COPYING)