b22853ef5152846ffbb007a9d89809a2a8a05072
[platform/upstream/libwebsockets.git] / README.lwsws.md
1 Libwebsockets Web Server
2 ------------------------
3
4 lwsws is an implementation of a very lightweight, ws-capable generic web
5 server, which uses libwebsockets to implement everything underneath.
6
7 Build
8 -----
9
10 Just enable -DLWS_WITH_LWSWS=1 at cmake-time.
11
12 It enables libuv and plugin support automatically.
13
14
15 Configuration
16 -------------
17
18 lwsws uses JSON config files, they're pure JSON but # may be used to turn the rest of the line into a comment.
19
20 There is a single file intended for global settings
21
22 /etc/lwsws/conf
23
24 ```
25 # these are the server global settings
26 # stuff related to vhosts should go in one
27 # file per vhost in ../conf.d/
28
29 {
30   "global": {
31    "uid": "48",  # apache user
32    "gid": "48",  # apache user
33    "count-threads": "1",
34    "server-string": "myserver v1", # returned in http headers
35    "init-ssl": "yes"
36  }
37 }
38 ```
39
40 and a config directory intended to take one file per vhost
41
42 /etc/lwsws/conf.d/warmcat.com
43
44 ```
45 {
46         "vhosts": [{
47                 "name": "warmcat.com",
48                 "port": "443",
49                 "interface": "eth0",  # optional
50                 "host-ssl-key": "/etc/pki/tls/private/warmcat.com.key",  # if given enable ssl
51                 "host-ssl-cert": "/etc/pki/tls/certs/warmcat.com.crt",
52                 "host-ssl-ca": "/etc/pki/tls/certs/warmcat.com.cer",
53                 "mounts": [{  # autoserve
54                         "mountpoint": "/",
55                         "origin": "file:///var/www/warmcat.com",
56                         "default": "index.html"
57                 }]
58         }]
59 }
60 ```
61
62 To get started quickly, an example config reproducing the old test server
63 on port 7681, non-SSL is provided.  To set it up
64
65 ```
66 # mkdir -p /etc/lwsws/conf.d /var/log/lwsws
67 # cp ./lwsws/etc-lwsws-conf-EXAMPLE /etc/lwsws/conf
68 # cp ./lwsws/etc-lwsws-conf.d-localhost-EXAMPLE /etc/lwsws/conf.d/test-server
69 # sudo lwsws
70 ```
71
72 Vhosts
73 ------
74
75 One server can run many vhosts, where SSL is in use SNI is used to match
76 the connection to a vhost and its vhost-specific SSL keys during SSL
77 negotiation.
78
79 Listing multiple vhosts looks something like this
80
81 ```
82 {
83  "vhosts": [ {
84      "name": "localhost",
85      "port": "443",
86      "host-ssl-key":  "/etc/pki/tls/private/libwebsockets.org.key",
87      "host-ssl-cert": "/etc/pki/tls/certs/libwebsockets.org.crt",
88      "host-ssl-ca":   "/etc/pki/tls/certs/libwebsockets.org.cer",
89      "mounts": [{
90        "mountpoint": "/",
91        "origin": "file:///var/www/libwebsockets.org",
92        "default": "index.html"
93        }, {
94         "mountpoint": "/testserver",
95         "origin": "file:///usr/local/share/libwebsockets-test-server",
96         "default": "test.html"
97        }],
98      # which protocols are enabled for this vhost, and optional
99      # vhost-specific config options for the protocol
100      #
101      "ws-protocols": [{
102        "warmcat,timezoom": {
103          "status": "ok"
104        }
105      }]
106     },
107     {
108     "name": "localhost",
109     "port": "7681",
110      "host-ssl-key":  "/etc/pki/tls/private/libwebsockets.org.key",
111      "host-ssl-cert": "/etc/pki/tls/certs/libwebsockets.org.crt",
112      "host-ssl-ca":   "/etc/pki/tls/certs/libwebsockets.org.cer",
113      "mounts": [{
114        "mountpoint": "/",
115        "origin": ">https://localhost"
116      }]
117    },
118     {
119     "name": "localhost",
120     "port": "80",
121      "mounts": [{
122        "mountpoint": "/",
123        "origin": ">https://localhost"
124      }]
125    }
126
127   ]
128 }
129 ```
130
131 That sets up three vhosts all called "localhost" on ports 443 and 7681 with SSL, and port 80 without SSL but with a forced redirect to https://localhost
132
133
134 Vhost name and port
135 -------------------
136
137 The vhost name field is used to match on incoming SNI or Host: header, so it
138 must always be the host name used to reach the vhost externally.
139
140  - Vhosts may have the same name and different ports, these will each create a
141 listening socket on the appropriate port.
142
143  - Vhosts may also have the same port and different name: these will be treated as
144 true vhosts on one listening socket and the active vhost decided at SSL
145 negotiation time (via SNI) or if no SSL, then after the Host: header from
146 the client has been parsed.
147
148
149 Protocols
150 ---------
151
152 Vhosts by default have available the union of any initial protocols from context creation time, and
153 any protocols exposed by plugins.
154
155 Vhosts can select which plugins they want to offer and give them per-vhost settings using this syntax
156
157 ```     
158      "ws-protocols": [{
159        "warmcat-timezoom": {
160          "status": "ok"
161        }
162      }]
163
164 ```
165
166 The "x":"y" parameters like "status":"ok" are made available to the protocol during its per-vhost
167 LWS_CALLBACK_PROTOCOL_INIT (@in is a pointer to a linked list of struct lws_protocol_vhost_options
168 containing the name and value pointers).
169
170 To indicate that a protocol should be used when no Protocol: header is sent
171 by the client, you can use "default": "1"
172
173 ```     
174      "ws-protocols": [{
175        "warmcat-timezoom": {
176          "status": "ok",
177          "default": "1"
178        }
179      }]
180
181 ```
182
183
184 Other vhost options
185 -------------------
186
187  - If the three options `host-ssl-cert`, `host-ssl-ca` and `host-ssl-key` are given, then the vhost supports SSL.
188
189  Each vhost may have its own certs, SNI is used during the initial connection negotiation to figure out which certs to use by the server name it's asking for from the request DNS name.
190
191  - `keeplive-timeout` (in secs) defaults to 60 for lwsws, it may be set as a vhost option
192
193  - `interface` lets you specify which network interface to listen on, if not given listens on all
194
195  - "`unix-socket`": "1" causes the unix socket specified in the interface option to be used instead of an INET socket
196
197  - "`sts`": "1" causes lwsws to send a Strict Transport Security header with responses that informs the client he should never accept to connect to this address using http.  This is needed to get the A+ security rating from SSL Labs for your server.
198
199  - "`access-log`": "filepath"   sets where apache-compatible access logs will be written
200
201  - `"enable-client-ssl"`: `"1"` enables the vhost's client SSL context, you will need this if you plan to create client conections on the vhost that will use SSL.  You don't need it if you only want http / ws client connections.
202
203  - "`ciphers`": "<cipher list>"   sets the allowed list of ciphers and key exchange protocols for the vhost.  The default list is restricted to only those providing PFS (Perfect Forward Secrecy) on the author's Fedora system.
204  
205  If you need to allow weaker ciphers,you can provide an alternative list here per-vhost.
206  
207  - "`ecdh-curve`": "<curve name>"   The default ecdh curve is "prime256v1", but you can override it here, per-vhost
208
209  - "`noipv6`": "on"  Disable ipv6 completely for this vhost
210
211  - "`ipv6only`": "on"  Only allow ipv6 on this vhost / "off" only allow ipv4 on this vhost
212
213  - "`ssl-option-set`": "<decimal>"  Sets the SSL option flag value for the vhost.
214  It may be used multiple times and OR's the flags together.
215  
216  The values are derived from /usr/include/openssl/ssl.h
217  
218  ```
219  # define SSL_OP_NO_TLSv1_1                               0x10000000L
220  ```
221  
222  would equate to
223  
224  ```
225  "`ssl-option-set`": "268435456"
226  ```
227  
228  - "`ssl-option-clear'": "<decimal>"   Clears the SSL option flag value for the vhost.
229  It may be used multiple times and OR's the flags together.
230
231 Mounts
232 ------
233
234 Where mounts are given in the vhost definition, then directory contents may
235 be auto-served if it matches the mountpoint.
236
237 Mount protocols are used to control what kind of translation happens
238
239  - file://  serve the uri using the remainder of the url past the mountpoint based on the origin directory.
240
241  Eg, with this mountpoint
242
243 ```
244        {
245         "mountpoint": "/",
246         "origin": "file:///var/www/mysite.com",
247         "default": "/"
248        }
249 ```
250
251  The uri /file.jpg would serve /var/www/mysite.com/file.jpg, since / matched.
252
253  - ^http:// or ^https://  these cause any url matching the mountpoint to issue a redirect to the origin url
254
255  - cgi://   this causes any matching url to be given to the named cgi, eg
256
257 ```
258        {
259         "mountpoint": "/git",
260         "origin": "cgi:///var/www/cgi-bin/cgit",
261         "default": "/"
262        }, {
263         "mountpoint": "/cgit-data",
264         "origin": "file:///usr/share/cgit",
265         "default": "/"
266        },
267 ```
268
269  would cause the url /git/myrepo to pass "myrepo" to the cgi /var/www/cgi-bin/cgit and send the results to the client.
270
271 Note: currently only a fixed set of mimetypes are supported.
272
273
274 Other mount options
275 -------------------
276
277 1) When using a cgi:// protcol origin at a mountpoint, you may also give cgi environment variables specific to the mountpoint like this
278
279 ```
280        {
281         "mountpoint": "/git",
282         "origin": "cgi:///var/www/cgi-bin/cgit",
283         "default": "/",
284         "cgi-env": [{
285                 "CGIT_CONFIG": "/etc/cgitrc/libwebsockets.org"
286         }]
287        }
288 ```
289
290  This allows you to customize one cgi depending on the mountpoint (and / or vhost).
291
292 2) It's also possible to set the cgi timeout (in secs) per cgi:// mount, like this
293
294 ```
295         "cgi-timeout": "30"
296 ```
297
298 3) `callback://` protocol may be used when defining a mount to associate a
299 named protocol callback with the URL namespace area.  For example
300
301 ```
302        {
303         "mountpoint": "/formtest",
304         "origin": "callback://protocol-post-demo"
305        }
306 ```
307
308 All handling of client access to /formtest[anything] will be passed to the
309 callback registered to the protocol "protocol-post-demo".
310
311 This is useful for handling POST http body content or general non-cgi http
312 payload generation inside a plugin.
313
314 See the related notes in README.coding.md
315
316 4) Cache policy of the files in the mount can also be set.  If no
317 options are given, the content is marked uncacheable.
318
319        {
320         "mountpoint": "/",
321         "origin": "file:///var/www/mysite.com",
322         "cache-max-age": "60",      # seconds
323         "cache-reuse": "1",         # allow reuse at client at all
324         "cache-revalidate": "1",    # check it with server each time
325         "cache-intermediaries": "1" # allow intermediary caches to hold
326        }
327
328
329 4) You can also define a list of additional mimetypes per-mount
330
331         "extra-mimetypes": {
332                  ".zip": "application/zip",
333                  ".doc": "text/evil"
334          }
335
336
337 Plugins
338 -------
339
340 Protcols and extensions may also be provided from "plugins", these are
341 lightweight dynamic libraries.  They are scanned for at init time, and
342 any protocols and extensions found are added to the list given at context
343 creation time.
344
345 Protocols receive init (LWS_CALLBACK_PROTOCOL_INIT) and destruction
346 (LWS_CALLBACK_PROTOCOL_DESTROY) callbacks per-vhost, and there are arrangements
347 they can make per-vhost allocations and get hold of the correct pointer from
348 the wsi at the callback.
349
350 This allows a protocol to choose to strictly segregate data on a per-vhost
351 basis, and also allows the plugin to handle its own initialization and
352 context storage.
353
354 To help that happen conveniently, there are some new apis
355
356  - lws_vhost_get(wsi)
357  - lws_protocol_get(wsi)
358  - lws_callback_on_writable_all_protocol_vhost(vhost, protocol)
359  - lws_protocol_vh_priv_zalloc(vhost, protocol, size)
360  - lws_protocol_vh_priv_get(vhost, protocol)
361  
362 dumb increment, mirror and status protocol plugins are provided as examples.
363
364
365 Additional plugin search paths
366 ------------------------------
367
368 Packages that have their own lws plugins can install them in their own
369 preferred dir and ask lwsws to scan there by using a config fragment
370 like this, in its own conf.d/ file managed by the other package
371
372 {
373   "global": {
374    "plugin-dir": "/usr/local/share/coherent-timeline/plugins"
375   }
376 }
377
378
379 lws-server-status plugin
380 ------------------------
381
382 One provided protocol can be used to monitor the server status.
383
384 Enable the protocol like this on a vhost's ws-protocols section
385
386        "lws-server-status": {
387          "status": "ok",
388          "update-ms": "5000"
389        }
390
391 "update-ms" is used to control how often updated JSON is sent on a ws link.
392
393 And map the provided HTML into the vhost in the mounts section
394
395        {
396         "mountpoint": "/server-status",
397         "origin": "file:///usr/local/share/libwebsockets-test-server/server-status",
398         "default": "server-status.html"
399        }
400
401 You might choose to put it on its own vhost which has "interface": "lo", so it's not
402 externally visible.
403
404
405 Integration with Systemd
406 ------------------------
407
408 lwsws needs a service file like this as `/usr/lib/systemd/system/lwsws.service`
409
410 ```
411 [Unit]
412 Description=Libwebsockets Web Server
413 After=syslog.target
414
415 [Service]
416 ExecStart=/usr/local/bin/lwsws
417 StandardError=null
418
419 [Install]
420 WantedBy=multi-user.target
421
422 ```
423
424 You can find this prepared in `./lwsws/usr-lib-systemd-system-lwsws.service`
425
426
427 Integration with logrotate
428 --------------------------
429
430 For correct operation with logrotate, `/etc/logrotate.d/lwsws` (if that's
431 where we're putting the logs) should contain
432
433 ```
434 /var/log/lwsws/*log {
435     copytruncate
436     missingok
437     notifempty
438     delaycompress
439 }
440 ```
441
442 You can find this prepared in `/lwsws/etc-logrotate.d-lwsws`
443
444 Prepare the log directory like this
445
446 ```
447 sudo mkdir /var/log/lwsws
448 sudo chmod 700 /var/log/lwsws
449 ```