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 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348
|
# lcagent - Librecast Multicast Agent

<p>
<a href="https://scan.coverity.com/projects/lcagent">
<img alt="Coverity Scan Build Status"
src="https://scan.coverity.com/projects/31719/badge.svg"/>
</a>
</p>
**lcagent** is the [Librecast](https://librecast.net) multicast agent.
In server mode, lcagent can be configured to listen on Librecast Channels
(multicast groups) and execute programs in response to packet data received on
those Channels.
Packets must be accompanied by an authorized token and signed by the matching
key or they will be silently dropped.
Data is encoded with RaptorQ using Librecast’s [liblcrq](https://librecast.net/lcrq.html)
library to provide forward error correction in the event of packet loss.
Any data received in addition to the required token will be piped to stdin of
the configured commands after they are executed. Multiple commands can be
executed sequentially.
lcagent can be used to send and receive data over multicast and to pipe data
between programs on one computer and as many receivers as the multicast network
can support simultaneously.
lcagent can be used for running CI builds on multiple build servers
simultaneously, triggered by multicasting the patch to all servers. Can also be
useful for monitoring and configuration management etc.
When an agent receives a command, it checks the supplied capability token
against its known trusted authorities before executing the command.
### CI Example
Each time a commit is made to a git repository, a patch can be generated and
sent to lcagent running on different CI test machines. The patch will be
applied and the tests run. This is a simple example, but very complex CI systems
can be set up and controlled in this way.
Example `.lcagentrc`:
```
# this channel will apply a git patch sent to it which was created
# with git-format-patch(1).
# If the patch applies without error, ‘gmake test‘ is run
channel "lcagent patchtest"
directory /home/lcagent/src/lcagent
command "git am --committer-date-is-author-date"
command "gmake test"
```
An example post-commit git hook which can be used to generate a patch suitable
for multicasting to the above Channel:
```
#!/bin/bash -eu
# SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
# Copyright (c) 2025 Brett Sheffield <bacs@librecast.net>
FILE=`git format-patch HEAD~ --base HEAD~`
lcagent send "lcagent patchtest" - < $FILE
exit 0
```
## Options
\-d | \-\-debug
: Enable debug mode to print additional debugging information.
\-\-bpslimit rate[KMGT]
: When sending, this option limits the sending speed to rate. Rate is a
number in bits per second (bps) and can be followed by a capital letter
representing SI units. eg. 100M limits the sending rate to 100 megabits per
second (Mbps).
\-\-expires seconds
: For the sign command, this sets the validity of the token in seconds.
\-f, \-\-follow
: In recv mode, do not stop after first data object received. Keep blocking and
receiving data until interrupted. eg. ˆC is pressed or SIGINT is received by the
process.
\-l, \-\-loopback
: Enable multicast loopback when sending. This will allow packets to be
received by the same host that sent them. By default multicast packets are
not received on the sending host.
\-\-overhead packets
: When sending, this option sets the number of additional repair packets sent to
aid with recovery of lost packets with RaptorQ encoding. Default: 5
\-v, \-\-verbose
: Print more verbose output.
## Commands
### exec
`lcagent exec [options] channel [data] [-]`
The **exec** command executes the commands configured for *channel* locally, without
requiring data to be received over the network.
This is a good way to test the configured commands that will be executed before
making them accessible on the network.
The *nojoin* configuration directive can be used to ensure that a channel is
not network-executable, by preventing lcagent from joining the associated
Librecast channel. See lcagentrc(1).
### help
`lcagent help`
Print some (possibly) helpful instructions for lcagent.
### key
`lcagent key [options] add|del key`
Add or delete a key from the `authorized_keys` file. Packets that do not include
a token signed by a key in the `authorized_keys` file are silently dropped.
### recv
`lcagent recv [options] channel`
Block and wait for data to be received on channel, where channel is a string
that will be hashed to create a Librecast channel.
Data received will be written to stdout. If expecting binary data, be sure to
redirect stdout somewhere appropriate.
By default, once EOF is received from the sender, the program will exit. This
behaviour can be changed by specifying the *\-\-follow* option.
### reload
`lcagent reload [options]`
Reload the lcagent configuration. Sends a SIGHUP to the daemon process. Has
no effect unless lcagent has been started using the start command. Service files
should simply send SIGHUP to the process.
### send
`lcagent send [options] channel [payload] [-]`
Send data to channel, where channel is a string that will be hashed to create a
Librecast channel.
If payload is specified, this string will be sent as data to the channel.
If no payload is specified, an NULL (empty) payload of zero bytes will be sent
to the channel.
A hyphen (-) at the end of the command indicates that the payload should instead
be read from stdin.
### server
`lcagent [server] [options]`
Starting lcagent with no command starts it in server mode. The `.lcagentrc` file
will be parsed and lcagent will join the configured channels and wait for data,
executing the configured commands when packets are received on one of the
configured channels and writing any payload data to `stdin` of the command when
executing it.
See lcagentrc(1) for details of the runtime control (configuration) file.
### sign
`lcagent sign [options] [--expires seconds] bearer_key channel`
Create and sign a token for the given *bearer\_key* and *channel* and write to disk.
The resulting token will be written to a file in the user’s state directory,
and the file pathname will be printed. If the token is copied to the state
directory of the bearer it will be used when sending to channel.
A signed token means that packets sent by the bearer will be accepted by any
receivers on chan‐ nel which have the signer’s key added to their
`authorized_keys` file. Tokens enable delegation of authority, which is
important for scaling. Using pre-signed tokens allows, say, a host to issue
tokens for virtual machines it creates without the need to add individual keys
for every machine to all receivers on the network.
In the absence of a signed token, packets will be sent with a self-signed token,
requiring that all receivers have the sender’s key installed in their
`authorized_keys` file.
If the expires option is supplied, this will be the validity in seconds of the
generated token. A value of zero (0) means that the token will never expire.
By default tokens do not expire.
### start
`lcagent start [options]`
Start lcagent in server mode and fork it as a daemon.
Not intended for use with daemon supervising programs. If you are running
lcagent as a service, just start lcagent with no command and let the init
system or daemon supervisor handle forking and pidfiles. If you are NOT running
lcagent as a service and want it to daemonize, use this command.
### stop
`lcagent stop [options]`
Stop the lcagent daemon. Has no effect unless lcagent has been started using
the start com‐ mand. Sends SIGINT to the running daemon process.
### version
`lcagent version`
Print the version of lcagent and exit.
### whoami
`lcagent whoami [options]`
Print the active key to stdout and exit. This key can be added to the `authorized_keys` file of
another host with:
`lcagent key add key`
## Configuration
See [lcagentrc](doc/lcagentrc.5.md) for details of the rcfile format.
## Mailing List
Join the low-traffic Librecast announce mailing list to stay up to date on
Librecast related news:
https://lists.sr.ht/~librecast
## Supported Systems
lcagent and its Librecast dependencies are expected to build and run on:
- GNU/Linux (any distribution)
- FreeBSD
- NetBSD
- OpenBSD
If you encounter problems building or running on these systems, please send a
bug report. See *Bugs*.
If you get lcagent running on something else, please drop us an email and let us
know.
We'd love to know what you are using lcagent for and any feedback you have.
## Dependencies
**lcagent** requires liblibrecast (>= 0.11) to be installed and configured with liblcrq (>= 0.2.4)
and libsodium.
You will also need a C toolchain (lcagent is tested with gcc and clang). gnumake
is required on \*BSD systems (sorry).
Additional build dependencies:
- flex
- bison
- gmake
## Obtaining the source
lcagent (and the Librecast dependencies liblcrq and liblibrecast) can be
downloaded from Codeberg or SourceHut:
- https://codeberg.org/librecast/lcagent
- https://git.sr.ht/~librecast/lcagent
## Installation
```
git clone https://git.sr.ht/~librecast/lcagent
cd lcagent
./configure
make
make test
make install
```
## Files
˜/.lcagentrc
: This is the runtime control file for lcagent. This is where global settings,
channels and commands are defined that affect the runtime operation of the
program. See lcagentrc(5) for more information.
˜/.local/state/lcagent/authorized\_keys
: This file contains the keys which are authorized to issue tokens which will be
accepted by the program when receiving data. One key is stored per line. It
can be managed with the lcagent key command.
## Security
Authenticity of data received is established by checking that each packet
received contains a token signed by an authority with their public key
installed in the `authorized_keys` file. If the token is valid, the packet must be
signed by the bearer key contained in the token.
Cryptographic signatures use the Ed25519ph algorithm provided by the libsodium library.
Data can be encrypted using the seed configuration directive in `.lcagentrc`. See [lcagentrc(5)](doc/lcagentrc.5.md).
The symmetric encryption key is generated from seed using BLAKE2b.
Symmetric encryption uses the XSalsa20 stream cipher from libsodium using a
Poly1305 MAC for authentication and random nonce.
If an encryption seed is used, the permissions for the rcfile must not be
world readable or lcagent will refuse to run and print an error.
## License
GPLv2 or (at your option) GPLv3
## Bugs
If you find one, email bugs@librecast.net or raise an issue in our online
bug tracker at: https://bugs.librecast.net/lcagent including as much relevant
information as you can.
## See Also
- [lcagent(1)](doc/lcagent.1.md)
- [lcagentrc(5)](doc/lcagentrc.5.md)
## Funding
This project was funded through [NGI Zero Core](https://nlnet.nl/core) and [NGI Assure](https://nlnet.nl/assure), funds established by [NLnet](https://nlnet.nl) with financial support from the European Commission's [Next Generation Internet](https://ngi.eu) program. Learn more at the [NLnet project page](https://nlnet.nl/project/Librecast-OverlayMulticast).
[<img src="https://nlnet.nl/logo/banner.png" alt="NLnet foundation logo" width="20%" align="left"/>](https://nlnet.nl)
[<img src="https://nlnet.nl/image/logos/NGI0Core_tag.svg" alt="NGI Zero Core Logo" width="20%" align="right"/>](https://nlnet.nl/core/)
|