mirror of
https://github.com/MeshCore-Beacon/beacon-server.git
synced 2026-10-16 22:30:43 +00:00
Imported boundaries override borderFile on the border map and for foreign marking, falling back to the manual border when MeshMapper has none.
251 lines
10 KiB
Plaintext
251 lines
10 KiB
Plaintext
# Beacon configuration file
|
|
# Copy to config.yaml and adjust as needed.
|
|
|
|
# Public reads stay available. No key means admin routes return 503.
|
|
# Prefer BEACON_API_KEY in the service environment; never commit a real key.
|
|
auth:
|
|
api_key: ""
|
|
|
|
log:
|
|
# Environment LOG_LEVEL / LOG_FORMAT override these values.
|
|
level: info # debug, info, warn, error
|
|
format: text # text or json
|
|
|
|
server:
|
|
# Only these direct proxy peers may set the client IP through X-Real-IP.
|
|
# The proxy must overwrite that header, not pass through client input.
|
|
# Leave empty for direct access (logs a startup warning). Invalid/empty CIDR
|
|
# entries prevent startup. A single host needs /32 for IPv4 or /128 for IPv6;
|
|
# bare IP addresses are not accepted.
|
|
# For Docker, list the actual proxy/compose network CIDR (e.g. 172.20.0.0/24).
|
|
# For a local host proxy, use ["127.0.0.1/32", "::1/128"].
|
|
# Direct-client proxy examples; X-Forwarded-For alone is not used:
|
|
# Apache 2.4.10+ (mod_headers, in the proxy virtual host):
|
|
# RequestHeader set X-Real-IP "expr=%{REMOTE_ADDR}"
|
|
# nginx (in the proxy location):
|
|
# proxy_set_header X-Real-IP $remote_addr;
|
|
# Caddy (inside the reverse_proxy block):
|
|
# header_up X-Real-IP {http.request.remote.host}
|
|
# With additional proxy hops, first configure their trust at the edge proxy
|
|
# and pass its validated client address rather than a client-supplied header.
|
|
trusted_proxies: []
|
|
|
|
# Applies to /api/v1/* only. Both counters are local to this Beacon instance.
|
|
# Set trusted_proxies correctly before using a reverse proxy, or clients share
|
|
# the proxy's budget. IPv6 clients share a /64 budget to prevent address rotation.
|
|
ratelimit:
|
|
enabled: true
|
|
requests_per_minute: 300
|
|
# Maximum requests in a one-second sliding window, not token-bucket capacity.
|
|
# Omitted/zero defaults to requests_per_minute. Negative limits prevent startup.
|
|
# A 429 returns error.code=rate_limited and Retry-After (1 or 60 seconds).
|
|
burst: 300
|
|
|
|
iatas:
|
|
YVR:
|
|
name: Vancouver International
|
|
lat: 49.1967
|
|
lng: -123.1815
|
|
# borderFile: borders/yvr.geojson # optional GeoJSON Feature (Polygon/MultiPolygon)
|
|
# # (meshmapper.zones overrides it when enabled)
|
|
# # for the region border map; path is relative to
|
|
# # this file's directory; validated at boot.
|
|
YYJ:
|
|
name: Victoria International
|
|
lat: 48.6469
|
|
lng: -123.4260
|
|
YYC:
|
|
name: Calgary International
|
|
lat: 51.1139
|
|
lng: -114.0200
|
|
YEG:
|
|
name: Edmonton International
|
|
lat: 53.3097
|
|
lng: -113.5797
|
|
YOW:
|
|
name: Ottawa International
|
|
lat: 45.3225
|
|
lng: -75.6692
|
|
YYZ:
|
|
name: Toronto Pearson
|
|
lat: 43.6777
|
|
lng: -79.6248
|
|
|
|
regions:
|
|
- slug: western-canada
|
|
name: Western Canada
|
|
display_order: 1
|
|
center_lat: 51.0
|
|
center_lng: -114.0
|
|
zoom_level: 5
|
|
iatas: [YVR, YYJ, YYC, YEG]
|
|
|
|
- slug: eastern-canada
|
|
name: Eastern Canada
|
|
display_order: 2
|
|
center_lat: 45.0
|
|
center_lng: -75.0
|
|
zoom_level: 5
|
|
iatas: [YOW, YYZ]
|
|
|
|
channel_keys:
|
|
# Hashtag channels: Beacon derives the PSK automatically from the tag name.
|
|
# secret = SHA256("#tag")[:16], channel_hash = SHA256(secret)[0]
|
|
# Hashtag names should be provided without the # prefix.
|
|
# Beacon prepends # automatically before deriving the key.
|
|
hashtags:
|
|
- meshcore
|
|
|
|
# Explicit keys: provide the channel hash (hex) and key (hex) directly.
|
|
# An optional name can be set for display purposes.
|
|
keys:
|
|
"11":
|
|
key: "8b3387e9c5cdea6ac9e5edbaa115cd72"
|
|
name: "Public"
|
|
|
|
# Regional transport scopes for matching TRANSPORT_FLOOD packets.
|
|
# Plain names have # prepended automatically (e.g. "bc" → "#bc").
|
|
scopes:
|
|
- name: bc
|
|
- name: "#west"
|
|
|
|
telemetry:
|
|
retention: 672h # 4 weeks
|
|
resolution: 1h # store one snapshot per observer per hour
|
|
|
|
# Optional authenticated database/config downloads. Disabled unless explicitly enabled.
|
|
# Requires auth.api_key, a supported PostgreSQL URL and a compatible pg_dump client.
|
|
# A failed prerequisite leaves this feature unavailable; ingest and other APIs continue.
|
|
#backup:
|
|
# enabled: false
|
|
|
|
# Also covers observations and channel messages.
|
|
packets:
|
|
retention: 168h # 7 days
|
|
|
|
# Known-route retention. Routes are distilled packet history (the path a packet
|
|
# took, hop by hop), so they may outlive packets.retention; there is no required
|
|
# relationship between the two.
|
|
routes:
|
|
# How long a route is kept after it was last observed. Every new observation
|
|
# of the same path resets this clock, so routes the mesh still uses never
|
|
# expire -- only paths nothing has traveled for this long age out.
|
|
retention: 336h # 14 days
|
|
# Shorter window for rarely-seen routes: one observed fewer than
|
|
# min_observations times in total is dropped once it goes unobserved for
|
|
# this long. Must be shorter than retention, or it never applies.
|
|
grace: 168h # 7 days
|
|
# Lifetime observation count a route must reach to earn the full retention
|
|
# window. Below it a route is treated as flood noise -- a path recorded once
|
|
# or twice and never confirmed -- and only kept for the grace window. The
|
|
# count never resets, so once a route crosses this bar it stays in the
|
|
# retention tier for good.
|
|
min_observations: 3
|
|
|
|
websocket:
|
|
max_connections_per_ip: 5 # default: 5
|
|
# Upgrade attempts, including failed handshakes; zero/omitted defaults to 10.
|
|
# IPv6 clients share a /64 attempt budget. Negative values prevent startup.
|
|
# Rate exhaustion rejects the handshake with 429 and Retry-After: 60.
|
|
# Within this rate budget, a full concurrent cap accepts then closes with 1013
|
|
# before hello, allowing browsers to back off without evicting existing clients.
|
|
max_connects_per_minute: 10
|
|
# Other sites allowed to open /ws. Exact scheme://host[:port], or
|
|
# scheme://*.domain[:port] for every subdomain of domain at any depth. The
|
|
# wildcard never matches the apex itself, and scheme and port stay exact.
|
|
#allowed_origins:
|
|
# - https://example.com
|
|
# - https://*.example.com
|
|
|
|
# Node staleness, deletion, and clock-drift thresholds.
|
|
#nodes:
|
|
# mark_foreign: false # opt in to possiblyForeign on repeater nodes
|
|
# # uses the union of configured iatas.*.borderFile polygons,
|
|
# # with meshmapper.zones boundaries replacing them; requires
|
|
# # a valid border file or meshmapper.zones; no packet filtering
|
|
# stale_threshold: 24h # default: 24h
|
|
# delete_after: 720h # default: 30 days
|
|
# clock_drift_threshold: 5m # default: 5m
|
|
|
|
# Optional observer age-out. Omitted or nonpositive leaves observers intact.
|
|
# Enable only with one Beacon ingest process for this database.
|
|
# At most 1000 old observers are deleted per background.cleanup interval;
|
|
# retained observations, telemetry and ownership records prevent deletion.
|
|
#observers:
|
|
# delete_after: 720h # opt in to 30 days unseen
|
|
|
|
# CORS configuration.
|
|
# Controls which origins, methods and headers are allowed for cross-origin requests.
|
|
# Defaults to allowing all origins with GET/HEAD/OPTIONS if omitted — appropriate
|
|
# for a public read-only API. Restrict allowed_origins if you expose write endpoints.
|
|
#cors:
|
|
# allowed_origins:
|
|
# - "https://app.example.com"
|
|
# allowed_methods: [GET, HEAD, OPTIONS, POST, PUT, DELETE] # admin UI writes
|
|
# allowed_headers: [Accept, Authorization, Content-Type]
|
|
# allow_credentials: false
|
|
# max_age: 300
|
|
|
|
# Redis caching layer.
|
|
# If REDIS_ADDR is not set, caching is disabled and all reads go directly to PostgreSQL.
|
|
# TTLs are specified as duration strings e.g. "30m", "1h", "2h".
|
|
# Per-category TTLs override the global ttl. Any category left unset inherits ttl.
|
|
cache:
|
|
# Global default TTL for all cached responses. Defaults to 1h if not set.
|
|
ttl: "1h"
|
|
ttls:
|
|
# Aggregated stats endpoints (overview, observations, breakdowns, top nodes/observers,
|
|
# radio presets, scope stats). Backed by materialized views refreshed hourly.
|
|
stats: "1h"
|
|
# Mostly-static reference data (IATAs, regions, scopes).
|
|
# Only changes when new observers arrive or config is reseeded.
|
|
reference: "1h"
|
|
# Individual node detail. Also explicitly invalidated on upsert.
|
|
nodes: "1h"
|
|
# Individual observer detail. Also explicitly invalidated on upsert.
|
|
observers: "1h"
|
|
|
|
# Geographic ingest filter (optional).
|
|
# Drop packets from observers outside the specified area at ingest time.
|
|
# Country codes are ISO 3166-1 alpha-2 (e.g. CA, US, GB).
|
|
# Continent codes: AF (Africa), AN (Antarctica), AS (Asia),
|
|
# EU (Europe), NA (North America), OC (Oceania), SA (South America).
|
|
# If both are set an IATA passes if it matches either (OR semantics).
|
|
# Omit this section entirely to accept packets from all IATAs (default).
|
|
#ingest:
|
|
# allow_countries: [CA, US]
|
|
# allow_continents: [NA]
|
|
|
|
# Optional public MeshMapper scope-name discovery. Manual scopes remain authoritative.
|
|
# No API key is needed. Sources must belong to a configured region's IATAs.
|
|
# Group endpoints are not supported: their names cannot be attributed to each IATA.
|
|
# At most 16 sources, 64 names per source, 64 KiB per response; no page scraping.
|
|
# Catalogues and ETags persist in PostgreSQL. Failed refreshes retain known names.
|
|
# Refresh success/failure/freshness is logged under component=meshmapper.scopes.
|
|
# Removing/turning off a source deactivates its imported matching keys on restart;
|
|
# historical scope identities and recorded evidence are retained.
|
|
#meshmapper:
|
|
# scopes:
|
|
# enabled: false
|
|
# refresh_interval: 1h # 5m-24h; one source checked per 15s tick
|
|
# sources:
|
|
# YOW: https://yow.meshmapper.net/get_scopes.php
|
|
#
|
|
# Optional MeshMapper region boundaries (Zones API). Every IATA in a configured
|
|
# region is looked up in its country's zone list, then its get_geojson.php outline
|
|
# is imported. An imported boundary overrides that IATA's borderFile on the border
|
|
# map and for nodes.mark_foreign. A missing or failed boundary keeps the last good
|
|
# import, or the borderFile when there is none. Disabling, or removing an IATA from
|
|
# every region, drops its import on restart. Logged under component=meshmapper.zones.
|
|
# zones:
|
|
# enabled: false
|
|
# refresh_interval: 24h # 1h-168h; one request per 15s tick, ETag-conditional
|
|
|
|
# Background task intervals.
|
|
# Shorter intervals are useful during initial deployment to confirm data is
|
|
# flowing. Back off to 1h or more once stable.
|
|
#background:
|
|
# view_refresh: 1h # default: 1h
|
|
# reconfirm: 1h # default: 1h
|
|
# cleanup: 1h # default: 1h
|