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
|
# SpaceBeans Gemini Server
This is an experimental server for the [Gemini](https://gemini.circumlunar.space/) protocol.
It is built using [Scala](https://www.scala-lang.org/) and [Akka Streams](https://doc.akka.io/docs/akka/current/stream/index.html).
The name tries to link the Gemini *theme* with the fact that the
server runs on the Java Virtual Machine.
Some of the **SpaceBeans** features:
- Static files, including optional directory listings
- IPv4 and IPv6
- Configurable MIME types, or a built-in resolver
- Virtual hosting, with SNI support
- User directories support
- Classic CGI scripts
- User provided certificates or auto-generated in memory (for development)
- Configurable SSL engine (e.g. TLSv1.2 and/or TLSv1.3), with configurable ciphers
Check [CHANGES](CHANGES.md) to see what's new in the latest release.
If you have a Gemini browser, you can also visit: `gemini://capsule.usebox.net/spacebeans/`
## How to run it
Download [the `jar` distribution file](https://gitlab.com/reidrac/spacebeans/-/releases) and install Java Runtime Environment 8 (or
later; [OpenJDK's JRE](https://adoptopenjdk.net/) recommended).
You can run the service with:
```
java -jar spacebeans-VERSION.jar -c spacebeans.conf
```
You can also run the server with `--help` flag for CLI help.
Please check [the example configuration file](spacebeans.conf.example) for instructions on
how to configure the service.
### Running it as a service
Check this document on [how to deploy on Debian](Deployment.md).
## On security
You should evaluate your security requirements when running **SpaceBeans**.
In this section *TOFU* refers to "Trust On First Use".
### Auto-generated self-signed certificate
This is the easiest option, no need to store securely the certificate. The
downside is that you get a new certificate every time you start the service,
and that's bad for TOFU validation.
This is recommended **only for development** and not for a service facing the
Internet.
Comment out the `key-store` section on your virtual host and you are done.
### Self-signed certificate
You can generate a self signed certificate using Java's `keytool`:
```
keytool -genkey -keyalg RSA -alias ALIAS -keystore keystore.jks -storepass SECRET -noprompt -validity 36500 -keysize 2048
```
When entering the certificate details, use the domain name as `CN`.
In the configuration file provide the path to the keystore, the alias and the
secret used when generating the certificate.
This is the recommended TOFU-compatible way of managing certificates. The
certificate **should be set to expire way in the future** because changing
certificates doesn't play well with TOFU validation.
### Import a CA signed certificate
The certificate has to be converted and imported into a JKS keystore to be
used by the server.
For example:
```
keytool -import -alias ALIAS -keystore keystore.jks -file cert.pem -storepass SECRET -noprompt
```
Answer "yes" when asked if the certificate should be trusted.
In the configuration file provide the path to the keystore, the alias and the
secret used when importing the certificate.
CA signed certificates don't play well with TOFU, but if the client is properly
validating the certificate, this is perfectly safe.
## CGI support
Classic CGI is supported via the `allow-cgi` flag in the `directories` directive.
The flag only affects to the specified directory.
The environment variables provided to the CGIs are:
| Variable | Example |
| --- | --- |
| REMOTE_ADDR | `127.0.0.1` |
| SERVER_PORT | `1965` |
| GEMINI_URL | `gemini://localhost/mycgi/example/path?test=1` |
| REMOTE_HOST | `127.0.0.1` |
| SERVER_PROTOCOL | `GEMINI` |
| SERVER_SOFTWARE | `spacebeans/v1.1.3` |
| SCRIPT_NAME | `mycgi` |
| SERVER_NAME | `localhost` |
| PATH_INFO | `/example/path` |
| GATEWAY_INTERFACE | `CGI/1.1` |
| QUERY_STRING | `test=1` |
These are described in [RFC-3875](https://datatracker.ietf.org/doc/html/rfc3875).
The server expects:
- the CGI must terminate with exit code `0` (success)
- the response will be in CGI's standard output
- it **must** be a valid Gemini response
An example of a CGI script written in Python that outputs the environment
variables could be:
```python
#!/usr/bin/env python3
import os
print("20 text/gemini\r\n")
print('\n'.join([k + "=" + v for k, v in os.environ.items()]))
```
## Development
Requirements:
- JDK 8 (or later)
- git (the git repo is required to set the version; GitLab's source archives won't compile)
Run the server with `./mill server.run` and the tests with `./mill server.test`.
To build the `jar` bundle, run `./mill server.assembly` and the result will be generated
in `out/server/assembly/dest/`.
## License
Copyright (C) 2021 Juan J. Martinez <jjm@usebox.net>
This software is distributed under MIT license, unless stated otherwise.
See COPYING file.
|