clavarium-relay 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -2
- package/clavarium-relay +282 -0
- package/package.json +4 -6
- package/keep.mjs +0 -5
package/README.md
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
# clavarium-relay
|
|
2
2
|
|
|
3
|
-
The maintenance program of a Clavarium relay
|
|
3
|
+
The maintenance program of a Clavarium relay, a small root program in bash:
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
clavarium-relay status | repair | update-os [--reboot] | update-relay X.Y.Z | rotate-key tunnel|keeper KEY
|
|
6
|
+
|
|
7
|
+
It is installed by `relay.sh` (or by `sudo clavarium online --relay HOST`) as
|
|
8
|
+
`/usr/local/sbin/clavarium-relay`. The home machine reaches it through the
|
|
9
|
+
account `clavarium-keeper`, which may run this program and nothing else.
|
|
10
|
+
|
|
11
|
+
`update-relay` is told a version number only: it fetches this package from the
|
|
12
|
+
npm registry itself and checks the registry's sha512 before installing it.
|
|
6
13
|
|
|
7
14
|
- Site: https://clavarium.org
|
|
8
15
|
- Source: https://github.com/clavarium/clavarium (folder relay/)
|
package/clavarium-relay
ADDED
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ---------------------------------------------------------------------------
|
|
3
|
+
# THE MAINTENANCE PROGRAM OF A CLAVARIUM RELAY. Runs as root, on the relay.
|
|
4
|
+
#
|
|
5
|
+
# clavarium-relay status what is set up, what runs, what is due
|
|
6
|
+
# clavarium-relay repair writes the rules and the port service again
|
|
7
|
+
# clavarium-relay update-os [--reboot] Ubuntu's updates now (and a restart if one is due)
|
|
8
|
+
# clavarium-relay update-relay X.Y.Z this program at exactly that version, from npm
|
|
9
|
+
# clavarium-relay rotate-key tunnel|keeper "ssh-ed25519 AAAA... name"
|
|
10
|
+
# clavarium-relay setup --key LINE [--keeper-key LINE] (relay.sh runs it once)
|
|
11
|
+
# clavarium-relay version
|
|
12
|
+
#
|
|
13
|
+
# WHO RUNS IT. Root, by hand; or the home machine, through the maintenance
|
|
14
|
+
# account "clavarium-keeper": that account's SSH key leads to "door" (below)
|
|
15
|
+
# and nowhere else, and sudo lets it run this one program, nothing else.
|
|
16
|
+
#
|
|
17
|
+
# IT NEVER TAKES CODE FROM THE HOME MACHINE. update-relay is told a version
|
|
18
|
+
# number only; it fetches the package "clavarium-relay" of that version from
|
|
19
|
+
# the npm registry itself, checks it against the registry's sha512, and only
|
|
20
|
+
# then replaces this file.
|
|
21
|
+
#
|
|
22
|
+
# Exit codes: 0 done (status: all is well); 1 something is wrong (said);
|
|
23
|
+
# 64 bad parameters; 78 refused.
|
|
24
|
+
# ---------------------------------------------------------------------------
|
|
25
|
+
set -euo pipefail
|
|
26
|
+
|
|
27
|
+
VERSION_OF_THIS="0.1.0"
|
|
28
|
+
# Tests run it on a folder that stands for "/": nothing outside it is touched.
|
|
29
|
+
ROOT="${CLAVARIUM_RELAY_ROOT:-}"
|
|
30
|
+
REGISTRY="https://registry.npmjs.org"
|
|
31
|
+
[ -z "$ROOT" ] || REGISTRY="${CLAVARIUM_RELAY_REGISTRY:-$REGISTRY}"
|
|
32
|
+
|
|
33
|
+
TUNNEL="clavarium-tunnel"
|
|
34
|
+
KEEPER="clavarium-keeper"
|
|
35
|
+
TLS_PORT="8443"
|
|
36
|
+
HTTP_PORT="8080"
|
|
37
|
+
PROGRAM="/usr/local/sbin/clavarium-relay"
|
|
38
|
+
KEYS="/etc/ssh/clavarium-relay"
|
|
39
|
+
SSHD_FILE="$ROOT/etc/ssh/sshd_config.d/10-clavarium-relay.conf"
|
|
40
|
+
RULES="$ROOT/etc/clavarium-relay.nft"
|
|
41
|
+
UNIT="$ROOT/etc/systemd/system/clavarium-relay-ports.service"
|
|
42
|
+
SUDOERS="$ROOT/etc/sudoers.d/clavarium-relay"
|
|
43
|
+
UPGRADES="$ROOT/etc/apt/apt.conf.d/52clavarium-relay"
|
|
44
|
+
KEY_RE='^ssh-ed25519 [A-Za-z0-9+/]{68}( [A-Za-z0-9@._-]{1,64})?$'
|
|
45
|
+
VERSION_RE='^[0-9]{1,4}\.[0-9]{1,4}\.[0-9]{1,6}(-[0-9A-Za-z.-]{1,40})?$'
|
|
46
|
+
|
|
47
|
+
bad() { echo "clavarium-relay: $*" >&2; echo "usage: clavarium-relay status | repair | update-os [--reboot] | update-relay X.Y.Z | rotate-key tunnel|keeper KEY | version" >&2; exit 64; }
|
|
48
|
+
refuse() { echo "clavarium-relay: REFUSED: $*" >&2; exit 78; }
|
|
49
|
+
as_root() { [ -n "$ROOT" ] || [ "$(id -u)" -eq 0 ] || refuse "run it as root (sudo)"; }
|
|
50
|
+
key_ok() { case "$1" in *"PRIVATE KEY"*) return 1 ;; esac; [[ "$1" =~ $KEY_RE ]]; }
|
|
51
|
+
|
|
52
|
+
# --- fetch_relay: shared, word for word, with deploy/relay.sh (a test says so) ---
|
|
53
|
+
# fetch_relay VERSION DIR: the package clavarium-relay@VERSION from the registry,
|
|
54
|
+
# checked against the registry's sha512, unpacked in DIR (DIR/package/...).
|
|
55
|
+
fetch_relay() {
|
|
56
|
+
local version="$1" dir="$2" meta integrity got proto="=https"
|
|
57
|
+
case "$REGISTRY" in file://*) proto="=file" ;; esac
|
|
58
|
+
meta="$(curl --proto "$proto" -fsSL --max-time 60 "$REGISTRY/clavarium-relay/$version")" || { echo "the registry did not answer for clavarium-relay@$version" >&2; return 1; }
|
|
59
|
+
printf '%s' "$meta" | grep -Eq "\"version\" *: *\"${version//./\\.}\"" || { echo "the registry has no clavarium-relay@$version" >&2; return 1; }
|
|
60
|
+
integrity="$(printf '%s' "$meta" | grep -Eo '"integrity" *: *"sha512-[A-Za-z0-9+/=]+"' | head -1 | sed 's/.*"\(sha512-[^"]*\)"$/\1/')"
|
|
61
|
+
[ -n "$integrity" ] || { echo "the registry gave no sha512 for clavarium-relay@$version" >&2; return 1; }
|
|
62
|
+
curl --proto "$proto" -fsSL --max-time 120 -o "$dir/relay.tgz" "$REGISTRY/clavarium-relay/-/clavarium-relay-$version.tgz" || { echo "the package could not be downloaded" >&2; return 1; }
|
|
63
|
+
got="sha512-$(openssl dgst -sha512 -binary "$dir/relay.tgz" | base64 -w0)"
|
|
64
|
+
[ "$got" = "$integrity" ] || { echo "the package is not the one the registry describes (sha512)" >&2; return 1; }
|
|
65
|
+
tar -xzf "$dir/relay.tgz" -C "$dir" --no-same-owner package/clavarium-relay package/package.json || { echo "the package does not hold the program" >&2; return 1; }
|
|
66
|
+
grep -Eq "\"name\" *: *\"clavarium-relay\"" "$dir/package/package.json" && grep -Eq "\"version\" *: *\"${version//./\\.}\"" "$dir/package/package.json" || { echo "the package is not clavarium-relay@$version" >&2; return 1; }
|
|
67
|
+
bash -n "$dir/package/clavarium-relay" || { echo "the program in the package does not parse" >&2; return 1; }
|
|
68
|
+
}
|
|
69
|
+
# --- end of fetch_relay ---
|
|
70
|
+
|
|
71
|
+
write_key() { # write_key ACCOUNT LINE: the one key of that account, in a file root owns
|
|
72
|
+
local account="$1" key="$2" options
|
|
73
|
+
key_ok "$key" || bad "a key is one line: ssh-ed25519, the key, and optionally a name"
|
|
74
|
+
if [ "$account" = "$TUNNEL" ]; then options="restrict,port-forwarding,permitlisten=\"$TLS_PORT\",permitlisten=\"$HTTP_PORT\""; else options="restrict"; fi
|
|
75
|
+
install -d -m 0755 "$ROOT$KEYS"
|
|
76
|
+
printf '%s %s\n' "$options" "$key" > "$ROOT$KEYS/$account.new"
|
|
77
|
+
chmod 0644 "$ROOT$KEYS/$account.new"
|
|
78
|
+
mv -f -- "$ROOT$KEYS/$account.new" "$ROOT$KEYS/$account"
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
do_repair() {
|
|
82
|
+
as_root
|
|
83
|
+
[ -s "$ROOT$KEYS/$TUNNEL" ] || refuse "this machine has no tunnel key: set it up with relay.sh --key ..."
|
|
84
|
+
export DEBIAN_FRONTEND=noninteractive NEEDRESTART_SUSPEND=1
|
|
85
|
+
local missing=""
|
|
86
|
+
command -v nft >/dev/null 2>&1 || missing="nftables"
|
|
87
|
+
[ -e "$ROOT/usr/bin/unattended-upgrade" ] || missing="$missing unattended-upgrades"
|
|
88
|
+
if [ -n "$missing" ]; then
|
|
89
|
+
# shellcheck disable=SC2086
|
|
90
|
+
apt-get update -qq && apt-get install -y -qq $missing >/dev/null || refuse "could not install:$missing"
|
|
91
|
+
fi
|
|
92
|
+
id "$TUNNEL" >/dev/null 2>&1 || useradd --system --home-dir /nonexistent --no-create-home --shell /usr/sbin/nologin "$TUNNEL"
|
|
93
|
+
# The keeper's commands go through its shell to "door": it needs one, and
|
|
94
|
+
# has no password and no other command.
|
|
95
|
+
if [ -s "$ROOT$KEYS/$KEEPER" ]; then id "$KEEPER" >/dev/null 2>&1 || useradd --system --home-dir /nonexistent --no-create-home --shell /bin/sh "$KEEPER"; fi
|
|
96
|
+
|
|
97
|
+
install -d "$(dirname "$SSHD_FILE")"
|
|
98
|
+
cat > "$SSHD_FILE" <<SSHD
|
|
99
|
+
# Clavarium relay: what its two accounts may do. Written by clavarium-relay.
|
|
100
|
+
Match User $TUNNEL
|
|
101
|
+
AuthorizedKeysFile $KEYS/%u
|
|
102
|
+
PasswordAuthentication no
|
|
103
|
+
KbdInteractiveAuthentication no
|
|
104
|
+
AllowTcpForwarding remote
|
|
105
|
+
GatewayPorts clientspecified
|
|
106
|
+
PermitListen $TLS_PORT $HTTP_PORT
|
|
107
|
+
PermitOpen none
|
|
108
|
+
PermitTTY no
|
|
109
|
+
X11Forwarding no
|
|
110
|
+
AllowAgentForwarding no
|
|
111
|
+
PermitTunnel no
|
|
112
|
+
ForceCommand /bin/false
|
|
113
|
+
# A tunnel that died without saying so gives its ports back within minutes.
|
|
114
|
+
ClientAliveInterval 30
|
|
115
|
+
ClientAliveCountMax 3
|
|
116
|
+
Match User $KEEPER
|
|
117
|
+
AuthorizedKeysFile $KEYS/%u
|
|
118
|
+
PasswordAuthentication no
|
|
119
|
+
KbdInteractiveAuthentication no
|
|
120
|
+
AllowTcpForwarding no
|
|
121
|
+
PermitTTY no
|
|
122
|
+
X11Forwarding no
|
|
123
|
+
AllowAgentForwarding no
|
|
124
|
+
PermitTunnel no
|
|
125
|
+
ForceCommand $PROGRAM door
|
|
126
|
+
# What follows this file in the server's settings is for everybody again.
|
|
127
|
+
Match all
|
|
128
|
+
SSHD
|
|
129
|
+
if ! sshd -t; then rm -f -- "$SSHD_FILE"; refuse "the SSH server refused these settings; they were taken out again"; fi
|
|
130
|
+
systemctl reload ssh.service 2>/dev/null || systemctl reload sshd.service
|
|
131
|
+
|
|
132
|
+
install -d "$(dirname "$SUDOERS")"
|
|
133
|
+
printf '# Clavarium relay: the maintenance account may run ONE program as root.\n%s ALL=(root) NOPASSWD: %s\n' "$KEEPER" "$PROGRAM" > "$SUDOERS.new"
|
|
134
|
+
visudo -cf "$SUDOERS.new" >/dev/null || { rm -f -- "$SUDOERS.new"; refuse "the sudo rule did not pass its check"; }
|
|
135
|
+
chmod 0440 "$SUDOERS.new"; mv -f -- "$SUDOERS.new" "$SUDOERS"
|
|
136
|
+
|
|
137
|
+
cat > "$RULES" <<NFT
|
|
138
|
+
# Clavarium relay: what arrives on 443 and 80 goes to the tunnel. Written by clavarium-relay.
|
|
139
|
+
table inet clavarium_relay
|
|
140
|
+
delete table inet clavarium_relay
|
|
141
|
+
table inet clavarium_relay {
|
|
142
|
+
chain arriving {
|
|
143
|
+
type nat hook prerouting priority dstnat;
|
|
144
|
+
tcp dport 443 redirect to :$TLS_PORT
|
|
145
|
+
tcp dport 80 redirect to :$HTTP_PORT
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
NFT
|
|
149
|
+
install -d "$(dirname "$UNIT")"
|
|
150
|
+
cat > "$UNIT" <<UNITFILE
|
|
151
|
+
[Unit]
|
|
152
|
+
Description=Clavarium relay - 443 and 80 go to the tunnel
|
|
153
|
+
After=network-pre.target
|
|
154
|
+
Before=network.target
|
|
155
|
+
|
|
156
|
+
[Service]
|
|
157
|
+
Type=oneshot
|
|
158
|
+
RemainAfterExit=yes
|
|
159
|
+
ExecStart=/usr/sbin/nft -f /etc/clavarium-relay.nft
|
|
160
|
+
ExecStop=/usr/sbin/nft delete table inet clavarium_relay
|
|
161
|
+
|
|
162
|
+
[Install]
|
|
163
|
+
WantedBy=multi-user.target
|
|
164
|
+
UNITFILE
|
|
165
|
+
systemctl daemon-reload
|
|
166
|
+
systemctl enable --quiet clavarium-relay-ports.service
|
|
167
|
+
systemctl restart clavarium-relay-ports.service
|
|
168
|
+
systemctl is-active --quiet clavarium-relay-ports.service || refuse "the port rule could not be loaded: journalctl -u clavarium-relay-ports"
|
|
169
|
+
|
|
170
|
+
# Ubuntu's security updates, by themselves, every day.
|
|
171
|
+
install -d "$(dirname "$UPGRADES")"
|
|
172
|
+
cat > "$UPGRADES" <<'APT'
|
|
173
|
+
// Clavarium relay: security updates install by themselves. Written by clavarium-relay.
|
|
174
|
+
APT::Periodic::Update-Package-Lists "1";
|
|
175
|
+
APT::Periodic::Unattended-Upgrade "1";
|
|
176
|
+
APT::Periodic::AutocleanInterval "7";
|
|
177
|
+
APT
|
|
178
|
+
systemctl enable --quiet --now unattended-upgrades.service 2>/dev/null || true
|
|
179
|
+
echo "repaired: ssh rules, sudo rule, port rule, automatic updates"
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
do_status() {
|
|
183
|
+
local bad_count=0 line
|
|
184
|
+
say() { printf '%-15s %s\n' "$1" "$2"; }
|
|
185
|
+
check() { if eval "$2"; then say "$1" "${3:-ok}"; else say "$1" "${4:-missing}"; bad_count=$((bad_count + 1)); fi; }
|
|
186
|
+
say version "$VERSION_OF_THIS"
|
|
187
|
+
check tunnel-account "id $TUNNEL >/dev/null 2>&1"
|
|
188
|
+
check tunnel-key "[ -s '$ROOT$KEYS/$TUNNEL' ]"
|
|
189
|
+
check keeper-account "id $KEEPER >/dev/null 2>&1"
|
|
190
|
+
check ssh-rules "[ -s '$SSHD_FILE' ]"
|
|
191
|
+
check sudo-rule "[ -s '$SUDOERS' ]"
|
|
192
|
+
check port-rules "systemctl is-active --quiet clavarium-relay-ports.service" ok "not loaded"
|
|
193
|
+
check os-updates "[ -s '$UPGRADES' ]" automatic off
|
|
194
|
+
line="waiting for home"
|
|
195
|
+
ss -ltnH "sport = :$TLS_PORT" 2>/dev/null | grep -q . && line="connected"
|
|
196
|
+
say tunnel "$line"
|
|
197
|
+
if [ -e "$ROOT/var/run/reboot-required" ]; then say reboot needed; else say reboot no; fi
|
|
198
|
+
[ "$bad_count" -eq 0 ]
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
do_update_os() {
|
|
202
|
+
as_root
|
|
203
|
+
export DEBIAN_FRONTEND=noninteractive NEEDRESTART_SUSPEND=1
|
|
204
|
+
apt-get update -qq
|
|
205
|
+
apt-get -y -qq -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confold upgrade >/dev/null
|
|
206
|
+
apt-get -y -qq autoremove >/dev/null || true
|
|
207
|
+
if [ -e "$ROOT/var/run/reboot-required" ]; then
|
|
208
|
+
if [ "${1:-}" = "--reboot" ]; then echo "updated; restarting now"; systemctl reboot; else echo "updated; a restart is due (update-os --reboot)"; fi
|
|
209
|
+
else echo "updated"; fi
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
do_update_relay() {
|
|
213
|
+
as_root
|
|
214
|
+
local version="${1:-}" dir
|
|
215
|
+
[[ "$version" =~ $VERSION_RE ]] || bad "update-relay takes an exact version, like 0.1.0"
|
|
216
|
+
dir="$(mktemp -d)"
|
|
217
|
+
if ! fetch_relay "$version" "$dir"; then rm -rf -- "$dir"; refuse "clavarium-relay@$version was not installed (above: why); this version stays"; fi
|
|
218
|
+
install -m 0755 "$dir/package/clavarium-relay" "$ROOT$PROGRAM.new"
|
|
219
|
+
mv -f -- "$ROOT$PROGRAM.new" "$ROOT$PROGRAM"
|
|
220
|
+
rm -rf -- "$dir"
|
|
221
|
+
echo "clavarium-relay $version installed"
|
|
222
|
+
# The new version writes its own rules.
|
|
223
|
+
exec "$ROOT$PROGRAM" repair
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
do_rotate_key() {
|
|
227
|
+
as_root
|
|
228
|
+
local who="${1:-}"; shift || true
|
|
229
|
+
local key="$*"
|
|
230
|
+
case "$who" in tunnel) who="$TUNNEL" ;; keeper) who="$KEEPER" ;; *) bad "rotate-key tunnel|keeper KEY" ;; esac
|
|
231
|
+
write_key "$who" "$key"
|
|
232
|
+
echo "the key of $who was replaced"
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
do_setup() {
|
|
236
|
+
as_root
|
|
237
|
+
local key="" keeper=""
|
|
238
|
+
while [ $# -gt 0 ]; do
|
|
239
|
+
case "$1" in
|
|
240
|
+
--key) key="${2:-}"; shift 2 || bad "--key needs a value" ;;
|
|
241
|
+
--keeper-key) keeper="${2:-}"; shift 2 || bad "--keeper-key needs a value" ;;
|
|
242
|
+
*) bad "unknown parameter: $1" ;;
|
|
243
|
+
esac
|
|
244
|
+
done
|
|
245
|
+
write_key "$TUNNEL" "$key"
|
|
246
|
+
[ -z "$keeper" ] || write_key "$KEEPER" "$keeper"
|
|
247
|
+
do_repair
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
# THE DOOR: what the maintenance account's SSH key leads to. It runs as that
|
|
251
|
+
# account, takes the command it was asked for, lets through only the verbs
|
|
252
|
+
# above with parameters of the expected shape, and asks sudo for this program.
|
|
253
|
+
do_door() {
|
|
254
|
+
local -a words
|
|
255
|
+
read -r -a words <<< "${SSH_ORIGINAL_COMMAND:-}"
|
|
256
|
+
local verb="${words[0]:-}"
|
|
257
|
+
local sudo=(sudo -n "$PROGRAM")
|
|
258
|
+
case "$verb" in
|
|
259
|
+
status|repair|version) [ "${#words[@]}" -eq 1 ] || bad "$verb takes nothing"; exec "${sudo[@]}" "$verb" ;;
|
|
260
|
+
update-os) [ "${#words[@]}" -eq 1 ] || { [ "${#words[@]}" -eq 2 ] && [ "${words[1]}" = "--reboot" ]; } || bad "update-os [--reboot]"; exec "${sudo[@]}" "${words[@]}" ;;
|
|
261
|
+
update-relay) [ "${#words[@]}" -eq 2 ] && [[ "${words[1]}" =~ $VERSION_RE ]] || bad "update-relay X.Y.Z"; exec "${sudo[@]}" update-relay "${words[1]}" ;;
|
|
262
|
+
rotate-key)
|
|
263
|
+
case "${words[1]:-}" in tunnel|keeper) : ;; *) bad "rotate-key tunnel|keeper KEY" ;; esac
|
|
264
|
+
local key="${words[*]:2}"
|
|
265
|
+
key_ok "$key" || bad "a key is one line: ssh-ed25519, the key, and optionally a name"
|
|
266
|
+
exec "${sudo[@]}" rotate-key "${words[1]}" "$key" ;;
|
|
267
|
+
*) bad "not a verb of this door: ${verb:-nothing}" ;;
|
|
268
|
+
esac
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
verb="${1:-}"; shift || true
|
|
272
|
+
case "$verb" in
|
|
273
|
+
status) do_status ;;
|
|
274
|
+
repair) do_repair ;;
|
|
275
|
+
update-os) do_update_os "$@" ;;
|
|
276
|
+
update-relay) do_update_relay "$@" ;;
|
|
277
|
+
rotate-key) do_rotate_key "$@" ;;
|
|
278
|
+
setup) do_setup "$@" ;;
|
|
279
|
+
door) do_door ;;
|
|
280
|
+
version|--version) echo "$VERSION_OF_THIS" ;;
|
|
281
|
+
*) bad "unknown verb: ${verb:-none}" ;;
|
|
282
|
+
esac
|
package/package.json
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clavarium-relay",
|
|
3
|
-
"version": "0.0
|
|
4
|
-
"description": "The maintenance program of a Clavarium relay
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "The maintenance program of a Clavarium relay: status, repair, updates, key rotation.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://clavarium.org",
|
|
7
7
|
"repository": { "type": "git", "url": "git+https://github.com/clavarium/clavarium.git", "directory": "relay" },
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"files": ["keep.mjs", "README.md"],
|
|
11
|
-
"dependencies": {},
|
|
8
|
+
"bin": { "clavarium-relay": "clavarium-relay" },
|
|
9
|
+
"files": ["clavarium-relay", "README.md"],
|
|
12
10
|
"publishConfig": { "access": "public" }
|
|
13
11
|
}
|
package/keep.mjs
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/* The relay's maintenance program is not built yet: this version only keeps
|
|
3
|
-
* the name. It runs nothing else, installs nothing and reaches no network. */
|
|
4
|
-
process.stderr.write('clavarium-relay is not built yet: it will be the maintenance program of a Clavarium relay.\nhttps://github.com/clavarium/clavarium\n');
|
|
5
|
-
process.exitCode = 1;
|