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)
|