コミットを比較
3 コミット
3733a213f0
...
7939362ef1
作成者 | SHA1 | 日付 |
---|---|---|
n9k | 7939362ef1 | |
n9k | 5d42b1470a | |
n9k | 97f42a132b |
|
@ -0,0 +1,61 @@
|
|||
## Configuration
|
||||
|
||||
This file documents all configuration options in [/config.toml][config]
|
||||
|
||||
### Secret key
|
||||
|
||||
The `secret_key` is used for cryptography. It can be any string, but should be
|
||||
one with a cryptographically secure amount of entropy. This command generates a
|
||||
128-bit secret key which is sufficient:
|
||||
```sh
|
||||
dd if=/dev/urandom bs=16 count=1 | base64
|
||||
```
|
||||
|
||||
Using a weak secret key has these practical consequences:
|
||||
* Tripcode algorithm becomes bruteforceable. This allows anyone to generate
|
||||
vanity tripcodes and it allows weak passwords to be cracked.
|
||||
* Token hashes become bruteforceable. Not a problem for tokens generated by
|
||||
us, but tokens are not authenticated (manually chosen tokens are allowed).
|
||||
A maually chosen low-entropy token could be cracked which allows
|
||||
impersonation.
|
||||
|
||||
### Sockets
|
||||
|
||||
The keys in this section are for the API sockets: the control socket and the
|
||||
event socket. See [/HACKING.md][hacking] for details about them.
|
||||
|
||||
| Option | Type | Explanation
|
||||
|--------------------------|------|----------------------------|
|
||||
| `socket.control.enabled` | bool | Enables the control socket |
|
||||
| `socket.control.address` | path | Path of the control socket |
|
||||
| `socket.event.enabled` | bool | Enables the event socket |
|
||||
| `socket.event.address` | path | Path of the event socket |
|
||||
|
||||
### Auth
|
||||
|
||||
The `auth.username` option is the username the broadcaster logs in as. It can
|
||||
be any string.
|
||||
|
||||
### Segments
|
||||
|
||||
| Option | Type | Explanation
|
||||
|--------------------------|------|----------------------------|
|
||||
| `segments.directory` | path | Search for stream segments in this directory |
|
||||
| `segments.playlist` | path | Path of the control socket |
|
||||
| `segments.playlist_stale_threshold` | bool | Enables the event socket |
|
||||
| `segments.playlist_cache_lifetime` | path | Path of the event socket |
|
||||
| `segments.search_cooldown` | path | Path of the event socket |
|
||||
| `segments.search_timeout` | path | Path of the event socket |
|
||||
| `segments.stream_initial_buffer` | path | Path of the event socket |
|
||||
|
||||
### Title
|
||||
|
||||
| Option | Type | Explanation
|
||||
|--------------------------|------|----------------------------|
|
||||
| `socket.control.enabled` | bool | Enables the control socket |
|
||||
| `socket.control.address` | path | Path of the control socket |
|
||||
| `socket.event.enabled` | bool | Enables the event socket |
|
||||
| `socket.event.address` | path | Path of the event socket |
|
||||
|
||||
config: https://git.076.ne.jp/ninya9k/anonstream/src/branch/master/config.toml
|
||||
hacking: https://git.076.ne.jp/ninya9k/anonstream/src/branch/master/HACKING.md
|
|
@ -14,13 +14,12 @@ comprehensive; you could craft commands that lead to undefined
|
|||
behaviour. If you have `socat`, you can use the control socket
|
||||
interactively like this:
|
||||
```sh
|
||||
rlwrap socat STDIN UNIX-CONNECT:control.sock
|
||||
```
|
||||
`rlwrap` only adds line editing and is optional. If you don't have it
|
||||
you can still get (inferior) line editing by doing:
|
||||
```sh
|
||||
socat READLINE UNIX-CONNECT:control.sock
|
||||
```
|
||||
If you have it, you can use `rlwrap` to get line editing that's a bit nicer:
|
||||
```sh
|
||||
rlwrap socat STDIN UNIX-CONNECT:control.sock
|
||||
```
|
||||
Once connected, type "help" and press enter to get a list of commands.
|
||||
|
||||
### Event socket
|
||||
|
|
10
README.md
10
README.md
|
@ -29,14 +29,14 @@ source venv/bin/activate
|
|||
python -m pip install -r requirements.txt
|
||||
```
|
||||
|
||||
Before you run it you may want to edit the config ([/config.toml][config]).
|
||||
Most of the defaults are probably okay, but here are some that you might want
|
||||
to know what they do:
|
||||
This is all the setup needed to run the application, but before you do you may
|
||||
want to edit the config ([/config.toml][config]). Most of the defaults are
|
||||
probably okay, but here are some that you might want to know what they do:
|
||||
|
||||
* `secret_key`:
|
||||
used for cryptography, make it any long random string (e.g.
|
||||
`$ dd if=/dev/urandom bs=16 count=1 | base64`), definitely set this
|
||||
yourself before running in "production" (whatever that is for you)
|
||||
`$ dd if=/dev/urandom bs=16 count=1 | base64`); set this
|
||||
before running in "production"
|
||||
|
||||
* `segments/directory`:
|
||||
directory containing stream segments, the default is `stream/` in
|
||||
|
|
34
config.toml
34
config.toml
|
@ -1,16 +1,9 @@
|
|||
# Configuration file for anonstream
|
||||
# Last updated 19 June 2022 for anonstream 1.2.3
|
||||
|
||||
|
||||
secret_key = "place secret key here"
|
||||
|
||||
[socket.control]
|
||||
enabled = true
|
||||
address = "control.sock"
|
||||
|
||||
[socket.event]
|
||||
enabled = true
|
||||
address = "event.sock"
|
||||
|
||||
[auth]
|
||||
username = "broadcaster"
|
||||
|
||||
[segments]
|
||||
directory = "stream/"
|
||||
playlist = "stream.m3u8"
|
||||
|
@ -20,6 +13,9 @@ search_cooldown = 0.25
|
|||
search_timeout = 5.0
|
||||
stream_initial_buffer = 3
|
||||
|
||||
[auth]
|
||||
username = "broadcaster"
|
||||
|
||||
[title]
|
||||
file = "title.txt"
|
||||
file_cache_lifetime = 0.5
|
||||
|
@ -27,6 +23,18 @@ file_cache_lifetime = 0.5
|
|||
[access]
|
||||
captcha = true
|
||||
|
||||
[socket.control]
|
||||
enabled = true
|
||||
address = "control.sock"
|
||||
|
||||
[socket.event]
|
||||
enabled = true
|
||||
address = "event.sock"
|
||||
|
||||
[names]
|
||||
broadcaster = "Broadcaster"
|
||||
anonymous = "Anonymous"
|
||||
|
||||
[captcha]
|
||||
lifetime = 1800
|
||||
fonts = []
|
||||
|
@ -51,10 +59,6 @@ broadcast_ping = 8.0
|
|||
broadcast_users_update = 4.0
|
||||
broadcast_stream_info_update = 3.0
|
||||
|
||||
[names]
|
||||
broadcaster = "Broadcaster"
|
||||
anonymous = "Anonymous"
|
||||
|
||||
[chat]
|
||||
max_comment_length = 512
|
||||
max_comment_lines = 12
|
||||
|
|
|
@ -0,0 +1,159 @@
|
|||
segments.directory
|
||||
path
|
||||
Search for stream segments in this directory
|
||||
|
||||
segments.playlist
|
||||
path
|
||||
M3U8-format file listing segments considered "live". `ffmpeg` generates this for you.
|
||||
|
||||
segments.playlist_stale_threshold
|
||||
duration
|
||||
If the playlist is not modified for this amount of time (according to the filesystem), consider the stream offline.
|
||||
|
||||
segments.playlist_cache_lifetime
|
||||
duration
|
||||
After reading the playlist, do not read it again for at least this amount of time. Instead use a cached copy.
|
||||
|
||||
segments.search_cooldown
|
||||
duration
|
||||
After listing the segments directory, do not list it again for this amount of time. Instead use a cached copy.
|
||||
|
||||
segments.search_timeout
|
||||
duration
|
||||
If no new segment appears in the segments directory for this amount of time, end the current HTTP response.
|
||||
|
||||
segments.stream_initial_buffer
|
||||
positive integer
|
||||
Upon starting a new video response, instead of at first sending the most recent segment, send the most recent n segments, where n is this number. If there aren't that many segments yet, send as many as possible. Increasing this makes playback more stable at the cost of latency.
|
||||
|
||||
title.file
|
||||
path
|
||||
The stream title is stored in this file.
|
||||
|
||||
title.file_cache_lifetime
|
||||
duration
|
||||
After reading the title, do not read the title again for at least this amount of time. Instead use a cached value.
|
||||
|
||||
captcha.lifetime
|
||||
duration
|
||||
Invalidate captchas after this amount of time. Invalid captchas will eventually be deleted by a background task.
|
||||
|
||||
captcha.fonts
|
||||
list of paths
|
||||
Use these fonts to draw captchas.
|
||||
|
||||
captcha.alphabet
|
||||
string
|
||||
Use these characters in captchas.
|
||||
|
||||
captcha.length
|
||||
positif integer
|
||||
Use exactly this many chacters in a captcha.
|
||||
|
||||
captcha.background_color
|
||||
CSS 6-hex colour
|
||||
Use this colour for the background of captchas.
|
||||
|
||||
captcha.foreground_color
|
||||
CSS 6-hex colour
|
||||
Use this colour for text in captchas.
|
||||
|
||||
memory.states
|
||||
positif integer
|
||||
Store at most this number of states for any user. States are used for clients without JavaScript to temporarily store information created during the processing of a POST request, to be retrieved by the client on a subsequent GET request. This allows the POST->redirect HTTP pattern. States store information like the reason a comment wasn't submitted, or the statement that the user's appearance was changed.
|
||||
|
||||
memory.captchas
|
||||
positif integer
|
||||
Store at most this number of captchas.
|
||||
|
||||
memory.chat_messages
|
||||
positif integer
|
||||
Keep this many chat messages. If adding a new message would exceed this limit, delete the oldest message.
|
||||
|
||||
memory.chat_scrollback
|
||||
positif integer
|
||||
Send this many chat messages to clients. JavaScript-enabled clients will delete old messages beyond this limit.
|
||||
|
||||
tasks.rotate_eyes
|
||||
interval
|
||||
Check if eyes have expired and delete the ones that have, at this interval. Eyes are a concept used to permission video responses. There is a bijection between eyes and video responses. Eyes are renewed just before a segment is sent. If eyes are not renewed, they will expire and the respective video response will end.
|
||||
|
||||
tasks.rotate_users
|
||||
interval
|
||||
Delete absent users at this interval. Users who have left messages are not deleted.
|
||||
|
||||
tasks.rotate_captchas
|
||||
interval
|
||||
Delete expired captchas at this interval.
|
||||
|
||||
tasks.rotate_websockets
|
||||
interval
|
||||
Close unresponsive websockets at this interval. Websockets are considered unresponsive if they do not pong pings after a certain threshold, currently equal to `tasks.broadcast_ping * 1.5 + 4.0`.
|
||||
|
||||
tasks.broadcast_ping
|
||||
interval
|
||||
Broadcast a ping to all websockets at this interval. Websockets are expected to pong upon receiving a ping, and if one does not for a certain amount of time (see above) it is considered unresponsive and is closed.
|
||||
|
||||
tasks.broadcast_users_update
|
||||
interval
|
||||
Broadcast buffered changes to users to all websockets at this interval. Changes to users are buffered and sent at a constant rate to prevent denial of service. if no changes are buffered, nothing is sent.
|
||||
|
||||
tasks.broadcast_stream_info_update
|
||||
interval
|
||||
Broadcast the stream title, uptime, and number of viewers to all sockets at this interval. Only values that have changed unpredictably are sent. If this is no values, nothing is sent.
|
||||
|
||||
names.broadcaster
|
||||
string
|
||||
The default name of the broadcaster.
|
||||
|
||||
names.anonymous
|
||||
string
|
||||
The default name of any user who isn't the broadcaster.
|
||||
|
||||
flood.messages.duration
|
||||
duration
|
||||
If a user sends `flood.messages.threshold` messages within `flood.messages.duration` seconds, require them to solve a captcha before sending another message.
|
||||
|
||||
flood.messages.threshold
|
||||
positif integer
|
||||
XXX
|
||||
|
||||
flood.lines.duration
|
||||
duration
|
||||
If a user sends `flood.lines.threshold` lines within `flood.lines.duration` seconds, block them from sending messages until the condition is no longer true.
|
||||
|
||||
flood.lines.threshold
|
||||
duration
|
||||
XXX
|
||||
|
||||
flood.video.max_eyes
|
||||
positif integer
|
||||
Ensure the number of eyes any user has never exceeds this. How this is carried out depends on `flood.video.overwrite`.
|
||||
|
||||
flood.video.cooldown
|
||||
duration
|
||||
After a user creates eyes, do not let them create more eyes for at least this duration. "Creating eyes" means starting a new video response. During this cooldown period, requests for video will be responded with 429 Too Many Requests.
|
||||
|
||||
flood.video.expire_after
|
||||
duration
|
||||
If eyes are not renewed for at least this duration, consider them expired. Expired eyes are deleted upon discovery.
|
||||
|
||||
flood.video.overwrite
|
||||
bool
|
||||
Controls what happens when the user tries to create new eyes when they are at the maximum. If true, allow the new eyes to be created and delete the oldest exising eyes. If false, do not allow new eyes to be created. In the second case requests for video will be responded wil 429 Too Many Requests.
|
||||
|
||||
thresholds.user_notwatching
|
||||
duration
|
||||
If a user has not been sent a stream segment for this amount of time, consider them not watching. The "presence" of a user is one of these four values: watching, not watching, tentative, absent.
|
||||
|
||||
thresholds.user_tentative
|
||||
duration
|
||||
If a user has not communicated with the server for this amount of time, consider them tentative. This must be greater than or equal to `thresholds.user_notwatching`. Tenative users are not shown in the list of users.
|
||||
|
||||
thresholds.user_absent
|
||||
duration
|
||||
If a user has not communicated with the server for this amount of time, consider them absent. Absent users are deleted by a background task.
|
||||
|
||||
thresholds.nojs_chat_timeout
|
||||
duration
|
||||
If the chat iframes have not refreshed within this amount of time, show a timeout banner.
|
読み込み中…
新しいイシューから参照