Blame


1 0111ad5d 2021-10-09 op <!doctype html>
2 0111ad5d 2021-10-09 op <html lang="en">
3 0111ad5d 2021-10-09 op <head>
4 35340c9f 2021-10-09 op <title>gmid quickstart</title>
5 0111ad5d 2021-10-09 op <meta charset="utf8" />
6 0111ad5d 2021-10-09 op <meta name="viewport" content="width=device-width, initial-scale=1" />
7 0111ad5d 2021-10-09 op <style>
8 0111ad5d 2021-10-09 op body {
9 0111ad5d 2021-10-09 op font-family: monospace;
10 0111ad5d 2021-10-09 op font-size: 14px;
11 0111ad5d 2021-10-09 op max-width: 780px;
12 0111ad5d 2021-10-09 op margin: 0 auto;
13 0111ad5d 2021-10-09 op padding: 20px;
14 0111ad5d 2021-10-09 op padding-bottom: 80px;
15 0111ad5d 2021-10-09 op }
16 0111ad5d 2021-10-09 op
17 0111ad5d 2021-10-09 op h1::before {
18 0111ad5d 2021-10-09 op content: "# ";
19 0111ad5d 2021-10-09 op }
20 0111ad5d 2021-10-09 op
21 0111ad5d 2021-10-09 op h2 {
22 0111ad5d 2021-10-09 op margin-top: 40px;
23 0111ad5d 2021-10-09 op }
24 0111ad5d 2021-10-09 op
25 0111ad5d 2021-10-09 op h2::before {
26 0111ad5d 2021-10-09 op content: "## ";
27 0111ad5d 2021-10-09 op }
28 0111ad5d 2021-10-09 op
29 0111ad5d 2021-10-09 op h3::before {
30 0111ad5d 2021-10-09 op content: "### ";
31 0111ad5d 2021-10-09 op }
32 0111ad5d 2021-10-09 op
33 0111ad5d 2021-10-09 op blockquote {
34 0111ad5d 2021-10-09 op margin: 0;
35 0111ad5d 2021-10-09 op padding: 0;
36 0111ad5d 2021-10-09 op }
37 0111ad5d 2021-10-09 op
38 0111ad5d 2021-10-09 op blockquote::before {
39 0111ad5d 2021-10-09 op content: "> ";
40 0111ad5d 2021-10-09 op }
41 0111ad5d 2021-10-09 op
42 0111ad5d 2021-10-09 op blockquote p {
43 0111ad5d 2021-10-09 op font-style: italic;
44 0111ad5d 2021-10-09 op display: inline;
45 0111ad5d 2021-10-09 op }
46 0111ad5d 2021-10-09 op
47 0111ad5d 2021-10-09 op p.link::before {
48 0111ad5d 2021-10-09 op content: "→ ";
49 0111ad5d 2021-10-09 op }
50 0111ad5d 2021-10-09 op
51 0111ad5d 2021-10-09 op strong::before { content: "*" }
52 0111ad5d 2021-10-09 op strong::after { content: "*" }
53 0111ad5d 2021-10-09 op
54 0111ad5d 2021-10-09 op hr {
55 0111ad5d 2021-10-09 op border: 0;
56 0111ad5d 2021-10-09 op height: 1px;
57 0111ad5d 2021-10-09 op background-color: #222;
58 0111ad5d 2021-10-09 op width: 100%;
59 0111ad5d 2021-10-09 op display: block;
60 0111ad5d 2021-10-09 op margin: 2em auto;
61 0111ad5d 2021-10-09 op }
62 0111ad5d 2021-10-09 op
63 0111ad5d 2021-10-09 op img {
64 0111ad5d 2021-10-09 op border-radius: 5px;
65 0111ad5d 2021-10-09 op }
66 0111ad5d 2021-10-09 op
67 0111ad5d 2021-10-09 op pre {
68 0111ad5d 2021-10-09 op overflow: auto;
69 0111ad5d 2021-10-09 op padding: 1rem;
70 0111ad5d 2021-10-09 op background-color: #f0f0f0;
71 0111ad5d 2021-10-09 op border-radius: 3px;
72 0111ad5d 2021-10-09 op }
73 0111ad5d 2021-10-09 op
74 0111ad5d 2021-10-09 op pre.banner {
75 0111ad5d 2021-10-09 op display: flex;
76 0111ad5d 2021-10-09 op flex-direction: row;
77 0111ad5d 2021-10-09 op justify-content: center;
78 0111ad5d 2021-10-09 op }
79 0111ad5d 2021-10-09 op
80 0111ad5d 2021-10-09 op code, kbd {
81 0111ad5d 2021-10-09 op color: #9d109d;
82 0111ad5d 2021-10-09 op }
83 0111ad5d 2021-10-09 op
84 0111ad5d 2021-10-09 op img {
85 0111ad5d 2021-10-09 op display: block;
86 0111ad5d 2021-10-09 op margin: 0 auto;
87 0111ad5d 2021-10-09 op max-width: 100%;
88 0111ad5d 2021-10-09 op }
89 0111ad5d 2021-10-09 op
90 0111ad5d 2021-10-09 op @media (prefers-color-scheme: dark) {
91 0111ad5d 2021-10-09 op body {
92 0111ad5d 2021-10-09 op background-color: #222;
93 0111ad5d 2021-10-09 op color: white;
94 0111ad5d 2021-10-09 op }
95 0111ad5d 2021-10-09 op
96 0111ad5d 2021-10-09 op a {
97 0111ad5d 2021-10-09 op color: aqua;
98 0111ad5d 2021-10-09 op }
99 0111ad5d 2021-10-09 op
100 0111ad5d 2021-10-09 op hr {
101 0111ad5d 2021-10-09 op background-color: #ddd;
102 0111ad5d 2021-10-09 op }
103 0111ad5d 2021-10-09 op
104 0111ad5d 2021-10-09 op pre {
105 0111ad5d 2021-10-09 op background-color: #353535;
106 0111ad5d 2021-10-09 op }
107 0111ad5d 2021-10-09 op
108 0111ad5d 2021-10-09 op code, kbd {
109 0111ad5d 2021-10-09 op color: #ff4cff;
110 0111ad5d 2021-10-09 op }
111 0111ad5d 2021-10-09 op }
112 0111ad5d 2021-10-09 op
113 0111ad5d 2021-10-09 op @media (max-width: 400px) {
114 0111ad5d 2021-10-09 op pre.banner { font-size: 9px; }
115 0111ad5d 2021-10-09 op }
116 0111ad5d 2021-10-09 op
117 0111ad5d 2021-10-09 op @media (max-width: 500px) {
118 0111ad5d 2021-10-09 op pre.banner { font-size: 10px; }
119 0111ad5d 2021-10-09 op }
120 0111ad5d 2021-10-09 op </style>
121 0111ad5d 2021-10-09 op </head>
122 0111ad5d 2021-10-09 op <body>
123 0111ad5d 2021-10-09 op <header>
124 0111ad5d 2021-10-09 op <nav>
125 0111ad5d 2021-10-09 op <a href="/">Home</a> |
126 0111ad5d 2021-10-09 op <a href="contrib.html">contrib</a> |
127 0111ad5d 2021-10-09 op Quickstart |
128 0111ad5d 2021-10-09 op <a href="gmid.1.html">docs</a>
129 0111ad5d 2021-10-09 op </nav>
130 0111ad5d 2021-10-09 op </header>
131 0111ad5d 2021-10-09 op <h1>gmid quickstart</h1>
132 0111ad5d 2021-10-09 op <p>gmid can be run in two different “modes”:</p>
133 0111ad5d 2021-10-09 op <dl>
134 0111ad5d 2021-10-09 op <dt>configless:</dt>
135 0111ad5d 2021-10-09 op <dd>
136 0111ad5d 2021-10-09 op a quick way to serve a directory tree from the shell, useful
137 0111ad5d 2021-10-09 op for testing a capsule before uploading it
138 0111ad5d 2021-10-09 op </dd>
139 0111ad5d 2021-10-09 op <dt>daemon mode:</dt>
140 0111ad5d 2021-10-09 op <dd>
141 0111ad5d 2021-10-09 op gmid reads the configuration file and runs in the background
142 0111ad5d 2021-10-09 op </dd>
143 0111ad5d 2021-10-09 op </dl>
144 0111ad5d 2021-10-09 op <p>To run gmid in the “configless” mode, just type:</p>
145 0111ad5d 2021-10-09 op <pre>$ gmid path/to/dir</pre>
146 0111ad5d 2021-10-09 op <p>
147 0111ad5d 2021-10-09 op gmid will then generate a certificate inside ~/.local/share/gmid
148 540d05de 2021-10-09 op and serve the given directory locally.
149 0111ad5d 2021-10-09 op </p>
150 fc4b58d4 2021-10-11 op <h2>Setting up a capsule with gmid</h2>
151 fc4b58d4 2021-10-11 op <p>To host a Gemini capsule you need to run gmid in “daemon” mode.</p>
152 0111ad5d 2021-10-09 op <p>
153 0111ad5d 2021-10-09 op To run gmid in daemon mode a configuration file is needed. The
154 0111ad5d 2021-10-09 op format of the configuration file is described in the manpage and
155 fc4b58d4 2021-10-11 op is quite flexible, but something like the following should be
156 fc4b58d4 2021-10-11 op enough to start:
157 0111ad5d 2021-10-09 op </p>
158 0111ad5d 2021-10-09 op <pre># /etc/gmid.conf
159 0111ad5d 2021-10-09 op
160 0111ad5d 2021-10-09 op server "example.com" {
161 33c4c3a5 2021-10-13 op cert "/etc/ssl/example.com.pem"
162 33c4c3a5 2021-10-13 op key "/etc/ssl/private/example.com/key"
163 33c4c3a5 2021-10-13 op
164 33c4c3a5 2021-10-13 op # path to the root directory of your capsule
165 0111ad5d 2021-10-09 op root "/var/gemini/example.com"
166 0111ad5d 2021-10-09 op }</pre>
167 0111ad5d 2021-10-09 op <p>
168 33c4c3a5 2021-10-13 op A certificate is needed for the capsule. Generate one for
169 33c4c3a5 2021-10-13 op e.g. using
170 0111ad5d 2021-10-09 op <a href="https://git.omarpolo.com/gmid/tree/contrib/gencert">contrib/gencert</a>:
171 0111ad5d 2021-10-09 op </p>
172 0111ad5d 2021-10-09 op <pre>$ ./contrib/gencert example.com
173 0111ad5d 2021-10-09 op Generating a 4096 bit RSA private key
174 0111ad5d 2021-10-09 op .................................................++++
175 0111ad5d 2021-10-09 op ..........++++
176 0111ad5d 2021-10-09 op writing new private key to './example.com.key'
177 0111ad5d 2021-10-09 op -----
178 0111ad5d 2021-10-09 op
179 0111ad5d 2021-10-09 op Generated files:
180 0111ad5d 2021-10-09 op ./example.com.pem : certificate
181 0111ad5d 2021-10-09 op ./example.com.key : private key</pre>
182 0111ad5d 2021-10-09 op <p>
183 33c4c3a5 2021-10-13 op Move ‘example.com.pem’ and ‘example.com.key’ to a safe place and
184 33c4c3a5 2021-10-13 op double check that the ‘cert’ and ‘key’ options in the
185 33c4c3a5 2021-10-13 op configuration points to these files.
186 0111ad5d 2021-10-09 op </p>
187 33c4c3a5 2021-10-13 op <p>For example, save them in ‘/etc/ssl/’ (as root)</p>
188 33c4c3a5 2021-10-13 op <pre># mkdir -p /etc/ssl/private
189 33c4c3a5 2021-10-13 op # chown 700 /etc/ssl/private
190 33c4c3a5 2021-10-13 op # mv example.com.pem /etc/ssl/
191 33c4c3a5 2021-10-13 op # mv example.com.key /etc/ssl/private/</pre>
192 0111ad5d 2021-10-09 op <p>
193 0111ad5d 2021-10-09 op Make sure that the ‘cert’ and ‘key’ options in the configuration
194 0111ad5d 2021-10-09 op file points to these files.
195 0111ad5d 2021-10-09 op </p>
196 0111ad5d 2021-10-09 op <p>Then running gmid is as easy as</p>
197 0111ad5d 2021-10-09 op <pre>$ gmid -c /etc/gmid.conf</pre>
198 fc4b58d4 2021-10-11 op <p>Congratulations, your capsule is online!</p>
199 0111ad5d 2021-10-09 op <h2>Securing your gmid installation</h2>
200 0111ad5d 2021-10-09 op <p>
201 0111ad5d 2021-10-09 op gmid employs various techniques to prevent the damage caused by
202 0111ad5d 2021-10-09 op bugs, but some steps needs to be done manually.
203 0111ad5d 2021-10-09 op </p>
204 0111ad5d 2021-10-09 op <p>
205 0111ad5d 2021-10-09 op If gmid was installed from your distribution package manager,
206 0111ad5d 2021-10-09 op chance are that it already does all of this and is also
207 33c4c3a5 2021-10-13 op providing a service to run gmid automatically (e.g. a rc script,
208 33c4c3a5 2021-10-13 op a systemd unit file …) Otherwise, it’s heavily suggested to
209 0111ad5d 2021-10-09 op create at least a dedicated user.
210 0111ad5d 2021-10-09 op </p>
211 0111ad5d 2021-10-09 op <h3>A dedicated user</h3>
212 0111ad5d 2021-10-09 op <p>
213 fc4b58d4 2021-10-11 op Ideally, gmid should be started as root and drop privileges to a
214 fc4b58d4 2021-10-11 op local user. This way, the certificates can be readable only by
215 fc4b58d4 2021-10-11 op root. For example, on GNU/linux systems a ‘gmid’ user can be
216 fc4b58d4 2021-10-11 op created with:
217 0111ad5d 2021-10-09 op </p>
218 35340c9f 2021-10-09 op <pre># useradd --system --no-create-home -s /bin/nologin -c "gmid Gemini server" gmid</pre>
219 0111ad5d 2021-10-09 op <p>
220 0111ad5d 2021-10-09 op Please consult your OS documentation for more information on the
221 0111ad5d 2021-10-09 op matter.
222 0111ad5d 2021-10-09 op </p>
223 0111ad5d 2021-10-09 op <p>
224 0111ad5d 2021-10-09 op The configuration then needs to be adjusted to include the
225 0111ad5d 2021-10-09 op ‘user’ directive at the top:
226 0111ad5d 2021-10-09 op </p>
227 0111ad5d 2021-10-09 op <pre># /etc/gmid.conf
228 0111ad5d 2021-10-09 op user "gmid"
229 0111ad5d 2021-10-09 op
230 0111ad5d 2021-10-09 op server "example.com" { … }</pre>
231 0111ad5d 2021-10-09 op <p>
232 0111ad5d 2021-10-09 op gmid then needs to be started with root privileges, but will
233 0111ad5d 2021-10-09 op then switch to the provided user automatically. If by accident
234 fc4b58d4 2021-10-11 op the ‘user’ option is omitted and gmid is running as root, it
235 fc4b58d4 2021-10-11 op will complain loudly in the logs.
236 0111ad5d 2021-10-09 op </p>
237 0111ad5d 2021-10-09 op <h3>chroot</h3>
238 0111ad5d 2021-10-09 op <p>
239 0111ad5d 2021-10-09 op It’s a common practice for system daemons to chroot themselves
240 0111ad5d 2021-10-09 op into a directory. From here on I’ll assume /var/gemini, but it
241 0111ad5d 2021-10-09 op can be any directory.
242 0111ad5d 2021-10-09 op </p>
243 0111ad5d 2021-10-09 op <p>
244 0111ad5d 2021-10-09 op A chroot on UNIX-like OS is an operation that changes the
245 fc4b58d4 2021-10-11 op “apparent” root directory (i.e. the “/”) from the current
246 fc4b58d4 2021-10-11 op process and its child. Think of it like imprisoning a process
247 fc4b58d4 2021-10-11 op into a directory and never letting it escape until it
248 fc4b58d4 2021-10-11 op terminates.
249 0111ad5d 2021-10-09 op </p>
250 0111ad5d 2021-10-09 op <p>
251 0111ad5d 2021-10-09 op Using a chroot may complicate the use of CGI scripts, because
252 fc4b58d4 2021-10-11 op then all the dependencies of the scripts (sh, perl, libraries…)
253 fc4b58d4 2021-10-11 op need to be installed inside the chroot too. For this very
254 fc4b58d4 2021-10-11 op reason gmid supports FastCGI.
255 0111ad5d 2021-10-09 op </p>
256 0111ad5d 2021-10-09 op <p>
257 0111ad5d 2021-10-09 op The chroot feature requires a dedicate user, see the previous
258 0111ad5d 2021-10-09 op section.
259 0111ad5d 2021-10-09 op </p>
260 0111ad5d 2021-10-09 op <p>
261 0111ad5d 2021-10-09 op To chroot gmid inside a directory, use the ‘chroot’ directive in
262 0111ad5d 2021-10-09 op the configuration file:
263 0111ad5d 2021-10-09 op </p>
264 0111ad5d 2021-10-09 op <pre># /etc/gmid.conf
265 0111ad5d 2021-10-09 op
266 35340c9f 2021-10-09 op user "gmid"
267 35340c9f 2021-10-09 op
268 0111ad5d 2021-10-09 op # the given directory, /var/gemini in this case, must exists.
269 0111ad5d 2021-10-09 op chroot "/var/gemini"</pre>
270 0111ad5d 2021-10-09 op <p>
271 0111ad5d 2021-10-09 op Note that once ‘chroot’ is in place, every ‘root’ directive is
272 0111ad5d 2021-10-09 op implicitly relative to the chroot, but ‘cert’ and ‘key’ aren’t!
273 0111ad5d 2021-10-09 op </p>
274 0111ad5d 2021-10-09 op <p>For example, given the following configuration:</p>
275 0111ad5d 2021-10-09 op <pre># /etc/gmid.conf
276 0111ad5d 2021-10-09 op
277 0111ad5d 2021-10-09 op user "gmid"
278 0111ad5d 2021-10-09 op chroot "/var/gemini"
279 0111ad5d 2021-10-09 op
280 0111ad5d 2021-10-09 op server "example.com" {
281 0111ad5d 2021-10-09 op cert "/etc/ssl/example.com.pem"
282 0111ad5d 2021-10-09 op key "/etc/ssl/example.com.key"
283 0111ad5d 2021-10-09 op root "/example.com"
284 0111ad5d 2021-10-09 op }</pre>
285 0111ad5d 2021-10-09 op <p>
286 0111ad5d 2021-10-09 op The certificate and the key path are the specified ones, but the
287 0111ad5d 2021-10-09 op root directory of the virtual host is actually
288 0111ad5d 2021-10-09 op “/var/gemini/example.com/”.
289 0111ad5d 2021-10-09 op </p>
290 0111ad5d 2021-10-09 op </body>
291 0111ad5d 2021-10-09 op </html>