@le-space/rootfs 0.1.4 → 0.1.6
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/index.js +17 -3
- package/package.json +1 -1
- package/reference/uc-go-peer/contract.json +58 -0
- package/reference/uc-go-peer/rootfs/Dockerfile.rootfs +24 -0
- package/reference/uc-go-peer/rootfs/build-rootfs-image.sh +94 -0
- package/reference/uc-go-peer/rootfs/build-rootfs.sh +490 -0
- package/reference/uc-go-peer/rootfs/read-rootfs-contract.py +72 -0
- package/reference/uc-go-peer/rootfs/uc-go-peer-autotls-refresh.py +144 -0
- package/reference/uc-go-peer/rootfs/uc-go-peer-autotls-refresh.service +23 -0
- package/reference/uc-go-peer/rootfs/uc-go-peer-bootstrap.service +17 -0
- package/reference/uc-go-peer/rootfs/uc-go-peer-bootstrap.sh +118 -0
- package/reference/uc-go-peer/rootfs/uc-go-peer-configure.sh +204 -0
- package/reference/uc-go-peer/rootfs/uc-go-peer-describe.py +195 -0
- package/reference/uc-go-peer/rootfs/uc-go-peer-setup-server.py +221 -0
- package/reference/uc-go-peer/rootfs/uc-go-peer.service +19 -0
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
import os
|
|
3
|
+
import re
|
|
4
|
+
import subprocess
|
|
5
|
+
import time
|
|
6
|
+
from typing import Iterable
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
ENV_FILE = os.environ.get("ENV_FILE", "/etc/default/uc-go-peer")
|
|
10
|
+
READY_FILE = os.environ.get("READY_FILE", "/etc/default/uc-go-peer.ready")
|
|
11
|
+
AUTOTLS_READY_FILE = os.environ.get("AUTOTLS_READY_FILE", "/etc/default/uc-go-peer.autotls-ready")
|
|
12
|
+
AUTOTLS_ZONE_FILE = os.environ.get("AUTOTLS_ZONE_FILE", "/etc/default/uc-go-peer.autotls-zone")
|
|
13
|
+
AUTOTLS_HOSTS_FILE = os.environ.get("AUTOTLS_HOSTS_FILE", "/etc/default/uc-go-peer.autotls-hosts")
|
|
14
|
+
SERVICE_NAME = os.environ.get("SERVICE_NAME", "uc-go-peer.service")
|
|
15
|
+
WAIT_TIMEOUT_SECONDS = int(os.environ.get("AUTOTLS_WAIT_TIMEOUT_SECONDS", "900"))
|
|
16
|
+
WAIT_INTERVAL_SECONDS = float(os.environ.get("AUTOTLS_WAIT_INTERVAL_SECONDS", "5"))
|
|
17
|
+
WS_BACKEND_PORT = os.environ.get("WS_BACKEND_PORT", "9097").strip()
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def parse_env_file(path: str) -> dict[str, str]:
|
|
21
|
+
values: dict[str, str] = {}
|
|
22
|
+
if not os.path.exists(path):
|
|
23
|
+
return values
|
|
24
|
+
|
|
25
|
+
with open(path, encoding="utf-8") as handle:
|
|
26
|
+
for line in handle:
|
|
27
|
+
stripped = line.strip()
|
|
28
|
+
if not stripped or stripped.startswith("#") or "=" not in stripped:
|
|
29
|
+
continue
|
|
30
|
+
key, value = stripped.split("=", 1)
|
|
31
|
+
values[key.strip()] = value.strip()
|
|
32
|
+
return values
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def write_env_var(path: str, key: str, value: str) -> None:
|
|
36
|
+
lines: list[str] = []
|
|
37
|
+
replaced = False
|
|
38
|
+
|
|
39
|
+
if os.path.exists(path):
|
|
40
|
+
with open(path, encoding="utf-8") as handle:
|
|
41
|
+
lines = handle.readlines()
|
|
42
|
+
|
|
43
|
+
with open(path, "w", encoding="utf-8") as handle:
|
|
44
|
+
for line in lines:
|
|
45
|
+
stripped = line.lstrip()
|
|
46
|
+
if stripped.startswith(f"{key}=") or stripped.startswith(f"#{key}="):
|
|
47
|
+
handle.write(f"{key}={value}\n")
|
|
48
|
+
replaced = True
|
|
49
|
+
else:
|
|
50
|
+
handle.write(line)
|
|
51
|
+
|
|
52
|
+
if not replaced:
|
|
53
|
+
handle.write(f"{key}={value}\n")
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def dedupe(sequence: Iterable[str]) -> list[str]:
|
|
57
|
+
seen: set[str] = set()
|
|
58
|
+
values: list[str] = []
|
|
59
|
+
for item in sequence:
|
|
60
|
+
if item and item not in seen:
|
|
61
|
+
seen.add(item)
|
|
62
|
+
values.append(item)
|
|
63
|
+
return values
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def wait_for_exact_hosts(ws_port: str) -> tuple[str, list[str], list[str]]:
|
|
67
|
+
deadline = time.monotonic() + WAIT_TIMEOUT_SECONDS
|
|
68
|
+
regex = re.compile(rf"(/(?:ip4|ip6)/[^ ]+/tcp/{re.escape(ws_port)}/tls/sni/([^/]+)/ws)")
|
|
69
|
+
zone_regex = re.compile(r'identifier": "\\*\.([^"]+)"')
|
|
70
|
+
last_error = "AutoTLS websocket hostnames not advertised yet"
|
|
71
|
+
|
|
72
|
+
while time.monotonic() < deadline:
|
|
73
|
+
result = subprocess.run(
|
|
74
|
+
["journalctl", "-u", SERVICE_NAME, "-n", "400", "--no-pager"],
|
|
75
|
+
capture_output=True,
|
|
76
|
+
text=True,
|
|
77
|
+
check=False,
|
|
78
|
+
)
|
|
79
|
+
output = result.stdout
|
|
80
|
+
pairs = regex.findall(output)
|
|
81
|
+
addrs = dedupe([pair[0] for pair in pairs])
|
|
82
|
+
hosts = dedupe([pair[1] for pair in pairs])
|
|
83
|
+
zone_match = zone_regex.search(output)
|
|
84
|
+
zone = zone_match.group(1) if zone_match else ""
|
|
85
|
+
if zone and hosts:
|
|
86
|
+
return zone, hosts, addrs
|
|
87
|
+
if hosts:
|
|
88
|
+
return "", hosts, addrs
|
|
89
|
+
if result.stderr.strip():
|
|
90
|
+
last_error = result.stderr.strip()
|
|
91
|
+
time.sleep(WAIT_INTERVAL_SECONDS)
|
|
92
|
+
|
|
93
|
+
raise RuntimeError(last_error)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def main() -> None:
|
|
97
|
+
if not os.path.exists(READY_FILE):
|
|
98
|
+
raise SystemExit(f"missing ready file: {READY_FILE}")
|
|
99
|
+
|
|
100
|
+
env_values = parse_env_file(ENV_FILE)
|
|
101
|
+
ws_port = env_values.get("GO_PEER_WSS_PORT", "").strip() or WS_BACKEND_PORT
|
|
102
|
+
if not ws_port:
|
|
103
|
+
raise RuntimeError("missing GO_PEER_WSS_PORT in environment file")
|
|
104
|
+
|
|
105
|
+
proxy_hostname = env_values.get("PROXY_HOSTNAME", "").strip()
|
|
106
|
+
|
|
107
|
+
zone, exact_hosts, exact_logged_addrs = wait_for_exact_hosts(ws_port)
|
|
108
|
+
if not exact_hosts:
|
|
109
|
+
raise RuntimeError("no AutoTLS websocket hostnames found in logs")
|
|
110
|
+
|
|
111
|
+
existing = [entry.strip() for entry in env_values.get("LIBP2P_ANNOUNCE_ADDRS", "").split(",") if entry.strip()]
|
|
112
|
+
wildcard_filtered = [entry for entry in existing if "/tls/sni/*." not in entry]
|
|
113
|
+
exact_announces: list[str] = list(exact_logged_addrs)
|
|
114
|
+
|
|
115
|
+
if proxy_hostname:
|
|
116
|
+
exact_announces.append(f"/dns4/{proxy_hostname}/tcp/443/tls/ws")
|
|
117
|
+
exact_announces.append(f"/dns6/{proxy_hostname}/tcp/443/tls/ws")
|
|
118
|
+
|
|
119
|
+
merged = dedupe(wildcard_filtered + exact_announces)
|
|
120
|
+
announce_value = ",".join(merged)
|
|
121
|
+
write_env_var(ENV_FILE, "LIBP2P_ANNOUNCE_ADDRS", announce_value)
|
|
122
|
+
if zone:
|
|
123
|
+
write_env_var(ENV_FILE, "AUTOTLS_SERVING_ZONE", zone)
|
|
124
|
+
|
|
125
|
+
with open(AUTOTLS_HOSTS_FILE, "w", encoding="utf-8") as handle:
|
|
126
|
+
for host in exact_hosts:
|
|
127
|
+
handle.write(f"{host}\n")
|
|
128
|
+
if zone:
|
|
129
|
+
with open(AUTOTLS_ZONE_FILE, "w", encoding="utf-8") as handle:
|
|
130
|
+
handle.write(f"{zone}\n")
|
|
131
|
+
|
|
132
|
+
service_restarted = False
|
|
133
|
+
if env_values.get("LIBP2P_ANNOUNCE_ADDRS", "") != announce_value:
|
|
134
|
+
subprocess.run(["systemctl", "restart", SERVICE_NAME], check=True)
|
|
135
|
+
service_restarted = True
|
|
136
|
+
|
|
137
|
+
open(AUTOTLS_READY_FILE, "a", encoding="utf-8").close()
|
|
138
|
+
print(f"Updated LIBP2P_ANNOUNCE_ADDRS={announce_value}")
|
|
139
|
+
if service_restarted:
|
|
140
|
+
print(f"Restarted {SERVICE_NAME} after AutoTLS hostname refresh")
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
if __name__ == "__main__":
|
|
144
|
+
main()
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
[Unit]
|
|
2
|
+
Description=Persist AutoTLS secure announce addresses for uc-go-peer
|
|
3
|
+
After=uc-go-peer.service
|
|
4
|
+
Wants=uc-go-peer.service
|
|
5
|
+
ConditionPathExists=/etc/default/uc-go-peer.ready
|
|
6
|
+
ConditionPathExists=!/etc/default/uc-go-peer.autotls-ready
|
|
7
|
+
|
|
8
|
+
[Service]
|
|
9
|
+
Type=oneshot
|
|
10
|
+
Environment=ENV_FILE=/etc/default/uc-go-peer
|
|
11
|
+
Environment=READY_FILE=/etc/default/uc-go-peer.ready
|
|
12
|
+
Environment=AUTOTLS_READY_FILE=/etc/default/uc-go-peer.autotls-ready
|
|
13
|
+
Environment=AUTOTLS_ZONE_FILE=/etc/default/uc-go-peer.autotls-zone
|
|
14
|
+
Environment=AUTOTLS_HOSTS_FILE=/etc/default/uc-go-peer.autotls-hosts
|
|
15
|
+
Environment=AUTOTLS_CADDY_READY_FILE=/etc/default/uc-go-peer.caddy-ready
|
|
16
|
+
Environment=SERVICE_NAME=uc-go-peer.service
|
|
17
|
+
Environment=WS_BACKEND_PORT=9097
|
|
18
|
+
ExecStart=/usr/bin/python3 /usr/local/sbin/uc-go-peer-autotls-refresh.py
|
|
19
|
+
StandardOutput=journal
|
|
20
|
+
StandardError=journal
|
|
21
|
+
|
|
22
|
+
[Install]
|
|
23
|
+
WantedBy=multi-user.target
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
[Unit]
|
|
2
|
+
Description=Temporary universal-connectivity go-peer setup endpoint
|
|
3
|
+
Wants=network-online.target
|
|
4
|
+
After=network-online.target
|
|
5
|
+
ConditionPathExists=!/etc/default/uc-go-peer.ready
|
|
6
|
+
|
|
7
|
+
[Service]
|
|
8
|
+
Environment=ENV_FILE=/etc/default/uc-go-peer
|
|
9
|
+
Environment=READY_FILE=/etc/default/uc-go-peer.ready
|
|
10
|
+
ExecStart=/usr/bin/python3 /usr/local/sbin/uc-go-peer-setup-server.py
|
|
11
|
+
StandardOutput=journal
|
|
12
|
+
StandardError=journal
|
|
13
|
+
Restart=on-failure
|
|
14
|
+
RestartSec=2s
|
|
15
|
+
|
|
16
|
+
[Install]
|
|
17
|
+
WantedBy=multi-user.target
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
set -x
|
|
4
|
+
|
|
5
|
+
INSTALL_DIR="${INSTALL_DIR:-/opt/go-peer}"
|
|
6
|
+
SERVICE_USER="${SERVICE_USER:-uc-go-peer}"
|
|
7
|
+
DATA_DIR="${DATA_DIR:-/var/lib/uc-go-peer}"
|
|
8
|
+
ENV_FILE="${ENV_FILE:-/etc/default/uc-go-peer}"
|
|
9
|
+
READY_FILE="${READY_FILE:-/etc/default/uc-go-peer.ready}"
|
|
10
|
+
AUTOTLS_READY_FILE="${AUTOTLS_READY_FILE:-/etc/default/uc-go-peer.autotls-ready}"
|
|
11
|
+
AUTOTLS_ZONE_FILE="${AUTOTLS_ZONE_FILE:-/etc/default/uc-go-peer.autotls-zone}"
|
|
12
|
+
AUTOTLS_HOSTS_FILE="${AUTOTLS_HOSTS_FILE:-/etc/default/uc-go-peer.autotls-hosts}"
|
|
13
|
+
AUTOTLS_CADDY_READY_FILE="${AUTOTLS_CADDY_READY_FILE:-/etc/default/uc-go-peer.caddy-ready}"
|
|
14
|
+
APP_BINARY="${APP_BINARY:-/usr/local/bin/universal-chat-go}"
|
|
15
|
+
PHASE="${1:-all}"
|
|
16
|
+
|
|
17
|
+
if [ ! -d "${INSTALL_DIR}" ]; then
|
|
18
|
+
echo "Missing ${INSTALL_DIR}; the rootfs build did not create the relay support directory."
|
|
19
|
+
exit 1
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
echo "[uc-go-peer-bootstrap] starting"
|
|
23
|
+
echo "[uc-go-peer-bootstrap] support dir: ${INSTALL_DIR}"
|
|
24
|
+
echo "[uc-go-peer-bootstrap] data dir: ${DATA_DIR}"
|
|
25
|
+
echo "[uc-go-peer-bootstrap] env file: ${ENV_FILE}"
|
|
26
|
+
echo "[uc-go-peer-bootstrap] app binary: ${APP_BINARY}"
|
|
27
|
+
|
|
28
|
+
run_phase_base() {
|
|
29
|
+
export DEBIAN_FRONTEND=noninteractive
|
|
30
|
+
echo "[uc-go-peer-bootstrap] phase=base"
|
|
31
|
+
echo "[uc-go-peer-bootstrap] running apt-get update"
|
|
32
|
+
apt-get update
|
|
33
|
+
echo "[uc-go-peer-bootstrap] installing base packages"
|
|
34
|
+
apt-get install -y ca-certificates curl caddy
|
|
35
|
+
rm -rf /var/lib/apt/lists/*
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
run_phase_build() {
|
|
39
|
+
echo "[uc-go-peer-bootstrap] phase=build"
|
|
40
|
+
if [ ! -x "${APP_BINARY}" ]; then
|
|
41
|
+
echo "[uc-go-peer-bootstrap] missing application binary: ${APP_BINARY}"
|
|
42
|
+
exit 1
|
|
43
|
+
fi
|
|
44
|
+
echo "[uc-go-peer-bootstrap] application binary already provisioned"
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
run_phase_finalize() {
|
|
48
|
+
echo "[uc-go-peer-bootstrap] phase=finalize"
|
|
49
|
+
echo "[uc-go-peer-bootstrap] creating runtime directories"
|
|
50
|
+
mkdir -p "${DATA_DIR}" "$(dirname "${ENV_FILE}")"
|
|
51
|
+
|
|
52
|
+
if ! id "${SERVICE_USER}" >/dev/null 2>&1; then
|
|
53
|
+
echo "[uc-go-peer-bootstrap] creating service user ${SERVICE_USER}"
|
|
54
|
+
useradd --system --home "${DATA_DIR}" --create-home --shell /usr/sbin/nologin "${SERVICE_USER}"
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
echo "[uc-go-peer-bootstrap] fixing ownership"
|
|
58
|
+
chown -R "${SERVICE_USER}:${SERVICE_USER}" "${DATA_DIR}" "${INSTALL_DIR}"
|
|
59
|
+
|
|
60
|
+
echo "[uc-go-peer-bootstrap] preparing environment file"
|
|
61
|
+
touch "${ENV_FILE}"
|
|
62
|
+
chmod 0640 "${ENV_FILE}"
|
|
63
|
+
chown "root:${SERVICE_USER}" "${ENV_FILE}"
|
|
64
|
+
rm -f "${READY_FILE}" "${AUTOTLS_READY_FILE}" "${AUTOTLS_ZONE_FILE}" "${AUTOTLS_HOSTS_FILE}" "${AUTOTLS_CADDY_READY_FILE}"
|
|
65
|
+
|
|
66
|
+
mkdir -p /etc/caddy /etc/systemd/system/caddy.service.d
|
|
67
|
+
cat > /etc/systemd/system/caddy.service.d/uc-go-peer.conf <<EOF
|
|
68
|
+
[Unit]
|
|
69
|
+
ConditionPathExists=${AUTOTLS_CADDY_READY_FILE}
|
|
70
|
+
EOF
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
write_env_var() {
|
|
74
|
+
local key="$1"
|
|
75
|
+
local value="$2"
|
|
76
|
+
|
|
77
|
+
if grep -Eq "^[#[:space:]]*${key}=" "${ENV_FILE}"; then
|
|
78
|
+
sed -i "s|^[#[:space:]]*${key}=.*|${key}=${value}|" "${ENV_FILE}"
|
|
79
|
+
else
|
|
80
|
+
printf '%s=%s\n' "${key}" "${value}" >> "${ENV_FILE}"
|
|
81
|
+
fi
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
seed_env() {
|
|
85
|
+
write_env_var "GO_PEER_DATA_DIR" "${DATA_DIR}"
|
|
86
|
+
write_env_var "GO_PEER_TCP_PORT" "9095"
|
|
87
|
+
write_env_var "GO_PEER_WS_PORT" "9096"
|
|
88
|
+
write_env_var "GO_PEER_WSS_PORT" "9097"
|
|
89
|
+
write_env_var "GO_PEER_IDENTITY_PATH" "${DATA_DIR}/identity.key"
|
|
90
|
+
write_env_var "GO_PEER_WS_BACKEND_PORT" "9096"
|
|
91
|
+
write_env_var "GO_PEER_AUTOTLS_CERT_DIR" "${DATA_DIR}/p2p-forge-certs"
|
|
92
|
+
write_env_var "LIBP2P_AUTO_PUBLIC_IP" "0"
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
case "${PHASE}" in
|
|
96
|
+
base)
|
|
97
|
+
run_phase_base
|
|
98
|
+
;;
|
|
99
|
+
build)
|
|
100
|
+
run_phase_build
|
|
101
|
+
;;
|
|
102
|
+
finalize)
|
|
103
|
+
run_phase_finalize
|
|
104
|
+
seed_env
|
|
105
|
+
;;
|
|
106
|
+
all)
|
|
107
|
+
run_phase_base
|
|
108
|
+
run_phase_build
|
|
109
|
+
run_phase_finalize
|
|
110
|
+
seed_env
|
|
111
|
+
;;
|
|
112
|
+
*)
|
|
113
|
+
echo "Unknown phase: ${PHASE}" >&2
|
|
114
|
+
exit 1
|
|
115
|
+
;;
|
|
116
|
+
esac
|
|
117
|
+
|
|
118
|
+
echo "[uc-go-peer-bootstrap] completed phase ${PHASE}"
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
ENV_FILE="${ENV_FILE:-/etc/default/uc-go-peer}"
|
|
5
|
+
READY_FILE="${READY_FILE:-/etc/default/uc-go-peer.ready}"
|
|
6
|
+
AUTOTLS_READY_FILE="${AUTOTLS_READY_FILE:-/etc/default/uc-go-peer.autotls-ready}"
|
|
7
|
+
AUTOTLS_ZONE_FILE="${AUTOTLS_ZONE_FILE:-/etc/default/uc-go-peer.autotls-zone}"
|
|
8
|
+
AUTOTLS_HOSTS_FILE="${AUTOTLS_HOSTS_FILE:-/etc/default/uc-go-peer.autotls-hosts}"
|
|
9
|
+
AUTOTLS_CADDY_READY_FILE="${AUTOTLS_CADDY_READY_FILE:-/etc/default/uc-go-peer.caddy-ready}"
|
|
10
|
+
SERVICE_NAME="${SERVICE_NAME:-uc-go-peer.service}"
|
|
11
|
+
AUTOTLS_REFRESH_SERVICE="${AUTOTLS_REFRESH_SERVICE:-uc-go-peer-autotls-refresh.service}"
|
|
12
|
+
CADDY_SERVICE="${CADDY_SERVICE:-caddy.service}"
|
|
13
|
+
CADDYFILE="${CADDYFILE:-/etc/caddy/Caddyfile}"
|
|
14
|
+
BOOTSTRAP_SERVICE="${BOOTSTRAP_SERVICE:-uc-go-peer-bootstrap.service}"
|
|
15
|
+
P2P_FORGE_DOMAIN="${P2P_FORGE_DOMAIN:-libp2p.direct}"
|
|
16
|
+
PUBLIC_IPV4=""
|
|
17
|
+
PUBLIC_IPV6=""
|
|
18
|
+
TCP_PORT="9095"
|
|
19
|
+
WS_PORT="9097"
|
|
20
|
+
WS_BACKEND_PORT="9096"
|
|
21
|
+
PROXY_HOSTNAME=""
|
|
22
|
+
UDP_PORT=""
|
|
23
|
+
START_SERVICE=1
|
|
24
|
+
|
|
25
|
+
usage() {
|
|
26
|
+
cat <<'EOF'
|
|
27
|
+
Usage:
|
|
28
|
+
uc-go-peer-configure.sh \
|
|
29
|
+
--public-ipv4 <ip> \
|
|
30
|
+
[--public-ipv6 <ipv6>] \
|
|
31
|
+
[--proxy-hostname <hostname>] \
|
|
32
|
+
[--tcp-port <host-port>] \
|
|
33
|
+
[--ws-port <host-port>] \
|
|
34
|
+
[--udp-port <host-port>] \
|
|
35
|
+
[--quic-port <host-port>] \
|
|
36
|
+
[--webtransport-port <host-port>] \
|
|
37
|
+
[--webrtc-port <host-port>] \
|
|
38
|
+
[--no-start]
|
|
39
|
+
EOF
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
write_env_var() {
|
|
43
|
+
local key="$1"
|
|
44
|
+
local value="$2"
|
|
45
|
+
|
|
46
|
+
if grep -Eq "^[#[:space:]]*${key}=" "${ENV_FILE}"; then
|
|
47
|
+
sed -i "s|^[#[:space:]]*${key}=.*|${key}=${value}|" "${ENV_FILE}"
|
|
48
|
+
else
|
|
49
|
+
printf '%s=%s\n' "${key}" "${value}" >> "${ENV_FILE}"
|
|
50
|
+
fi
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
render_proxy_caddyfile() {
|
|
54
|
+
local proxy_hostname="$1"
|
|
55
|
+
cat <<EOF
|
|
56
|
+
{
|
|
57
|
+
auto_https disable_redirects
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
https://${proxy_hostname} {
|
|
61
|
+
tls {
|
|
62
|
+
issuer acme {
|
|
63
|
+
disable_http_challenge
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
reverse_proxy http://127.0.0.1:${WS_BACKEND_PORT}
|
|
67
|
+
}
|
|
68
|
+
EOF
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
while [ "$#" -gt 0 ]; do
|
|
72
|
+
case "$1" in
|
|
73
|
+
--public-ipv4)
|
|
74
|
+
PUBLIC_IPV4="${2:-}"
|
|
75
|
+
shift 2
|
|
76
|
+
;;
|
|
77
|
+
--public-ipv6)
|
|
78
|
+
PUBLIC_IPV6="${2:-}"
|
|
79
|
+
shift 2
|
|
80
|
+
;;
|
|
81
|
+
--tcp-port)
|
|
82
|
+
TCP_PORT="${2:-}"
|
|
83
|
+
shift 2
|
|
84
|
+
;;
|
|
85
|
+
--ws-port)
|
|
86
|
+
WS_PORT="${2:-}"
|
|
87
|
+
shift 2
|
|
88
|
+
;;
|
|
89
|
+
--udp-port)
|
|
90
|
+
UDP_PORT="${2:-}"
|
|
91
|
+
shift 2
|
|
92
|
+
;;
|
|
93
|
+
--proxy-hostname)
|
|
94
|
+
PROXY_HOSTNAME="${2:-}"
|
|
95
|
+
shift 2
|
|
96
|
+
;;
|
|
97
|
+
--quic-port)
|
|
98
|
+
UDP_PORT="${2:-}"
|
|
99
|
+
shift 2
|
|
100
|
+
;;
|
|
101
|
+
--webtransport-port)
|
|
102
|
+
UDP_PORT="${2:-}"
|
|
103
|
+
shift 2
|
|
104
|
+
;;
|
|
105
|
+
--webrtc-port)
|
|
106
|
+
UDP_PORT="${2:-}"
|
|
107
|
+
shift 2
|
|
108
|
+
;;
|
|
109
|
+
--no-start)
|
|
110
|
+
START_SERVICE=0
|
|
111
|
+
shift
|
|
112
|
+
;;
|
|
113
|
+
-h|--help)
|
|
114
|
+
usage
|
|
115
|
+
exit 0
|
|
116
|
+
;;
|
|
117
|
+
*)
|
|
118
|
+
echo "Unknown argument: $1" >&2
|
|
119
|
+
usage >&2
|
|
120
|
+
exit 1
|
|
121
|
+
;;
|
|
122
|
+
esac
|
|
123
|
+
done
|
|
124
|
+
|
|
125
|
+
if [ -z "${PUBLIC_IPV4}" ]; then
|
|
126
|
+
usage >&2
|
|
127
|
+
exit 1
|
|
128
|
+
fi
|
|
129
|
+
|
|
130
|
+
touch "${ENV_FILE}"
|
|
131
|
+
rm -f "${AUTOTLS_READY_FILE}" "${AUTOTLS_ZONE_FILE}" "${AUTOTLS_HOSTS_FILE}" "${AUTOTLS_CADDY_READY_FILE}"
|
|
132
|
+
|
|
133
|
+
announce=(
|
|
134
|
+
"/ip4/${PUBLIC_IPV4}/tcp/${TCP_PORT}"
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
if [ -n "${WS_PORT}" ]; then
|
|
138
|
+
announce+=("/ip4/${PUBLIC_IPV4}/tcp/${WS_PORT}/tls/sni/*.${P2P_FORGE_DOMAIN}/ws")
|
|
139
|
+
fi
|
|
140
|
+
|
|
141
|
+
if [ -n "${UDP_PORT}" ]; then
|
|
142
|
+
announce+=(
|
|
143
|
+
"/ip4/${PUBLIC_IPV4}/udp/${UDP_PORT}/quic-v1"
|
|
144
|
+
"/ip4/${PUBLIC_IPV4}/udp/${UDP_PORT}/quic-v1/webtransport"
|
|
145
|
+
"/ip4/${PUBLIC_IPV4}/udp/${UDP_PORT}/webrtc-direct"
|
|
146
|
+
)
|
|
147
|
+
fi
|
|
148
|
+
|
|
149
|
+
if [ -n "${PUBLIC_IPV6}" ]; then
|
|
150
|
+
announce+=("/ip6/${PUBLIC_IPV6}/tcp/${TCP_PORT}")
|
|
151
|
+
if [ -n "${WS_PORT}" ]; then
|
|
152
|
+
announce+=("/ip6/${PUBLIC_IPV6}/tcp/${WS_PORT}/tls/sni/*.${P2P_FORGE_DOMAIN}/ws")
|
|
153
|
+
fi
|
|
154
|
+
if [ -n "${UDP_PORT}" ]; then
|
|
155
|
+
announce+=(
|
|
156
|
+
"/ip6/${PUBLIC_IPV6}/udp/${UDP_PORT}/quic-v1"
|
|
157
|
+
"/ip6/${PUBLIC_IPV6}/udp/${UDP_PORT}/quic-v1/webtransport"
|
|
158
|
+
"/ip6/${PUBLIC_IPV6}/udp/${UDP_PORT}/webrtc-direct"
|
|
159
|
+
)
|
|
160
|
+
fi
|
|
161
|
+
fi
|
|
162
|
+
|
|
163
|
+
announce_value="$(IFS=,; printf '%s' "${announce[*]}")"
|
|
164
|
+
write_env_var "PUBLIC_IPV4" "${PUBLIC_IPV4}"
|
|
165
|
+
if [ -n "${PUBLIC_IPV6}" ]; then
|
|
166
|
+
write_env_var "PUBLIC_IPV6" "${PUBLIC_IPV6}"
|
|
167
|
+
fi
|
|
168
|
+
write_env_var "EXTERNAL_RELAY_TCP_PORT" "${TCP_PORT}"
|
|
169
|
+
write_env_var "EXTERNAL_RELAY_WS_PORT" "${WS_PORT}"
|
|
170
|
+
write_env_var "GO_PEER_WSS_PORT" "${GO_PEER_WSS_PORT:-9097}"
|
|
171
|
+
if [ -n "${PROXY_HOSTNAME}" ]; then
|
|
172
|
+
write_env_var "PROXY_HOSTNAME" "${PROXY_HOSTNAME}"
|
|
173
|
+
mkdir -p "$(dirname "${CADDYFILE}")"
|
|
174
|
+
render_proxy_caddyfile "${PROXY_HOSTNAME}" > "${CADDYFILE}"
|
|
175
|
+
touch "${AUTOTLS_CADDY_READY_FILE}"
|
|
176
|
+
else
|
|
177
|
+
write_env_var "PROXY_HOSTNAME" ""
|
|
178
|
+
rm -f "${AUTOTLS_CADDY_READY_FILE}"
|
|
179
|
+
fi
|
|
180
|
+
if [ -n "${UDP_PORT}" ]; then
|
|
181
|
+
write_env_var "EXTERNAL_RELAY_UDP_PORT" "${UDP_PORT}"
|
|
182
|
+
write_env_var "EXTERNAL_RELAY_QUIC_PORT" "${UDP_PORT}"
|
|
183
|
+
write_env_var "EXTERNAL_RELAY_WEBTRANSPORT_PORT" "${UDP_PORT}"
|
|
184
|
+
write_env_var "EXTERNAL_RELAY_WEBRTC_PORT" "${UDP_PORT}"
|
|
185
|
+
fi
|
|
186
|
+
write_env_var "LIBP2P_ANNOUNCE_ADDRS" "${announce_value}"
|
|
187
|
+
touch "${READY_FILE}"
|
|
188
|
+
|
|
189
|
+
if [ "${START_SERVICE}" -eq 1 ]; then
|
|
190
|
+
systemctl daemon-reload
|
|
191
|
+
systemctl enable "${SERVICE_NAME}"
|
|
192
|
+
systemctl restart "${SERVICE_NAME}"
|
|
193
|
+
systemctl enable "${AUTOTLS_REFRESH_SERVICE}"
|
|
194
|
+
if [ -n "${PROXY_HOSTNAME}" ]; then
|
|
195
|
+
systemctl enable "${CADDY_SERVICE}"
|
|
196
|
+
systemctl restart "${CADDY_SERVICE}"
|
|
197
|
+
else
|
|
198
|
+
systemctl stop "${CADDY_SERVICE}" || true
|
|
199
|
+
fi
|
|
200
|
+
systemctl restart --no-block "${AUTOTLS_REFRESH_SERVICE}"
|
|
201
|
+
fi
|
|
202
|
+
|
|
203
|
+
printf 'Configured LIBP2P_ANNOUNCE_ADDRS=%s\n' "${announce_value}"
|
|
204
|
+
printf 'Ready file: %s\n' "${READY_FILE}"
|