New node form for Freifunk
Find a file
2022-09-01 14:47:24 +02:00
admin Implement custom logger to replace scribe.js. 2022-02-09 18:02:59 +01:00
app Updated bower dependencies for client. 2022-08-02 15:24:19 +02:00
assets First shot on a favicon. 2014-06-06 13:58:48 +02:00
bin Added some sanity checks to password hashing scripts. 2022-07-14 10:52:22 +02:00
doc First shot for the README 2016-07-19 14:07:35 +02:00
git-hooks Add pre-commit hook that runs all the checks. 2022-08-26 16:25:50 +02:00
nix yarn audit fix 2022-07-11 11:25:24 +02:00
server Fix: Avoid coordinates picked from map not validating. 2022-09-01 14:47:24 +02:00
shared/validation Fix: Avoid coordinates picked from map not validating. 2022-09-01 14:47:24 +02:00
.bowerrc Initial commit. 2014-05-12 20:08:19 +02:00
.editorconfig Fixed editor config. 2014-05-30 19:28:58 +02:00
.eslintrc.cjs Server: ESLint setup. 2022-08-23 19:18:02 +02:00
.gitattributes Initial commit. 2014-05-12 20:08:19 +02:00
.gitignore Quick and dirty typescript setup to get going. 2020-04-08 01:55:48 +02:00
.jshintrc Initial commit. 2014-05-12 20:08:19 +02:00
bower.json Updated bower dependencies for client. 2022-08-02 15:24:19 +02:00
client Open node in form and map. 2016-06-07 14:18:28 +02:00
config.json.example Allow having multiple users for admin login. 2022-07-07 13:10:57 +02:00
Gruntfile.js Remove unused build steps. 2022-07-21 13:08:49 +02:00
jest.server.config.js Update jest config to avoid deprecated settings. 2022-02-07 21:06:30 +01:00
LICENSE Updated LICENSE. 2022-02-09 18:16:59 +01:00
package.json Update server dependencies. 2022-08-30 15:12:58 +02:00
publish.sh Fix deployment: No more symlinks in dist. 2022-07-11 12:13:06 +02:00
README.md Added more explicit type for SMTP config and refactored transport initialization. 2022-07-28 14:45:28 +02:00
REFACTOR.md Removed already done TODO. 2022-07-28 11:28:15 +02:00
shell.nix Extracted some types to shared module. 2022-07-07 11:08:15 +02:00
yarn.lock Update server dependencies. 2022-08-30 15:12:58 +02:00

ffffng Freifunk Knotenverwaltung

Disclaimer

ACHTUNG: Die Knotenverwaltung legt aktuell die Daten zentral ab. Im Freifunk-Sinne ist eine dezentrale Datenhaltung auf den Knoten sinnvoller, daher führt diese Knotenverwaltung bitte nicht neu in Freifunk-Communities ein, in denen die Knotendaten bereits auf den Knoten hinterlegt sind.

Beschreibung / Motivation

Die Freifunk Knotenverwaltung ist in Hamburg ursprünglich entstanden (damals noch ffff), um eine Registrierung von fastd-Keys neuer Knoten zu ermöglichen. Dabei wurden auch die MAC-Adresse, der Knotenname und die GPS-Koordinaten erfasst. Die Idee war die Verwendung in der Knotenkarte. Da der Config-Mode von gluon keinen Internet-Zugang bietet, wurde die Erfassung der Koordinaten ausgelagert, um zunächst die Koordinaten in einem neuen Tab aus der Karte kopieren und später mit ffffng die Karte zur Positionierung direkt in die Knotenverwaltung einbetten zu können.

Zusätzlich werden Kontaktdaten erfasst (Pflichtfelder), um im Notfall die Knotenbetreiber erreichen zu können. Die Kontaktdaten sind nicht öffentlich einsehbar.

Mit der Version 0.9.0 sind die neue Monitoring-Funktion sowie das Admin-Panel hinzugekommen.

Features

  • Anlegen, Bearbeiten und Löschen von Knoten.
  • Auswahl der Koordinaten über eingebettete Karte.
  • Automatische Benachrichtigung, wenn ein Knoten zu lange offline ist.
  • Admin-Panel mit Statistiken, Suchfunktion, ...

Anti-Features

  • Zentrale Ablage der Daten auf einem Server statt auf den Knoten selber.
  • Migration der Daten zurück auf die Knoten oder in andere Systeme bisher nicht möglich. D. h. sobald einmal diese Knotenverwaltung verwendet wird, ist es nicht einfach möglich, diese wieder loszuwerden.
  • Angepasste Version des Karten-Backends für die Knotenkarte (meshviewer o.ä.) nötig.

Screenshots

Startseite der Knotenverwaltung

Formular zur Erfassung der Knotendaten

Option zum automatischen Versand von Monitoring-E-Mails

Bestätigungsseite nach dem Speichern

Statistiken im Admin-Panel

Knotenübersicht im Admin-Panel

Installation / Konfiguration

Vorbereitungen

Verzeichnisstruktur für die Installation anlegen (im Weiteren $FFFFNG_HOME). Z. B.:

mkdir -p $FFFFNG_HOME
mkdir -p $FFFFNG_HOME/fastdkeys
mkdir -p $FFFFNG_HOME/logs

Nicht vergessen: Berechtigungen anpassen für den User unter dem der Server läuft.

Installation

Abhängigkeiten installieren:

  • node.js + NPM
  • nginx o.ä. für SSL-Offloading und Proxy (hier nicht weiter beschrieben)

Danach die Knotenverwaltung via npm installieren:

cd $FFFFNG_HOME
npm install ffffng

Konfiguration

cp $FFFFNG_HOME/node_modules/ffffng/config.json.example $FFFFNG_HOME/config.json

Dann die config.json anpassen nach belieben. Es gibt die folgenden Konfigurations-Optionen:

  • server.baseUrl Basis-URL unter der die Knotenverwaltung erreichbar ist, z. B.: "https://formular.musterstadt.freifunk.net" oder "https://musterstadt.freifunk.net/formular"

  • server.port Port unter dem der Server lokal läuft, z. B.: 8080

  • server.databaseFile Pfad zur Datenbank-Datei, z. B.: "$FFFFNG_HOME/ffffng.sqlite"

  • server.peersPath Verzeichnis unter dem die fastd Key-Files angelegt werden, z. B.: "$FFFFNG_HOME/fastdkeys"

  • server.logging.enabled Ob geloggt werden soll (Achtung: false sorgt dafür, dass überhaupt kein Output mehr auf stdout oder in den Logs erscheint und überschreibt damit alle anderen Logging-Optionen!), z. B.: false

  • server.logging.debug Gibt an, ob Debug-Output geloggt werden soll (Achtung, viel!), z. B.: false

  • server.logging.profile Gibt an, ob Profiling-Output geloggt werden soll (Achtung, viel!), z. B.: false

  • server.internal.active Gibt an, ob interne URLs, wie Admin-Panel und Logging-Interface, erreichbar sein sollen, z. B.: true

  • server.internal.users Liste an Nutzer*innen im folgenden Format. Der Passwort-Hash kann mit dem Befehl mkpasswd -m bcrypt -R 10 oder dem beiliegenden Skript bin/mkpasswd.sh generiert werden.

{
    "server": {
        ...
        "internal": {
            ...
            "users": [
                {
                    "user": "username",
                    "passwordHash": "$2b$05$VPAg8XHOjhEXlY03SOe7huG1NE.UFvPLdukS0VMiolajdZjrdgj.W"
                }
            ]
            ...
        }
        ...
    }
    ...
}
  • server.email.from Absender für versendete E-Mails, z. B.: "Freifunk Knotenformular <no-reply@musterstadt.freifunk.net>"
  • server.email.smtp Konfiguration des SMTP-Servers für den E-Mail-Versand entsprechend der Dokumentation unter https://nodemailer.com/smtp/, z. B.:
{
    "server": {
        ...
        
        "email": {
            ...
            
            "smtp": {
                "host": "mail.example.com",
                "port": 465,
                "secure": true,
                "auth": {
                    "user": "user@example.com",
                    "pass": "pass"
                }
            }
        }
        
        ...
    }
    ...
}
  • server.map.nodesJsonUrl URL der nodes.json von hopglass (Format muss Version 2 sein), z. B.: ["http://musterstadt.freifunk.net/nodes.json"]

  • client.community.name Name der Freifunk-Community, z. B.: "Freifunk Musterstadt"

  • client.community.domain Domain der Freifunk-Community, z. B.: "musterstadt.freifunk.net"

  • client.community.contactEmail Kontakt-E-Mail-Adresse der Freifunk-Community, z. B.: "kontakt@musterstadt.freifunk.net"

  • client.community.sites Liste der gültige Site-Codes in der nodes.json, z. B.: ["ffms-site1", "ffms-site2"]

  • client.community.domains Liste der gültige Domänen-Codes in der nodes.json, z. B.: ["ffms-domain1", "ffms-domain2"]

  • client.legal.privacyUrl optional: URL zum Impressum, z. B.: "http://map.musterstadt.freifunk.net/impressum"

  • client.legal.imprintUrl optional: URL zur Datenschutzerklärung, z. B.: "http://map.musterstadt.freifunk.net/datenschutz"

  • client.map.mapUrl URL der Knotenkarte, z. B.: "http://map.musterstadt.freifunk.net"

  • client.monitoring.enabled Gibt an, ob die Nutzer*innen Monitoring für ihre Knoten aktivieren können sollen, z. B.: true

  • client.coordsSelector.lat Breitengrad auf den die Karte zur Auswahl der Koordinaten zentriert werden soll, z. B.: 53.565278

  • client.coordsSelector.lng Längengrad auf den die Karte zur Auswahl der Koordinaten zentriert werden soll, z. B.: 10.001389

  • client.coordsSelector.defaultZoom Default-Zoom-Level für die Karte, z. B.: 10

  • client.coordsSelector.layers Die Layers für die Karte. Hier können einer oder mehrere Tile-Provider eingetragen werden. Eine Übersicht über mögliche Kandidaten gibt es z. B. unter http://leaflet-extras.github.io/leaflet-providers/preview/index.html. Die Tile-Provider können dann z. B. wie folgt eingetragen werden (erlaubt ist alles, was von https://github.com/tombatossals/angular-leaflet-directive als Konfiguration für baseLayers verwendet werden kann):

{
    ...

    "client": {
        ...

        "coordsSelector": {
            ...

            "layers": {
                "example-provider": {
                    "name": "Beispiel Tile Server",
                    "url": "https:///tiles{s}.example.com/{z}/{x}/{y}.png",
                    "type": "xyz",
                    "layerOptions": {
                        "maxZoom": 18,
                        "subdomains": "1234",
                        "attribution": "&copy; Beispiel Tile Provider und OSM"
                    }
                },
                "another-provider": {
                    "name": "Noch ein Tile Server",
                    "url": "https://more-tiles-{s}.example.com/foo/{z}/{x}/{y}.png",
                    "type": "xyz",
                    "layerOptions": {
                        "maxZoom": 18,
                        "subdomains": "abcd",
                        "attribution": "Attribution goes here"
                    }
                }
                
                ...
            }
            
            ...
        }
        
        ...
    }
    
    ...
}
  • client.otherCommunityInfo.showInfo Gibt an, ob für Knoten außerhalb der Community-Grenzen ein Info-Dialog angezeigt werden soll, z. B.: true
  • client.otherCommunityInfo.showBorderForDebugging Gibt an, ob in der Karte die Community-Grenze (zum Debugging) angezeigt werden soll, z. B.: false
  • client.otherCommunityInfo.localCommunityPolygon Polygon für die Community-Grenze (Tipp: Koordinaten durch Klicken in der Karte bestimmen und kopieren), z. B.:
{
    ...
    "client": {
        ...
        "otherCommunityInfo": {
            ...
            "localCommunityPolygon": [{
                "lat": 53.63975308945899, "lng": 9.764785766601562
            }, {
                "lat": 53.578646152866504, "lng": 10.208358764648438
            }, {
                "lat": 53.49039461941655, "lng": 9.795341491699219
            }, {
                "lat": 53.60921067445695, "lng": 9.737663269042969
            }]
        }
    }
}

Starten des Servers

Je nach System ggf. z. B. ein Init-Skript oder eine systemd-Unit schreiben. Dabei sollte der Server vorzugsweise nicht als root laufen. Generell lässt sich der Server wie folgt starten:

$FFFFNG_HOME/node_modules/.bin/ffffng -c $FFFFNG_HOME/config.json

Der Server ist dann via HTTP unter dem in der config.json konfigurierten Port erreichbar. Für vhost-Konfiguration und HTTPs biete es sich an, nginx o.ä. als Proxy zu verwenden.

Synchronisierung der fastd-Keys

Die Synchronisierung und Verteilung der fastd-Keys auf die Gateways lässt sich z. B. via git und cron-Jobs realisieren. Details hierzu auf Anfrage.

Karten-Backend

Für die Verwendung von meshviewer o.ä. muss das jeweilige Kartenbackend angepasst werden, sodass die Knotendaten aus dem Formular zusätzlich zu denen aus alfred verwendet werden. Details hierzu auf Anfrage.

Administration

Das Admin-Panel ist dann entsprechend erreichbar unter: https://formular.musterstadt.freifunk.net/internal/admin. (Die Domain muss natürlich angepasst werden.)

Das Admin-Panel besteht aus folgenden Bereichen:

  • Dashboard / Statistics: Übersichtsseite.
  • Nodes: Liste aller in der Knotenverwaltung registrierten Knoten.
  • Monitoring: Liste aller aus der Karte bekannten Knoten inkl. Online- und Monitoring-Status.
  • Mail-Queue: Liste der als nächste zu versendenden E-Mails. E-Mails werden bis zu 5 mal versucht zu versenden. Sollte der Versand dann immer noch nicht geklappt haben, können sie hier gelöscht oder resettet werden (werden dann erneut versendet).
  • Background-Jobs: Übersicht über alle in der Knotenverwaltung laufenden Background-Jobs. Diese können dort bei Bedarf auch manuell gestartet, aktiviert und deaktiviert werden. ACHTUNG, das Deaktivieren von Jobs kann dazu führen, dass die Knotenverwaltung nicht mehr korrekt arbeitet. Die Jobs bleiben nur bis zum nächsten Neustart des Servers deaktiviert.
  • Logs: Verlinkung auf eine Übersicht der Knotenverwaltungs-Logs. Diese ist nicht wirklich stabil und kann bei großen Log-Dateien schnell den Browser überfordern.

gluon Config-Mode

Soll das Formular zum Anlegen neuer Knoten im gluon Config-Mode verlinkt werden, so bietet es sich an, die Übersetzungsdateien der Firmware unter i18n/ so ähnlich wie hier unten anzupassen:

msgid "gluon-config-mode:pubkey"
msgstr ""
...
"<a href=\"https://formular.musterstadt.freifunk.net/#/new?hostname=<%=hostname%>&key=<%=pubkey%>&mac=<%= sysconfig.primary_mac %>\" target=\"_blank\">https://formular.musterstadt.freifunk.net/</a> ein.</p>"
"<div class=\"the-key\">"
" # <%= hostname %>"
" <br/>"
"<%= pubkey %>"
...
"</div>"

Auf diese Weise landet der Nutzer*innen direkt im teilweise vorausgefüllten Formular und muss nicht mehr den Knotennamen, fastd-Key und die MAC-Adresse angeben.

Entwicklung

Abhängigkeiten

  • node.js + yarn
  • compass (Installation z. B. via Ruby's gem)
  • ggf. bower (Installation z. B. via yarn install bower)

Build

yarn run clean && yarn run build

Der Output landet dann unter dist/.

Server starten

  1. Zunächst eine config.json anlegen wie oben unter "Installation / Konfiguration" beschrieben.
  2. yarn run server:run -- -c config.json

Der Server ist dann erreichbar unter http://localhost:8080.

Life-Reload vom Client

yarn client:serve

Der Client ist dann erreichbar via http://localhost:9000, erwartet aber, dass der Server für die REST-API auch läuft (s. o.) und auf Port 8080 erreichbar ist.

Publishen auf npmjs.com

Geht nur, wenn man die Berechtigungen für das Package auf npmjs.com hat.

Zunächst sicherstellen, dass in der package.json die korrekte neue Versionsnummer eingetragen und committed ist, dann einfach ./publish.sh aufrufen.